Redesign Scoped Access Tokens (#24767)

## Changes
- Adds the following high level access scopes, each with `read` and
`write` levels:
    - `activitypub`
    - `admin` (hidden if user is not a site admin)
    - `misc`
    - `notification`
    - `organization`
    - `package`
    - `issue`
    - `repository`
    - `user`
- Adds new middleware function `tokenRequiresScopes()` in addition to
`reqToken()`
  -  `tokenRequiresScopes()` is used for each high-level api section
- _if_ a scoped token is present, checks that the required scope is
included based on the section and HTTP method
  - `reqToken()` is used for individual routes
- checks that required authentication is present (but does not check
scope levels as this will already have been handled by
`tokenRequiresScopes()`
- Adds migration to convert old scoped access tokens to the new set of
scopes
- Updates the user interface for scope selection

### User interface example
<img width="903" alt="Screen Shot 2023-05-31 at 1 56 55 PM"
src="654766ec-2143-4f59-9037-3b51600e32f3">
<img width="917" alt="Screen Shot 2023-05-31 at 1 56 43 PM"
src="1ad64081-012c-4a73-b393-66b30352654c">

## tokenRequiresScopes  Design Decision
- `tokenRequiresScopes()` was added to more reliably cover api routes.
For an incoming request, this function uses the given scope category
(say `AccessTokenScopeCategoryOrganization`) and the HTTP method (say
`DELETE`) and verifies that any scoped tokens in use include
`delete:organization`.
- `reqToken()` is used to enforce auth for individual routes that
require it. If a scoped token is not present for a request,
`tokenRequiresScopes()` will not return an error

## TODO
- [x] Alphabetize scope categories
- [x] Change 'public repos only' to a radio button (private vs public).
Also expand this to organizations
- [X] Disable token creation if no scopes selected. Alternatively, show
warning
- [x] `reqToken()` is missing from many `POST/DELETE` routes in the api.
`tokenRequiresScopes()` only checks that a given token has the correct
scope, `reqToken()` must be used to check that a token (or some other
auth) is present.
   -  _This should be addressed in this PR_
- [x] The migration should be reviewed very carefully in order to
minimize access changes to existing user tokens.
   - _This should be addressed in this PR_
- [x] Link to api to swagger documentation, clarify what
read/write/delete levels correspond to
- [x] Review cases where more than one scope is needed as this directly
deviates from the api definition.
   - _This should be addressed in this PR_
   - For example: 
   ```go
	m.Group("/users/{username}/orgs", func() {
		m.Get("", reqToken(), org.ListUserOrgs)
		m.Get("/{org}/permissions", reqToken(), org.GetUserOrgsPermissions)
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser,
auth_model.AccessTokenScopeCategoryOrganization),
context_service.UserAssignmentAPI())
   ```

## Future improvements
- [ ] Add required scopes to swagger documentation
- [ ] Redesign `reqToken()` to be opt-out rather than opt-in
- [ ] Subdivide scopes like `repository`
- [ ] Once a token is created, if it has no scopes, we should display
text instead of an empty bullet point
- [ ] If the 'public repos only' option is selected, should read
categories be selected by default

Closes #24501
Closes #24799

Co-authored-by: Jonathan Tran <jon@allspice.io>
Co-authored-by: Kyle D <kdumontnu@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
This commit is contained in:
Jack Hay 2023-06-04 14:57:16 -04:00 committed by GitHub
parent 520eb57d76
commit 18de83b2a3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
102 changed files with 2183 additions and 1038 deletions

View file

@ -44,42 +44,43 @@ To use the Authorization Code Grant as a third party application it is required
## Scopes
Gitea supports the following scopes for tokens:
Gitea supports scoped access tokens, which allow users the ability to restrict tokens to operate only on selected url routes. Scopes are grouped by high-level API routes, and further refined to the following:
| Name | Description |
| ---- | ----------- |
| **(no scope)** | Grants read-only access to public user profile and public repositories. |
| **repo** | Full control over all repositories. |
| &nbsp;&nbsp;&nbsp; **repo:status** | Grants read/write access to commit status in all repositories. |
| &nbsp;&nbsp;&nbsp; **public_repo** | Grants read/write access to public repositories only. |
| **admin:repo_hook** | Grants access to repository hooks of all repositories. This is included in the `repo` scope. |
| &nbsp;&nbsp;&nbsp; **write:repo_hook** | Grants read/write access to repository hooks |
| &nbsp;&nbsp;&nbsp; **read:repo_hook** | Grants read-only access to repository hooks |
| **admin:org** | Grants full access to organization settings |
| &nbsp;&nbsp;&nbsp; **write:org** | Grants read/write access to organization settings |
| &nbsp;&nbsp;&nbsp; **read:org** | Grants read-only access to organization settings |
| **admin:public_key** | Grants full access for managing public keys |
| &nbsp;&nbsp;&nbsp; **write:public_key** | Grant read/write access to public keys |
| &nbsp;&nbsp;&nbsp; **read:public_key** | Grant read-only access to public keys |
| **admin:org_hook** | Grants full access to organizational-level hooks |
| **admin:user_hook** | Grants full access to user-level hooks |
| **notification** | Grants full access to notifications |
| **user** | Grants full access to user profile info |
| &nbsp;&nbsp;&nbsp; **read:user** | Grants read access to user's profile |
| &nbsp;&nbsp;&nbsp; **user:email** | Grants read access to user's email addresses |
| &nbsp;&nbsp;&nbsp; **user:follow** | Grants access to follow/un-follow a user |
| **delete_repo** | Grants access to delete repositories as an admin |
| **package** | Grants full access to hosted packages |
| &nbsp;&nbsp;&nbsp; **write:package** | Grants read/write access to packages |
| &nbsp;&nbsp;&nbsp; **read:package** | Grants read access to packages |
| &nbsp;&nbsp;&nbsp; **delete:package** | Grants delete access to packages |
| **admin:gpg_key** | Grants full access for managing GPG keys |
| &nbsp;&nbsp;&nbsp; **write:gpg_key** | Grants read/write access to GPG keys |
| &nbsp;&nbsp;&nbsp; **read:gpg_key** | Grants read-only access to GPG keys |
| **admin:application** | Grants full access to manage applications |
| &nbsp;&nbsp;&nbsp; **write:application** | Grants read/write access for managing applications |
| &nbsp;&nbsp;&nbsp; **read:application** | Grants read access for managing applications |
| **sudo** | Allows to perform actions as the site admin. |
- `read`: `GET` routes
- `write`: `POST`, `PUT`, `PATCH`, and `DELETE` routes (in addition to `GET`)
Gitea token scopes are as follows:
| Name | Description |
| ---- |--------------------------------------------------------------------------------------------------------------------------------------------------|
| **(no scope)** | Not supported. A scope is required even for public repositories. |
| **activitypub** | `activitypub` API routes: ActivityPub related operations. |
| &nbsp;&nbsp;&nbsp; **read:activitypub** | Grants read access for ActivityPub operations. |
| &nbsp;&nbsp;&nbsp; **write:activitypub** | Grants read/write/delete access for ActivityPub operations. |
| **admin** | `/admin/*` API routes: Site-wide administrative operations (hidden for non-admin accounts). |
| &nbsp;&nbsp;&nbsp; **read:admin** | Grants read access for admin operations, such as getting cron jobs or registered user emails. |
| &nbsp;&nbsp;&nbsp; **write:admin** | Grants read/write/delete access for admin operations, such as running cron jobs or updating user accounts. | |
| **issue** | `issues/*`, `labels/*`, `milestones/*` API routes: Issue-related operations. |
| &nbsp;&nbsp;&nbsp; **read:issue** | Grants read access for issues operations, such as getting issue comments, issue attachments, and milestones. |
| &nbsp;&nbsp;&nbsp; **write:issue** | Grants read/write/delete access for issues operations, such as posting or editing an issue comment or attachment, and updating milestones. |
| **misc** | miscellaneous and settings top-level API routes. |
| &nbsp;&nbsp;&nbsp; **read:misc** | Grants read access to miscellaneous operations, such as getting label and gitignore templates. |
| &nbsp;&nbsp;&nbsp; **write:misc** | Grants read/write/delete access to miscellaneous operations, such as markup utility operations. |
| **notification** | `notification/*` API routes: user notification operations. |
| &nbsp;&nbsp;&nbsp; **read:notification** | Grants read access to user notifications, such as which notifications users are subscribed to and read new notifications. |
| &nbsp;&nbsp;&nbsp; **write:notification** | Grants read/write/delete access to user notifications, such as marking notifications as read. |
| **organization** | `orgs/*` and `teams/*` API routes: Organization and team management operations. |
| &nbsp;&nbsp;&nbsp; **read:organization** | Grants read access to org and team status, such as listing all orgs a user has visibility to, teams, and team members. |
| &nbsp;&nbsp;&nbsp; **write:organization** | Grants read/write/delete access to org and team status, such as creating and updating teams and updating org settings. |
| **package** | `/packages/*` API routes: Packages operations |
| &nbsp;&nbsp;&nbsp; **read:package** | Grants read access to package operations, such as reading and downloading available packages. |
| &nbsp;&nbsp;&nbsp; **write:package** | Grants read/write/delete access to package operations. Currently the same as `read:package`. |
| **repository** | `/repos/*` API routes except `/repos/issues/*`: Repository file, pull-request, and release operations. |
| &nbsp;&nbsp;&nbsp; **read:repository** | Grants read access to repository operations, such as getting repository files, releases, collaborators. |
| &nbsp;&nbsp;&nbsp; **write:repository** | Grants read/write/delete access to repository operations, such as getting updating repository files, creating pull requests, updating collaborators. |
| **user** | `/user/*` and `/users/*` API routes: User-related operations. |
| &nbsp;&nbsp;&nbsp; **read:user** | Grants read access to user operations, such as getting user repo subscriptions and user settings. |
| &nbsp;&nbsp;&nbsp; **write:user** | Grants read/write/delete access to user operations, such as updating user repo subscriptions, followed users, and user settings. |
## Client types