Skip to content

Feat/mcdi auth - #83

Closed
ademboukabes wants to merge 12 commits into
developfrom
feat/mcdi-auth
Closed

ademboukabes wants to merge 12 commits into
developfrom
feat/mcdi-auth

Conversation

@ademboukabes

Copy link
Copy Markdown
Collaborator

Description

This PR migrates the authentication system of multAI from a custom email/password + OTP flow to the MicroClub Digital Identity (MCDI) OAuth Single Sign-On (SSO). MCDI is the centralized identity provider used across MicroClub services, and this integration allows multAI users to authenticate using their existing MCDI accounts instead of managing separate credentials.

Context

Previously, the backend handled authentication entirely on its own: users would register with an email and password, verify via a one-time password (OTP) sent by email, and then log in with their credentials. With this PR, the backend now supports authenticating through MCDI's OAuth2 flow, where the frontend redirects the user to MCDI's login page, receives an authorization code, and sends it to our backend to exchange it for a valid session.

Both the old method (email/password/OTP) and the new method (MCDI SSO) coexist in the codebase. The old method is kept intact because it is still used during development and testing, and may serve as a fallback for the mobile app in the future.

What was added

New service: McdiService (app/service/mcdi.py)

  • Handles the full OAuth2 code-to-token exchange with the MCDI authorization server.
  • Validates MCDI access tokens by fetching the user profile from the MCDI API.
  • Implements Redis-based caching for token validation responses to avoid exceeding the MCDI API rate limit of 60 requests per minute.
  • Provides a logout method that revokes the MCDI token on the identity provider side.

New endpoint: POST /mobile/auth/mcdi/exchange (app/router/mobile/auth.py)

  • Accepts an MCDI authorization code from the mobile app.
  • Exchanges it for an access token via McdiService.
  • Looks up or creates the corresponding user in our database (matched by Discord ID from the MCDI profile).
  • Returns a JWT session (access token + refresh token) just like the legacy login flow.
  • Logs an audit event for signup or login accordingly.

New endpoint: staff/web MCDI authentication (app/router/web/auth.py, app/deps/cookie_auth.py)

  • Cookie-based MCDI session for the staff/admin web panel.
  • CSRF state validation to prevent cross-site request forgery during the OAuth redirect flow.

Updated AuthService / UsersService (app/service/users.py)

  • Added the mcdi_exchange method that orchestrates the full flow: token exchange, profile fetch, user lookup/creation, and session creation.
  • The mcdi_service dependency is optional, so services that do not need MCDI (e.g., background workers) are not affected.
  • All legacy methods (mobile_login, mobile_register, mobile_register_resend_otp, verify_mobile_register) remain unchanged and fully functional.

Updated database layer (db/generated/user.py)

  • create_user now accepts optional parameters (e.g., discord_id) to support creating users from MCDI profiles where no password is provided.

What was NOT changed

  • The legacy authentication endpoints (/login, /register, /register/resend, /register/verify) are untouched. They work exactly as before.
  • The existing session management (JWT access/refresh tokens, device tracking, logout) is reused by the MCDI flow without modification.
  • No database migrations were required; the existing discord_id column on the users table is used for MCDI account linking.

Testing

  • Added 11 new unit tests in tests/unit/test_mcdi_auth.py covering:
    • Successful OAuth code exchange and token caching.
    • Token validation with cache hit and cache miss scenarios.
    • User creation for new MCDI users and account linking for existing users.
    • Error handling: revoked tokens, failed exchanges, MCDI API errors.
    • Staff/web session validation and CSRF protection.
  • All existing tests (integration, security, unit) continue to pass without modification.
  • Full test suite result: 197 passed, 28 skipped, 0 failed.

Configuration

The following environment variables must be set for MCDI to work (already present in .env.example):

Variable Description
MCDI_CLIENT_ID OAuth client ID registered on the MCDI platform
MCDI_CLIENT_SECRET OAuth client secret
MCDI_REDIRECT_URI The redirect URI configured in the MCDI app settings
MCDI_SERVER_ID The MicroClub server/organization ID

This PR targets the develop branch.

@ademboukabes
ademboukabes changed the base branch from main to develop October 7, 2026 00:19
v0 and others added 3 commits October 7, 2026 00:32
…ntend setup

Co-authored-by: adem boukabes <142881379+ademboukabes@users.noreply.github.com>
…ui-7696c83a

Build the senior multAI workspace interface
@vercel

vercel Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
multai-back Error Error Oct 7, 2026 12:40am UTC

This branch had an error being deployed

1 failed deployment
Preview — 5344fc90 Deployed Oct 7, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants