Skip to content

feat: support provider-specific OAuth whitelists#882

Merged
steveiliop56 merged 2 commits into
tinyauthapp:mainfrom
puneetdixit200:feature/622-provider-oauth-whitelist
May 24, 2026
Merged

feat: support provider-specific OAuth whitelists#882
steveiliop56 merged 2 commits into
tinyauthapp:mainfrom
puneetdixit200:feature/622-provider-oauth-whitelist

Conversation

@puneetdixit200
Copy link
Copy Markdown
Contributor

@puneetdixit200 puneetdixit200 commented May 20, 2026

Summary

  • Add per-provider OAuth whitelist and whitelist file config fields.
  • Use a provider-specific whitelist during OAuth callbacks and session validation when one is configured; otherwise keep the existing global OAuth whitelist behavior.
  • Document the new provider-level env vars in .env.example.

Closes #622

Validation

  • go test ./internal/service -run TestIsEmailWhitelistedUsesProviderSpecificList -count=1
  • go test ./internal/service ./internal/controller ./internal/model ./internal/utils ./internal/utils/decoders
  • go test ./... (with a temporary internal/assets/dist/index.html placeholder so the Go embed target exists in a fresh checkout; removed before commit)
  • git diff HEAD^ --check

AI assistance

OpenAI GPT-5 assisted with repository navigation, drafting the focused regression test, and summarizing validation. I reviewed the change and take responsibility for the submitted code.

Summary by CodeRabbit

  • New Features

    • Per-OAuth-provider email allowlists: configure provider-specific whitelists via TINYAUTH_OAUTH_PROVIDERS_WHITELIST and TINYAUTH_OAUTH_PROVIDERS_WHITELISTFILE. Provider-specific lists load from inline values or files and take precedence over the global whitelist when present.
    • OAuth session and callback flows now validate emails against the provider-specific allowlist.
  • Tests

    • Added unit test verifying provider-specific whitelist behavior and global fallback.

Review Change Stack

@dosubot dosubot Bot added the size:S This PR changes 10-29 lines, ignoring generated files. label May 20, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: abf94460-7f1e-4f1a-8e9d-25869314bd81

📥 Commits

Reviewing files that changed from the base of the PR and between a61870a and 3c9f434.

📒 Files selected for processing (2)
  • internal/controller/oauth_controller.go
  • internal/service/auth_service_test.go

📝 Walkthrough

Walkthrough

The PR enables per-provider OAuth email whitelisting by extending the configuration model with provider-specific allowlists, loading them during bootstrap, updating the auth service to accept and evaluate provider context, and integrating these changes into OAuth callback and session middleware paths.

Changes

Provider-specific OAuth whitelists

Layer / File(s) Summary
Config contract and environment variables
.env.example, internal/model/config.go
Environment template and OAuthServiceConfig now define per-provider Whitelist and WhitelistFile fields with YAML/env bindings.
Bootstrap provider whitelist loading
internal/bootstrap/app_bootstrap.go
Application setup loads each provider's whitelist from configuration or file using utils.GetStringList(), assigning the resolved list to the provider and failing fast on load errors.
Auth service provider-specific evaluation
internal/service/auth_service.go, internal/service/auth_service_test.go
IsEmailWhitelisted signature expanded to accept a provider; method selects provider-specific whitelist when available, otherwise falls back to the global whitelist; new unit test validates behavior.
OAuth callback and session middleware integration
internal/controller/oauth_controller.go, internal/middleware/context_middleware.go
OAuth callback handler and session cookie authentication updated to pass provider ID alongside email to IsEmailWhitelisted, enabling provider-scoped access control.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • tinyauthapp/tinyauth#826: Shares the utils.GetStringList() file-backed whitelist loading mechanism and config structure pattern; this PR extends that infrastructure to provider-specific contexts.

Suggested labels

size:M, lgtm

Suggested reviewers

  • steveiliop56
  • Rycochet

Poem

I nibble configs with delight, 🐇
Per-provider lists now keep things right,
Bootstrap chews files, tests hop along,
OAuth checks each provider's song,
A tiny rabbit, applauding strong.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main objective of the PR: adding provider-specific OAuth whitelist support, which is clear and specific.
Linked Issues check ✅ Passed The PR fully addresses issue #622 by implementing provider-specific OAuth whitelists, allowing different emails to be whitelisted per OAuth provider (GitHub vs PocketID).
Out of Scope Changes check ✅ Passed All changes are directly aligned with implementing provider-specific OAuth whitelists: config fields, bootstrap logic, controller/middleware updates, and supporting tests.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@puneetdixit200 puneetdixit200 force-pushed the feature/622-provider-oauth-whitelist branch from 4852cfd to a61870a Compare May 24, 2026 15:33
@puneetdixit200
Copy link
Copy Markdown
Contributor Author

Rebased this branch on current main (e532cde). No code changes beyond the rebase.

Verified locally:

  • go test ./internal/service -run TestIsEmailWhitelistedUsesProviderSpecificList -count=1
  • git diff --check upstream/main...HEAD

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
internal/service/auth_service_test.go (1)

19-34: ⚡ Quick win

Add one edge-case assertion for configured-but-empty provider whitelist.

This test covers unknown-provider fallback, but not a configured provider whose whitelist resolves to empty. Adding that case will lock the intended len(...) == 0 fallback behavior.

Proposed test extension
 		runtime: model.RuntimeConfig{
 			OAuthWhitelist: []string{"[email protected]"},
 			OAuthProviders: map[string]model.OAuthServiceConfig{
 				"github": {
 					Whitelist: []string{"[email protected]"},
 				},
 				"pocketid": {
 					Whitelist: []string{"[email protected]"},
 				},
+				"gitlab": {
+					Whitelist: []string{},
+				},
 			},
 		},
 	}

 	assert.True(t, auth.IsEmailWhitelisted("github", "[email protected]"))
 	assert.False(t, auth.IsEmailWhitelisted("github", "[email protected]"))
 	assert.True(t, auth.IsEmailWhitelisted("pocketid", "[email protected]"))
 	assert.True(t, auth.IsEmailWhitelisted("google", "[email protected]"))
+	assert.True(t, auth.IsEmailWhitelisted("gitlab", "[email protected]"))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/service/auth_service_test.go` around lines 19 - 34, Add a test case
for a configured provider whose Whitelist is present but empty: in the existing
OAuthProviders map (used by auth.IsEmailWhitelisted), add a provider key like
"emptyprov" with Whitelist: []string{} and then assert the function falls back
to the global whitelist behavior (e.g., assert.True(t,
auth.IsEmailWhitelisted("emptyprov", "[email protected]")) and assert.False for
an email not in global). This ensures the len(...) == 0 fallback path in
IsEmailWhitelisted is exercised.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/controller/oauth_controller.go`:
- Line 186: Change the whitelist check to use the session-bound provider
identity: first verify provider/session consistency (compare req.Provider with
the session service identity svc.ID() or return an error), and only after that
call controller.auth.IsEmailWhitelisted with svc.ID() (not req.Provider); update
the condition around the existing IsEmailWhitelisted call so whitelist
evaluation uses svc.ID() and occurs after the provider mismatch check.

---

Nitpick comments:
In `@internal/service/auth_service_test.go`:
- Around line 19-34: Add a test case for a configured provider whose Whitelist
is present but empty: in the existing OAuthProviders map (used by
auth.IsEmailWhitelisted), add a provider key like "emptyprov" with Whitelist:
[]string{} and then assert the function falls back to the global whitelist
behavior (e.g., assert.True(t, auth.IsEmailWhitelisted("emptyprov",
"[email protected]")) and assert.False for an email not in global). This
ensures the len(...) == 0 fallback path in IsEmailWhitelisted is exercised.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 44388392-b334-4569-9e45-432b77db26f1

📥 Commits

Reviewing files that changed from the base of the PR and between 4852cfd and a61870a.

📒 Files selected for processing (7)
  • .env.example
  • internal/bootstrap/app_bootstrap.go
  • internal/controller/oauth_controller.go
  • internal/middleware/context_middleware.go
  • internal/model/config.go
  • internal/service/auth_service.go
  • internal/service/auth_service_test.go

Comment thread internal/controller/oauth_controller.go Outdated
Verify the OAuth service identity from the pending session before evaluating provider-specific whitelists, and cover the configured-empty provider fallback path.

AI-assisted: Codex
@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. and removed size:S This PR changes 10-29 lines, ignoring generated files. labels May 24, 2026
@puneetdixit200
Copy link
Copy Markdown
Contributor Author

Addressed the review on the current head 3c9f434:

  • OAuth callback now verifies the session-bound service/provider match before whitelist enforcement.
  • Provider-specific whitelist enforcement now uses svc.ID() instead of the request parameter.
  • Added coverage for a configured provider with an empty whitelist falling back to the global whitelist.

Verification run locally:

GOMODCACHE=/private/tmp/tinyauth-882-gomod GOCACHE=/private/tmp/tinyauth-882-gocache go test ./internal/controller ./internal/service -count=1
GOMODCACHE=/private/tmp/tinyauth-882-gomod GOCACHE=/private/tmp/tinyauth-882-gocache go test ./internal/service -run TestIsEmailWhitelistedUsesProviderSpecificList -count=1
git diff --check

AI-assisted: Codex helped draft this small follow-up; I reviewed the diff and verification output.

Copy link
Copy Markdown
Member

@steveiliop56 steveiliop56 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, @Rycochet and @scottmckendry everything ok with you?

@dosubot dosubot Bot added the lgtm This PR has been approved by a maintainer label May 24, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented May 24, 2026

Codecov Report

❌ Patch coverage is 22.72727% with 17 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/controller/oauth_controller.go 0.00% 11 Missing ⚠️
internal/bootstrap/app_bootstrap.go 0.00% 4 Missing ⚠️
internal/middleware/context_middleware.go 0.00% 1 Missing ⚠️
internal/service/auth_service.go 83.33% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Member

@scottmckendry scottmckendry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@steveiliop56 steveiliop56 merged commit c346113 into tinyauthapp:main May 24, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm This PR has been approved by a maintainer size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] OAuth whitelist provider specific

3 participants