PESU Auth Implementation for PESU-MC - #13
Merged
Merged
Conversation
Thought mc_ready was global variable lol
dotpmm
requested review from
PrathamSGowda,
Thanas-R,
chitniskedar,
Copilot,
itsDivyaDSouza and
joshua-rajj
June 14, 2026 06:25
There was a problem hiding this comment.
Pull request overview
This PR adds a PESU authentication/verification flow to the Discord bot, splits MongoDB usage into separate “stats” and “auth” databases, and updates deployment config to better support Render-style environments.
Changes:
- Introduces
/verify,/deverify,/info, and/authcommands (PESUAuth-backed) plus shared auth config/error-embed utilities. - Adds separate MongoDB configuration for stats vs auth and gates Minecraft-related DB initialization/commands behind an
MC_READYflag. - Updates Docker/startup configuration (port 10000 /
$PORT) and addshttpxdependency.
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
uv.lock |
Locks new dependency set including httpx and its transitive deps. |
pyproject.toml |
Renames project/version and adds httpx dependency. |
.env.example |
Documents new env vars for dual MongoDB connections, guild scoping, and MC_READY. |
Dockerfile |
Updates exposed port and default Gunicorn concurrency env vars. |
start.sh |
Binds Gunicorn to $PORT (default 10000). |
stats/mongo.py |
Switches to STATS_* env vars and conditionally initializes stats DB when MC_READY is true. |
main.py |
Adds MC command gating via custom command tree, adds auth DB client wiring, loads auth extension, and syncs commands by guild when configured. |
auth/config.py |
Adds centralized role/channel/guild configuration and lookup helpers. |
auth/general.py |
Adds standardized “unknown error” embed builder. |
auth/verify.py |
Implements PESUAuth-backed verification + admin tooling and role assignment/removal logic. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
1
to
+9
| import os | ||
| from dotenv import load_dotenv | ||
|
|
||
| import asyncio | ||
| import discord | ||
| from discord.ext import commands, tasks | ||
| from discord import app_commands | ||
| import asyncio | ||
| from datetime import datetime, timezone | ||
|
|
||
| from pymongo import AsyncMongoClient |
Collaborator
Author
There was a problem hiding this comment.
gng, they serve different purpose 😭
Comment on lines
+50
to
+55
| # new async client for auth db, cuz 1 project db can only have 1 cluster under mongo free plan | ||
| mongo_uri = os.getenv("AUTH_MONGO_URI", os.getenv("MONGO_URI", "")) | ||
| auth_db_name = os.getenv("AUTH_DB_NAME", "xymic") | ||
| _mongo = AsyncMongoClient(mongo_uri, tz_aware=True) if mongo_uri else None | ||
| bot.link_collection = _mongo[auth_db_name]["link"] | ||
| bot.verify_enabled = True |
Collaborator
Author
There was a problem hiding this comment.
ahh, wont happen! so....
| Login acknowledgement and start timers for `check_server` | ||
| """ | ||
| await tree.sync() | ||
| await bot.load_extension("auth.verify") |
Comment on lines
+147
to
+166
| profile = data.get("profile", {}) | ||
| verified_srn = profile.get("srn", srn.strip().upper()) | ||
| raw_branch = profile.get("branch", "") | ||
| campus_api = profile.get("campus", "RR").strip().upper() | ||
| year = _year_from_srn(verified_srn) | ||
| branch_key = _normalise_branch(raw_branch) | ||
|
|
||
| if year: | ||
| grad_year = str(int(year) + 4) | ||
| display_year = f"Batch of {grad_year}" | ||
|
|
||
| display_campus = "RRC" if campus_api == "RR" else "ECC" if campus_api == "EC" else campus_api | ||
| # i like to call it RR'C' and EC'C' so ....had to do this drama ^^ | ||
| roles_to_add: list[discord.Role] = [] | ||
| skipped: list[str] = [] | ||
| for role_type, key, label in [ | ||
| ("YEAR", grad_year, f"Year ({display_year})"), | ||
| ("BRANCH", branch_key, f"Branch ({branch_key})"), | ||
| ("CAMPUS", campus_api, f"Campus ({display_campus})"), | ||
| ]: |
Comment on lines
+52
to
+57
| try: | ||
| async with httpx.AsyncClient(timeout=60) as http: | ||
| resp = await http.post(_PESUAUTH_URL, json=payload) | ||
| return resp.json() if resp.status_code == 200 else None | ||
| except (httpx.HTTPError, httpx.TimeoutException): | ||
| return None |
Comment on lines
+8
to
+10
| if TYPE_CHECKING: | ||
| from bot import DiscordBot | ||
|
|
Comment on lines
+1
to
+21
| from datetime import datetime | ||
|
|
||
| import discord | ||
|
|
||
|
|
||
| def build_unknown_error_embed(error: Exception) -> discord.Embed: | ||
| return ( | ||
| discord.Embed( | ||
| title="Unexpected Error", | ||
| description="Something went wrong while processing the command.", | ||
| color=discord.Color.red(), | ||
| timestamp=datetime.now(), | ||
| ) | ||
| .add_field(name="Error Type", value=type(error).__name__, inline=True) | ||
| .add_field( | ||
| name="Details", | ||
| value=str(error)[:1000] or "No details available.", | ||
| inline=False, | ||
| ) | ||
| .set_footer(text="Xymic") | ||
| ) |
Comment on lines
+5
to
+10
| GUILD_ID | ||
| STATS_MONGO_URI | ||
| STATS_DB_NAME | ||
| AUTH_MONGO_URI | ||
| AUTH_DB_NAME | ||
| MC_READY |
Collaborator
Author
|
Request to change the name of the repo from |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request introduces several configuration and structural changes to support multiple MongoDB databases, improve Discord bot command handling, and add new authentication utilities. The main updates include environment variable changes, Docker and startup script adjustments, new authentication configuration and error handling utilities, and improvements to how the bot manages Minecraft-related commands and database connections.
Environment and Configuration Updates:
.env.example: ReplacesMONGO_URIandMONGO_DBwith separate variables for stats and auth databases (STATS_MONGO_URI,STATS_DB_NAME,AUTH_MONGO_URI,AUTH_DB_NAME), addsGUILD_IDandMC_READYflags, and explains the need for two MongoDB connections due to free plan limitations.pyproject.toml: Updates project name and version, and addshttpxas a dependency.Docker and Startup Script Adjustments:
Dockerfile: Changes exposed port from 7860 to 10000 and reduces default Gunicorn concurrency settings to 1 worker and 1 thread each.start.sh: Updates Gunicorn to bind to port 10000 (or the value of$PORT) instead of 7860.Authentication and Error Handling Enhancements:
auth/config.py: Introduces aConfigclass to centrally manage Discord role and channel IDs, guild access, and role/channel lookup utilities, with robust error handling.auth/general.py: Adds a utility to build a standardized Discord embed for unknown errors, improving error reporting.Bot and Database Handling Improvements:
main.py:MinecraftCommandTreeto disable Minecraft commands when theMC_READYflag is false.auth.verifyextension and synchronizes commands to a specific guild ifGUILD_IDis set, otherwise syncs globally. [1] [2] [3]stats/mongo.py: Switches to usingSTATS_MONGO_URIandSTATS_DB_NAMEfor stats data, and only initializes the MongoDB client ifMC_READYis true, with improved error handling.These changes collectively improve maintainability, allow for better resource separation, and provide a more robust and configurable Discord bot deployment.
Tested locally and deployed it on render.com here with uptimerobot hook!