Support for Custom URI Schemes in OAuth2 Redirect URIs#37356
Support for Custom URI Schemes in OAuth2 Redirect URIs#37356wxiaoguang merged 5 commits intogo-gitea:mainfrom
Conversation
64c616d to
78f358f
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds support for OAuth2 application redirect URIs that use custom URI schemes (for native/mobile/desktop app integrations), controlled by a new CUSTOM_SCHEMES setting, and wires this validation into both the web UI and API endpoints.
Changes:
- Introduces
OAuth2.CustomSchemesconfiguration and documents it inapp.example.ini. - Replaces the previous redirect URI list validation with a new scheme-based validator shared by web UI and API.
- Updates Swagger responses and adjusts integration tests for the new behavior.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
services/forms/user_form.go |
Adds redirect-URI validation helper and custom-scheme support for the settings UI form. |
routers/api/v1/user/app.go |
Adds redirect-URI validation to create/update OAuth2 application API endpoints. |
modules/setting/oauth2.go |
Adds CustomSchemes to OAuth2 settings struct. |
custom/conf/app.example.ini |
Documents new CUSTOM_SCHEMES configuration option. |
modules/web/middleware/binding.go |
Adds ReportValidationError helper for form validation reporting. |
templates/swagger/v1_json.tmpl |
Adds 400 response to an OAuth2 application endpoint in Swagger JSON. |
tests/integration/user_settings_test.go |
Updates assertions and adds coverage for custom scheme acceptance in UI. |
modules/validation/binding.go / modules/validation/binding_test.go / modules/validation/validurllist_test.go |
Removes the ValidUrlList binding rule and its tests. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
f564d78 to
f5c3c5c
Compare
f5c3c5c to
8698b11
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 19 out of 19 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
tests/integration/oauth_test.go:512
- testRefreshTokenInvalidation mutates the global setting.OAuth2.InvalidateRefreshTokens but does not restore it. Since this file now runs many OAuth2 subtests under a single PrepareTestEnv, this can leak state into later subtests and make the suite order-dependent/flaky. Save the original value and defer restoring it (or use test.MockVariableValue) around these assignments.
// test without invalidation
setting.OAuth2.InvalidateRefreshTokens = false
req = NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{
"grant_type": "refresh_token",
"client_id": "da7da3ba-9a13-4167-856f-3899de0b0138",
// omit secret
"redirect_uri": "https://example.com",
"refresh_token": parsed.RefreshToken,
})
resp = MakeRequest(t, req, http.StatusBadRequest)
parsedError := new(oauth2_provider.AccessTokenError)
assert.NoError(t, json.Unmarshal(resp.Body.Bytes(), parsedError))
assert.Equal(t, "invalid_client", string(parsedError.ErrorCode))
assert.Equal(t, "invalid empty client secret", parsedError.ErrorDescription)
req = NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{
"grant_type": "refresh_token",
"client_id": "da7da3ba-9a13-4167-856f-3899de0b0138",
"client_secret": "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA=",
"redirect_uri": "https://example.com",
"refresh_token": "UNEXPECTED",
})
resp = MakeRequest(t, req, http.StatusBadRequest)
parsedError = new(oauth2_provider.AccessTokenError)
assert.NoError(t, json.Unmarshal(resp.Body.Bytes(), parsedError))
assert.Equal(t, "unauthorized_client", string(parsedError.ErrorCode))
assert.Equal(t, "unable to parse refresh token", parsedError.ErrorDescription)
req = NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{
"grant_type": "refresh_token",
"client_id": "da7da3ba-9a13-4167-856f-3899de0b0138",
"client_secret": "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA=",
"redirect_uri": "https://example.com",
"refresh_token": parsed.RefreshToken,
})
bs, err := io.ReadAll(req.Body)
assert.NoError(t, err)
req.Body = io.NopCloser(bytes.NewReader(bs))
MakeRequest(t, req, http.StatusOK)
req.Body = io.NopCloser(bytes.NewReader(bs))
MakeRequest(t, req, http.StatusOK)
// test with invalidation
setting.OAuth2.InvalidateRefreshTokens = true
req.Body = io.NopCloser(bytes.NewReader(bs))
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This comment was written with the help of Claude Opus 4.7 |
No need. No bad case
Site admin added it, they must like it. Just like they can run
What's wrong?
Totally useless. |
Although it is useless, in case some newbie would complain that "Oh, the URL I inputted is invalid", added the IsValidURL check in 787d61e |
* main: fix: commit status reporting (go-gitea#37372) Support for Custom URI Schemes in OAuth2 Redirect URIs (go-gitea#37356) Fix cmd tests by mocking builtin paths (go-gitea#37369) chore: upgrade Go version in devcontainer image to 1.26 (go-gitea#37374) Fix button layout shift when collapsing file tree in editor (go-gitea#37363) Update `Block a user` form (go-gitea#37359) Remove IsValidExternalURL/IsAPIURL and use IsValidURL at call sites (go-gitea#37364)
* origin/main: (32 commits) fix: commit status reporting (go-gitea#37372) Support for Custom URI Schemes in OAuth2 Redirect URIs (go-gitea#37356) Fix cmd tests by mocking builtin paths (go-gitea#37369) chore: upgrade Go version in devcontainer image to 1.26 (go-gitea#37374) Fix button layout shift when collapsing file tree in editor (go-gitea#37363) Update `Block a user` form (go-gitea#37359) Remove IsValidExternalURL/IsAPIURL and use IsValidURL at call sites (go-gitea#37364) Add URL to `Learn more about blocking a user` (go-gitea#37355) fix: use TriggerEvent instead of Event in workflow runs API response for scheduled runs (go-gitea#37288) Add event.schedule context for schedule actions task (go-gitea#37320) Fix typos (go-gitea#37346) Fix an issue where changing an organization’s visibility caused problems when users had forked its repositories. (go-gitea#37324) Fail vite build on rolldown warnings via NODE_ENV=test (go-gitea#37270) Use modern "git update-index --cacheinfo" syntax to support more file names (go-gitea#37338) Fix URL related escaping for oauth2 (go-gitea#37334) When the requested arch rpm is missing fall back to noarch (go-gitea#37236) Fix `relative-time` error and improve global error handler (go-gitea#37241) Enhance styling in actions page (go-gitea#37323) fix(oauth): Error on auth sources with spaces (go-gitea#37327) Fix actions concurrency groups cross-branch leak (go-gitea#37311) ... # Conflicts: # services/actions/commit_status.go
* origin/main: (204 commits) fix: commit status reporting (go-gitea#37372) Support for Custom URI Schemes in OAuth2 Redirect URIs (go-gitea#37356) Fix cmd tests by mocking builtin paths (go-gitea#37369) chore: upgrade Go version in devcontainer image to 1.26 (go-gitea#37374) Fix button layout shift when collapsing file tree in editor (go-gitea#37363) Update `Block a user` form (go-gitea#37359) Remove IsValidExternalURL/IsAPIURL and use IsValidURL at call sites (go-gitea#37364) Add URL to `Learn more about blocking a user` (go-gitea#37355) fix: use TriggerEvent instead of Event in workflow runs API response for scheduled runs (go-gitea#37288) Add event.schedule context for schedule actions task (go-gitea#37320) Fix typos (go-gitea#37346) Fix an issue where changing an organization’s visibility caused problems when users had forked its repositories. (go-gitea#37324) Fail vite build on rolldown warnings via NODE_ENV=test (go-gitea#37270) Use modern "git update-index --cacheinfo" syntax to support more file names (go-gitea#37338) Fix URL related escaping for oauth2 (go-gitea#37334) When the requested arch rpm is missing fall back to noarch (go-gitea#37236) Fix `relative-time` error and improve global error handler (go-gitea#37241) Enhance styling in actions page (go-gitea#37323) fix(oauth): Error on auth sources with spaces (go-gitea#37327) Fix actions concurrency groups cross-branch leak (go-gitea#37311) ... # Conflicts: # web_src/js/index-domready.ts # web_src/js/markup/content.ts # web_src/js/markup/refissue.ts
* origin/main: (204 commits) fix: commit status reporting (go-gitea#37372) Support for Custom URI Schemes in OAuth2 Redirect URIs (go-gitea#37356) Fix cmd tests by mocking builtin paths (go-gitea#37369) chore: upgrade Go version in devcontainer image to 1.26 (go-gitea#37374) Fix button layout shift when collapsing file tree in editor (go-gitea#37363) Update `Block a user` form (go-gitea#37359) Remove IsValidExternalURL/IsAPIURL and use IsValidURL at call sites (go-gitea#37364) Add URL to `Learn more about blocking a user` (go-gitea#37355) fix: use TriggerEvent instead of Event in workflow runs API response for scheduled runs (go-gitea#37288) Add event.schedule context for schedule actions task (go-gitea#37320) Fix typos (go-gitea#37346) Fix an issue where changing an organization’s visibility caused problems when users had forked its repositories. (go-gitea#37324) Fail vite build on rolldown warnings via NODE_ENV=test (go-gitea#37270) Use modern "git update-index --cacheinfo" syntax to support more file names (go-gitea#37338) Fix URL related escaping for oauth2 (go-gitea#37334) When the requested arch rpm is missing fall back to noarch (go-gitea#37236) Fix `relative-time` error and improve global error handler (go-gitea#37241) Enhance styling in actions page (go-gitea#37323) fix(oauth): Error on auth sources with spaces (go-gitea#37327) Fix actions concurrency groups cross-branch leak (go-gitea#37311) ... Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com> # Conflicts: # web_src/js/index-domready.ts # web_src/js/markup/content.ts # web_src/js/markup/refissue.ts
* origin/main: (127 commits) Refactor pull request view (1) (go-gitea#37380) Improve AGENTS.md (go-gitea#37382) Remove dead CSS (go-gitea#37376) Add pr-review e2e test and speed up e2e tests (go-gitea#37345) Drop Fomantic tab, checkbox and form patches (go-gitea#37377) fix: dump with default zip type produces uncompressed zip (go-gitea#37401) Allow fast-forward-only merge when signed commits are required (go-gitea#37335) Introduce `ActionRunAttempt` to represent each execution of a run (go-gitea#37119) Move review request functions to a standalone file (go-gitea#37358) Fix repo init README EOL (go-gitea#37388) Fix org team assignee/reviewer lookups for team member permissions (go-gitea#37365) Remove external service dependencies in migration tests (go-gitea#36866) Extend issue context popup beyond markdown content (go-gitea#36908) fix: commit status reporting (go-gitea#37372) Support for Custom URI Schemes in OAuth2 Redirect URIs (go-gitea#37356) Fix cmd tests by mocking builtin paths (go-gitea#37369) chore: upgrade Go version in devcontainer image to 1.26 (go-gitea#37374) Fix button layout shift when collapsing file tree in editor (go-gitea#37363) Update `Block a user` form (go-gitea#37359) Remove IsValidExternalURL/IsAPIURL and use IsValidURL at call sites (go-gitea#37364) ... # Conflicts: # modules/eventsource/event.go # tests/e2e/events.test.ts
* origin/main: (51 commits) Fix color regressions, add `priority` color (go-gitea#37417) [skip ci] Updated translations via Crowdin Stabilize e2e logout propagation test (go-gitea#37403) refactor: serve site manifest via `/assets/site-manifest.json` endpoint (go-gitea#37405) feat(security): set X-Content-Type-Options: nosniff by default (go-gitea#37354) Refactor pull request view (1) (go-gitea#37380) Improve AGENTS.md (go-gitea#37382) Remove dead CSS (go-gitea#37376) Add pr-review e2e test and speed up e2e tests (go-gitea#37345) Drop Fomantic tab, checkbox and form patches (go-gitea#37377) fix: dump with default zip type produces uncompressed zip (go-gitea#37401) Allow fast-forward-only merge when signed commits are required (go-gitea#37335) Introduce `ActionRunAttempt` to represent each execution of a run (go-gitea#37119) Move review request functions to a standalone file (go-gitea#37358) Fix repo init README EOL (go-gitea#37388) Fix org team assignee/reviewer lookups for team member permissions (go-gitea#37365) Remove external service dependencies in migration tests (go-gitea#36866) Extend issue context popup beyond markdown content (go-gitea#36908) fix: commit status reporting (go-gitea#37372) Support for Custom URI Schemes in OAuth2 Redirect URIs (go-gitea#37356) ...

Fix #34349
https://gitea.com/gitea/docs/pulls/387
Diff with ignoring spaces: https://github.com/go-gitea/gitea/pull/37356/changes?w=1
By the way, remove
(ctx *APIContext) HasAPIError()and(ctx *APIContext) GetErrMsg()because they do nothing, the error handling has been done in API's middewareThe existing OAuth2 tests were not quite right, refactored them together