Skip to content

Add Google OAuth login option and update documentation#89

Open
cycomachead wants to merge 1 commit into
mainfrom
cycomachead/ai/1/1
Open

Add Google OAuth login option and update documentation#89
cycomachead wants to merge 1 commit into
mainfrom
cycomachead/ai/1/1

Conversation

@cycomachead
Copy link
Copy Markdown

Add Google OAuth as a secondary login option

Adds Google OAuth as an optional sign-in alternative alongside Canvas. Google login only authenticates existing users matched by email — it never creates new accounts. When Google credentials are not configured, the login flow is unchanged.

Changes

Auth flow

  • New /login/canvas/ and /login/google/ routes; /login/ now shows a provider chooser when Google is enabled, otherwise falls back to Canvas directly
  • Google callback validates email verification, optional hosted-domain restrictions, and rejects unknown emails with a clear error message
  • On first successful Google sign-in, the stable Google subject ID (sub) is stored so subsequent logins aren't dependent on email matching alone

Model

  • Added nullable email and google_id columns to User; Canvas login now populates email on create/update

Configuration

  • GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, GOOGLE_HOSTED_DOMAINS env vars (all optional); added to config.py and .env.sample
  • Google OAuth provider is only registered when credentials are present

Templates

  • New login.html.j2 login chooser shown when Google is enabled

Docs

  • New docs/google-oauth.md with step-by-step Google Cloud Console setup (consent screen, OAuth client, redirect URIs, JS origins), env var reference, matching logic explanation, and troubleshooting table
  • README.md updated with an Authentication section linking to the doc

Tests

  • 8 new unit tests covering: login chooser rendering, Google redirect, successful callback, unknown email rejection, hosted-domain enforcement, and unverified email rejection

Superconductor Ticket Implementation | Guided Review

- Implement Google OAuth authentication as a secondary login provider
- Restrict Google login to existing users matched by email (no new user creation)
- Add configuration for Google Client ID, Secret, and Hosted Domain restrictions
- Update User model to store email and Google ID
- Add comprehensive documentation for Google Cloud setup and environment variables
- Add unit tests for Google login flow and domain validation

Co-authored-by: Claude Code <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

Coverage

Coverage for unit tests for Python 3.10
FileStmtsMissCoverMissing
server
   __init__.py50492%21–22, 67, 75
   cache.py6183%12
   forms.py1221588%23–25, 41–43, 68–70, 149–152, 159, 167
   models.py1693579%58, 62, 65, 68, 71, 74–79, 109, 112–121, 124, 127, 153, 165, 169, 173, 177–178, 184, 187, 207, 210, 231, 234, 248
   views.py69259115%35, 45–81, 91–125, 136–140, 157–166, 182–199, 210–217, 226–248, 259–272, 281, 292–295, 306–325, 338–362, 371–393, 402–429, 438–447, 456–498, 509–514, 522–526, 535–565, 574–604, 613–646, 655–685, 694–711, 718, 723–727, 736–782, 788–839, 845–855, 860–880, 885–910, 915–930, 935–954, 959–960, 965–978, 992, 997, 1005–1006
server/controllers
   __init__.py824644%26–44, 47–49, 60–87, 90, 101–110, 113
   auth_controllers.py1083667%24, 37–39, 44–75, 90, 95–96, 132–133, 143–144, 172–174
   dev_login_controllers.py342332%11–25, 30–39, 44–56
   health_controllers.py20765%17–18, 23–27
server/services/auth
   __init__.py391172%22, 51, 60–76, 80, 85–86, 91–92
server/services/canvas
   __init__.py806124%18–25, 29, 33, 37, 43, 55–64, 69–105, 109–124, 128
   fake_canvas.py392633%9, 12, 15, 20–25, 28–29, 37–46, 49–56
server/services/core
   assign.py65395%25, 28, 92
   data.py543731%12–17, 21–25, 29–33, 37–39, 43–54, 58, 69–71, 75–76, 80–81, 85–86
   export.py272219%11–44
   room.py61568%11–33, 41–89
   student.py116596%29, 33–34, 43, 150
server/services/csv
   __init__.py201335%11–12, 19, 26–29, 36–41
server/services/email
   __init__.py413124%19–36, 40–72
   smtp.py923166%18, 29–31, 33–35, 49–51, 68–76, 88–89, 101–108, 112–114, 125–126
server/services/email/templates
   __init__.py33197%20
server/services/google
   __init__.py542946%23, 31, 33, 41–44, 48–54, 58–77
server/typings
   exception.py34682%42, 53, 59–60, 69, 72
server/utils
   date.py7186%30
   misc.py161319%5–9, 13–19, 23
TOTAL2100110447% 

Tests Skipped Failures Errors Time
74 0 💤 0 ❌ 0 🔥 10.938s ⏱️

@github-actions
Copy link
Copy Markdown

Coverage

Coverage for unit tests for Python 3.11
FileStmtsMissCoverMissing
server
   __init__.py50492%21–22, 67, 75
   cache.py6183%12
   forms.py1221588%23–25, 41–43, 68–70, 149–152, 159, 167
   models.py1693579%58, 62, 65, 68, 71, 74–79, 109, 112–121, 124, 127, 153, 165, 169, 173, 177–178, 184, 187, 207, 210, 231, 234, 248
   views.py69259115%35, 45–81, 91–125, 136–140, 157–166, 182–199, 210–217, 226–248, 259–272, 281, 292–295, 306–325, 338–362, 371–393, 402–429, 438–447, 456–498, 509–514, 522–526, 535–565, 574–604, 613–646, 655–685, 694–711, 718, 723–727, 736–782, 788–839, 845–855, 860–880, 885–910, 915–930, 935–954, 959–960, 965–978, 992, 997, 1005–1006
server/controllers
   __init__.py824644%26–44, 47–49, 60–87, 90, 101–110, 113
   auth_controllers.py1083667%24, 37–39, 44–75, 90, 95–96, 132–133, 143–144, 172–174
   dev_login_controllers.py342332%11–25, 30–39, 44–56
   health_controllers.py20765%17–18, 23–27
server/services/auth
   __init__.py391172%22, 51, 60–76, 80, 85–86, 91–92
server/services/canvas
   __init__.py806124%18–25, 29, 33, 37, 43, 55–64, 69–105, 109–124, 128
   fake_canvas.py392633%9, 12, 15, 20–25, 28–29, 37–46, 49–56
server/services/core
   assign.py65395%25, 28, 92
   data.py543731%12–17, 21–25, 29–33, 37–39, 43–54, 58, 69–71, 75–76, 80–81, 85–86
   export.py272219%11–44
   room.py61568%11–33, 41–89
   student.py116596%29, 33–34, 43, 150
server/services/csv
   __init__.py201335%11–12, 19, 26–29, 36–41
server/services/email
   __init__.py413124%19–36, 40–72
   smtp.py923166%18, 29–31, 33–35, 49–51, 68–76, 88–89, 101–108, 112–114, 125–126
server/services/email/templates
   __init__.py33197%20
server/services/google
   __init__.py542946%23, 31, 33, 41–44, 48–54, 58–77
server/typings
   exception.py34682%42, 53, 59–60, 69, 72
server/utils
   date.py7186%30
   misc.py161319%5–9, 13–19, 23
TOTAL2100110447% 

Tests Skipped Failures Errors Time
74 0 💤 0 ❌ 0 🔥 10.029s ⏱️

@codecov
Copy link
Copy Markdown

codecov Bot commented May 11, 2026

Codecov Report

❌ Patch coverage is 78.82353% with 18 lines in your changes missing coverage. Please review.
✅ Project coverage is 47.42%. Comparing base (4b805f6) to head (16ae9e2).

Files with missing lines Patch % Lines
server/controllers/auth_controllers.py 82.19% 13 Missing ⚠️
server/services/auth/__init__.py 50.00% 5 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #89      +/-   ##
==========================================
+ Coverage   46.08%   47.42%   +1.34%     
==========================================
  Files          28       28              
  Lines        2018     2100      +82     
==========================================
+ Hits          930      996      +66     
- Misses       1088     1104      +16     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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.

1 participant