You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gitea/services
Marcell Mars a3881ffa3d
Enhancing Gitea OAuth2 Provider with Granular Scopes for Resource Access (#32573)
Resolve #31609

This PR was initiated following my personal research to find the
lightest possible Single Sign-On solution for self-hosted setups. The
existing solutions often seemed too enterprise-oriented, involving many
moving parts and services, demanding significant resources while
promising planetary-scale capabilities. Others were adequate in
supporting basic OAuth2 flows but lacked proper user management
features, such as a change password UI.

Gitea hits the sweet spot for me, provided it supports more granular
access permissions for resources under users who accept the OAuth2
application.

This PR aims to introduce granularity in handling user resources as
nonintrusively and simply as possible. It allows third parties to inform
users about their intent to not ask for the full access and instead
request a specific, reduced scope. If the provided scopes are **only**
the typical ones for OIDC/OAuth2—`openid`, `profile`, `email`, and
`groups`—everything remains unchanged (currently full access to user's
resources). Additionally, this PR supports processing scopes already
introduced with [personal
tokens](https://docs.gitea.com/development/oauth2-provider#scopes) (e.g.
`read:user`, `write:issue`, `read:group`, `write:repository`...)

Personal tokens define scopes around specific resources: user info,
repositories, issues, packages, organizations, notifications,
miscellaneous, admin, and activitypub, with access delineated by read
and/or write permissions.

The initial case I wanted to address was to have Gitea act as an OAuth2
Identity Provider. To achieve that, with this PR, I would only add
`openid public-only` to provide access token to the third party to
authenticate the Gitea's user but no further access to the API and users
resources.

Another example: if a third party wanted to interact solely with Issues,
it would need to add `read:user` (for authorization) and
`read:issue`/`write:issue` to manage Issues.

My approach is based on my understanding of how scopes can be utilized,
supported by examples like [Sample Use Cases: Scopes and
Claims](https://auth0.com/docs/get-started/apis/scopes/sample-use-cases-scopes-and-claims)
on auth0.com.

I renamed `CheckOAuthAccessToken` to `GetOAuthAccessTokenScopeAndUserID`
so now it returns AccessTokenScope and user's ID. In the case of
additional scopes in `userIDFromToken` the default `all` would be
reduced to whatever was asked via those scopes. The main difference is
the opportunity to reduce the permissions from `all`, as is currently
the case, to what is provided by the additional scopes described above.

Screenshots:

![Screenshot_20241121_121405](https://github.com/user-attachments/assets/29deaed7-4333-4b02-8898-b822e6f2463e)

![Screenshot_20241121_120211](https://github.com/user-attachments/assets/7a4a4ef7-409c-4116-9d5f-2fe00eb37167)

![Screenshot_20241121_120119](https://github.com/user-attachments/assets/aa52c1a2-212d-4e64-bcdf-7122cee49eb6)

![Screenshot_20241121_120018](https://github.com/user-attachments/assets/9eac318c-e381-4ea9-9e2c-3a3f60319e47)
---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
3 months ago
..
actions allow the actions user to login via the jwt token (#32527) 3 months ago
agit Add reviewers selection to new pull request (#32403) 3 months ago
asymkey Fix some pending problems (#29985) 11 months ago
attachment Include file extension checks in attachment API (#32151) 3 months ago
auth Enhancing Gitea OAuth2 Provider with Granular Scopes for Resource Access (#32573) 3 months ago
automerge Add new event commit status creation and webhook implementation (#27151) 3 months ago
context Remove unnecessary code (#32560) 3 months ago
contexttest Check if reverse proxy is correctly configured (#30890) 9 months ago
convert Fix milestone deadline and date related problems (#32339) 3 months ago
cron Support repo license (#24872) 4 months ago
doctor Add a doctor check to disable the "Actions" unit for mirrors (#32424) 3 months ago
externalaccount allow synchronizing user status from OAuth2 login providers (#31572) 7 months ago
feed Move AddCollabrator and CreateRepositoryByExample to service layer (#32419) 3 months ago
forms Refactor push mirror find and add check for updating push mirror (#32539) 3 months ago
gitdiff Reduce integration test overhead (#32475) 3 months ago
indexer Update issue indexer after merging a PR (#30715) 9 months ago
issue Add reviewers selection to new pull request (#32403) 3 months ago
lfs Fix LFS route mock, realm, middleware names (#32488) 3 months ago
mailer Add reviewers selection to new pull request (#32403) 3 months ago
markup Enable more `revive` linter rules (#30608) 10 months ago
migrations Support migrating GitHub/GitLab PR draft status (#32242) 4 months ago
mirror Refactor push mirror find and add check for updating push mirror (#32539) 3 months ago
notify Add new event commit status creation and webhook implementation (#27151) 3 months ago
oauth2_provider Enhancing Gitea OAuth2 Provider with Granular Scopes for Resource Access (#32573) 3 months ago
org Update misspell to 0.5.1 and add `misspellings.csv` (#30573) 10 months ago
packages Fix `missing signature key` error when pulling Docker images with `SERVE_DIRECT` enabled (#32365) 3 months ago
projects Add issue comment when moving issues from one column to another of the project (#29311) 6 months ago
pull Add reviewers selection to new pull request (#32403) 3 months ago
release Trim title before insert/update to database to match the size requirements of database (#32498) 3 months ago
repository disable gravatar in test (#32529) 3 months ago
secrets Refactor deletion (#28610) 1 year ago
task Fix "force private" logic (#31012) 9 months ago
uinotification Penultimate round of `db.DefaultContext` refactor (#27414) 1 year ago
user Add warn log when deleting inactive users (#32318) 4 months ago
webhook Only provide the commit summary for Discord webhook push events (#32432) 3 months ago
webtheme Initial support for colorblindness-friendly themes (#30625) 10 months ago
wiki Use global lock instead of NewExclusivePool to allow distributed lock between multiple Gitea instances (#31813) 5 months ago