summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChongyi Zheng <harryzheng25@gmail.com>2023-01-17 16:46:03 -0500
committerGitHub <noreply@github.com>2023-01-17 15:46:03 -0600
commitde484e86bc495a67d2f122ed438178d587a92526 (patch)
tree82ebe623a517a31006699a21613c0307020417b0
parentdb2286bbb69f5453f5b184a16a9dca999f3f3eb8 (diff)
downloadgitea-de484e86bc495a67d2f122ed438178d587a92526.tar.gz
gitea-de484e86bc495a67d2f122ed438178d587a92526.zip
Support scoped access tokens (#20908)
This PR adds the support for scopes of access tokens, mimicking the design of GitHub OAuth scopes. The changes of the core logic are in `models/auth` that `AccessToken` struct will have a `Scope` field. The normalized (no duplication of scope), comma-separated scope string will be stored in `access_token` table in the database. In `services/auth`, the scope will be stored in context, which will be used by `reqToken` middleware in API calls. Only OAuth2 tokens will have granular token scopes, while others like BasicAuth will default to scope `all`. A large amount of work happens in `routers/api/v1/api.go` and the corresponding `tests/integration` tests, that is adding necessary scopes to each of the API calls as they fit. - [x] Add `Scope` field to `AccessToken` - [x] Add access control to all API endpoints - [x] Update frontend & backend for when creating tokens - [x] Add a database migration for `scope` column (enable 'all' access to past tokens) I'm aiming to complete it before Gitea 1.19 release. Fixes #4300
-rw-r--r--docs/content/doc/developers/oauth2-provider.en-us.md36
-rw-r--r--models/auth/token.go1
-rw-r--r--models/auth/token_scope.go251
-rw-r--r--models/auth/token_scope_test.go84
-rw-r--r--models/migrations/migrations.go2
-rw-r--r--models/migrations/v1_19/v239.go22
-rw-r--r--options/locale/locale_en-US.ini1
-rw-r--r--routers/api/v1/api.go422
-rw-r--r--routers/web/user/setting/applications.go10
-rw-r--r--services/auth/oauth2.go4
-rw-r--r--services/forms/user_form.go10
-rw-r--r--services/forms/user_form_test.go27
-rw-r--r--templates/user/settings/applications.tmpl201
-rw-r--r--tests/integration/api_admin_org_test.go5
-rw-r--r--tests/integration/api_admin_test.go21
-rw-r--r--tests/integration/api_branch_test.go17
-rw-r--r--tests/integration/api_comment_attachment_test.go7
-rw-r--r--tests/integration/api_comment_test.go14
-rw-r--r--tests/integration/api_gpg_keys_test.go14
-rw-r--r--tests/integration/api_helper_for_declarative_test.go5
-rw-r--r--tests/integration/api_httpsig_test.go3
-rw-r--r--tests/integration/api_issue_attachment_test.go7
-rw-r--r--tests/integration/api_issue_label_test.go9
-rw-r--r--tests/integration/api_issue_milestone_test.go3
-rw-r--r--tests/integration/api_issue_reaction_test.go5
-rw-r--r--tests/integration/api_issue_stopwatch_test.go9
-rw-r--r--tests/integration/api_issue_subscription_test.go3
-rw-r--r--tests/integration/api_issue_test.go7
-rw-r--r--tests/integration/api_issue_tracked_time_test.go7
-rw-r--r--tests/integration/api_keys_test.go9
-rw-r--r--tests/integration/api_notification_test.go5
-rw-r--r--tests/integration/api_oauth2_apps_test.go26
-rw-r--r--tests/integration/api_org_test.go28
-rw-r--r--tests/integration/api_packages_container_test.go5
-rw-r--r--tests/integration/api_packages_test.go24
-rw-r--r--tests/integration/api_pull_review_test.go7
-rw-r--r--tests/integration/api_pull_test.go13
-rw-r--r--tests/integration/api_releases_test.go11
-rw-r--r--tests/integration/api_repo_archive_test.go3
-rw-r--r--tests/integration/api_repo_collaborator_test.go9
-rw-r--r--tests/integration/api_repo_edit_test.go5
-rw-r--r--tests/integration/api_repo_file_create_test.go7
-rw-r--r--tests/integration/api_repo_file_delete_test.go5
-rw-r--r--tests/integration/api_repo_file_get_test.go3
-rw-r--r--tests/integration/api_repo_file_update_test.go5
-rw-r--r--tests/integration/api_repo_git_hook_test.go19
-rw-r--r--tests/integration/api_repo_git_tags_test.go3
-rw-r--r--tests/integration/api_repo_hook_test.go3
-rw-r--r--tests/integration/api_repo_lfs_migrate_test.go3
-rw-r--r--tests/integration/api_repo_lfs_test.go3
-rw-r--r--tests/integration/api_repo_raw_test.go3
-rw-r--r--tests/integration/api_repo_tags_test.go3
-rw-r--r--tests/integration/api_repo_teams_test.go5
-rw-r--r--tests/integration/api_repo_test.go50
-rw-r--r--tests/integration/api_repo_topic_test.go5
-rw-r--r--tests/integration/api_team_test.go15
-rw-r--r--tests/integration/api_team_user_test.go3
-rw-r--r--tests/integration/api_user_email_test.go7
-rw-r--r--tests/integration/api_user_follow_test.go3
-rw-r--r--tests/integration/api_user_org_perm_test.go7
-rw-r--r--tests/integration/api_user_orgs_test.go16
-rw-r--r--tests/integration/api_user_star_test.go12
-rw-r--r--tests/integration/api_user_watch_test.go12
-rw-r--r--tests/integration/api_wiki_test.go5
-rw-r--r--tests/integration/dump_restore_test.go3
-rw-r--r--tests/integration/eventsource_test.go3
-rw-r--r--tests/integration/git_test.go9
-rw-r--r--tests/integration/gpg_git_test.go25
-rw-r--r--tests/integration/integration_test.go26
-rw-r--r--tests/integration/migrate_test.go3
-rw-r--r--tests/integration/org_count_test.go3
-rw-r--r--tests/integration/org_test.go3
-rw-r--r--tests/integration/privateactivity_test.go3
-rw-r--r--tests/integration/pull_merge_test.go5
-rw-r--r--tests/integration/pull_status_test.go3
-rw-r--r--tests/integration/pull_update_test.go5
-rw-r--r--tests/integration/repo_commits_test.go7
-rw-r--r--tests/integration/ssh_key_test.go18
-rw-r--r--tests/integration/user_test.go3
79 files changed, 1220 insertions, 448 deletions
diff --git a/docs/content/doc/developers/oauth2-provider.en-us.md b/docs/content/doc/developers/oauth2-provider.en-us.md
index c6765f19e7..17c12d22f2 100644
--- a/docs/content/doc/developers/oauth2-provider.en-us.md
+++ b/docs/content/doc/developers/oauth2-provider.en-us.md
@@ -42,7 +42,41 @@ To use the Authorization Code Grant as a third party application it is required
## Scopes
-Currently Gitea does not support scopes (see [#4300](https://github.com/go-gitea/gitea/issues/4300)) and all third party applications will be granted access to all resources of the user and their organizations.
+Gitea supports the following scopes for tokens:
+
+| 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 |
+| **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. |
## Client types
diff --git a/models/auth/token.go b/models/auth/token.go
index 0dfcb7629b..3f9f117f73 100644
--- a/models/auth/token.go
+++ b/models/auth/token.go
@@ -65,6 +65,7 @@ type AccessToken struct {
TokenHash string `xorm:"UNIQUE"` // sha256 of token
TokenSalt string
TokenLastEight string `xorm:"INDEX token_last_eight"`
+ Scope AccessTokenScope
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
diff --git a/models/auth/token_scope.go b/models/auth/token_scope.go
new file mode 100644
index 0000000000..c61c306496
--- /dev/null
+++ b/models/auth/token_scope.go
@@ -0,0 +1,251 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package auth
+
+import (
+ "fmt"
+ "strings"
+)
+
+// AccessTokenScope represents the scope for an access token.
+type AccessTokenScope string
+
+const (
+ AccessTokenScopeAll AccessTokenScope = "all"
+
+ AccessTokenScopeRepo AccessTokenScope = "repo"
+ AccessTokenScopeRepoStatus AccessTokenScope = "repo:status"
+ AccessTokenScopePublicRepo AccessTokenScope = "public_repo"
+
+ AccessTokenScopeAdminOrg AccessTokenScope = "admin:org"
+ AccessTokenScopeWriteOrg AccessTokenScope = "write:org"
+ AccessTokenScopeReadOrg AccessTokenScope = "read:org"
+
+ AccessTokenScopeAdminPublicKey AccessTokenScope = "admin:public_key"
+ AccessTokenScopeWritePublicKey AccessTokenScope = "write:public_key"
+ AccessTokenScopeReadPublicKey AccessTokenScope = "read:public_key"
+
+ AccessTokenScopeAdminRepoHook AccessTokenScope = "admin:repo_hook"
+ AccessTokenScopeWriteRepoHook AccessTokenScope = "write:repo_hook"
+ AccessTokenScopeReadRepoHook AccessTokenScope = "read:repo_hook"
+
+ AccessTokenScopeAdminOrgHook AccessTokenScope = "admin:org_hook"
+
+ AccessTokenScopeNotification AccessTokenScope = "notification"
+
+ AccessTokenScopeUser AccessTokenScope = "user"
+ AccessTokenScopeReadUser AccessTokenScope = "read:user"
+ AccessTokenScopeUserEmail AccessTokenScope = "user:email"
+ AccessTokenScopeUserFollow AccessTokenScope = "user:follow"
+
+ AccessTokenScopeDeleteRepo AccessTokenScope = "delete_repo"
+
+ AccessTokenScopePackage AccessTokenScope = "package"
+ AccessTokenScopeWritePackage AccessTokenScope = "write:package"
+ AccessTokenScopeReadPackage AccessTokenScope = "read:package"
+ AccessTokenScopeDeletePackage AccessTokenScope = "delete:package"
+
+ AccessTokenScopeAdminGPGKey AccessTokenScope = "admin:gpg_key"
+ AccessTokenScopeWriteGPGKey AccessTokenScope = "write:gpg_key"
+ AccessTokenScopeReadGPGKey AccessTokenScope = "read:gpg_key"
+
+ AccessTokenScopeAdminApplication AccessTokenScope = "admin:application"
+ AccessTokenScopeWriteApplication AccessTokenScope = "write:application"
+ AccessTokenScopeReadApplication AccessTokenScope = "read:application"
+
+ AccessTokenScopeSudo AccessTokenScope = "sudo"
+)
+
+// AccessTokenScopeBitmap represents a bitmap of access token scopes.
+type AccessTokenScopeBitmap uint64
+
+// Bitmap of each scope, including the child scopes.
+const (
+ // AccessTokenScopeAllBits is the bitmap of all access token scopes, except `sudo`.
+ AccessTokenScopeAllBits AccessTokenScopeBitmap = AccessTokenScopeRepoBits |
+ AccessTokenScopeAdminOrgBits | AccessTokenScopeAdminPublicKeyBits | AccessTokenScopeAdminOrgHookBits |
+ AccessTokenScopeNotificationBits | AccessTokenScopeUserBits | AccessTokenScopeDeleteRepoBits |
+ AccessTokenScopePackageBits | AccessTokenScopeAdminGPGKeyBits | AccessTokenScopeAdminApplicationBits
+
+ AccessTokenScopeRepoBits AccessTokenScopeBitmap = 1<<iota | AccessTokenScopeRepoStatusBits | AccessTokenScopePublicRepoBits | AccessTokenScopeAdminRepoHookBits
+ AccessTokenScopeRepoStatusBits AccessTokenScopeBitmap = 1 << iota
+ AccessTokenScopePublicRepoBits AccessTokenScopeBitmap = 1 << iota
+
+ AccessTokenScopeAdminOrgBits AccessTokenScopeBitmap = 1<<iota | AccessTokenScopeWriteOrgBits
+ AccessTokenScopeWriteOrgBits AccessTokenScopeBitmap = 1<<iota | AccessTokenScopeReadOrgBits
+ AccessTokenScopeReadOrgBits AccessTokenScopeBitmap = 1 << iota
+
+ AccessTokenScopeAdminPublicKeyBits AccessTokenScopeBitmap = 1<<iota | AccessTokenScopeWritePublicKeyBits
+ AccessTokenScopeWritePublicKeyBits AccessTokenScopeBitmap = 1<<iota | AccessTokenScopeReadPublicKeyBits
+ AccessTokenScopeReadPublicKeyBits AccessTokenScopeBitmap = 1 << iota
+
+ AccessTokenScopeAdminRepoHookBits AccessTokenScopeBitmap = 1<<iota | AccessTokenScopeWriteRepoHookBits
+ AccessTokenScopeWriteRepoHookBits AccessTokenScopeBitmap = 1<<iota | AccessTokenScopeReadRepoHookBits
+ AccessTokenScopeReadRepoHookBits AccessTokenScopeBitmap = 1 << iota
+
+ AccessTokenScopeAdminOrgHookBits AccessTokenScopeBitmap = 1 << iota
+
+ AccessTokenScopeNotificationBits AccessTokenScopeBitmap = 1 << iota
+
+ AccessTokenScopeUserBits AccessTokenScopeBitmap = 1<<iota | AccessTokenScopeReadUserBits | AccessTokenScopeUserEmailBits | AccessTokenScopeUserFollowBits
+ AccessTokenScopeReadUserBits AccessTokenScopeBitmap = 1 << iota
+ AccessTokenScopeUserEmailBits AccessTokenScopeBitmap = 1 << iota
+ AccessTokenScopeUserFollowBits AccessTokenScopeBitmap = 1 << iota
+
+ AccessTokenScopeDeleteRepoBits AccessTokenScopeBitmap = 1 << iota
+
+ AccessTokenScopePackageBits AccessTokenScopeBitmap = 1<<iota | AccessTokenScopeWritePackageBits | AccessTokenScopeDeletePackageBits
+ AccessTokenScopeWritePackageBits AccessTokenScopeBitmap = 1<<iota | AccessTokenScopeReadPackageBits
+ AccessTokenScopeReadPackageBits AccessTokenScopeBitmap = 1 << iota
+ AccessTokenScopeDeletePackageBits AccessTokenScopeBitmap = 1 << iota
+
+ AccessTokenScopeAdminGPGKeyBits AccessTokenScopeBitmap = 1<<iota | AccessTokenScopeWriteGPGKeyBits
+ AccessTokenScopeWriteGPGKeyBits AccessTokenScopeBitmap = 1<<iota | AccessTokenScopeReadGPGKeyBits
+ AccessTokenScopeReadGPGKeyBits AccessTokenScopeBitmap = 1 << iota
+
+ AccessTokenScopeAdminApplicationBits AccessTokenScopeBitmap = 1<<iota | AccessTokenScopeWriteApplicationBits
+ AccessTokenScopeWriteApplicationBits AccessTokenScopeBitmap = 1<<iota | AccessTokenScopeReadApplicationBits
+ AccessTokenScopeReadApplicationBits AccessTokenScopeBitmap = 1 << iota
+
+ AccessTokenScopeSudoBits AccessTokenScopeBitmap = 1 << iota
+
+ // The current implementation only supports up to 64 token scopes.
+ // If we need to support > 64 scopes,
+ // refactoring the whole implementation in this file (and only this file) is needed.
+)
+
+// allAccessTokenScopes contains all access token scopes.
+// The order is important: parent scope must precedes child scopes.
+var allAccessTokenScopes = []AccessTokenScope{
+ AccessTokenScopeRepo, AccessTokenScopeRepoStatus, AccessTokenScopePublicRepo,
+ AccessTokenScopeAdminOrg, AccessTokenScopeWriteOrg, AccessTokenScopeReadOrg,
+ AccessTokenScopeAdminPublicKey, AccessTokenScopeWritePublicKey, AccessTokenScopeReadPublicKey,
+ AccessTokenScopeAdminRepoHook, AccessTokenScopeWriteRepoHook, AccessTokenScopeReadRepoHook,
+ AccessTokenScopeAdminOrgHook,
+ AccessTokenScopeNotification,
+ AccessTokenScopeUser, AccessTokenScopeReadUser, AccessTokenScopeUserEmail, AccessTokenScopeUserFollow,
+ AccessTokenScopeDeleteRepo,
+ AccessTokenScopePackage, AccessTokenScopeWritePackage, AccessTokenScopeReadPackage, AccessTokenScopeDeletePackage,
+ AccessTokenScopeAdminGPGKey, AccessTokenScopeWriteGPGKey, AccessTokenScopeReadGPGKey,
+ AccessTokenScopeAdminApplication, AccessTokenScopeWriteApplication, AccessTokenScopeReadApplication,
+ AccessTokenScopeSudo,
+}
+
+// allAccessTokenScopeBits contains all access token scopes.
+var allAccessTokenScopeBits = map[AccessTokenScope]AccessTokenScopeBitmap{
+ AccessTokenScopeRepo: AccessTokenScopeRepoBits,
+ AccessTokenScopeRepoStatus: AccessTokenScopeRepoStatusBits,
+ AccessTokenScopePublicRepo: AccessTokenScopePublicRepoBits,
+ AccessTokenScopeAdminOrg: AccessTokenScopeAdminOrgBits,
+ AccessTokenScopeWriteOrg: AccessTokenScopeWriteOrgBits,
+ AccessTokenScopeReadOrg: AccessTokenScopeReadOrgBits,
+ AccessTokenScopeAdminPublicKey: AccessTokenScopeAdminPublicKeyBits,
+ AccessTokenScopeWritePublicKey: AccessTokenScopeWritePublicKeyBits,
+ AccessTokenScopeReadPublicKey: AccessTokenScopeReadPublicKeyBits,
+ AccessTokenScopeAdminRepoHook: AccessTokenScopeAdminRepoHookBits,
+ AccessTokenScopeWriteRepoHook: AccessTokenScopeWriteRepoHookBits,
+ AccessTokenScopeReadRepoHook: AccessTokenScopeReadRepoHookBits,
+ AccessTokenScopeAdminOrgHook: AccessTokenScopeAdminOrgHookBits,
+ AccessTokenScopeNotification: AccessTokenScopeNotificationBits,
+ AccessTokenScopeUser: AccessTokenScopeUserBits,
+ AccessTokenScopeReadUser: AccessTokenScopeReadUserBits,
+ AccessTokenScopeUserEmail: AccessTokenScopeUserEmailBits,
+ AccessTokenScopeUserFollow: AccessTokenScopeUserFollowBits,
+ AccessTokenScopeDeleteRepo: AccessTokenScopeDeleteRepoBits,
+ AccessTokenScopePackage: AccessTokenScopePackageBits,
+ AccessTokenScopeWritePackage: AccessTokenScopeWritePackageBits,
+ AccessTokenScopeReadPackage: AccessTokenScopeReadPackageBits,
+ AccessTokenScopeDeletePackage: AccessTokenScopeDeletePackageBits,
+ AccessTokenScopeAdminGPGKey: AccessTokenScopeAdminGPGKeyBits,
+ AccessTokenScopeWriteGPGKey: AccessTokenScopeWriteGPGKeyBits,
+ AccessTokenScopeReadGPGKey: AccessTokenScopeReadGPGKeyBits,
+ AccessTokenScopeAdminApplication: AccessTokenScopeAdminApplicationBits,
+ AccessTokenScopeWriteApplication: AccessTokenScopeWriteApplicationBits,
+ AccessTokenScopeReadApplication: AccessTokenScopeReadApplicationBits,
+ AccessTokenScopeSudo: AccessTokenScopeSudoBits,
+}
+
+// Parse parses the scope string into a bitmap, thus removing possible duplicates.
+func (s AccessTokenScope) Parse() (AccessTokenScopeBitmap, error) {
+ list := strings.Split(string(s), ",")
+
+ var bitmap AccessTokenScopeBitmap
+ for _, v := range list {
+ singleScope := AccessTokenScope(v)
+ if singleScope == "" {
+ continue
+ }
+ if singleScope == AccessTokenScopeAll {
+ bitmap |= AccessTokenScopeAllBits
+ continue
+ }
+
+ bits, ok := allAccessTokenScopeBits[singleScope]
+ if !ok {
+ return 0, fmt.Errorf("invalid access token scope: %s", singleScope)
+ }
+ bitmap |= bits
+ }
+ return bitmap, nil
+}
+
+// Normalize returns a normalized scope string without any duplicates.
+func (s AccessTokenScope) Normalize() (AccessTokenScope, error) {
+ bitmap, err := s.Parse()
+ if err != nil {
+ return "", err
+ }
+
+ return bitmap.ToScope(), nil
+}
+
+// HasScope returns true if the string has the given scope
+func (s AccessTokenScope) HasScope(scope AccessTokenScope) (bool, error) {
+ bitmap, err := s.Parse()
+ if err != nil {
+ return false, err
+ }
+
+ return bitmap.HasScope(scope)
+}
+
+// HasScope returns true if the string has the given scope
+func (bitmap AccessTokenScopeBitmap) HasScope(scope AccessTokenScope) (bool, error) {
+ expectedBits, ok := allAccessTokenScopeBits[scope]
+ if !ok {
+ return false, fmt.Errorf("invalid access token scope: %s", scope)
+ }
+
+ return bitmap&expectedBits == expectedBits, nil
+}
+
+// ToScope returns a normalized scope string without any duplicates.
+func (bitmap AccessTokenScopeBitmap) ToScope() AccessTokenScope {
+ var scopes []string
+
+ // iterate over all scopes, and reconstruct the bitmap
+ // if the reconstructed bitmap doesn't change, then the scope is already included
+ var reconstruct AccessTokenScopeBitmap
+
+ for _, singleScope := range allAccessTokenScopes {
+ // no need for error checking here, since we know the scope is valid
+ if ok, _ := bitmap.HasScope(singleScope); ok {
+ current := reconstruct | allAccessTokenScopeBits[singleScope]
+ if current == reconstruct {
+ continue
+ }
+
+ reconstruct = current
+ scopes = append(scopes, string(singleScope))
+ }
+ }
+
+ scope := AccessTokenScope(strings.Join(scopes, ","))
+ scope = AccessTokenScope(strings.ReplaceAll(
+ string(scope),
+ "repo,admin:org,admin:public_key,admin:org_hook,notification,user,delete_repo,package,admin:gpg_key,admin:application",
+ "all",
+ ))
+ return scope
+}
diff --git a/models/auth/token_scope_test.go b/models/auth/token_scope_test.go
new file mode 100644
index 0000000000..1d7f4794a4
--- /dev/null
+++ b/models/auth/token_scope_test.go
@@ -0,0 +1,84 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package auth
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestAccessTokenScope_Normalize(t *testing.T) {
+ tests := []struct {
+ in AccessTokenScope
+ out AccessTokenScope
+ err error
+ }{
+ {"", "", nil},
+ {"repo", "repo", nil},
+ {"repo,repo:status", "repo", nil},
+ {"repo,public_repo", "repo", nil},
+ {"admin:public_key,write:public_key", "admin:public_key", nil},
+ {"admin:public_key,read:public_key", "admin:public_key", nil},
+ {"write:public_key,read:public_key", "write:public_key", nil}, // read is include in write
+ {"admin:repo_hook,write:repo_hook", "admin:repo_hook", nil},
+ {"admin:repo_hook,read:repo_hook", "admin:repo_hook", nil},
+ {"repo,admin:repo_hook,read:repo_hook", "repo", nil}, // admin:repo_hook is a child scope of repo
+ {"repo,read:repo_hook", "repo", nil}, // read:repo_hook is a child scope of repo
+ {"user", "user", nil},
+ {"user,read:user", "user", nil},
+ {"user,admin:org,write:org", "admin:org,user", nil},
+ {"admin:org,write:org,user", "admin:org,user", nil},
+ {"package", "package", nil},
+ {"package,write:package", "package", nil},
+ {"package,write:package,delete:package", "package", nil},
+ {"write:package,read:package", "write:package", nil}, // read is include in write
+ {"write:package,delete:package", "write:package,delete:package", nil}, // write and delete are not include in each other
+ {"admin:gpg_key", "admin:gpg_key", nil},
+ {"admin:gpg_key,write:gpg_key", "admin:gpg_key", nil},
+ {"admin:gpg_key,write:gpg_key,user", "user,admin:gpg_key", nil},
+ {"admin:application,write:application,user", "user,admin:application", nil},
+ {"all", "all", nil},
+ {"repo,admin:org,admin:public_key,admin:repo_hook,admin:org_hook,notification,user,delete_repo,package,admin:gpg_key,admin:application", "all", nil},
+ {"repo,admin:org,admin:public_key,admin:repo_hook,admin:org_hook,notification,user,delete_repo,package,admin:gpg_key,admin:application,sudo", "all,sudo", nil},
+ }
+
+ for _, test := range tests {
+ t.Run(string(test.in), func(t *testing.T) {
+ scope, err := test.in.Normalize()
+ assert.Equal(t, test.out, scope)
+ assert.Equal(t, test.err, err)
+ })
+ }
+}
+
+func TestAccessTokenScope_HasScope(t *testing.T) {
+ tests := []struct {
+ in AccessTokenScope
+ scope AccessTokenScope
+ out bool
+ err error
+ }{
+ {"repo", "repo", true, nil},
+ {"repo", "repo:status", true, nil},
+ {"repo", "public_repo", true, nil},
+ {"repo", "admin:org", false, nil},
+ {"repo", "admin:public_key", false, nil},
+ {"repo:status", "repo", false, nil},
+ {"repo:status", "public_repo", false, nil},
+ {"admin:org", "write:org", true, nil},
+ {"admin:org", "read:org", true, nil},
+ {"admin:org", "admin:org", true, nil},
+ {"user", "read:user", true, nil},
+ {"package", "write:package", true, nil},
+ }
+
+ for _, test := range tests {
+ t.Run(string(test.in), func(t *testing.T) {
+ scope, err := test.in.HasScope(test.scope)
+ assert.Equal(t, test.out, scope)
+ assert.Equal(t, test.err, err)
+ })
+ }
+}
diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go
index 4e211617c0..2058fcec0f 100644
--- a/models/migrations/migrations.go
+++ b/models/migrations/migrations.go
@@ -451,6 +451,8 @@ var migrations = []Migration{
NewMigration("Drop ForeignReference table", v1_19.DropForeignReferenceTable),
// v238 -> v239
NewMigration("Add updated unix to LFSMetaObject", v1_19.AddUpdatedUnixToLFSMetaObject),
+ // v239 -> v240
+ NewMigration("Add scope for access_token", v1_19.AddScopeForAccessTokens),
}
// GetCurrentDBVersion returns the current db version
diff --git a/models/migrations/v1_19/v239.go b/models/migrations/v1_19/v239.go
new file mode 100644
index 0000000000..10076f2401
--- /dev/null
+++ b/models/migrations/v1_19/v239.go
@@ -0,0 +1,22 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package v1_19 //nolint
+
+import (
+ "xorm.io/xorm"
+)
+
+func AddScopeForAccessTokens(x *xorm.Engine) error {
+ type AccessToken struct {
+ Scope string
+ }
+
+ if err := x.Sync(new(AccessToken)); err != nil {
+ return err
+ }
+
+ // all previous tokens have `all` and `sudo` scopes
+ _, err := x.Exec("UPDATE access_token SET scope = ? WHERE scope IS NULL OR scope = ''", "all,sudo")
+ return err
+}
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index 1cd4e6a1d0..9d1d279b0e 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -747,6 +747,7 @@ access_token_deletion_cancel_action = Cancel
access_token_deletion_confirm_action = Delete
access_token_deletion_desc = Deleting a token will revoke access to your account for applications using it. This cannot be undone. Continue?
delete_token_success = The token has been deleted. Applications using it no longer have access to your account.
+select_scopes = Select scopes
manage_oauth2_applications = Manage OAuth2 Applications
edit_oauth2_application = Edit OAuth2 Application
diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go
index d5a12ead85..cd08aae414 100644
--- a/routers/api/v1/api.go
+++ b/routers/api/v1/api.go
@@ -69,6 +69,7 @@ import (
"net/http"
"strings"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/perm"
access_model "code.gitea.io/gitea/models/perm/access"
@@ -206,9 +207,36 @@ func reqPackageAccess(accessMode perm.AccessMode) func(ctx *context.APIContext)
}
// Contexter middleware already checks token for user sign in process.
-func reqToken() func(ctx *context.APIContext) {
+func reqToken(requiredScope auth_model.AccessTokenScope) func(ctx *context.APIContext) {
return func(ctx *context.APIContext) {
- if true == ctx.Data["IsApiToken"] {
+ // If OAuth2 token is present
+ if _, ok := ctx.Data["ApiTokenScope"]; ctx.Data["IsApiToken"] == true && ok {
+ // no scope required
+ if requiredScope == "" {
+ return
+ }
+
+ // check scope
+ scope := ctx.Data["ApiTokenScope"].(auth_model.AccessTokenScope)
+ allow, err := scope.HasScope(requiredScope)
+ if err != nil {
+ ctx.Error(http.StatusForbidden, "reqToken", "parsing token failed: "+err.Error())
+ return
+ }
+ if allow {
+ return
+ }
+
+ // if requires 'repo' scope, but only has 'public_repo' scope, allow it only if the repo is public
+ if requiredScope == auth_model.AccessTokenScopeRepo {
+ if allowPublicRepo, err := scope.HasScope(auth_model.AccessTokenScopePublicRepo); err == nil && allowPublicRepo {
+ if ctx.Repo.Repository != nil && !ctx.Repo.Repository.IsPrivate {
+ return
+ }
+ }
+ }
+
+ ctx.Error(http.StatusForbidden, "reqToken", "token does not have required scope: "+requiredScope)
return
}
if ctx.Context.IsBasicAuth {
@@ -631,7 +659,7 @@ func Routes(ctx gocontext.Context) *web.Route {
}))
m.Group("", func() {
- // Miscellaneous
+ // Miscellaneous (no scope required)
if setting.API.EnableSwagger {
m.Get("/swagger", func(ctx *context.APIContext) {
ctx.Redirect(setting.AppSubURL + "/api/swagger")
@@ -657,7 +685,7 @@ func Routes(ctx gocontext.Context) *web.Route {
m.Get("/repository", settings.GetGeneralRepoSettings)
})
- // Notifications
+ // Notifications (requires 'notification' scope)
m.Group("/notifications", func() {
m.Combo("").
Get(notify.ListNotifications).
@@ -666,9 +694,9 @@ func Routes(ctx gocontext.Context) *web.Route {
m.Combo("/threads/{id}").
Get(notify.GetThread).
Patch(notify.ReadThread)
- }, reqToken())
+ }, reqToken(auth_model.AccessTokenScopeNotification))
- // Users
+ // Users (no scope required)
m.Group("/users", func() {
m.Get("/search", reqExploreSignIn(), user.Search)
@@ -688,6 +716,7 @@ func Routes(ctx gocontext.Context) *web.Route {
}, context_service.UserAssignmentAPI())
})
+ // (no scope required)
m.Group("/users", func() {
m.Group("/{username}", func() {
m.Get("/keys", user.ListPublicKeys)
@@ -703,57 +732,62 @@ func Routes(ctx gocontext.Context) *web.Route {
m.Get("/subscriptions", user.GetWatchedRepos)
}, context_service.UserAssignmentAPI())
- }, reqToken())
+ }, reqToken(""))
m.Group("/user", func() {
m.Get("", user.GetAuthenticatedUser)
m.Group("/settings", func() {
- m.Get("", user.GetUserSettings)
- m.Patch("", bind(api.UserSettingsOptions{}), user.UpdateUserSettings)
- }, reqToken())
- m.Combo("/emails").Get(user.ListEmails).
- Post(bind(api.CreateEmailOption{}), user.AddEmail).
- Delete(bind(api.DeleteEmailOption{}), user.DeleteEmail)
+ m.Get("", reqToken(auth_model.AccessTokenScopeReadUser), user.GetUserSettings)
+ m.Patch("", reqToken(auth_model.AccessTokenScopeUser), bind(api.UserSettingsOptions{}), user.UpdateUserSettings)
+ })
+ m.Combo("/emails").Get(reqToken(auth_model.AccessTokenScopeReadUser), user.ListEmails).
+ Post(reqToken(auth_model.AccessTokenScopeUser), bind(api.CreateEmailOption{}), user.AddEmail).
+ Delete(reqToken(auth_model.AccessTokenScopeUser), bind(api.DeleteEmailOption{}), user.DeleteEmail)
m.Get("/followers", user.ListMyFollowers)
m.Group("/following", func() {
m.Get("", user.ListMyFollowing)
m.Group("/{username}", func() {
m.Get("", user.CheckMyFollowing)
- m.Put("", user.Follow)
- m.Delete("", user.Unfollow)
+ m.Put("", reqToken(auth_model.AccessTokenScopeUserFollow), user.Follow) // requires 'user:follow' scope
+ m.Delete("", reqToken(auth_model.AccessTokenScopeUserFollow), user.Unfollow) // requires 'user:follow' scope
}, context_service.UserAssignmentAPI())
})
+ // (admin:public_key scope)
m.Group("/keys", func() {
- m.Combo("").Get(user.ListMyPublicKeys).
- Post(bind(api.CreateKeyOption{}), user.CreatePublicKey)
- m.Combo("/{id}").Get(user.GetPublicKey).
- Delete(user.DeletePublicKey)
+ m.Combo("").Get(reqToken(auth_model.AccessTokenScopeReadPublicKey), user.ListMyPublicKeys).
+ Post(reqToken(auth_model.AccessTokenScopeWritePublicKey), bind(api.CreateKeyOption{}), user.CreatePublicKey)
+ m.Combo("/{id}").Get(reqToken(auth_model.AccessTokenScopeReadPublicKey), user.GetPublicKey).
+ Delete(reqToken(auth_model.AccessTokenScopeWritePublicKey), user.DeletePublicKey)
})
+
+ // (admin:application scope)
m.Group("/applications", func() {
m.Combo("/oauth2").
- Get(user.ListOauth2Applications).
- Post(bind(api.CreateOAuth2ApplicationOptions{}), user.CreateOauth2Application)
+ Get(reqToken(auth_model.AccessTokenScopeReadApplication), user.ListOauth2Applications).
+ Post(reqToken(auth_model.AccessTokenScopeWriteApplication), bind(api.CreateOAuth2ApplicationOptions{}), user.CreateOauth2Application)
m.Combo("/oauth2/{id}").
- Delete(user.DeleteOauth2Application).
- Patch(bind(api.CreateOAuth2ApplicationOptions{}), user.UpdateOauth2Application).
- Get(user.GetOauth2Application)
- }, reqToken())
+ Delete(reqToken(auth_model.AccessTokenScopeWriteApplication), user.DeleteOauth2Application).
+ Patch(reqToken(auth_model.AccessTokenScopeWriteApplication), bind(api.CreateOAuth2ApplicationOptions{}), user.UpdateOauth2Application).
+ Get(reqToken(auth_model.AccessTokenScopeReadApplication), user.GetOauth2Application)
+ })
+ // (admin:gpg_key scope)
m.Group("/gpg_keys", func() {
- m.Combo("").Get(user.ListMyGPGKeys).
- Post(bind(api.CreateGPGKeyOption{}), user.CreateGPGKey)
- m.Combo("/{id}").Get(user.GetGPGKey).
- Delete(user.DeleteGPGKey)
+ m.Combo("").Get(reqToken(auth_model.AccessTokenScopeReadGPGKey), user.ListMyGPGKeys).
+ Post(reqToken(auth_model.AccessTokenScopeWriteGPGKey), bind(api.CreateGPGKeyOption{}), user.CreateGPGKey)
+ m.Combo("/{id}").Get(reqToken(auth_model.AccessTokenScopeReadGPGKey), user.GetGPGKey).
+ Delete(reqToken(auth_model.AccessTokenScopeWriteGPGKey), user.DeleteGPGKey)
})
+ m.Get("/gpg_key_token", reqToken(auth_model.AccessTokenScopeReadGPGKey), user.GetVerificationToken)
+ m.Post("/gpg_key_verify", reqToken(auth_model.AccessTokenScopeReadGPGKey), bind(api.VerifyGPGKeyOption{}), user.VerifyUserGPGKey)
- m.Get("/gpg_key_token", user.GetVerificationToken)
- m.Post("/gpg_key_verify", bind(api.VerifyGPGKeyOption{}), user.VerifyUserGPGKey)
-
- m.Combo("/repos").Get(user.ListMyRepos).
+ // (repo scope)
+ m.Combo("/repos", reqToken(auth_model.AccessTokenScopeRepo)).Get(user.ListMyRepos).
Post(bind(api.CreateRepoOption{}), repo.Create)
+ // (repo scope)
m.Group("/starred", func() {
m.Get("", user.GetMyStarredRepos)
m.Group("/{username}/{reponame}", func() {
@@ -761,57 +795,57 @@ func Routes(ctx gocontext.Context) *web.Route {
m.Put("", user.Star)
m.Delete("", user.Unstar)
}, repoAssignment())
- })
- m.Get("/times", repo.ListMyTrackedTimes)
-
- m.Get("/stopwatches", repo.GetStopwatches)
-
- m.Get("/subscriptions", user.GetMyWatchedRepos)
-
- m.Get("/teams", org.ListUserTeams)
- }, reqToken())
+ }, reqToken(auth_model.AccessTokenScopeRepo))
+ m.Get("/times", reqToken(auth_model.AccessTokenScopeRepo), repo.ListMyTrackedTimes)
+ m.Get("/stopwatches", reqToken(auth_model.AccessTokenScopeRepo), repo.GetStopwatches)
+ m.Get("/subscriptions", reqToken(auth_model.AccessTokenScopeRepo), user.GetMyWatchedRepos)
+ m.Get("/teams", reqToken(auth_model.AccessTokenScopeRepo), org.ListUserTeams)
+ }, reqToken(""))
// Repositories
- m.Post("/org/{org}/repos", reqToken(), bind(api.CreateRepoOption{}), repo.CreateOrgRepoDeprecated)
+ m.Post("/org/{org}/repos", reqToken(auth_model.AccessTokenScopeAdminOrg), bind(api.CreateRepoOption{}), repo.CreateOrgRepoDeprecated)
- m.Combo("/repositories/{id}", reqToken()).Get(repo.GetByID)
+ m.Combo("/repositories/{id}", reqToken(auth_model.AccessTokenScopeRepo)).Get(repo.GetByID)
m.Group("/repos", func() {
m.Get("/search", repo.Search)
m.Get("/issues/search", repo.SearchIssues)
- m.Post("/migrate", reqToken(), bind(api.MigrateRepoOptions{}), repo.Migrate)
+ // (repo scope)
+ m.Post("/migrate", reqToken(auth_model.AccessTokenScopeRepo), bind(api.MigrateRepoOptions{}), repo.Migrate)
m.Group("/{username}/{reponame}", func() {
m.Combo("").Get(reqAnyRepoReader(), repo.Get).
- Delete(reqToken(), reqOwner(), repo.Delete).
- Patch(reqToken(), reqAdmin(), bind(api.EditRepoOption{}), repo.Edit)
- m.Post("/generate", reqToken(), reqRepoReader(unit.TypeCode), bind(api.GenerateRepoOption{}), repo.Generate)
- m.Post("/transfer", reqOwner(), bind(api.TransferRepoOption{}), repo.Transfer)
- m.Post("/transfer/accept", reqToken(), repo.AcceptTransfer)
- m.Post("/transfer/reject", reqToken(), repo.RejectTransfer)
- m.Combo("/notifications").
- Get(reqToken(), notify.ListRepoNotifications).
- Put(reqToken(), notify.ReadRepoNotifications)
+ Delete(reqToken(auth_model.AccessTokenScopeDeleteRepo), reqOwner(), repo.Delete).
+ Patch(reqToken(auth_model.AccessTokenScopeRepo), reqAdmin(), bind(api.EditRepoOption{}), repo.Edit)
+ m.Post("/generate", reqToken(auth_model.AccessTokenScopeRepo), reqRepoReader(unit.TypeCode), bind(api.GenerateRepoOption{}), repo.Generate)
+ m.Group("/transfer", func() {
+ m.Post("", reqOwner(), bind(api.TransferRepoOption{}), repo.Transfer)
+ m.Post("/accept", repo.AcceptTransfer)
+ m.Post("/reject", repo.RejectTransfer)
+ }, reqToken(auth_model.AccessTokenScopeRepo))
+ m.Combo("/notifications", reqToken(auth_model.AccessTokenScopeNotification)).
+ Get(notify.ListRepoNotifications).
+ Put(notify.ReadRepoNotifications)
m.Group("/hooks/git", func() {
- m.Combo("").Get(repo.ListGitHooks)
+ m.Combo("").Get(reqToken(auth_model.AccessTokenScopeReadRepoHook), repo.ListGitHooks)
m.Group("/{id}", func() {
- m.Combo("").Get(repo.GetGitHook).
- Patch(bind(api.EditGitHookOption{}), repo.EditGitHook).
- Delete(repo.DeleteGitHook)
+ m.Combo("").Get(reqToken(auth_model.AccessTokenScopeReadRepoHook), repo.GetGitHook).
+ Patch(reqToken(auth_model.AccessTokenScopeWriteRepoHook), bind(api.EditGitHookOption{}), repo.EditGitHook).
+ Delete(reqToken(auth_model.AccessTokenScopeWriteRepoHook), repo.DeleteGitHook)
})
- }, reqToken(), reqAdmin(), reqGitHook(), context.ReferencesGitRepo(true))
+ }, reqAdmin(), reqGitHook(), context.ReferencesGitRepo(true))
m.Group("/hooks", func() {
- m.Combo("").Get(repo.ListHooks).
- Post(bind(api.CreateHookOption{}), repo.CreateHook)
+ m.Combo("").Get(reqToken(auth_model.AccessTokenScopeReadRepoHook), repo.ListHooks).
+ Post(reqToken(auth_model.AccessTokenScopeWriteRepoHook), bind(api.CreateHookOption{}), repo.CreateHook)
m.Group("/{id}", func() {
- m.Combo("").Get(repo.GetHook).
- Patch(bind(api.EditHookOption{}), repo.EditHook).
- Delete(repo.DeleteHook)
- m.Post("/tests", context.ReferencesGitRepo(), context.RepoRefForAPI, repo.TestHook)
+ m.Combo("").Get(reqToken(auth_model.AccessTokenScopeReadRepoHook), repo.GetHook).
+ Patch(reqToken(auth_model.AccessTokenScopeWriteRepoHook), bind(api.EditHookOption{}), repo.EditHook).
+ Delete(reqToken(auth_model.AccessTokenScopeWriteRepoHook), repo.DeleteHook)
+ m.Post("/tests", reqToken(auth_model.AccessTokenScopeReadRepoHook), context.ReferencesGitRepo(), context.RepoRefForAPI, repo.TestHook)
})
- }, reqToken(), reqAdmin(), reqWebhooksEnabled())
+ }, reqAdmin(), reqWebhooksEnabled())
m.Group("/collaborators", func() {
m.Get("", reqAnyRepoReader(), repo.ListCollaborators)
m.Group("/{collaborator}", func() {
@@ -819,26 +853,26 @@ func Routes(ctx gocontext.Context) *web.Route {
Put(reqAdmin(), bind(api.AddCollaboratorOption{}), repo.AddCollaborator).
Delete(reqAdmin(), repo.DeleteCollaborator)
m.Get("/permission", repo.GetRepoPermissions)
- }, reqToken())
- }, reqToken())
- m.Get("/assignees", reqToken(), reqAnyRepoReader(), repo.GetAssignees)
- m.Get("/reviewers", reqToken(), reqAnyRepoReader(), repo.GetReviewers)
+ })
+ }, reqToken(auth_model.AccessTokenScopeRepo))
+ m.Get("/assignees", reqToken(auth_model.AccessTokenScopeRepo), reqAnyRepoReader(), repo.GetAssignees)
+ m.Get("/reviewers", reqToken(auth_model.AccessTokenScopeRepo), reqAnyRepoReader(), repo.GetReviewers)
m.Group("/teams", func() {
m.Get("", reqAnyRepoReader(), repo.ListTeams)
m.Combo("/{team}").Get(reqAnyRepoReader(), repo.IsTeam).
Put(reqAdmin(), repo.AddTeam).
Delete(reqAdmin(), repo.DeleteTeam)
- }, reqToken())
+ }, reqToken(auth_model.AccessTokenScopeRepo))
m.Get("/raw/*", context.ReferencesGitRepo(), context.RepoRefForAPI, reqRepoReader(unit.TypeCode), repo.GetRawFile)
m.Get("/media/*", context.ReferencesGitRepo(), context.RepoRefForAPI, reqRepoReader(unit.TypeCode), repo.GetRawFileOrLFS)
m.Get("/archive/*", reqRepoReader(unit.TypeCode), repo.GetArchive)
m.Combo("/forks").Get(repo.ListForks).
- Post(reqToken(), reqRepoReader(unit.TypeCode), bind(api.CreateForkOption{}), repo.CreateFork)
+ Post(reqToken(auth_model.AccessTokenScopeRepo), reqRepoReader(unit.TypeCode), bind(api.CreateForkOption{}), repo.CreateFork)
m.Group("/branches", func() {
m.Get("", repo.ListBranches)
m.Get("/*", repo.GetBranch)
- m.Delete("/*", reqRepoWriter(unit.TypeCode), repo.DeleteBranch)
- m.Post("", reqRepoWriter(unit.TypeCode), bind(api.CreateBranchRepoOption{}), repo.CreateBranch)
+ m.Delete("/*", reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeCode), repo.DeleteBranch)
+ m.Post("", reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeCode), bind(api.CreateBranchRepoOption{}), repo.CreateBranch)
}, context.ReferencesGitRepo(), reqRepoReader(unit.TypeCode))
m.Group("/branch_protections", func() {
m.Get("", repo.ListBranchProtections)
@@ -848,74 +882,74 @@ func Routes(ctx gocontext.Context) *web.Route {
m.Patch("", bind(api.EditBranchProtectionOption{}), repo.EditBranchProtection)
m.Delete("", repo.DeleteBranchProtection)
})
- }, reqToken(), reqAdmin())
+ }, reqToken(auth_model.AccessTokenScopeRepo), reqAdmin())
m.Group("/tags", func() {
m.Get("", repo.ListTags)
m.Get("/*", repo.GetTag)
- m.Post("", reqRepoWriter(unit.TypeCode), bind(api.CreateTagOption{}), repo.CreateTag)
- m.Delete("/*", repo.DeleteTag)
+ m.Post("", reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeCode), bind(api.CreateTagOption{}), repo.CreateTag)
+ m.Delete("/*", reqToken(auth_model.AccessTokenScopeRepo), repo.DeleteTag)
}, reqRepoReader(unit.TypeCode), context.ReferencesGitRepo(true))
m.Group("/keys", func() {
m.Combo("").Get(repo.ListDeployKeys).
Post(bind(api.CreateKeyOption{}), repo.CreateDeployKey)
m.Combo("/{id}").Get(repo.GetDeployKey).
Delete(repo.DeleteDeploykey)
- }, reqToken(), reqAdmin())
+ }, reqToken(auth_model.AccessTokenScopeRepo), reqAdmin())
m.Group("/times", func() {
m.Combo("").Get(repo.ListTrackedTimesByRepository)
m.Combo("/{timetrackingusername}").Get(repo.ListTrackedTimesByUser)
- }, mustEnableIssues, reqToken())
+ }, mustEnableIssues, reqToken(auth_model.AccessTokenScopeRepo))
m.Group("/wiki", func() {
m.Combo("/page/{pageName}").
Get(repo.GetWikiPage).
- Patch(mustNotBeArchived, reqRepoWriter(unit.TypeWiki), bind(api.CreateWikiPageOptions{}), repo.EditWikiPage).
- Delete(mustNotBeArchived, reqRepoWriter(unit.TypeWiki), repo.DeleteWikiPage)
+ Patch(mustNotBeArchived, reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeWiki), bind(api.CreateWikiPageOptions{}), repo.EditWikiPage).
+ Delete(mustNotBeArchived, reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeWiki), repo.DeleteWikiPage)
m.Get("/revisions/{pageName}", repo.ListPageRevisions)
- m.Post("/new", mustNotBeArchived, reqRepoWriter(unit.TypeWiki), bind(api.CreateWikiPageOptions{}), repo.NewWikiPage)
+ m.Post("/new", mustNotBeArchived, reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeWiki), bind(api.CreateWikiPageOptions{}), repo.NewWikiPage)
m.Get("/pages", repo.ListWikiPages)
}, mustEnableWiki)
m.Group("/issues", func() {
m.Combo("").Get(repo.ListIssues).
- Post(reqToken(), mustNotBeArchived, bind(api.CreateIssueOption{}), repo.CreateIssue)
+ Post(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.CreateIssueOption{}), repo.CreateIssue)
m.Group("/comments", func() {
m.Get("", repo.ListRepoIssueComments)
m.Group("/{id}", func() {
m.Combo("").
Get(repo.GetIssueComment).
- Patch(mustNotBeArchived, reqToken(), bind(api.EditIssueCommentOption{}), repo.EditIssueComment).
- Delete(reqToken(), repo.DeleteIssueComment)
+ Patch(mustNotBeArchived, reqToken(auth_model.AccessTokenScopeRepo), bind(api.EditIssueCommentOption{}), repo.EditIssueComment).
+ Delete(reqToken(auth_model.AccessTokenScopeRepo), repo.DeleteIssueComment)
m.Combo("/reactions").
Get(repo.GetIssueCommentReactions).
- Post(reqToken(), bind(api.EditReactionOption{}), repo.PostIssueCommentReaction).
- Delete(reqToken(), bind(api.EditReactionOption{}), repo.DeleteIssueCommentReaction)
+ Post(reqToken(auth_model.AccessTokenScopeRepo), bind(api.EditReactionOption{}), repo.PostIssueCommentReaction).
+ Delete(reqToken(auth_model.AccessTokenScopeRepo), bind(api.EditReactionOption{}), repo.DeleteIssueCommentReaction)
m.Group("/assets", func() {
m.Combo("").
Get(repo.ListIssueCommentAttachments).
- Post(reqToken(), mustNotBeArchived, repo.CreateIssueCommentAttachment)
+ Post(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, repo.CreateIssueCommentAttachment)
m.Combo("/{asset}").
Get(repo.GetIssueCommentAttachment).
- Patch(reqToken(), mustNotBeArchived, bind(api.EditAttachmentOptions{}), repo.EditIssueCommentAttachment).
- Delete(reqToken(), mustNotBeArchived, repo.DeleteIssueCommentAttachment)
+ Patch(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.EditAttachmentOptions{}), repo.EditIssueCommentAttachment).
+ Delete(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, repo.DeleteIssueCommentAttachment)
}, mustEnableAttachments)
})
})
m.Group("/{index}", func() {
m.Combo("").Get(repo.GetIssue).
- Patch(reqToken(), bind(api.EditIssueOption{}), repo.EditIssue).
- Delete(reqToken(), reqAdmin(), context.ReferencesGitRepo(), repo.DeleteIssue)
+ Patch(reqToken(auth_model.AccessTokenScopeRepo), bind(api.EditIssueOption{}), repo.EditIssue).
+ Delete(reqToken(auth_model.AccessTokenScopeRepo), reqAdmin(), context.ReferencesGitRepo(), repo.DeleteIssue)
m.Group("/comments", func() {
m.Combo("").Get(repo.ListIssueComments).
- Post(reqToken(), mustNotBeArchived, bind(api.CreateIssueCommentOption{}), repo.CreateIssueComment)
- m.Combo("/{id}", reqToken()).Patch(bind(api.EditIssueCommentOption{}), repo.EditIssueCommentDeprecated).
+ Post(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.CreateIssueCommentOption{}), repo.CreateIssueComment)
+ m.Combo("/{id}", reqToken(auth_model.AccessTokenScopeRepo)).Patch(bind(api.EditIssueCommentOption{}), repo.EditIssueCommentDeprecated).
Delete(repo.DeleteIssueCommentDeprecated)
})
m.Get("/timeline", repo.ListIssueCommentsAndTimeline)
m.Group("/labels", func() {
m.Combo("").Get(repo.ListIssueLabels).
- Post(reqToken(), bind(api.IssueLabelsOption{}), repo.AddIssueLabels).
- Put(reqToken(), bind(api.IssueLabelsOption{}), repo.ReplaceIssueLabels).
- Delete(reqToken(), repo.ClearIssueLabels)
- m.Delete("/{id}", reqToken(), repo.DeleteIssueLabel)
+ Post(reqToken(auth_model.AccessTokenScopeRepo), bind(api.IssueLabelsOption{}), repo.AddIssueLabels).
+ Put(reqToken(auth_model.AccessTokenScopeRepo), bind(api.IssueLabelsOption{}), repo.ReplaceIssueLabels).
+ Delete(reqToken(auth_model.AccessTokenScopeRepo), repo.ClearIssueLabels)
+ m.Delete("/{id}", reqToken(auth_model.AccessTokenScopeRepo), repo.DeleteIssueLabel)
})
m.Group("/times", func() {
m.Combo("").
@@ -923,125 +957,125 @@ func Routes(ctx gocontext.Context) *web.Route {
Post(bind(api.AddTimeOption{}), repo.AddTime).
Delete(repo.ResetIssueTime)
m.Delete("/{id}", repo.DeleteTime)
- }, reqToken())
- m.Combo("/deadline").Post(reqToken(), bind(api.EditDeadlineOption{}), repo.UpdateIssueDeadline)
+ }, reqToken(auth_model.AccessTokenScopeRepo))
+ m.Combo("/deadline").Post(reqToken(auth_model.AccessTokenScopeRepo), bind(api.EditDeadlineOption{}), repo.UpdateIssueDeadline)
m.Group("/stopwatch", func() {
- m.Post("/start", reqToken(), repo.StartIssueStopwatch)
- m.Post("/stop", reqToken(), repo.StopIssueStopwatch)
- m.Delete("/delete", reqToken(), repo.DeleteIssueStopwatch)
+ m.Post("/start", reqToken(auth_model.AccessTokenScopeRepo), repo.StartIssueStopwatch)
+ m.Post("/stop", reqToken(auth_model.AccessTokenScopeRepo), repo.StopIssueStopwatch)
+ m.Delete("/delete", reqToken(auth_model.AccessTokenScopeRepo), repo.DeleteIssueStopwatch)
})
m.Group("/subscriptions", func() {
m.Get("", repo.GetIssueSubscribers)
- m.Get("/check", reqToken(), repo.CheckIssueSubscription)
- m.Put("/{user}", reqToken(), repo.AddIssueSubscription)
- m.Delete("/{user}", reqToken(), repo.DelIssueSubscription)
+ m.Get("/check", reqToken(auth_model.AccessTokenScopeRepo), repo.CheckIssueSubscription)
+ m.Put("/{user}", reqToken(auth_model.AccessTokenScopeRepo), repo.AddIssueSubscription)
+ m.Delete("/{user}", reqToken(auth_model.AccessTokenScopeRepo), repo.DelIssueSubscription)
})
m.Combo("/reactions").
Get(repo.GetIssueReactions).
- Post(reqToken(), bind(api.EditReactionOption{}), repo.PostIssueReaction).
- Delete(reqToken(), bind(api.EditReactionOption{}), repo.DeleteIssueReaction)
+ Post(reqToken(auth_model.AccessTokenScopeRepo), bind(api.EditReactionOption{}), repo.PostIssueReaction).
+ Delete(reqToken(auth_model.AccessTokenScopeRepo), bind(api.EditReactionOption{}), repo.DeleteIssueReaction)
m.Group("/assets", func() {
m.Combo("").
Get(repo.ListIssueAttachments).
- Post(reqToken(), mustNotBeArchived, repo.CreateIssueAttachment)
+ Post(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, repo.CreateIssueAttachment)
m.Combo("/{asset}").
Get(repo.GetIssueAttachment).
- Patch(reqToken(), mustNotBeArchived, bind(api.EditAttachmentOptions{}), repo.EditIssueAttachment).
- Delete(reqToken(), mustNotBeArchived, repo.DeleteIssueAttachment)
+ Patch(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.EditAttachmentOptions{}), repo.EditIssueAttachment).
+ Delete(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, repo.DeleteIssueAttachment)
}, mustEnableAttachments)
})
}, mustEnableIssuesOrPulls)
m.Group("/labels", func() {
m.Combo("").Get(repo.ListLabels).
- Post(reqToken(), reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), bind(api.CreateLabelOption{}), repo.CreateLabel)
+ Post(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), bind(api.CreateLabelOption{}), repo.CreateLabel)
m.Combo("/{id}").Get(repo.GetLabel).
- Patch(reqToken(), reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), bind(api.EditLabelOption{}), repo.EditLabel).
- Delete(reqToken(), reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), repo.DeleteLabel)
+ Patch(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), bind(api.EditLabelOption{}), repo.EditLabel).
+ Delete(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), repo.DeleteLabel)
})
- m.Post("/markdown", bind(api.MarkdownOption{}), misc.Markdown)
- m.Post("/markdown/raw", misc.MarkdownRaw)
+ m.Post("/markdown", reqToken(auth_model.AccessTokenScopeRepo), bind(api.MarkdownOption{}), misc.Markdown)
+ m.Post("/markdown/raw", reqToken(auth_model.AccessTokenScopeRepo), misc.MarkdownRaw)
m.Group("/milestones", func() {
m.Combo("").Get(repo.ListMilestones).
- Post(reqToken(), reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), bind(api.CreateMilestoneOption{}), repo.CreateMilestone)
+ Post(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), bind(api.CreateMilestoneOption{}), repo.CreateMilestone)
m.Combo("/{id}").Get(repo.GetMilestone).
- Patch(reqToken(), reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), bind(api.EditMilestoneOption{}), repo.EditMilestone).
- Delete(reqToken(), reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), repo.DeleteMilestone)
+ Patch(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), bind(api.EditMilestoneOption{}), repo.EditMilestone).
+ Delete(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), repo.DeleteMilestone)
})
m.Get("/stargazers", repo.ListStargazers)
m.Get("/subscribers", repo.ListSubscribers)
m.Group("/subscription", func() {
m.Get("", user.IsWatching)
- m.Put("", reqToken(), user.Watch)
- m.Delete("", reqToken(), user.Unwatch)
+ m.Put("", reqToken(auth_model.AccessTokenScopeRepo), user.Watch)
+ m.Delete("", reqToken(auth_model.AccessTokenScopeRepo), user.Unwatch)
})
m.Group("/releases", func() {
m.Combo("").Get(repo.ListReleases).
- Post(reqToken(), reqRepoWriter(unit.TypeReleases), context.ReferencesGitRepo(), bind(api.CreateReleaseOption{}), repo.CreateRelease)
+ Post(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeReleases), context.ReferencesGitRepo(), bind(api.CreateReleaseOption{}), repo.CreateRelease)
m.Group("/{id}", func() {
m.Combo("").Get(repo.GetRelease).
- Patch(reqToken(), reqRepoWriter(unit.TypeReleases), context.ReferencesGitRepo(), bind(api.EditReleaseOption{}), repo.EditRelease).
- Delete(reqToken(), reqRepoWriter(unit.TypeReleases), repo.DeleteRelease)
+ Patch(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeReleases), context.ReferencesGitRepo(), bind(api.EditReleaseOption{}), repo.EditRelease).
+ Delete(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeReleases), repo.DeleteRelease)
m.Group("/assets", func() {
m.Combo("").Get(repo.ListReleaseAttachments).
- Post(reqToken(), reqRepoWriter(unit.TypeReleases), repo.CreateReleaseAttachment)
+ Post(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeReleases), repo.CreateReleaseAttachment)
m.Combo("/{asset}").Get(repo.GetReleaseAttachment).
- Patch(reqToken(), reqRepoWriter(unit.TypeReleases), bind(api.EditAttachmentOptions{}), repo.EditReleaseAttachment).
- Delete(reqToken(), reqRepoWriter(unit.TypeReleases), repo.DeleteReleaseAttachment)
+ Patch(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeReleases), bind(api.EditAttachmentOptions{}), repo.EditReleaseAttachment).
+ Delete(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeReleases), repo.DeleteReleaseAttachment)
})
})
m.Group("/tags", func() {
m.Combo("/{tag}").
Get(repo.GetReleaseByTag).
- Delete(reqToken(), reqRepoWriter(unit.TypeReleases), repo.DeleteReleaseByTag)
+ Delete(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeReleases), repo.DeleteReleaseByTag)
})
}, reqRepoReader(unit.TypeReleases))
- m.Post("/mirror-sync", reqToken(), reqRepoWriter(unit.TypeCode), repo.MirrorSync)
- m.Post("/push_mirrors-sync", reqAdmin(), repo.PushMirrorSync)
+ m.Post("/mirror-sync", reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeCode), repo.MirrorSync)
+ m.Post("/push_mirrors-sync", reqAdmin(), reqToken(auth_model.AccessTokenScopeRepo), repo.PushMirrorSync)
m.Group("/push_mirrors", func() {
m.Combo("").Get(repo.ListPushMirrors).
Post(bind(api.CreatePushMirrorOption{}), repo.AddPushMirror)
m.Combo("/{name}").
Delete(repo.DeletePushMirrorByRemoteName).
Get(repo.GetPushMirrorByName)
- }, reqAdmin())
+ }, reqAdmin(), reqToken(auth_model.AccessTokenScopeRepo))
m.Get("/editorconfig/{filename}", context.ReferencesGitRepo(), context.RepoRefForAPI, reqRepoReader(unit.TypeCode), repo.GetEditorconfig)
m.Group("/pulls", func() {
m.Combo("").Get(repo.ListPullRequests).
- Post(reqToken(), mustNotBeArchived, bind(api.CreatePullRequestOption{}), repo.CreatePullRequest)
+ Post(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.CreatePullRequestOption{}), repo.CreatePullRequest)
m.Group("/{index}", func() {
m.Combo("").Get(repo.GetPullRequest).
- Patch(reqToken(), bind(api.EditPullRequestOption{}), repo.EditPullRequest)
+ Patch(reqToken(auth_model.AccessTokenScopeRepo), bind(api.EditPullRequestOption{}), repo.EditPullRequest)
m.Get(".{diffType:diff|patch}", repo.DownloadPullDiffOrPatch)
- m.Post("/update", reqToken(), repo.UpdatePullRequest)
+ m.Post("/update", reqToken(auth_model.AccessTokenScopeRepo), repo.UpdatePullRequest)
m.Get("/commits", repo.GetPullRequestCommits)
m.Get("/files", repo.GetPullRequestFiles)
m.Combo("/merge").Get(repo.IsPullRequestMerged).
- Post(reqToken(), mustNotBeArchived, bind(forms.MergePullRequestForm{}), repo.MergePullRequest).
- Delete(reqToken(), mustNotBeArchived, repo.CancelScheduledAutoMerge)
+ Post(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(forms.MergePullRequestForm{}), repo.MergePullRequest).
+ Delete(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, repo.CancelScheduledAutoMerge)
m.Group("/reviews", func() {
m.Combo("").
Get(repo.ListPullReviews).
- Post(reqToken(), bind(api.CreatePullReviewOptions{}), repo.CreatePullReview)
+ Post(reqToken(auth_model.AccessTokenScopeRepo), bind(api.CreatePullReviewOptions{}), repo.CreatePullReview)
m.Group("/{id}", func() {
m.Combo("").
Get(repo.GetPullReview).
- Delete(reqToken(), repo.DeletePullReview).
- Post(reqToken(), bind(api.SubmitPullReviewOptions{}), repo.SubmitPullReview)
+ Delete(reqToken(auth_model.AccessTokenScopeRepo), repo.DeletePullReview).
+ Post(reqToken(auth_model.AccessTokenScopeRepo), bind(api.SubmitPullReviewOptions{}), repo.SubmitPullReview)
m.Combo("/comments").
Get(repo.GetPullReviewComments)
- m.Post("/dismissals", reqToken(), bind(api.DismissPullReviewOptions{}), repo.DismissPullReview)
- m.Post("/undismissals", reqToken(), repo.UnDismissPullReview)
+ m.Post("/dismissals", reqToken(auth_model.AccessTokenScopeRepo), bind(api.DismissPullReviewOptions{}), repo.DismissPullReview)
+ m.Post("/undismissals", reqToken(auth_model.AccessTokenScopeRepo), repo.UnDismissPullReview)
})
})
- m.Combo("/requested_reviewers").
- Delete(reqToken(), bind(api.PullReviewRequestOptions{}), repo.DeleteReviewRequests).
- Post(reqToken(), bind(api.PullReviewRequestOptions{}), repo.CreateReviewRequests)
+ m.Combo("/requested_reviewers", reqToken(auth_model.AccessTokenScopeRepo)).
+ Delete(bind(api.PullReviewRequestOptions{}), repo.DeleteReviewRequests).
+ Post(bind(api.PullReviewRequestOptions{}), repo.CreateReviewRequests)
})
}, mustAllowPulls, reqRepoReader(unit.TypeCode), context.ReferencesGitRepo())
m.Group("/statuses", func() {
m.Combo("/{sha}").Get(repo.GetCommitStatuses).
- Post(reqToken(), reqRepoWriter(unit.TypeCode), bind(api.CreateStatusOption{}), repo.NewCommitStatus)
+ Post(reqToken(auth_model.AccessTokenScopeRepoStatus), reqRepoWriter(unit.TypeCode), bind(api.CreateStatusOption{}), repo.NewCommitStatus)
}, reqRepoReader(unit.TypeCode))
m.Group("/commits", func() {
m.Get("", context.ReferencesGitRepo(), repo.GetAllCommits)
@@ -1062,7 +1096,7 @@ func Routes(ctx gocontext.Context) *web.Route {
m.Get("/tags/{sha}", repo.GetAnnotatedTag)
m.Get("/notes/{sha}", repo.GetNote)
}, context.ReferencesGitRepo(true), reqRepoReader(unit.TypeCode))
- m.Post("/diffpatch", reqRepoWriter(unit.TypeCode), reqToken(), bind(api.ApplyDiffPatchFileOptions{}), repo.ApplyDiffPatch)
+ m.Post("/diffpatch", reqRepoWriter(unit.TypeCode), reqToken(auth_model.AccessTokenScopeRepo), bind(api.ApplyDiffPatchFileOptions{}), repo.ApplyDiffPatch)
m.Group("/contents", func() {
m.Get("", repo.GetContentsList)
m.Get("/*", repo.GetContents)
@@ -1070,15 +1104,15 @@ func Routes(ctx gocontext.Context) *web.Route {
m.Post("", bind(api.CreateFileOptions{}), reqRepoBranchWriter, repo.CreateFile)
m.Put("", bind(api.UpdateFileOptions{}), reqRepoBranchWriter, repo.UpdateFile)
m.Delete("", bind(api.DeleteFileOptions{}), reqRepoBranchWriter, repo.DeleteFile)
- }, reqToken())
+ }, reqToken(auth_model.AccessTokenScopeRepo))
}, reqRepoReader(unit.TypeCode))
m.Get("/signing-key.gpg", misc.SigningKey)
m.Group("/topics", func() {
m.Combo("").Get(repo.ListTopics).
- Put(reqToken(), reqAdmin(), bind(api.RepoTopicOptions{}), repo.UpdateTopics)
+ Put(reqToken(auth_model.AccessTokenScopeRepo), reqAdmin(), bind(api.RepoTopicOptions{}), repo.UpdateTopics)
m.Group("/{topic}", func() {
- m.Combo("").Put(reqToken(), repo.AddTopic).
- Delete(reqToken(), repo.DeleteTopic)
+ m.Combo("").Put(reqToken(auth_model.AccessTokenScopeRepo), repo.AddTopic).
+ Delete(reqToken(auth_model.AccessTokenScopeRepo), repo.DeleteTopic)
}, reqAdmin())
}, reqAnyRepoReader())
m.Get("/issue_templates", context.ReferencesGitRepo(), repo.GetIssueTemplates)
@@ -1089,49 +1123,49 @@ func Routes(ctx gocontext.Context) *web.Route {
// NOTE: these are Gitea package management API - see packages.CommonRoutes and packages.DockerContainerRoutes for endpoints that implement package manager APIs
m.Group("/packages/{username}", func() {
m.Group("/{type}/{name}/{version}", func() {
- m.Get("", packages.GetPackage)
- m.Delete("", reqPackageAccess(perm.AccessModeWrite), packages.DeletePackage)
- m.Get("/files", packages.ListPackageFiles)
+ m.Get("", reqToken(auth_model.AccessTokenScopeReadPackage), packages.GetPackage)
+ m.Delete("", reqToken(auth_model.AccessTokenScopeDeletePackage), reqPackageAccess(perm.AccessModeWrite), packages.DeletePackage)
+ m.Get("/files", reqToken(auth_model.AccessTokenScopeReadPackage), packages.ListPackageFiles)
})
- m.Get("/", packages.ListPackages)
+ m.Get("/", reqToken(auth_model.AccessTokenScopeReadPackage), packages.ListPackages)
}, context_service.UserAssignmentAPI(), context.PackageAssignmentAPI(), reqPackageAccess(perm.AccessModeRead))
// Organizations
- m.Get("/user/orgs", reqToken(), org.ListMyOrgs)
+ m.Get("/user/orgs", reqToken(auth_model.AccessTokenScopeReadOrg), org.ListMyOrgs)
m.Group("/users/{username}/orgs", func() {
- m.Get("", org.ListUserOrgs)
- m.Get("/{org}/permissions", reqToken(), org.GetUserOrgsPermissions)
+ m.Get("", reqToken(auth_model.AccessTokenScopeReadOrg), org.ListUserOrgs)
+ m.Get("/{org}/permissions", reqToken(auth_model.AccessTokenScopeReadOrg), org.GetUserOrgsPermissions)
}, context_service.UserAssignmentAPI())
- m.Post("/orgs", reqToken(), bind(api.CreateOrgOption{}), org.Create)
- m.Get("/orgs", org.GetAll)
+ m.Post("/orgs", reqToken(auth_model.AccessTokenScopeWriteOrg), bind(api.CreateOrgOption{}), org.Create)
+ m.Get("/orgs", reqToken(auth_model.AccessTokenScopeReadOrg), org.GetAll)
m.Group("/orgs/{org}", func() {
- m.Combo("").Get(org.Get).
- Patch(reqToken(), reqOrgOwnership(), bind(api.EditOrgOption{}), org.Edit).
- Delete(reqToken(), reqOrgOwnership(), org.Delete)
- m.Combo("/repos").Get(user.ListOrgRepos).
- Post(reqToken(), bind(api.CreateRepoOption{}), repo.CreateOrgRepo)
+ m.Combo("").Get(reqToken(auth_model.AccessTokenScopeReadOrg), org.Get).
+ Patch(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgOwnership(), bind(api.EditOrgOption{}), org.Edit).
+ Delete(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgOwnership(), org.Delete)
+ m.Combo("/repos").Get(reqToken(auth_model.AccessTokenScopeReadOrg), user.ListOrgRepos).
+ Post(reqToken(auth_model.AccessTokenScopeWriteOrg), bind(api.CreateRepoOption{}), repo.CreateOrgRepo)
m.Group("/members", func() {
- m.Get("", org.ListMembers)
- m.Combo("/{username}").Get(org.IsMember).
- Delete(reqToken(), reqOrgOwnership(), org.DeleteMember)
+ m.Get("", reqToken(auth_model.AccessTokenScopeReadOrg), org.ListMembers)
+ m.Combo("/{username}").Get(reqToken(auth_model.AccessTokenScopeReadOrg), org.IsMember).
+ Delete(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgOwnership(), org.DeleteMember)
})
m.Group("/public_members", func() {
- m.Get("", org.ListPublicMembers)
- m.Combo("/{username}").Get(org.IsPublicMember).
- Put(reqToken(), reqOrgMembership(), org.PublicizeMember).
- Delete(reqToken(), reqOrgMembership(), org.ConcealMember)
+ m.Get("", reqToken(auth_model.AccessTokenScopeReadOrg), org.ListPublicMembers)
+ m.Combo("/{username}").Get(reqToken(auth_model.AccessTokenScopeReadOrg), org.IsPublicMember).
+ Put(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgMembership(), org.PublicizeMember).
+ Delete(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgMembership(), org.ConcealMember)
})
m.Group("/teams", func() {
- m.Get("", org.ListTeams)
- m.Post("", reqOrgOwnership(), bind(api.CreateTeamOption{}), org.CreateTeam)
- m.Get("/search", org.SearchTeam)
- }, reqToken(), reqOrgMembership())
+ m.Get("", reqToken(auth_model.AccessTokenScopeReadOrg), org.ListTeams)
+ m.Post("", reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgOwnership(), bind(api.CreateTeamOption{}), org.CreateTeam)
+ m.Get("/search", reqToken(auth_model.AccessTokenScopeReadOrg), org.SearchTeam)
+ }, reqOrgMembership())
m.Group("/labels", func() {
- m.Get("", org.ListLabels)
- m.Post("", reqToken(), reqOrgOwnership(), bind(api.CreateLabelOption{}), org.CreateLabel)
- m.Combo("/{id}").Get(org.GetLabel).
- Patch(reqToken(), reqOrgOwnership(), bind(api.EditLabelOption{}), org.EditLabel).
- Delete(reqToken(), reqOrgOwnership(), org.DeleteLabel)
+ m.Get("", reqToken(auth_model.AccessTokenScopeReadOrg), org.ListLabels)
+ m.Post("", reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgOwnership(), bind(api.CreateLabelOption{}), org.CreateLabel)
+ m.Combo("/{id}").Get(reqToken(auth_model.AccessTokenScopeReadOrg), org.GetLabel).
+ Patch(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgOwnership(), bind(api.EditLabelOption{}), org.EditLabel).
+ Delete(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgOwnership(), org.DeleteLabel)
})
m.Group("/hooks", func() {
m.Combo("").Get(org.ListHooks).
@@ -1139,27 +1173,27 @@ func Routes(ctx gocontext.Context) *web.Route {
m.Combo("/{id}").Get(org.GetHook).
Patch(bind(api.EditHookOption{}), org.EditHook).
Delete(org.DeleteHook)
- }, reqToken(), reqOrgOwnership(), reqWebhooksEnabled())
+ }, reqToken(auth_model.AccessTokenScopeAdminOrgHook), reqOrgOwnership(), reqWebhooksEnabled())
}, orgAssignment(true))
m.Group("/teams/{teamid}", func() {
- m.Combo("").Get(org.GetTeam).
- Patch(reqOrgOwnership(), bind(api.EditTeamOption{}), org.EditTeam).
- Delete(reqOrgOwnership(), org.DeleteTeam)
+ m.Combo("").Get(reqToken(auth_model.AccessTokenScopeReadOrg), org.GetTeam).
+ Patch(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgOwnership(), bind(api.EditTeamOption{}), org.EditTeam).
+ Delete(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgOwnership(), org.DeleteTeam)
m.Group("/members", func() {
- m.Get("", org.GetTeamMembers)
+ m.Get("", reqToken(auth_model.AccessTokenScopeReadOrg), org.GetTeamMembers)
m.Combo("/{username}").
- Get(org.GetTeamMember).
- Put(reqOrgOwnership(), org.AddTeamMember).
- Delete(reqOrgOwnership(), org.RemoveTeamMember)
+ Get(reqToken(auth_model.AccessTokenScopeReadOrg), org.GetTeamMember).
+ Put(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgOwnership(), org.AddTeamMember).
+ Delete(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgOwnership(), org.RemoveTeamMember)
})
m.Group("/repos", func() {
- m.Get("", org.GetTeamRepos)
+ m.Get("", reqToken(auth_model.AccessTokenScopeReadOrg), org.GetTeamRepos)
m.Combo("/{org}/{reponame}").
- Put(org.AddTeamRepository).
- Delete(org.RemoveTeamRepository).
- Get(org.GetTeamRepo)
+ Put(reqToken(auth_model.AccessTokenScopeWriteOrg), org.AddTeamRepository).
+ Delete(reqToken(auth_model.AccessTokenScopeWriteOrg), org.RemoveTeamRepository).
+ Get(reqToken(auth_model.AccessTokenScopeReadOrg), org.GetTeamRepo)
})
- }, orgAssignment(false, true), reqToken(), reqTeamMembership())
+ }, orgAssignment(false, true), reqToken(""), reqTeamMembership())
m.Group("/admin", func() {
m.Group("/cron", func() {
@@ -1187,7 +1221,7 @@ func Routes(ctx gocontext.Context) *web.Route {
m.Post("/{username}/{reponame}", admin.AdoptRepository)
m.Delete("/{username}/{reponame}", admin.DeleteUnadoptedRepository)
})
- }, reqToken(), reqSiteAdmin())
+ }, reqToken(auth_model.AccessTokenScopeSudo), reqSiteAdmin())
m.Group("/topics", func() {
m.Get("/search", repo.TopicSearch)
diff --git a/routers/web/user/setting/applications.go b/routers/web/user/setting/applications.go
index 23c215738d..b66806ff2d 100644
--- a/routers/web/user/setting/applications.go
+++ b/routers/web/user/setting/applications.go
@@ -42,9 +42,15 @@ func ApplicationsPost(ctx *context.Context) {
return
}
+ scope, err := form.GetScope()
+ if err != nil {
+ ctx.ServerError("GetScope", err)
+ return
+ }
t := &auth_model.AccessToken{
- UID: ctx.Doer.ID,
- Name: form.Name,
+ UID: ctx.Doer.ID,
+ Name: form.Name,
+ Scope: scope,
}
exist, err := auth_model.AccessTokenByNameExists(t)
diff --git a/services/auth/oauth2.go b/services/auth/oauth2.go
index c0a8250e95..1be78b85c5 100644
--- a/services/auth/oauth2.go
+++ b/services/auth/oauth2.go
@@ -59,6 +59,8 @@ func (o *OAuth2) Name() string {
}
// userIDFromToken returns the user id corresponding to the OAuth token.
+// It will set 'IsApiToken' to true if the token is an API token and
+// set 'ApiTokenScope' to the scope of the access token
func (o *OAuth2) userIDFromToken(req *http.Request, store DataStore) int64 {
_ = req.ParseForm()
@@ -86,6 +88,7 @@ func (o *OAuth2) userIDFromToken(req *http.Request, store DataStore) int64 {
uid := CheckOAuthAccessToken(tokenSHA)
if uid != 0 {
store.GetData()["IsApiToken"] = true
+ store.GetData()["ApiTokenScope"] = auth_model.AccessTokenScopeAll // fallback to all
}
return uid
}
@@ -101,6 +104,7 @@ func (o *OAuth2) userIDFromToken(req *http.Request, store DataStore) int64 {
log.Error("UpdateAccessToken: %v", err)
}
store.GetData()["IsApiToken"] = true
+ store.GetData()["ApiTokenScope"] = t.Scope
return t.UID
}
diff --git a/services/forms/user_form.go b/services/forms/user_form.go
index bbea58310a..285bc398b2 100644
--- a/services/forms/user_form.go
+++ b/services/forms/user_form.go
@@ -9,6 +9,7 @@ import (
"net/http"
"strings"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs"
@@ -377,7 +378,8 @@ func (f *AddSecretForm) Validate(req *http.Request, errs binding.Errors) binding
// NewAccessTokenForm form for creating access token
type NewAccessTokenForm struct {
- Name string `binding:"Required;MaxSize(255)"`
+ Name string `binding:"Required;MaxSize(255)"`
+ Scope []string
}
// Validate validates the fields
@@ -386,6 +388,12 @@ func (f *NewAccessTokenForm) Validate(req *http.Request, errs binding.Errors) bi
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
}
+func (f *NewAccessTokenForm) GetScope() (auth_model.AccessTokenScope, error) {
+ scope := strings.Join(f.Scope, ",")
+ s, err := auth_model.AccessTokenScope(scope).Normalize()
+ return s, err
+}
+
// EditOAuth2ApplicationForm form for editing oauth2 applications
type EditOAuth2ApplicationForm struct {
Name string `binding:"Required;MaxSize(255)" form:"application_name"`
diff --git a/services/forms/user_form_test.go b/services/forms/user_form_test.go
index 463b39d0bf..225686f0fe 100644
--- a/services/forms/user_form_test.go
+++ b/services/forms/user_form_test.go
@@ -4,8 +4,10 @@
package forms
import (
+ "strconv"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/modules/setting"
"github.com/stretchr/testify/assert"
@@ -83,3 +85,28 @@ func TestRegisterForm_IsDomainAllowed_BlocklistedEmail(t *testing.T) {
assert.Equal(t, v.valid, form.IsEmailDomainAllowed())
}
}
+
+func TestNewAccessTokenForm_GetScope(t *testing.T) {
+ tests := []struct {
+ form NewAccessTokenForm
+ scope auth_model.AccessTokenScope
+ expectedErr error
+ }{
+ {
+ form: NewAccessTokenForm{Name: "test", Scope: []string{"repo"}},
+ scope: "repo",
+ },
+ {
+ form: NewAccessTokenForm{Name: "test", Scope: []string{"repo", "user"}},
+ scope: "repo,user",
+ },
+ }
+
+ for i, test := range tests {
+ t.Run(strconv.Itoa(i), func(t *testing.T) {
+ scope, err := test.form.GetScope()
+ assert.Equal(t, test.expectedErr, err)
+ assert.Equal(t, test.scope, scope)
+ })
+ }
+}
diff --git a/templates/user/settings/applications.tmpl b/templates/user/settings/applications.tmpl
index e05cebb0e4..c108f20b5b 100644
--- a/templates/user/settings/applications.tmpl
+++ b/templates/user/settings/applications.tmpl
@@ -41,6 +41,207 @@
<label for="name">{{.locale.Tr "settings.token_name"}}</label>
<input id="name" name="name" value="{{.name}}" autofocus required>
</div>
+ <details class="ui optional field">
+ <summary class="p-2">
+ {{.locale.Tr "settings.select_scopes"}}
+ </summary>
+ <div class="field pl-2">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="repo">
+ <label>repo</label>
+ </div>
+ </div>
+ <div class="field pl-4">
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="repo:status">
+ <label>repo:status</label>
+ </div>
+ </div>
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="public:repo">
+ <label>public_repo</label>
+ </div>
+ </div>
+ </div>
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="admin:org">
+ <label>admin:org</label>
+ </div>
+ </div>
+ <div class="field pl-4">
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="write:org">
+ <label>write:org</label>
+ </div>
+ </div>
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="read:public_key">
+ <label>read:public_key</label>
+ </div>
+ </div>
+ </div>
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="admin:public_key">
+ <label>admin:public_key</label>
+ </div>
+ </div>
+ <div class="field pl-4">
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="write:public_key">
+ <label>write:public_key</label>
+ </div>
+ </div>
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="read:public_key">
+ <label>read:public_key</label>
+ </div>
+ </div>
+ </div>
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="admin:repo_hook">
+ <label>admin:repo_hook</label>
+ </div>
+ </div>
+ <div class="field pl-4">
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="write:repo_hook">
+ <label>write:repo_hook</label>
+ </div>
+ </div>
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="read:repo_hook">
+ <label>read:repo_hook</label>
+ </div>
+ </div>
+ </div>
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="admin:org_hook">
+ <label>admin:org_hook</label>
+ </div>
+ </div>
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="notification">
+ <label>notification</label>
+ </div>
+ </div>
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="user">
+ <label>user</label>
+ </div>
+ </div>
+ <div class="field pl-4">
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="read:user">
+ <label>read:user</label>
+ </div>
+ </div>
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="user:email">
+ <label>user:email</label>
+ </div>
+ </div>
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="user:follow">
+ <label>user:follow</label>
+ </div>
+ </div>
+ </div>
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="delete:repo">
+ <label>delete_repo</label>
+ </div>
+ </div>
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="package">
+ <label>package</label>
+ </div>
+ </div>
+ <div class="field pl-4">
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="write:package">
+ <label>write:package</label>
+ </div>
+ </div>
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="read:package">
+ <label>read:package</label>
+ </div>
+ </div>
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="delete:package">
+ <label>delete:package</label>
+ </div>
+ </div>
+ </div>
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="admin:gpg_key">
+ <label>admin:gpg_key</label>
+ </div>
+ </div>
+ <div class="field pl-4">
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="write:gpg_key">
+ <label>write:gpg_key</label>
+ </div>
+ </div>
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="read:gpg_key">
+ <label>read:gpg_key</label>
+ </div>
+ </div>
+ </div>
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="admin:application">
+ <label>admin:application</label>
+ </div>
+ </div>
+ <div class="field pl-4">
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="write:application">
+ <label>write:application</label>
+ </div>
+ </div>
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="read:application">
+ <label>read:application</label>
+ </div>
+ </div>
+ </div>
+ <div class="field">
+ <div class="ui checkbox">
+ <input class="enable-system" type="checkbox" name="scope" value="sudo">
+ <label>sudo</label>
+ </div>
+ </div>
+ </details>
<button class="ui green button">
{{.locale.Tr "settings.generate_token"}}
</button>
diff --git a/tests/integration/api_admin_org_test.go b/tests/integration/api_admin_org_test.go
index 05825eff31..89617f7a2c 100644
--- a/tests/integration/api_admin_org_test.go
+++ b/tests/integration/api_admin_org_test.go
@@ -9,6 +9,7 @@ import (
"strings"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
api "code.gitea.io/gitea/modules/structs"
@@ -20,7 +21,7 @@ import (
func TestAPIAdminOrgCreate(t *testing.T) {
onGiteaRun(t, func(*testing.T, *url.URL) {
session := loginUser(t, "user1")
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeSudo)
org := api.CreateOrgOption{
UserName: "user2_org",
@@ -54,7 +55,7 @@ func TestAPIAdminOrgCreate(t *testing.T) {
func TestAPIAdminOrgCreateBadVisibility(t *testing.T) {
onGiteaRun(t, func(*testing.T, *url.URL) {
session := loginUser(t, "user1")
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeSudo)
org := api.CreateOrgOption{
UserName: "user2_org",
diff --git a/tests/integration/api_admin_test.go b/tests/integration/api_admin_test.go
index 53952210fd..b608c26f6e 100644
--- a/tests/integration/api_admin_test.go
+++ b/tests/integration/api_admin_test.go
@@ -9,6 +9,7 @@ import (
"testing"
asymkey_model "code.gitea.io/gitea/models/asymkey"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/json"
@@ -24,7 +25,7 @@ func TestAPIAdminCreateAndDeleteSSHKey(t *testing.T) {
session := loginUser(t, "user1")
keyOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user2"})
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeSudo)
urlStr := fmt.Sprintf("/api/v1/admin/users/%s/keys?token=%s", keyOwner.Name, token)
req := NewRequestWithValues(t, "POST", urlStr, map[string]string{
"key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM= nocomment\n",
@@ -51,7 +52,7 @@ func TestAPIAdminDeleteMissingSSHKey(t *testing.T) {
defer tests.PrepareTestEnv(t)()
// user1 is an admin user
- token := getUserToken(t, "user1")
+ token := getUserToken(t, "user1", auth_model.AccessTokenScopeSudo)
req := NewRequestf(t, "DELETE", "/api/v1/admin/users/user1/keys/%d?token=%s", unittest.NonexistentID, token)
MakeRequest(t, req, http.StatusNotFound)
}
@@ -60,7 +61,7 @@ func TestAPIAdminDeleteUnauthorizedKey(t *testing.T) {
defer tests.PrepareTestEnv(t)()
adminUsername := "user1"
normalUsername := "user2"
- token := getUserToken(t, adminUsername)
+ token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeSudo)
urlStr := fmt.Sprintf("/api/v1/admin/users/%s/keys?token=%s", adminUsername, token)
req := NewRequestWithValues(t, "POST", urlStr, map[string]string{
@@ -81,7 +82,7 @@ func TestAPISudoUser(t *testing.T) {
defer tests.PrepareTestEnv(t)()
adminUsername := "user1"
normalUsername := "user2"
- token := getUserToken(t, adminUsername)
+ token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeSudo)
urlStr := fmt.Sprintf("/api/v1/user?sudo=%s&token=%s", normalUsername, token)
req := NewRequest(t, "GET", urlStr)
@@ -97,7 +98,7 @@ func TestAPISudoUserForbidden(t *testing.T) {
adminUsername := "user1"
normalUsername := "user2"
- token := getUserToken(t, normalUsername)
+ token := getUserToken(t, normalUsername, auth_model.AccessTokenScopeSudo)
urlStr := fmt.Sprintf("/api/v1/user?sudo=%s&token=%s", adminUsername, token)
req := NewRequest(t, "GET", urlStr)
MakeRequest(t, req, http.StatusForbidden)
@@ -106,7 +107,7 @@ func TestAPISudoUserForbidden(t *testing.T) {
func TestAPIListUsers(t *testing.T) {
defer tests.PrepareTestEnv(t)()
adminUsername := "user1"
- token := getUserToken(t, adminUsername)
+ token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeSudo)
urlStr := fmt.Sprintf("/api/v1/admin/users?token=%s", token)
req := NewRequest(t, "GET", urlStr)
@@ -142,7 +143,7 @@ func TestAPIListUsersNonAdmin(t *testing.T) {
func TestAPICreateUserInvalidEmail(t *testing.T) {
defer tests.PrepareTestEnv(t)()
adminUsername := "user1"
- token := getUserToken(t, adminUsername)
+ token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeSudo)
urlStr := fmt.Sprintf("/api/v1/admin/users?token=%s", token)
req := NewRequestWithValues(t, "POST", urlStr, map[string]string{
"email": "invalid_email@domain.com\r\n",
@@ -160,7 +161,7 @@ func TestAPICreateUserInvalidEmail(t *testing.T) {
func TestAPICreateAndDeleteUser(t *testing.T) {
defer tests.PrepareTestEnv(t)()
adminUsername := "user1"
- token := getUserToken(t, adminUsername)
+ token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeSudo)
req := NewRequestWithValues(
t,
@@ -186,7 +187,7 @@ func TestAPICreateAndDeleteUser(t *testing.T) {
func TestAPIEditUser(t *testing.T) {
defer tests.PrepareTestEnv(t)()
adminUsername := "user1"
- token := getUserToken(t, adminUsername)
+ token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeSudo)
urlStr := fmt.Sprintf("/api/v1/admin/users/%s?token=%s", "user2", token)
req := NewRequestWithValues(t, "PATCH", urlStr, map[string]string{
@@ -228,7 +229,7 @@ func TestAPIEditUser(t *testing.T) {
func TestAPICreateRepoForUser(t *testing.T) {
defer tests.PrepareTestEnv(t)()
adminUsername := "user1"
- token := getUserToken(t, adminUsername)
+ token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeSudo)
req := NewRequestWithJSON(
t,
diff --git a/tests/integration/api_branch_test.go b/tests/integration/api_branch_test.go
index 278edfbf9c..0d4a750a29 100644
--- a/tests/integration/api_branch_test.go
+++ b/tests/integration/api_branch_test.go
@@ -8,6 +8,7 @@ import (
"net/url"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/tests"
@@ -15,7 +16,7 @@ import (
)
func testAPIGetBranch(t *testing.T, branchName string, exists bool) {
- token := getUserToken(t, "user2")
+ token := getUserToken(t, "user2", auth_model.AccessTokenScopeRepo)
req := NewRequestf(t, "GET", "/api/v1/repos/user2/repo1/branches/%s?token=%s", branchName, token)
resp := MakeRequest(t, req, NoExpectedStatus)
if !exists {
@@ -31,7 +32,7 @@ func testAPIGetBranch(t *testing.T, branchName string, exists bool) {
}
func testAPIGetBranchProtection(t *testing.T, branchName string, expectedHTTPStatus int) {
- token := getUserToken(t, "user2")
+ token := getUserToken(t, "user2", auth_model.AccessTokenScopeRepo)
req := NewRequestf(t, "GET", "/api/v1/repos/user2/repo1/branch_protections/%s?token=%s", branchName, token)
resp := MakeRequest(t, req, expectedHTTPStatus)
@@ -43,7 +44,7 @@ func testAPIGetBranchProtection(t *testing.T, branchName string, expectedHTTPSta
}
func testAPICreateBranchProtection(t *testing.T, branchName string, expectedHTTPStatus int) {
- token := getUserToken(t, "user2")
+ token := getUserToken(t, "user2", auth_model.AccessTokenScopeRepo)
req := NewRequestWithJSON(t, "POST", "/api/v1/repos/user2/repo1/branch_protections?token="+token, &api.BranchProtection{
RuleName: branchName,
})
@@ -57,7 +58,7 @@ func testAPICreateBranchProtection(t *testing.T, branchName string, expectedHTTP
}
func testAPIEditBranchProtection(t *testing.T, branchName string, body *api.BranchProtection, expectedHTTPStatus int) {
- token := getUserToken(t, "user2")
+ token := getUserToken(t, "user2", auth_model.AccessTokenScopeRepo)
req := NewRequestWithJSON(t, "PATCH", "/api/v1/repos/user2/repo1/branch_protections/"+branchName+"?token="+token, body)
resp := MakeRequest(t, req, expectedHTTPStatus)
@@ -69,13 +70,13 @@ func testAPIEditBranchProtection(t *testing.T, branchName string, body *api.Bran
}
func testAPIDeleteBranchProtection(t *testing.T, branchName string, expectedHTTPStatus int) {
- token := getUserToken(t, "user2")
+ token := getUserToken(t, "user2", auth_model.AccessTokenScopeRepo)
req := NewRequestf(t, "DELETE", "/api/v1/repos/user2/repo1/branch_protections/%s?token=%s", branchName, token)
MakeRequest(t, req, expectedHTTPStatus)
}
func testAPIDeleteBranch(t *testing.T, branchName string, expectedHTTPStatus int) {
- token := getUserToken(t, "user2")
+ token := getUserToken(t, "user2", auth_model.AccessTokenScopeRepo)
req := NewRequestf(t, "DELETE", "/api/v1/repos/user2/repo1/branches/%s?token=%s", branchName, token)
MakeRequest(t, req, expectedHTTPStatus)
}
@@ -101,7 +102,7 @@ func TestAPICreateBranch(t *testing.T) {
func testAPICreateBranches(t *testing.T, giteaURL *url.URL) {
username := "user2"
- ctx := NewAPITestContext(t, username, "my-noo-repo")
+ ctx := NewAPITestContext(t, username, "my-noo-repo", auth_model.AccessTokenScopeRepo)
giteaURL.Path = ctx.GitPath()
t.Run("CreateRepo", doAPICreateRepository(ctx, false))
@@ -149,7 +150,7 @@ func testAPICreateBranches(t *testing.T, giteaURL *url.URL) {
}
func testAPICreateBranch(t testing.TB, session *TestSession, user, repo, oldBranch, newBranch string, status int) bool {
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
req := NewRequestWithJSON(t, "POST", "/api/v1/repos/"+user+"/"+repo+"/branches?token="+token, &api.CreateBranchRepoOption{
BranchName: newBranch,
OldBranchName: oldBranch,
diff --git a/tests/integration/api_comment_attachment_test.go b/tests/integration/api_comment_attachment_test.go
index b23db53d28..1f916ffa15 100644
--- a/tests/integration/api_comment_attachment_test.go
+++ b/tests/integration/api_comment_attachment_test.go
@@ -12,6 +12,7 @@ import (
"net/http"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
@@ -81,7 +82,7 @@ func TestAPICreateCommentAttachment(t *testing.T) {
repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, repoOwner.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d/assets?token=%s",
repoOwner.Name, repo.Name, comment.ID, token)
@@ -120,7 +121,7 @@ func TestAPIEditCommentAttachment(t *testing.T) {
repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, repoOwner.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d/assets/%d?token=%s",
repoOwner.Name, repo.Name, comment.ID, attachment.ID, token)
req := NewRequestWithValues(t, "PATCH", urlStr, map[string]string{
@@ -143,7 +144,7 @@ func TestAPIDeleteCommentAttachment(t *testing.T) {
repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, repoOwner.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d/assets/%d?token=%s",
repoOwner.Name, repo.Name, comment.ID, attachment.ID, token)
diff --git a/tests/integration/api_comment_test.go b/tests/integration/api_comment_test.go
index fb2d41223e..cc7712e548 100644
--- a/tests/integration/api_comment_test.go
+++ b/tests/integration/api_comment_test.go
@@ -9,6 +9,7 @@ import (
"net/url"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
@@ -75,8 +76,9 @@ func TestAPIListIssueComments(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID})
repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
- req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/%d/comments",
- repoOwner.Name, repo.Name, issue.Index)
+ token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeRepo)
+ req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/%d/comments?token=%s",
+ repoOwner.Name, repo.Name, issue.Index, token)
resp := MakeRequest(t, req, http.StatusOK)
var comments []*api.Comment
@@ -94,7 +96,7 @@ func TestAPICreateComment(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID})
repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
- token := getUserToken(t, repoOwner.Name)
+ token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeRepo)
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/comments?token=%s",
repoOwner.Name, repo.Name, issue.Index, token)
req := NewRequestWithValues(t, "POST", urlStr, map[string]string{
@@ -116,7 +118,7 @@ func TestAPIGetComment(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: comment.Issue.RepoID})
repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
- token := getUserToken(t, repoOwner.Name)
+ token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeRepo)
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d", repoOwner.Name, repo.Name, comment.ID)
MakeRequest(t, req, http.StatusOK)
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d?token=%s", repoOwner.Name, repo.Name, comment.ID, token)
@@ -144,7 +146,7 @@ func TestAPIEditComment(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID})
repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
- token := getUserToken(t, repoOwner.Name)
+ token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeRepo)
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d?token=%s",
repoOwner.Name, repo.Name, comment.ID, token)
req := NewRequestWithValues(t, "PATCH", urlStr, map[string]string{
@@ -168,7 +170,7 @@ func TestAPIDeleteComment(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID})
repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
- token := getUserToken(t, repoOwner.Name)
+ token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeRepo)
req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/comments/%d?token=%s",
repoOwner.Name, repo.Name, comment.ID, token)
MakeRequest(t, req, http.StatusNoContent)
diff --git a/tests/integration/api_gpg_keys_test.go b/tests/integration/api_gpg_keys_test.go
index 162a5a4fd5..f66961786f 100644
--- a/tests/integration/api_gpg_keys_test.go
+++ b/tests/integration/api_gpg_keys_test.go
@@ -9,6 +9,7 @@ import (
"strconv"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/tests"
@@ -20,7 +21,8 @@ type makeRequestFunc func(testing.TB, *http.Request, int) *httptest.ResponseReco
func TestGPGKeys(t *testing.T) {
defer tests.PrepareTestEnv(t)()
session := loginUser(t, "user2")
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
+ tokenWithGPGKeyScope := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAdminGPGKey, auth_model.AccessTokenScopeRepo)
tt := []struct {
name string
@@ -34,6 +36,10 @@ func TestGPGKeys(t *testing.T) {
},
{
name: "LoggedAsUser2", makeRequest: session.MakeRequest, token: token,
+ results: []int{http.StatusForbidden, http.StatusOK, http.StatusForbidden, http.StatusForbidden, http.StatusForbidden, http.StatusForbidden, http.StatusForbidden, http.StatusForbidden, http.StatusForbidden},
+ },
+ {
+ name: "LoggedAsUser2WithScope", makeRequest: session.MakeRequest, token: tokenWithGPGKeyScope,
results: []int{http.StatusOK, http.StatusOK, http.StatusNotFound, http.StatusNoContent, http.StatusUnprocessableEntity, http.StatusNotFound, http.StatusCreated, http.StatusNotFound, http.StatusCreated},
},
}
@@ -73,7 +79,7 @@ func TestGPGKeys(t *testing.T) {
t.Run("CheckState", func(t *testing.T) {
var keys []*api.GPGKey
- req := NewRequest(t, "GET", "/api/v1/user/gpg_keys?token="+token) // GET all keys
+ req := NewRequest(t, "GET", "/api/v1/user/gpg_keys?token="+tokenWithGPGKeyScope) // GET all keys
resp := MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &keys)
assert.Len(t, keys, 1)
@@ -89,7 +95,7 @@ func TestGPGKeys(t *testing.T) {
assert.Empty(t, subKey.Emails)
var key api.GPGKey
- req = NewRequest(t, "GET", "/api/v1/user/gpg_keys/"+strconv.FormatInt(primaryKey1.ID, 10)+"?token="+token) // Primary key 1
+ req = NewRequest(t, "GET", "/api/v1/user/gpg_keys/"+strconv.FormatInt(primaryKey1.ID, 10)+"?token="+tokenWithGPGKeyScope) // Primary key 1
resp = MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &key)
assert.EqualValues(t, "38EA3BCED732982C", key.KeyID)
@@ -97,7 +103,7 @@ func TestGPGKeys(t *testing.T) {
assert.EqualValues(t, "user2@example.com", key.Emails[0].Email)
assert.True(t, key.Emails[0].Verified)
- req = NewRequest(t, "GET", "/api/v1/user/gpg_keys/"+strconv.FormatInt(subKey.ID, 10)+"?token="+token) // Subkey of 38EA3BCED732982C
+ req = NewRequest(t, "GET", "/api/v1/user/gpg_keys/"+strconv.FormatInt(subKey.ID, 10)+"?token="+tokenWithGPGKeyScope) // Subkey of 38EA3BCED732982C
resp = MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &key)
assert.EqualValues(t, "70D7C694D17D03AD", key.KeyID)
diff --git a/tests/integration/api_helper_for_declarative_test.go b/tests/integration/api_helper_for_declarative_test.go
index dbfe502ec1..3524ce9834 100644
--- a/tests/integration/api_helper_for_declarative_test.go
+++ b/tests/integration/api_helper_for_declarative_test.go
@@ -13,6 +13,7 @@ import (
"testing"
"time"
+ "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/perm"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/json"
@@ -31,9 +32,9 @@ type APITestContext struct {
ExpectedCode int
}
-func NewAPITestContext(t *testing.T, username, reponame string) APITestContext {
+func NewAPITestContext(t *testing.T, username, reponame string, scope ...auth.AccessTokenScope) APITestContext {
session := loginUser(t, username)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, scope...)
return APITestContext{
Session: session,
Token: token,
diff --git a/tests/integration/api_httpsig_test.go b/tests/integration/api_httpsig_test.go
index 881bb45ca4..57f83490dc 100644
--- a/tests/integration/api_httpsig_test.go
+++ b/tests/integration/api_httpsig_test.go
@@ -10,6 +10,7 @@ import (
"net/url"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/tests"
@@ -52,7 +53,7 @@ func TestHTTPSigPubKey(t *testing.T) {
// Add our public key to user1
defer tests.PrepareTestEnv(t)()
session := loginUser(t, "user1")
- token := url.QueryEscape(getTokenForLoggedInUser(t, session))
+ token := url.QueryEscape(getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAdminPublicKey, auth_model.AccessTokenScopeSudo))
keysURL := fmt.Sprintf("/api/v1/user/keys?token=%s", token)
keyType := "ssh-rsa"
keyContent := "AAAAB3NzaC1yc2EAAAADAQABAAABAQCqOZB5vkRvXFXups1/0StDRdG8plbNSwsWEnNnP4Bvurxa0+z3W9B8GLKnDiLw5MbpbMNyBlpXw13GfuIeciy10DWTz0xUbiy3J3KabCaT36asIw2y7k6Z0jL0UBnrVENwq5/lUbZYqSZ4rRU744wkhh8TULpzM14npQCZwg6aEbG+MwjzddQ72fR+3BPBrKn5dTmmu8rH99O+U+Nuto81Tg7PA+NUupcHOmhdiEGq49plgVFXK98Vks5tiybL4GuzFyWgyX73Dg/QBMn2eMHt1EMv5Gs3i6GFhKKGo4rjDi9qI6PX5oDR4LTNe6cR8td8YhVD8WFZwLLl/vaYyIqd"
diff --git a/tests/integration/api_issue_attachment_test.go b/tests/integration/api_issue_attachment_test.go
index 0558dda56a..b4d6dab42a 100644
--- a/tests/integration/api_issue_attachment_test.go
+++ b/tests/integration/api_issue_attachment_test.go
@@ -12,6 +12,7 @@ import (
"net/http"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
@@ -72,7 +73,7 @@ func TestAPICreateIssueAttachment(t *testing.T) {
repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, repoOwner.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/assets?token=%s",
repoOwner.Name, repo.Name, issue.Index, token)
@@ -110,7 +111,7 @@ func TestAPIEditIssueAttachment(t *testing.T) {
repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, repoOwner.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/assets/%d?token=%s",
repoOwner.Name, repo.Name, issue.Index, attachment.ID, token)
req := NewRequestWithValues(t, "PATCH", urlStr, map[string]string{
@@ -132,7 +133,7 @@ func TestAPIDeleteIssueAttachment(t *testing.T) {
repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, repoOwner.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/assets/%d?token=%s",
repoOwner.Name, repo.Name, issue.Index, attachment.ID, token)
diff --git a/tests/integration/api_issue_label_test.go b/tests/integration/api_issue_label_test.go
index 6f0fd87913..1824015983 100644
--- a/tests/integration/api_issue_label_test.go
+++ b/tests/integration/api_issue_label_test.go
@@ -9,6 +9,7 @@ import (
"strings"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
@@ -24,7 +25,7 @@ func TestAPIModifyLabels(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/labels?token=%s", owner.Name, repo.Name, token)
// CreateLabel
@@ -96,7 +97,7 @@ func TestAPIAddIssueLabels(t *testing.T) {
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/labels?token=%s",
repo.OwnerName, repo.Name, issue.Index, token)
req := NewRequestWithJSON(t, "POST", urlStr, &api.IssueLabelsOption{
@@ -119,7 +120,7 @@ func TestAPIReplaceIssueLabels(t *testing.T) {
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/labels?token=%s",
owner.Name, repo.Name, issue.Index, token)
req := NewRequestWithJSON(t, "PUT", urlStr, &api.IssueLabelsOption{
@@ -143,7 +144,7 @@ func TestAPIModifyOrgLabels(t *testing.T) {
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
user := "user1"
session := loginUser(t, user)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo, auth_model.AccessTokenScopeAdminOrg)
urlStr := fmt.Sprintf("/api/v1/orgs/%s/labels?token=%s", owner.Name, token)
// CreateLabel
diff --git a/tests/integration/api_issue_milestone_test.go b/tests/integration/api_issue_milestone_test.go
index 60766e10fd..cbce795bc9 100644
--- a/tests/integration/api_issue_milestone_test.go
+++ b/tests/integration/api_issue_milestone_test.go
@@ -8,6 +8,7 @@ import (
"net/http"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
@@ -28,7 +29,7 @@ func TestAPIIssuesMilestone(t *testing.T) {
assert.Equal(t, structs.StateOpen, milestone.State())
session := loginUser(t, owner.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
// update values of issue
milestoneState := "closed"
diff --git a/tests/integration/api_issue_reaction_test.go b/tests/integration/api_issue_reaction_test.go
index 4e2ae3d57d..76140d7511 100644
--- a/tests/integration/api_issue_reaction_test.go
+++ b/tests/integration/api_issue_reaction_test.go
@@ -9,6 +9,7 @@ import (
"testing"
"time"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/unittest"
@@ -28,7 +29,7 @@ func TestAPIIssuesReactions(t *testing.T) {
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID})
session := loginUser(t, owner.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/reactions?token=%s",
@@ -87,7 +88,7 @@ func TestAPICommentReactions(t *testing.T) {
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID})
session := loginUser(t, owner.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
diff --git a/tests/integration/api_issue_stopwatch_test.go b/tests/integration/api_issue_stopwatch_test.go
index d1a3e86fda..a8a832414d 100644
--- a/tests/integration/api_issue_stopwatch_test.go
+++ b/tests/integration/api_issue_stopwatch_test.go
@@ -7,6 +7,7 @@ import (
"net/http"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
@@ -25,7 +26,7 @@ func TestAPIListStopWatches(t *testing.T) {
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
req := NewRequestf(t, "GET", "/api/v1/user/stopwatches?token=%s", token)
resp := MakeRequest(t, req, http.StatusOK)
var apiWatches []*api.StopWatch
@@ -51,7 +52,7 @@ func TestAPIStopStopWatches(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
session := loginUser(t, user.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
req := NewRequestf(t, "POST", "/api/v1/repos/%s/%s/issues/%d/stopwatch/stop?token=%s", owner.Name, issue.Repo.Name, issue.Index, token)
MakeRequest(t, req, http.StatusCreated)
@@ -67,7 +68,7 @@ func TestAPICancelStopWatches(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
session := loginUser(t, user.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/%d/stopwatch/delete?token=%s", owner.Name, issue.Repo.Name, issue.Index, token)
MakeRequest(t, req, http.StatusNoContent)
@@ -83,7 +84,7 @@ func TestAPIStartStopWatches(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
session := loginUser(t, user.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
req := NewRequestf(t, "POST", "/api/v1/repos/%s/%s/issues/%d/stopwatch/start?token=%s", owner.Name, issue.Repo.Name, issue.Index, token)
MakeRequest(t, req, http.StatusCreated)
diff --git a/tests/integration/api_issue_subscription_test.go b/tests/integration/api_issue_subscription_test.go
index a32b51e6fc..473e720754 100644
--- a/tests/integration/api_issue_subscription_test.go
+++ b/tests/integration/api_issue_subscription_test.go
@@ -8,6 +8,7 @@ import (
"net/http"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
@@ -30,7 +31,7 @@ func TestAPIIssueSubscriptions(t *testing.T) {
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue1.PosterID})
session := loginUser(t, owner.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
testSubscription := func(issue *issues_model.Issue, isWatching bool) {
issueRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID})
diff --git a/tests/integration/api_issue_test.go b/tests/integration/api_issue_test.go
index 2074bbee7c..2f27978a37 100644
--- a/tests/integration/api_issue_test.go
+++ b/tests/integration/api_issue_test.go
@@ -10,6 +10,7 @@ import (
"testing"
"time"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
@@ -29,7 +30,7 @@ func TestAPIListIssues(t *testing.T) {
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
link, _ := url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/issues", owner.Name, repo.Name))
link.RawQuery = url.Values{"token": {token}, "state": {"all"}}.Encode()
@@ -80,7 +81,7 @@ func TestAPICreateIssue(t *testing.T) {
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID})
session := loginUser(t, owner.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues?state=all&token=%s", owner.Name, repoBefore.Name, token)
req := NewRequestWithJSON(t, "POST", urlStr, &api.CreateIssueOption{
Body: body,
@@ -116,7 +117,7 @@ func TestAPIEditIssue(t *testing.T) {
assert.Equal(t, api.StateOpen, issueBefore.State())
session := loginUser(t, owner.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
// update values of issue
issueState := "closed"
diff --git a/tests/integration/api_issue_tracked_time_test.go b/tests/integration/api_issue_tracked_time_test.go
index eda4150f8c..7d9c785474 100644
--- a/tests/integration/api_issue_tracked_time_test.go
+++ b/tests/integration/api_issue_tracked_time_test.go
@@ -9,6 +9,7 @@ import (
"testing"
"time"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/unittest"
@@ -27,7 +28,7 @@ func TestAPIGetTrackedTimes(t *testing.T) {
assert.NoError(t, issue2.LoadRepo(db.DefaultContext))
session := loginUser(t, user2.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/%d/times?token=%s", user2.Name, issue2.Repo.Name, issue2.Index, token)
resp := MakeRequest(t, req, http.StatusOK)
@@ -70,7 +71,7 @@ func TestAPIDeleteTrackedTime(t *testing.T) {
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
session := loginUser(t, user2.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
// Deletion not allowed
req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/%d/times/%d?token=%s", user2.Name, issue2.Repo.Name, issue2.Index, time6.ID, token)
@@ -105,7 +106,7 @@ func TestAPIAddTrackedTimes(t *testing.T) {
admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
session := loginUser(t, admin.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/times?token=%s", user2.Name, issue2.Repo.Name, issue2.Index, token)
diff --git a/tests/integration/api_keys_test.go b/tests/integration/api_keys_test.go
index d24db2bd16..dc25cbfc1a 100644
--- a/tests/integration/api_keys_test.go
+++ b/tests/integration/api_keys_test.go
@@ -10,6 +10,7 @@ import (
"testing"
asymkey_model "code.gitea.io/gitea/models/asymkey"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/perm"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
@@ -53,7 +54,7 @@ func TestCreateReadOnlyDeployKey(t *testing.T) {
repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, repoOwner.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
keysURL := fmt.Sprintf("/api/v1/repos/%s/%s/keys?token=%s", repoOwner.Name, repo.Name, token)
rawKeyBody := api.CreateKeyOption{
Title: "read-only",
@@ -79,7 +80,7 @@ func TestCreateReadWriteDeployKey(t *testing.T) {
repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, repoOwner.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
keysURL := fmt.Sprintf("/api/v1/repos/%s/%s/keys?token=%s", repoOwner.Name, repo.Name, token)
rawKeyBody := api.CreateKeyOption{
Title: "read-write",
@@ -103,7 +104,7 @@ func TestCreateUserKey(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"})
session := loginUser(t, "user1")
- token := url.QueryEscape(getTokenForLoggedInUser(t, session))
+ token := url.QueryEscape(getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAdminPublicKey))
keysURL := fmt.Sprintf("/api/v1/user/keys?token=%s", token)
keyType := "ssh-rsa"
keyContent := "AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM="
@@ -167,7 +168,7 @@ func TestCreateUserKey(t *testing.T) {
// Now login as user 2
session2 := loginUser(t, "user2")
- token2 := url.QueryEscape(getTokenForLoggedInUser(t, session2))
+ token2 := url.QueryEscape(getTokenForLoggedInUser(t, session2, auth_model.AccessTokenScopeAdminPublicKey))
// Should find key even though not ours, but we shouldn't know whose it is
fingerprintURL = fmt.Sprintf("/api/v1/user/keys?token=%s&fingerprint=%s", token2, newPublicKey.Fingerprint)
diff --git a/tests/integration/api_notification_test.go b/tests/integration/api_notification_test.go
index cd230d6883..0ff13704cf 100644
--- a/tests/integration/api_notification_test.go
+++ b/tests/integration/api_notification_test.go
@@ -9,6 +9,7 @@ import (
"testing"
activities_model "code.gitea.io/gitea/models/activities"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
@@ -27,7 +28,7 @@ func TestAPINotification(t *testing.T) {
thread5 := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{ID: 5})
assert.NoError(t, thread5.LoadAttributes(db.DefaultContext))
session := loginUser(t, user2.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeNotification)
// -- GET /notifications --
// test filter
@@ -145,7 +146,7 @@ func TestAPINotificationPUT(t *testing.T) {
thread5 := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{ID: 5})
assert.NoError(t, thread5.LoadAttributes(db.DefaultContext))
session := loginUser(t, user2.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeNotification)
// Check notifications are as expected
req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?all=true&token=%s", token))
diff --git a/tests/integration/api_oauth2_apps_test.go b/tests/integration/api_oauth2_apps_test.go
index d2a85992ac..c320efb391 100644
--- a/tests/integration/api_oauth2_apps_test.go
+++ b/tests/integration/api_oauth2_apps_test.go
@@ -8,7 +8,7 @@ import (
"net/http"
"testing"
- "code.gitea.io/gitea/models/auth"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
api "code.gitea.io/gitea/modules/structs"
@@ -49,15 +49,15 @@ func testAPICreateOAuth2Application(t *testing.T) {
assert.True(t, createdApp.ConfidentialClient)
assert.NotEmpty(t, createdApp.Created)
assert.EqualValues(t, appBody.RedirectURIs[0], createdApp.RedirectURIs[0])
- unittest.AssertExistsAndLoadBean(t, &auth.OAuth2Application{UID: user.ID, Name: createdApp.Name})
+ unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{UID: user.ID, Name: createdApp.Name})
}
func testAPIListOAuth2Applications(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
session := loginUser(t, user.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadApplication)
- existApp := unittest.AssertExistsAndLoadBean(t, &auth.OAuth2Application{
+ existApp := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{
UID: user.ID,
Name: "test-app-1",
RedirectURIs: []string{
@@ -80,15 +80,15 @@ func testAPIListOAuth2Applications(t *testing.T) {
assert.Len(t, expectedApp.ClientID, 36)
assert.Empty(t, expectedApp.ClientSecret)
assert.EqualValues(t, existApp.RedirectURIs[0], expectedApp.RedirectURIs[0])
- unittest.AssertExistsAndLoadBean(t, &auth.OAuth2Application{ID: expectedApp.ID, Name: expectedApp.Name})
+ unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: expectedApp.ID, Name: expectedApp.Name})
}
func testAPIDeleteOAuth2Application(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
session := loginUser(t, user.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteApplication)
- oldApp := unittest.AssertExistsAndLoadBean(t, &auth.OAuth2Application{
+ oldApp := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{
UID: user.ID,
Name: "test-app-1",
})
@@ -97,7 +97,7 @@ func testAPIDeleteOAuth2Application(t *testing.T) {
req := NewRequest(t, "DELETE", urlStr)
MakeRequest(t, req, http.StatusNoContent)
- unittest.AssertNotExistsBean(t, &auth.OAuth2Application{UID: oldApp.UID, Name: oldApp.Name})
+ unittest.AssertNotExistsBean(t, &auth_model.OAuth2Application{UID: oldApp.UID, Name: oldApp.Name})
// Delete again will return not found
req = NewRequest(t, "DELETE", urlStr)
@@ -107,9 +107,9 @@ func testAPIDeleteOAuth2Application(t *testing.T) {
func testAPIGetOAuth2Application(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
session := loginUser(t, user.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadApplication)
- existApp := unittest.AssertExistsAndLoadBean(t, &auth.OAuth2Application{
+ existApp := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{
UID: user.ID,
Name: "test-app-1",
RedirectURIs: []string{
@@ -133,13 +133,13 @@ func testAPIGetOAuth2Application(t *testing.T) {
assert.Empty(t, expectedApp.ClientSecret)
assert.Len(t, expectedApp.RedirectURIs, 1)
assert.EqualValues(t, existApp.RedirectURIs[0], expectedApp.RedirectURIs[0])
- unittest.AssertExistsAndLoadBean(t, &auth.OAuth2Application{ID: expectedApp.ID, Name: expectedApp.Name})
+ unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: expectedApp.ID, Name: expectedApp.Name})
}
func testAPIUpdateOAuth2Application(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
- existApp := unittest.AssertExistsAndLoadBean(t, &auth.OAuth2Application{
+ existApp := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{
UID: user.ID,
Name: "test-app-1",
RedirectURIs: []string{
@@ -169,5 +169,5 @@ func testAPIUpdateOAuth2Application(t *testing.T) {
assert.EqualValues(t, expectedApp.RedirectURIs[0], appBody.RedirectURIs[0])
assert.EqualValues(t, expectedApp.RedirectURIs[1], appBody.RedirectURIs[1])
assert.Equal(t, expectedApp.ConfidentialClient, appBody.ConfidentialClient)
- unittest.AssertExistsAndLoadBean(t, &auth.OAuth2Application{ID: expectedApp.ID, Name: expectedApp.Name})
+ unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: expectedApp.ID, Name: expectedApp.Name})
}
diff --git a/tests/integration/api_org_test.go b/tests/integration/api_org_test.go
index 0be0c170d6..84166861a7 100644
--- a/tests/integration/api_org_test.go
+++ b/tests/integration/api_org_test.go
@@ -10,6 +10,7 @@ import (
"strings"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
@@ -21,7 +22,7 @@ import (
func TestAPIOrgCreate(t *testing.T) {
onGiteaRun(t, func(*testing.T, *url.URL) {
- token := getUserToken(t, "user1")
+ token := getUserToken(t, "user1", auth_model.AccessTokenScopeWriteOrg)
org := api.CreateOrgOption{
UserName: "user1_org",
@@ -79,7 +80,7 @@ func TestAPIOrgEdit(t *testing.T) {
onGiteaRun(t, func(*testing.T, *url.URL) {
session := loginUser(t, "user1")
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrg)
org := api.EditOrgOption{
FullName: "User3 organization new full name",
Description: "A new description",
@@ -106,7 +107,7 @@ func TestAPIOrgEditBadVisibility(t *testing.T) {
onGiteaRun(t, func(*testing.T, *url.URL) {
session := loginUser(t, "user1")
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrg)
org := api.EditOrgOption{
FullName: "User3 organization new full name",
Description: "A new description",
@@ -126,14 +127,16 @@ func TestAPIOrgDeny(t *testing.T) {
setting.Service.RequireSignInView = false
}()
+ token := getUserToken(t, "user1", auth_model.AccessTokenScopeReadOrg)
+
orgName := "user1_org"
- req := NewRequestf(t, "GET", "/api/v1/orgs/%s", orgName)
+ req := NewRequestf(t, "GET", "/api/v1/orgs/%s?token=%s", orgName, token)
MakeRequest(t, req, http.StatusNotFound)
- req = NewRequestf(t, "GET", "/api/v1/orgs/%s/repos", orgName)
+ req = NewRequestf(t, "GET", "/api/v1/orgs/%s/repos?token=%s", orgName, token)
MakeRequest(t, req, http.StatusNotFound)
- req = NewRequestf(t, "GET", "/api/v1/orgs/%s/members", orgName)
+ req = NewRequestf(t, "GET", "/api/v1/orgs/%s/members?token=%s", orgName, token)
MakeRequest(t, req, http.StatusNotFound)
})
}
@@ -141,20 +144,23 @@ func TestAPIOrgDeny(t *testing.T) {
func TestAPIGetAll(t *testing.T) {
defer tests.PrepareTestEnv(t)()
- req := NewRequestf(t, "GET", "/api/v1/orgs")
+ token := getUserToken(t, "user1", auth_model.AccessTokenScopeReadOrg)
+
+ req := NewRequestf(t, "GET", "/api/v1/orgs?token=%s", token)
resp := MakeRequest(t, req, http.StatusOK)
var apiOrgList []*api.Organization
DecodeJSON(t, resp, &apiOrgList)
- assert.Len(t, apiOrgList, 7)
- assert.Equal(t, "org25", apiOrgList[0].FullName)
- assert.Equal(t, "public", apiOrgList[0].Visibility)
+ // accessing with a token will return all orgs
+ assert.Len(t, apiOrgList, 9)
+ assert.Equal(t, "org25", apiOrgList[1].FullName)
+ assert.Equal(t, "public", apiOrgList[1].Visibility)
}
func TestAPIOrgSearchEmptyTeam(t *testing.T) {
onGiteaRun(t, func(*testing.T, *url.URL) {
- token := getUserToken(t, "user1")
+ token := getUserToken(t, "user1", auth_model.AccessTokenScopeAdminOrg)
orgName := "org_with_empty_team"
// create org
diff --git a/tests/integration/api_packages_container_test.go b/tests/integration/api_packages_container_test.go
index 1dcd76a317..39297c7d94 100644
--- a/tests/integration/api_packages_container_test.go
+++ b/tests/integration/api_packages_container_test.go
@@ -13,6 +13,7 @@ import (
"sync"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
packages_model "code.gitea.io/gitea/models/packages"
container_model "code.gitea.io/gitea/models/packages/container"
@@ -31,6 +32,8 @@ func TestPackageContainer(t *testing.T) {
defer tests.PrepareTestEnv(t)()
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ session := loginUser(t, user.Name)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadPackage)
has := func(l packages_model.PackagePropertyList, name string) bool {
for _, pp := range l {
@@ -558,7 +561,7 @@ func TestPackageContainer(t *testing.T) {
assert.Equal(t, c.ExpectedLink, resp.Header().Get("Link"))
}
- req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s?type=container&q=%s", user.Name, image))
+ req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s?type=container&q=%s&token=%s", user.Name, image, token))
resp := MakeRequest(t, req, http.StatusOK)
var apiPackages []*api.Package
diff --git a/tests/integration/api_packages_test.go b/tests/integration/api_packages_test.go
index 8346e3bccc..9bca6a20ee 100644
--- a/tests/integration/api_packages_test.go
+++ b/tests/integration/api_packages_test.go
@@ -10,6 +10,7 @@ import (
"testing"
"time"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
packages_model "code.gitea.io/gitea/models/packages"
container_model "code.gitea.io/gitea/models/packages/container"
@@ -28,7 +29,8 @@ func TestPackageAPI(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
session := loginUser(t, user.Name)
- token := getTokenForLoggedInUser(t, session)
+ tokenReadPackage := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadPackage)
+ tokenDeletePackage := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeletePackage)
packageName := "test-package"
packageVersion := "1.0.3"
@@ -42,7 +44,7 @@ func TestPackageAPI(t *testing.T) {
t.Run("ListPackages", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
- req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s?token=%s", user.Name, token))
+ req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s?token=%s", user.Name, tokenReadPackage))
resp := MakeRequest(t, req, http.StatusOK)
var apiPackages []*api.Package
@@ -59,10 +61,10 @@ func TestPackageAPI(t *testing.T) {
t.Run("GetPackage", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
- req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/dummy/%s/%s?token=%s", user.Name, packageName, packageVersion, token))
+ req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/dummy/%s/%s?token=%s", user.Name, packageName, packageVersion, tokenReadPackage))
MakeRequest(t, req, http.StatusNotFound)
- req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s?token=%s", user.Name, packageName, packageVersion, token))
+ req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s?token=%s", user.Name, packageName, packageVersion, tokenReadPackage))
resp := MakeRequest(t, req, http.StatusOK)
var p *api.Package
@@ -81,7 +83,7 @@ func TestPackageAPI(t *testing.T) {
assert.NoError(t, err)
// no repository link
- req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s?token=%s", user.Name, packageName, packageVersion, token))
+ req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s?token=%s", user.Name, packageName, packageVersion, tokenReadPackage))
resp := MakeRequest(t, req, http.StatusOK)
var ap1 *api.Package
@@ -91,7 +93,7 @@ func TestPackageAPI(t *testing.T) {
// link to public repository
assert.NoError(t, packages_model.SetRepositoryLink(db.DefaultContext, p.ID, 1))
- req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s?token=%s", user.Name, packageName, packageVersion, token))
+ req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s?token=%s", user.Name, packageName, packageVersion, tokenReadPackage))
resp = MakeRequest(t, req, http.StatusOK)
var ap2 *api.Package
@@ -102,7 +104,7 @@ func TestPackageAPI(t *testing.T) {
// link to private repository
assert.NoError(t, packages_model.SetRepositoryLink(db.DefaultContext, p.ID, 2))
- req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s?token=%s", user.Name, packageName, packageVersion, token))
+ req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s?token=%s", user.Name, packageName, packageVersion, tokenReadPackage))
resp = MakeRequest(t, req, http.StatusOK)
var ap3 *api.Package
@@ -116,10 +118,10 @@ func TestPackageAPI(t *testing.T) {
t.Run("ListPackageFiles", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
- req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/dummy/%s/%s/files?token=%s", user.Name, packageName, packageVersion, token))
+ req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/dummy/%s/%s/files?token=%s", user.Name, packageName, packageVersion, tokenReadPackage))
MakeRequest(t, req, http.StatusNotFound)
- req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s/files?token=%s", user.Name, packageName, packageVersion, token))
+ req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s/files?token=%s", user.Name, packageName, packageVersion, tokenReadPackage))
resp := MakeRequest(t, req, http.StatusOK)
var files []*api.PackageFile
@@ -137,10 +139,10 @@ func TestPackageAPI(t *testing.T) {
t.Run("DeletePackage", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
- req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/packages/%s/dummy/%s/%s?token=%s", user.Name, packageName, packageVersion, token))
+ req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/packages/%s/dummy/%s/%s?token=%s", user.Name, packageName, packageVersion, tokenDeletePackage))
MakeRequest(t, req, http.StatusNotFound)
- req = NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s?token=%s", user.Name, packageName, packageVersion, token))
+ req = NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s?token=%s", user.Name, packageName, packageVersion, tokenDeletePackage))
MakeRequest(t, req, http.StatusNoContent)
})
}
diff --git a/tests/integration/api_pull_review_test.go b/tests/integration/api_pull_review_test.go
index 4b9c601783..cfb56724a6 100644
--- a/tests/integration/api_pull_review_test.go
+++ b/tests/integration/api_pull_review_test.go
@@ -8,6 +8,7 @@ import (
"net/http"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
@@ -27,7 +28,7 @@ func TestAPIPullReview(t *testing.T) {
// test ListPullReviews
session := loginUser(t, "user2")
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
req := NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/%s/pulls/%d/reviews?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, token)
resp := MakeRequest(t, req, http.StatusOK)
@@ -230,7 +231,7 @@ func TestAPIPullReviewRequest(t *testing.T) {
// Test add Review Request
session := loginUser(t, "user2")
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, token), &api.PullReviewRequestOptions{
Reviewers: []string{"user4@example.com", "user8"},
})
@@ -250,7 +251,7 @@ func TestAPIPullReviewRequest(t *testing.T) {
// Test Remove Review Request
session2 := loginUser(t, "user4")
- token2 := getTokenForLoggedInUser(t, session2)
+ token2 := getTokenForLoggedInUser(t, session2, auth_model.AccessTokenScopeRepo)
req = NewRequestWithJSON(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, token2), &api.PullReviewRequestOptions{
Reviewers: []string{"user4"},
diff --git a/tests/integration/api_pull_test.go b/tests/integration/api_pull_test.go
index 89d39179a6..4427c610bf 100644
--- a/tests/integration/api_pull_test.go
+++ b/tests/integration/api_pull_test.go
@@ -9,6 +9,7 @@ import (
"net/http"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
@@ -28,7 +29,7 @@ func TestAPIViewPulls(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
- ctx := NewAPITestContext(t, "user2", repo.Name)
+ ctx := NewAPITestContext(t, "user2", repo.Name, auth_model.AccessTokenScopeRepo)
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/pulls?state=all&token="+ctx.Token, owner.Name, repo.Name)
resp := ctx.Session.MakeRequest(t, req, http.StatusOK)
@@ -74,7 +75,7 @@ func TestAPIMergePullWIP(t *testing.T) {
assert.Contains(t, pr.Issue.Title, setting.Repository.PullRequest.WorkInProgressPrefixes[0])
session := loginUser(t, owner.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/merge?token=%s", owner.Name, repo.Name, pr.Index, token), &forms.MergePullRequestForm{
MergeMessageField: pr.Issue.Title,
Do: string(repo_model.MergeStyleMerge),
@@ -93,7 +94,7 @@ func TestAPICreatePullSuccess(t *testing.T) {
owner11 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo11.OwnerID})
session := loginUser(t, owner11.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls?token=%s", owner10.Name, repo10.Name, token), &api.CreatePullRequestOption{
Head: fmt.Sprintf("%s:master", owner11.Name),
Base: "master",
@@ -113,7 +114,7 @@ func TestAPICreatePullWithFieldsSuccess(t *testing.T) {
owner11 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo11.OwnerID})
session := loginUser(t, owner11.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
opts := &api.CreatePullRequestOption{
Head: fmt.Sprintf("%s:master", owner11.Name),
@@ -150,7 +151,7 @@ func TestAPICreatePullWithFieldsFailure(t *testing.T) {
owner11 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo11.OwnerID})
session := loginUser(t, owner11.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
opts := &api.CreatePullRequestOption{
Head: fmt.Sprintf("%s:master", owner11.Name),
@@ -180,7 +181,7 @@ func TestAPIEditPull(t *testing.T) {
owner10 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo10.OwnerID})
session := loginUser(t, owner10.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls?token=%s", owner10.Name, repo10.Name, token), &api.CreatePullRequestOption{
Head: "develop",
Base: "master",
diff --git a/tests/integration/api_releases_test.go b/tests/integration/api_releases_test.go
index 12d2a02fb1..d7f2a1b8b1 100644
--- a/tests/integration/api_releases_test.go
+++ b/tests/integration/api_releases_test.go
@@ -9,6 +9,7 @@ import (
"net/url"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@@ -24,7 +25,7 @@ func TestAPIListReleases(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
- token := getUserToken(t, user2.LowerName)
+ token := getUserToken(t, user2.LowerName, auth_model.AccessTokenScopeRepo)
link, _ := url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/releases", user2.Name, repo.Name))
link.RawQuery = url.Values{"token": {token}}.Encode()
@@ -100,7 +101,7 @@ func TestAPICreateAndUpdateRelease(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.LowerName)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
gitRepo, err := git.OpenRepository(git.DefaultContext, repo.RepoPath())
assert.NoError(t, err)
@@ -152,7 +153,7 @@ func TestAPICreateReleaseToDefaultBranch(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.LowerName)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
createNewReleaseUsingAPI(t, session, token, owner, repo, "v0.0.1", "", "v0.0.1", "test")
}
@@ -163,7 +164,7 @@ func TestAPICreateReleaseToDefaultBranchOnExistingTag(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.LowerName)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
gitRepo, err := git.OpenRepository(git.DefaultContext, repo.RepoPath())
assert.NoError(t, err)
@@ -213,7 +214,7 @@ func TestAPIDeleteReleaseByTagName(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.LowerName)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
createNewReleaseUsingAPI(t, session, token, owner, repo, "release-tag", "", "Release Tag", "test")
diff --git a/tests/integration/api_repo_archive_test.go b/tests/integration/api_repo_archive_test.go
index a3c03ba2fc..fbcc12ccb6 100644
--- a/tests/integration/api_repo_archive_test.go
+++ b/tests/integration/api_repo_archive_test.go
@@ -10,6 +10,7 @@ import (
"net/url"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@@ -24,7 +25,7 @@ func TestAPIDownloadArchive(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
session := loginUser(t, user2.LowerName)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
link, _ := url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/archive/master.zip", user2.Name, repo.Name))
link.RawQuery = url.Values{"token": {token}}.Encode()
diff --git a/tests/integration/api_repo_collaborator_test.go b/tests/integration/api_repo_collaborator_test.go
index 318c86e2c3..ed01538477 100644
--- a/tests/integration/api_repo_collaborator_test.go
+++ b/tests/integration/api_repo_collaborator_test.go
@@ -8,6 +8,7 @@ import (
"net/url"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/perm"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
@@ -27,7 +28,7 @@ func TestAPIRepoCollaboratorPermission(t *testing.T) {
user10 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 10})
user11 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 11})
- testCtx := NewAPITestContext(t, repo2Owner.Name, repo2.Name)
+ testCtx := NewAPITestContext(t, repo2Owner.Name, repo2.Name, auth_model.AccessTokenScopeRepo)
t.Run("RepoOwnerShouldBeOwner", func(t *testing.T) {
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/collaborators/%s/permission?token=%s", repo2Owner.Name, repo2.Name, repo2Owner.Name, testCtx.Token)
@@ -84,7 +85,7 @@ func TestAPIRepoCollaboratorPermission(t *testing.T) {
t.Run("AddUserAsCollaboratorWithReadAccess", doAPIAddCollaborator(testCtx, user5.Name, perm.AccessModeRead))
_session := loginUser(t, user5.Name)
- _testCtx := NewAPITestContext(t, user5.Name, repo2.Name)
+ _testCtx := NewAPITestContext(t, user5.Name, repo2.Name, auth_model.AccessTokenScopeRepo)
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/collaborators/%s/permission?token=%s", repo2Owner.Name, repo2.Name, user5.Name, _testCtx.Token)
resp := _session.MakeRequest(t, req, http.StatusOK)
@@ -99,7 +100,7 @@ func TestAPIRepoCollaboratorPermission(t *testing.T) {
t.Run("AddUserAsCollaboratorWithReadAccess", doAPIAddCollaborator(testCtx, user5.Name, perm.AccessModeRead))
_session := loginUser(t, user5.Name)
- _testCtx := NewAPITestContext(t, user5.Name, repo2.Name)
+ _testCtx := NewAPITestContext(t, user5.Name, repo2.Name, auth_model.AccessTokenScopeRepo)
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/collaborators/%s/permission?token=%s", repo2Owner.Name, repo2.Name, user5.Name, _testCtx.Token)
resp := _session.MakeRequest(t, req, http.StatusOK)
@@ -115,7 +116,7 @@ func TestAPIRepoCollaboratorPermission(t *testing.T) {
t.Run("AddUserAsCollaboratorWithReadAccess", doAPIAddCollaborator(testCtx, user11.Name, perm.AccessModeRead))
_session := loginUser(t, user10.Name)
- _testCtx := NewAPITestContext(t, user10.Name, repo2.Name)
+ _testCtx := NewAPITestContext(t, user10.Name, repo2.Name, auth_model.AccessTokenScopeRepo)
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/collaborators/%s/permission?token=%s", repo2Owner.Name, repo2.Name, user11.Name, _testCtx.Token)
resp := _session.MakeRequest(t, req, http.StatusOK)
diff --git a/tests/integration/api_repo_edit_test.go b/tests/integration/api_repo_edit_test.go
index 716cebeb7c..9594b86d7e 100644
--- a/tests/integration/api_repo_edit_test.go
+++ b/tests/integration/api_repo_edit_test.go
@@ -9,6 +9,7 @@ import (
"net/url"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
unit_model "code.gitea.io/gitea/models/unit"
@@ -146,10 +147,10 @@ func TestAPIRepoEdit(t *testing.T) {
// Get user2's token
session := loginUser(t, user2.Name)
- token2 := getTokenForLoggedInUser(t, session)
+ token2 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
// Get user4's token
session = loginUser(t, user4.Name)
- token4 := getTokenForLoggedInUser(t, session)
+ token4 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
// Test editing a repo1 which user2 owns, changing name and many properties
origRepoEditOption := getRepoEditOptionFromRepo(repo1)
diff --git a/tests/integration/api_repo_file_create_test.go b/tests/integration/api_repo_file_create_test.go
index 476441dbb1..b2098fdd03 100644
--- a/tests/integration/api_repo_file_create_test.go
+++ b/tests/integration/api_repo_file_create_test.go
@@ -13,6 +13,7 @@ import (
"testing"
"time"
+ auth_model "code.gitea.io/gitea/models/auth"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@@ -150,10 +151,10 @@ func TestAPICreateFile(t *testing.T) {
// Get user2's token
session := loginUser(t, user2.Name)
- token2 := getTokenForLoggedInUser(t, session)
+ token2 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
// Get user4's token
session = loginUser(t, user4.Name)
- token4 := getTokenForLoggedInUser(t, session)
+ token4 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
// Test creating a file in repo1 which user2 owns, try both with branch and empty branch
for _, branch := range [...]string{
@@ -279,7 +280,7 @@ func TestAPICreateFile(t *testing.T) {
MakeRequest(t, req, http.StatusForbidden)
// Test creating a file in an empty repository
- doAPICreateRepository(NewAPITestContext(t, "user2", "empty-repo"), true)(t)
+ doAPICreateRepository(NewAPITestContext(t, "user2", "empty-repo", auth_model.AccessTokenScopeRepo), true)(t)
createFileOptions = getCreateFileOptions()
fileID++
treePath = fmt.Sprintf("new/file%d.txt", fileID)
diff --git a/tests/integration/api_repo_file_delete_test.go b/tests/integration/api_repo_file_delete_test.go
index 196d3208f5..9b80dc150a 100644
--- a/tests/integration/api_repo_file_delete_test.go
+++ b/tests/integration/api_repo_file_delete_test.go
@@ -9,6 +9,7 @@ import (
"net/url"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@@ -48,10 +49,10 @@ func TestAPIDeleteFile(t *testing.T) {
// Get user2's token
session := loginUser(t, user2.Name)
- token2 := getTokenForLoggedInUser(t, session)
+ token2 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
// Get user4's token
session = loginUser(t, user4.Name)
- token4 := getTokenForLoggedInUser(t, session)
+ token4 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
// Test deleting a file in repo1 which user2 owns, try both with branch and empty branch
for _, branch := range [...]string{
diff --git a/tests/integration/api_repo_file_get_test.go b/tests/integration/api_repo_file_get_test.go
index 4fca55c93d..a6a1e63439 100644
--- a/tests/integration/api_repo_file_get_test.go
+++ b/tests/integration/api_repo_file_get_test.go
@@ -8,6 +8,7 @@ import (
"net/url"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/tests"
@@ -24,7 +25,7 @@ func TestAPIGetRawFileOrLFS(t *testing.T) {
// Test with LFS
onGiteaRun(t, func(t *testing.T, u *url.URL) {
- httpContext := NewAPITestContext(t, "user2", "repo-lfs-test")
+ httpContext := NewAPITestContext(t, "user2", "repo-lfs-test", auth_model.AccessTokenScopeRepo, auth_model.AccessTokenScopeDeleteRepo)
doAPICreateRepository(httpContext, false, func(t *testing.T, repository api.Repository) {
u.Path = httpContext.GitPath()
dstPath := t.TempDir()
diff --git a/tests/integration/api_repo_file_update_test.go b/tests/integration/api_repo_file_update_test.go
index 6dd06b7125..8e07511aaf 100644
--- a/tests/integration/api_repo_file_update_test.go
+++ b/tests/integration/api_repo_file_update_test.go
@@ -12,6 +12,7 @@ import (
"path/filepath"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@@ -116,10 +117,10 @@ func TestAPIUpdateFile(t *testing.T) {
// Get user2's token
session := loginUser(t, user2.Name)
- token2 := getTokenForLoggedInUser(t, session)
+ token2 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
// Get user4's token
session = loginUser(t, user4.Name)
- token4 := getTokenForLoggedInUser(t, session)
+ token4 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
// Test updating a file in repo1 which user2 owns, try both with branch and empty branch
for _, branch := range [...]string{
diff --git a/tests/integration/api_repo_git_hook_test.go b/tests/integration/api_repo_git_hook_test.go
index a3bbe9bbad..e1c4682e6d 100644
--- a/tests/integration/api_repo_git_hook_test.go
+++ b/tests/integration/api_repo_git_hook_test.go
@@ -8,6 +8,7 @@ import (
"net/http"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@@ -30,7 +31,7 @@ func TestAPIListGitHooks(t *testing.T) {
// user1 is an admin user
session := loginUser(t, "user1")
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepoHook)
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/hooks/git?token=%s",
owner.Name, repo.Name, token)
resp := MakeRequest(t, req, http.StatusOK)
@@ -56,7 +57,7 @@ func TestAPIListGitHooksNoHooks(t *testing.T) {
// user1 is an admin user
session := loginUser(t, "user1")
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepoHook)
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/hooks/git?token=%s",
owner.Name, repo.Name, token)
resp := MakeRequest(t, req, http.StatusOK)
@@ -76,7 +77,7 @@ func TestAPIListGitHooksNoAccess(t *testing.T) {
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepoHook)
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/hooks/git?token=%s",
owner.Name, repo.Name, token)
MakeRequest(t, req, http.StatusForbidden)
@@ -90,7 +91,7 @@ func TestAPIGetGitHook(t *testing.T) {
// user1 is an admin user
session := loginUser(t, "user1")
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepoHook)
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/hooks/git/pre-receive?token=%s",
owner.Name, repo.Name, token)
resp := MakeRequest(t, req, http.StatusOK)
@@ -107,7 +108,7 @@ func TestAPIGetGitHookNoAccess(t *testing.T) {
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepoHook)
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/hooks/git/pre-receive?token=%s",
owner.Name, repo.Name, token)
MakeRequest(t, req, http.StatusForbidden)
@@ -121,7 +122,7 @@ func TestAPIEditGitHook(t *testing.T) {
// user1 is an admin user
session := loginUser(t, "user1")
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAdminRepoHook)
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/hooks/git/pre-receive?token=%s",
owner.Name, repo.Name, token)
@@ -150,7 +151,7 @@ func TestAPIEditGitHookNoAccess(t *testing.T) {
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepoHook)
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/hooks/git/pre-receive?token=%s",
owner.Name, repo.Name, token)
req := NewRequestWithJSON(t, "PATCH", urlStr, &api.EditGitHookOption{
@@ -167,7 +168,7 @@ func TestAPIDeleteGitHook(t *testing.T) {
// user1 is an admin user
session := loginUser(t, "user1")
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAdminRepoHook)
req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/hooks/git/pre-receive?token=%s",
owner.Name, repo.Name, token)
@@ -189,7 +190,7 @@ func TestAPIDeleteGitHookNoAccess(t *testing.T) {
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepoHook)
req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/hooks/git/pre-receive?token=%s",
owner.Name, repo.Name, token)
MakeRequest(t, req, http.StatusForbidden)
diff --git a/tests/integration/api_repo_git_tags_test.go b/tests/integration/api_repo_git_tags_test.go
index 146b4b74bd..b29fc45cf5 100644
--- a/tests/integration/api_repo_git_tags_test.go
+++ b/tests/integration/api_repo_git_tags_test.go
@@ -8,6 +8,7 @@ import (
"net/http"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@@ -69,7 +70,7 @@ func TestAPIDeleteTagByName(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.LowerName)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/tags/delete-tag?token=%s",
owner.Name, repo.Name, token)
diff --git a/tests/integration/api_repo_hook_test.go b/tests/integration/api_repo_hook_test.go
index cf080575da..0fa2402992 100644
--- a/tests/integration/api_repo_hook_test.go
+++ b/tests/integration/api_repo_hook_test.go
@@ -8,6 +8,7 @@ import (
"net/http"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@@ -25,7 +26,7 @@ func TestAPICreateHook(t *testing.T) {
// user1 is an admin user
session := loginUser(t, "user1")
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepoHook)
completeURL := func(lastSegment string) string {
return fmt.Sprintf("/api/v1/repos/%s/%s/%s?token=%s", owner.Name, repo.Name, lastSegment, token)
}
diff --git a/tests/integration/api_repo_lfs_migrate_test.go b/tests/integration/api_repo_lfs_migrate_test.go
index 50d0c5966b..e66ca6b147 100644
--- a/tests/integration/api_repo_lfs_migrate_test.go
+++ b/tests/integration/api_repo_lfs_migrate_test.go
@@ -8,6 +8,7 @@ import (
"path"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/lfs"
@@ -30,7 +31,7 @@ func TestAPIRepoLFSMigrateLocal(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
session := loginUser(t, user.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
req := NewRequestWithJSON(t, "POST", "/api/v1/repos/migrate?token="+token, &api.MigrateRepoOptions{
CloneAddr: path.Join(setting.RepoRootPath, "migration/lfs-test.git"),
diff --git a/tests/integration/api_repo_lfs_test.go b/tests/integration/api_repo_lfs_test.go
index c0ceaa8ba8..a7a70baeef 100644
--- a/tests/integration/api_repo_lfs_test.go
+++ b/tests/integration/api_repo_lfs_test.go
@@ -11,6 +11,7 @@ import (
"strings"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
git_model "code.gitea.io/gitea/models/git"
repo_model "code.gitea.io/gitea/models/repo"
@@ -59,7 +60,7 @@ func TestAPILFSMediaType(t *testing.T) {
}
func createLFSTestRepository(t *testing.T, name string) *repo_model.Repository {
- ctx := NewAPITestContext(t, "user2", "lfs-"+name+"-repo")
+ ctx := NewAPITestContext(t, "user2", "lfs-"+name+"-repo", auth_model.AccessTokenScopeRepo)
t.Run("CreateRepo", doAPICreateRepository(ctx, false))
repo, err := repo_model.GetRepositoryByOwnerAndName(db.DefaultContext, "user2", "lfs-"+name+"-repo")
diff --git a/tests/integration/api_repo_raw_test.go b/tests/integration/api_repo_raw_test.go
index a35f1285b9..60e9eeed6b 100644
--- a/tests/integration/api_repo_raw_test.go
+++ b/tests/integration/api_repo_raw_test.go
@@ -7,6 +7,7 @@ import (
"net/http"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/tests"
@@ -19,7 +20,7 @@ func TestAPIReposRaw(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Login as User2.
session := loginUser(t, user.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
for _, ref := range [...]string{
"master", // Branch
diff --git a/tests/integration/api_repo_tags_test.go b/tests/integration/api_repo_tags_test.go
index 6c7ab7971c..d4fd9097dd 100644
--- a/tests/integration/api_repo_tags_test.go
+++ b/tests/integration/api_repo_tags_test.go
@@ -8,6 +8,7 @@ import (
"net/http"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
@@ -22,7 +23,7 @@ func TestAPIRepoTags(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Login as User2.
session := loginUser(t, user.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
repoName := "repo1"
diff --git a/tests/integration/api_repo_teams_test.go b/tests/integration/api_repo_teams_test.go
index 102f170d94..1f444e3141 100644
--- a/tests/integration/api_repo_teams_test.go
+++ b/tests/integration/api_repo_teams_test.go
@@ -8,6 +8,7 @@ import (
"net/http"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/models/unittest"
@@ -27,7 +28,7 @@ func TestAPIRepoTeams(t *testing.T) {
// user4
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
session := loginUser(t, user.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
// ListTeams
url := fmt.Sprintf("/api/v1/repos/%s/teams?token=%s", publicOrgRepo.FullName(), token)
@@ -67,7 +68,7 @@ func TestAPIRepoTeams(t *testing.T) {
// AddTeam with user2
user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
session = loginUser(t, user.Name)
- token = getTokenForLoggedInUser(t, session)
+ token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
url = fmt.Sprintf("/api/v1/repos/%s/teams/%s?token=%s", publicOrgRepo.FullName(), "team1", token)
req = NewRequest(t, "PUT", url)
MakeRequest(t, req, http.StatusNoContent)
diff --git a/tests/integration/api_repo_test.go b/tests/integration/api_repo_test.go
index 76850fb827..76ceb779e0 100644
--- a/tests/integration/api_repo_test.go
+++ b/tests/integration/api_repo_test.go
@@ -10,6 +10,7 @@ import (
"testing"
"code.gitea.io/gitea/models"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
access_model "code.gitea.io/gitea/models/perm/access"
repo_model "code.gitea.io/gitea/models/repo"
@@ -286,24 +287,17 @@ func TestAPIOrgRepos(t *testing.T) {
count int
includesPrivate bool
}{
- nil: {count: 1},
+ user: {count: 1},
user: {count: 3, includesPrivate: true},
user2: {count: 3, includesPrivate: true},
user3: {count: 1},
}
for userToLogin, expected := range expectedResults {
- var session *TestSession
- var testName string
- var token string
- if userToLogin != nil && userToLogin.ID > 0 {
- testName = fmt.Sprintf("LoggedUser%d", userToLogin.ID)
- session = loginUser(t, userToLogin.Name)
- token = getTokenForLoggedInUser(t, session)
- } else {
- testName = "AnonymousUser"
- session = emptyTestSession(t)
- }
+ testName := fmt.Sprintf("LoggedUser%d", userToLogin.ID)
+ session := loginUser(t, userToLogin.Name)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrg)
+
t.Run(testName, func(t *testing.T) {
req := NewRequestf(t, "GET", "/api/v1/orgs/%s/repos?token="+token, sourceOrg.Name)
resp := MakeRequest(t, req, http.StatusOK)
@@ -324,7 +318,7 @@ func TestAPIGetRepoByIDUnauthorized(t *testing.T) {
defer tests.PrepareTestEnv(t)()
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
session := loginUser(t, user.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
req := NewRequestf(t, "GET", "/api/v1/repositories/2?token="+token)
MakeRequest(t, req, http.StatusNotFound)
}
@@ -348,7 +342,7 @@ func TestAPIRepoMigrate(t *testing.T) {
for _, testCase := range testCases {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: testCase.ctxUserID})
session := loginUser(t, user.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
req := NewRequestWithJSON(t, "POST", "/api/v1/repos/migrate?token="+token, &api.MigrateRepoOptions{
CloneAddr: testCase.cloneURL,
RepoOwnerID: testCase.userID,
@@ -378,7 +372,7 @@ func TestAPIRepoMigrateConflict(t *testing.T) {
func testAPIRepoMigrateConflict(t *testing.T, u *url.URL) {
username := "user2"
- baseAPITestContext := NewAPITestContext(t, username, "repo1")
+ baseAPITestContext := NewAPITestContext(t, username, "repo1", auth_model.AccessTokenScopeRepo)
u.Path = baseAPITestContext.GitPath()
@@ -413,7 +407,7 @@ func TestAPIMirrorSyncNonMirrorRepo(t *testing.T) {
defer tests.PrepareTestEnv(t)()
session := loginUser(t, "user2")
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
var repo api.Repository
req := NewRequest(t, "GET", "/api/v1/repos/user2/repo1")
@@ -445,7 +439,7 @@ func TestAPIOrgRepoCreate(t *testing.T) {
for _, testCase := range testCases {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: testCase.ctxUserID})
session := loginUser(t, user.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAdminOrg)
req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/org/%s/repos?token="+token, testCase.orgName), &api.CreateRepoOption{
Name: testCase.repoName,
})
@@ -459,7 +453,7 @@ func TestAPIRepoCreateConflict(t *testing.T) {
func testAPIRepoCreateConflict(t *testing.T, u *url.URL) {
username := "user2"
- baseAPITestContext := NewAPITestContext(t, username, "repo1")
+ baseAPITestContext := NewAPITestContext(t, username, "repo1", auth_model.AccessTokenScopeRepo)
u.Path = baseAPITestContext.GitPath()
@@ -509,7 +503,7 @@ func TestAPIRepoTransfer(t *testing.T) {
// create repo to move
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
session := loginUser(t, user.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
repoName := "moveME"
apiRepo := new(api.Repository)
req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/user/repos?token=%s", token), &api.CreateRepoOption{
@@ -527,7 +521,7 @@ func TestAPIRepoTransfer(t *testing.T) {
user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: testCase.ctxUserID})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiRepo.ID})
session = loginUser(t, user.Name)
- token = getTokenForLoggedInUser(t, session)
+ token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer?token=%s", repo.OwnerName, repo.Name, token), &api.TransferRepoOption{
NewOwner: testCase.newOwner,
TeamIDs: testCase.teams,
@@ -544,7 +538,7 @@ func transfer(t *testing.T) *repo_model.Repository {
// create repo to move
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
session := loginUser(t, user.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
repoName := "moveME"
apiRepo := new(api.Repository)
req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/user/repos?token=%s", token), &api.CreateRepoOption{
@@ -574,7 +568,7 @@ func TestAPIAcceptTransfer(t *testing.T) {
// try to accept with not authorized user
session := loginUser(t, "user2")
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
req := NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer/reject?token=%s", repo.OwnerName, repo.Name, token))
MakeRequest(t, req, http.StatusForbidden)
@@ -584,7 +578,7 @@ func TestAPIAcceptTransfer(t *testing.T) {
// accept transfer
session = loginUser(t, "user4")
- token = getTokenForLoggedInUser(t, session)
+ token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
req = NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer/accept?token=%s", repo.OwnerName, repo.Name, token))
resp := MakeRequest(t, req, http.StatusAccepted)
@@ -600,7 +594,7 @@ func TestAPIRejectTransfer(t *testing.T) {
// try to reject with not authorized user
session := loginUser(t, "user2")
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
req := NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer/reject?token=%s", repo.OwnerName, repo.Name, token))
MakeRequest(t, req, http.StatusForbidden)
@@ -610,7 +604,7 @@ func TestAPIRejectTransfer(t *testing.T) {
// reject transfer
session = loginUser(t, "user4")
- token = getTokenForLoggedInUser(t, session)
+ token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
req = NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer/reject?token=%s", repo.OwnerName, repo.Name, token))
resp := MakeRequest(t, req, http.StatusOK)
@@ -624,7 +618,7 @@ func TestAPIGenerateRepo(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
session := loginUser(t, user.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
templateRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 44})
@@ -660,7 +654,7 @@ func TestAPIRepoGetReviewers(t *testing.T) {
defer tests.PrepareTestEnv(t)()
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
session := loginUser(t, user.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/reviewers?token=%s", user.Name, repo.Name, token)
@@ -674,7 +668,7 @@ func TestAPIRepoGetAssignees(t *testing.T) {
defer tests.PrepareTestEnv(t)()
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
session := loginUser(t, user.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/assignees?token=%s", user.Name, repo.Name, token)
diff --git a/tests/integration/api_repo_topic_test.go b/tests/integration/api_repo_topic_test.go
index 81eb1a9427..ab9fd9bb96 100644
--- a/tests/integration/api_repo_topic_test.go
+++ b/tests/integration/api_repo_topic_test.go
@@ -9,6 +9,7 @@ import (
"net/url"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@@ -59,7 +60,7 @@ func TestAPIRepoTopic(t *testing.T) {
repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
// Get user2's token
- token2 := getUserToken(t, user2.Name)
+ token2 := getUserToken(t, user2.Name, auth_model.AccessTokenScopeRepo)
// Test read topics using login
url := fmt.Sprintf("/api/v1/repos/%s/%s/topics", user2.Name, repo2.Name)
@@ -139,7 +140,7 @@ func TestAPIRepoTopic(t *testing.T) {
MakeRequest(t, req, http.StatusNotFound)
// Get user4's token
- token4 := getUserToken(t, user4.Name)
+ token4 := getUserToken(t, user4.Name, auth_model.AccessTokenScopeRepo)
// Test read topics with write access
url = fmt.Sprintf("/api/v1/repos/%s/%s/topics?token=%s", user3.Name, repo3.Name, token4)
diff --git a/tests/integration/api_team_test.go b/tests/integration/api_team_test.go
index 06d47bf70b..27fe5e12e6 100644
--- a/tests/integration/api_team_test.go
+++ b/tests/integration/api_team_test.go
@@ -9,6 +9,7 @@ import (
"sort"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
@@ -29,7 +30,7 @@ func TestAPITeam(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: teamUser.UID})
session := loginUser(t, user.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAdminOrg)
req := NewRequestf(t, "GET", "/api/v1/teams/%d?token="+token, teamUser.TeamID)
resp := MakeRequest(t, req, http.StatusOK)
@@ -43,7 +44,7 @@ func TestAPITeam(t *testing.T) {
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: teamUser2.UID})
session = loginUser(t, user2.Name)
- token = getTokenForLoggedInUser(t, session)
+ token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrg)
req = NewRequestf(t, "GET", "/api/v1/teams/%d?token="+token, teamUser.TeamID)
_ = MakeRequest(t, req, http.StatusForbidden)
@@ -53,7 +54,7 @@ func TestAPITeam(t *testing.T) {
// Get an admin user able to create, update and delete teams.
user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
session = loginUser(t, user.Name)
- token = getTokenForLoggedInUser(t, session)
+ token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAdminOrg)
org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 6})
@@ -227,7 +228,7 @@ func TestAPITeamSearch(t *testing.T) {
var results TeamSearchResults
- token := getUserToken(t, user.Name)
+ token := getUserToken(t, user.Name, auth_model.AccessTokenScopeReadOrg)
req := NewRequestf(t, "GET", "/api/v1/orgs/%s/teams/search?q=%s&token=%s", org.Name, "_team", token)
resp := MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &results)
@@ -237,7 +238,7 @@ func TestAPITeamSearch(t *testing.T) {
// no access if not organization member
user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
- token5 := getUserToken(t, user5.Name)
+ token5 := getUserToken(t, user5.Name, auth_model.AccessTokenScopeReadOrg)
req = NewRequestf(t, "GET", "/api/v1/orgs/%s/teams/search?q=%s&token=%s", org.Name, "team", token5)
MakeRequest(t, req, http.StatusForbidden)
@@ -252,7 +253,7 @@ func TestAPIGetTeamRepo(t *testing.T) {
var results api.Repository
- token := getUserToken(t, user.Name)
+ token := getUserToken(t, user.Name, auth_model.AccessTokenScopeReadOrg)
req := NewRequestf(t, "GET", "/api/v1/teams/%d/repos/%s/?token=%s", team.ID, teamRepo.FullName(), token)
resp := MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &results)
@@ -260,7 +261,7 @@ func TestAPIGetTeamRepo(t *testing.T) {
// no access if not organization member
user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
- token5 := getUserToken(t, user5.Name)
+ token5 := getUserToken(t, user5.Name, auth_model.AccessTokenScopeReadOrg)
req = NewRequestf(t, "GET", "/api/v1/teams/%d/repos/%s/?token=%s", team.ID, teamRepo.FullName(), token5)
MakeRequest(t, req, http.StatusNotFound)
diff --git a/tests/integration/api_team_user_test.go b/tests/integration/api_team_user_test.go
index a5078aedcc..ec977fa572 100644
--- a/tests/integration/api_team_user_test.go
+++ b/tests/integration/api_team_user_test.go
@@ -8,6 +8,7 @@ import (
"testing"
"time"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
api "code.gitea.io/gitea/modules/structs"
@@ -22,7 +23,7 @@ func TestAPITeamUser(t *testing.T) {
normalUsername := "user2"
session := loginUser(t, normalUsername)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrg)
req := NewRequest(t, "GET", "/api/v1/teams/1/members/user1?token="+token)
MakeRequest(t, req, http.StatusNotFound)
diff --git a/tests/integration/api_user_email_test.go b/tests/integration/api_user_email_test.go
index 147f703e9a..09083d9ce8 100644
--- a/tests/integration/api_user_email_test.go
+++ b/tests/integration/api_user_email_test.go
@@ -7,6 +7,7 @@ import (
"net/http"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/tests"
@@ -18,7 +19,7 @@ func TestAPIListEmails(t *testing.T) {
normalUsername := "user2"
session := loginUser(t, normalUsername)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser)
req := NewRequest(t, "GET", "/api/v1/user/emails?token="+token)
resp := MakeRequest(t, req, http.StatusOK)
@@ -45,7 +46,7 @@ func TestAPIAddEmail(t *testing.T) {
normalUsername := "user2"
session := loginUser(t, normalUsername)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeUser)
opts := api.CreateEmailOption{
Emails: []string{"user101@example.com"},
@@ -82,7 +83,7 @@ func TestAPIDeleteEmail(t *testing.T) {
normalUsername := "user2"
session := loginUser(t, normalUsername)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeUser)
opts := api.DeleteEmailOption{
Emails: []string{"user2-3@example.com"},
diff --git a/tests/integration/api_user_follow_test.go b/tests/integration/api_user_follow_test.go
index 65749521cc..c7ad62e649 100644
--- a/tests/integration/api_user_follow_test.go
+++ b/tests/integration/api_user_follow_test.go
@@ -8,6 +8,7 @@ import (
"net/http"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/tests"
@@ -24,7 +25,7 @@ func TestAPIFollow(t *testing.T) {
token1 := getTokenForLoggedInUser(t, session1)
session2 := loginUser(t, user2)
- token2 := getTokenForLoggedInUser(t, session2)
+ token2 := getTokenForLoggedInUser(t, session2, auth_model.AccessTokenScopeUserFollow)
t.Run("Follow", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
diff --git a/tests/integration/api_user_org_perm_test.go b/tests/integration/api_user_org_perm_test.go
index 8df418494a..ac575b1f01 100644
--- a/tests/integration/api_user_org_perm_test.go
+++ b/tests/integration/api_user_org_perm_test.go
@@ -8,6 +8,7 @@ import (
"net/http"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/tests"
@@ -32,7 +33,7 @@ func sampleTest(t *testing.T, auoptc apiUserOrgPermTestCase) {
defer tests.PrepareTestEnv(t)()
session := loginUser(t, auoptc.LoginUser)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrg)
req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s/orgs/%s/permissions?token=%s", auoptc.User, auoptc.Organization, token))
resp := MakeRequest(t, req, http.StatusOK)
@@ -125,7 +126,7 @@ func TestUnknowUser(t *testing.T) {
defer tests.PrepareTestEnv(t)()
session := loginUser(t, "user1")
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrg)
req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/unknow/orgs/org25/permissions?token=%s", token))
resp := MakeRequest(t, req, http.StatusNotFound)
@@ -139,7 +140,7 @@ func TestUnknowOrganization(t *testing.T) {
defer tests.PrepareTestEnv(t)()
session := loginUser(t, "user1")
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrg)
req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/user1/orgs/unknow/permissions?token=%s", token))
resp := MakeRequest(t, req, http.StatusNotFound)
diff --git a/tests/integration/api_user_orgs_test.go b/tests/integration/api_user_orgs_test.go
index 1f9ee2ea6e..831ca018b4 100644
--- a/tests/integration/api_user_orgs_test.go
+++ b/tests/integration/api_user_orgs_test.go
@@ -8,6 +8,7 @@ import (
"net/http"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
api "code.gitea.io/gitea/modules/structs"
@@ -61,15 +62,14 @@ func TestUserOrgs(t *testing.T) {
orgs = getUserOrgs(t, unrelatedUsername, privateMemberUsername)
assert.Len(t, orgs, 0)
- // not authenticated call also should hide org membership
- orgs = getUserOrgs(t, "", privateMemberUsername)
- assert.Len(t, orgs, 0)
+ // not authenticated call should not be allowed
+ testUserOrgsUnauthenticated(t, privateMemberUsername)
}
func getUserOrgs(t *testing.T, userDoer, userCheck string) (orgs []*api.Organization) {
token := ""
if len(userDoer) != 0 {
- token = getUserToken(t, userDoer)
+ token = getUserToken(t, userDoer, auth_model.AccessTokenScopeReadOrg)
}
urlStr := fmt.Sprintf("/api/v1/users/%s/orgs?token=%s", userCheck, token)
req := NewRequest(t, "GET", urlStr)
@@ -78,6 +78,12 @@ func getUserOrgs(t *testing.T, userDoer, userCheck string) (orgs []*api.Organiza
return orgs
}
+func testUserOrgsUnauthenticated(t *testing.T, userCheck string) {
+ session := emptyTestSession(t)
+ req := NewRequestf(t, "GET", "/api/v1/users/%s/orgs", userCheck)
+ session.MakeRequest(t, req, http.StatusUnauthorized)
+}
+
func TestMyOrgs(t *testing.T) {
defer tests.PrepareTestEnv(t)()
@@ -85,7 +91,7 @@ func TestMyOrgs(t *testing.T) {
MakeRequest(t, req, http.StatusUnauthorized)
normalUsername := "user2"
- token := getUserToken(t, normalUsername)
+ token := getUserToken(t, normalUsername, auth_model.AccessTokenScopeReadOrg)
req = NewRequest(t, "GET", "/api/v1/user/orgs?token="+token)
resp := MakeRequest(t, req, http.StatusOK)
var orgs []*api.Organization
diff --git a/tests/integration/api_user_star_test.go b/tests/integration/api_user_star_test.go
index 63363f22de..6a486c19a8 100644
--- a/tests/integration/api_user_star_test.go
+++ b/tests/integration/api_user_star_test.go
@@ -8,6 +8,7 @@ import (
"net/http"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/tests"
@@ -22,11 +23,12 @@ func TestAPIStar(t *testing.T) {
session := loginUser(t, user)
token := getTokenForLoggedInUser(t, session)
+ tokenWithRepoScope := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
t.Run("Star", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
- req := NewRequest(t, "PUT", fmt.Sprintf("/api/v1/user/starred/%s?token=%s", repo, token))
+ req := NewRequest(t, "PUT", fmt.Sprintf("/api/v1/user/starred/%s?token=%s", repo, tokenWithRepoScope))
MakeRequest(t, req, http.StatusNoContent)
})
@@ -47,7 +49,7 @@ func TestAPIStar(t *testing.T) {
t.Run("GetMyStarredRepos", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
- req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/starred?token=%s", token))
+ req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/starred?token=%s", tokenWithRepoScope))
resp := MakeRequest(t, req, http.StatusOK)
assert.Equal(t, "1", resp.Header().Get("X-Total-Count"))
@@ -61,17 +63,17 @@ func TestAPIStar(t *testing.T) {
t.Run("IsStarring", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
- req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/starred/%s?token=%s", repo, token))
+ req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/starred/%s?token=%s", repo, tokenWithRepoScope))
MakeRequest(t, req, http.StatusNoContent)
- req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/starred/%s?token=%s", repo+"notexisting", token))
+ req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/starred/%s?token=%s", repo+"notexisting", tokenWithRepoScope))
MakeRequest(t, req, http.StatusNotFound)
})
t.Run("Unstar", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
- req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/user/starred/%s?token=%s", repo, token))
+ req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/user/starred/%s?token=%s", repo, tokenWithRepoScope))
MakeRequest(t, req, http.StatusNoContent)
})
}
diff --git a/tests/integration/api_user_watch_test.go b/tests/integration/api_user_watch_test.go
index 295e639fd1..5702962573 100644
--- a/tests/integration/api_user_watch_test.go
+++ b/tests/integration/api_user_watch_test.go
@@ -8,6 +8,7 @@ import (
"net/http"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/tests"
@@ -22,11 +23,12 @@ func TestAPIWatch(t *testing.T) {
session := loginUser(t, user)
token := getTokenForLoggedInUser(t, session)
+ tokenWithRepoScope := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
t.Run("Watch", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
- req := NewRequest(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/subscription?token=%s", repo, token))
+ req := NewRequest(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/subscription?token=%s", repo, tokenWithRepoScope))
MakeRequest(t, req, http.StatusOK)
})
@@ -47,7 +49,7 @@ func TestAPIWatch(t *testing.T) {
t.Run("GetMyWatchedRepos", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
- req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/subscriptions?token=%s", token))
+ req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/subscriptions?token=%s", tokenWithRepoScope))
resp := MakeRequest(t, req, http.StatusOK)
assert.Equal(t, "1", resp.Header().Get("X-Total-Count"))
@@ -61,17 +63,17 @@ func TestAPIWatch(t *testing.T) {
t.Run("IsWatching", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
- req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/subscription?token=%s", repo, token))
+ req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/subscription?token=%s", repo, tokenWithRepoScope))
MakeRequest(t, req, http.StatusOK)
- req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/subscription?token=%s", repo+"notexisting", token))
+ req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/subscription?token=%s", repo+"notexisting", tokenWithRepoScope))
MakeRequest(t, req, http.StatusNotFound)
})
t.Run("Unwatch", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
- req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/subscription?token=%s", repo, token))
+ req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/subscription?token=%s", repo, tokenWithRepoScope))
MakeRequest(t, req, http.StatusNoContent)
})
}
diff --git a/tests/integration/api_wiki_test.go b/tests/integration/api_wiki_test.go
index 546f4d0e3e..3f85074c8a 100644
--- a/tests/integration/api_wiki_test.go
+++ b/tests/integration/api_wiki_test.go
@@ -9,6 +9,7 @@ import (
"net/http"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/tests"
@@ -179,7 +180,7 @@ func TestAPINewWikiPage(t *testing.T) {
defer tests.PrepareTestEnv(t)()
username := "user2"
session := loginUser(t, username)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/wiki/new?token=%s", username, "repo1", token)
@@ -196,7 +197,7 @@ func TestAPIEditWikiPage(t *testing.T) {
defer tests.PrepareTestEnv(t)()
username := "user2"
session := loginUser(t, username)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/wiki/page/Page-With-Spaced-Name?token=%s", username, "repo1", token)
diff --git a/tests/integration/dump_restore_test.go b/tests/integration/dump_restore_test.go
index e34738aaf1..9ad795d53a 100644
--- a/tests/integration/dump_restore_test.go
+++ b/tests/integration/dump_restore_test.go
@@ -14,6 +14,7 @@ import (
"strings"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@@ -50,7 +51,7 @@ func TestDumpRestore(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame})
repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, repoOwner.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
//
// Phase 1: dump repo1 from the Gitea instance to the filesystem
diff --git a/tests/integration/eventsource_test.go b/tests/integration/eventsource_test.go
index e810a9fa24..4fdb8cd6f5 100644
--- a/tests/integration/eventsource_test.go
+++ b/tests/integration/eventsource_test.go
@@ -10,6 +10,7 @@ import (
"time"
activities_model "code.gitea.io/gitea/models/activities"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
@@ -59,7 +60,7 @@ func TestEventSourceManagerRun(t *testing.T) {
thread5 := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{ID: 5})
assert.NoError(t, thread5.LoadAttributes(db.DefaultContext))
session := loginUser(t, user2.Name)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeNotification)
var apiNL []api.NotificationThread
diff --git a/tests/integration/git_test.go b/tests/integration/git_test.go
index f7e1e04b1e..a11bad21b7 100644
--- a/tests/integration/git_test.go
+++ b/tests/integration/git_test.go
@@ -16,6 +16,7 @@ import (
"testing"
"time"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/perm"
@@ -42,11 +43,11 @@ func TestGit(t *testing.T) {
func testGit(t *testing.T, u *url.URL) {
username := "user2"
- baseAPITestContext := NewAPITestContext(t, username, "repo1")
+ baseAPITestContext := NewAPITestContext(t, username, "repo1", auth_model.AccessTokenScopeRepo, auth_model.AccessTokenScopeWritePublicKey, auth_model.AccessTokenScopeDeleteRepo)
u.Path = baseAPITestContext.GitPath()
- forkedUserCtx := NewAPITestContext(t, "user4", "repo1")
+ forkedUserCtx := NewAPITestContext(t, "user4", "repo1", auth_model.AccessTokenScopeRepo)
t.Run("HTTP", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
@@ -357,7 +358,7 @@ func doBranchProtectPRMerge(baseCtx *APITestContext, dstPath string) func(t *tes
t.Run("CreateBranchProtected", doGitCreateBranch(dstPath, "protected"))
t.Run("PushProtectedBranch", doGitPushTestRepository(dstPath, "origin", "protected"))
- ctx := NewAPITestContext(t, baseCtx.Username, baseCtx.Reponame)
+ ctx := NewAPITestContext(t, baseCtx.Username, baseCtx.Reponame, auth_model.AccessTokenScopeRepo)
t.Run("ProtectProtectedBranchNoWhitelist", doProtectBranch(ctx, "protected", "", ""))
t.Run("GenerateCommit", func(t *testing.T) {
_, err := generateCommitWithNewData(littleSize, dstPath, "user2@example.com", "User Two", "branch-data-file-")
@@ -601,7 +602,7 @@ func doAutoPRMerge(baseCtx *APITestContext, dstPath string) func(t *testing.T) {
return func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
- ctx := NewAPITestContext(t, baseCtx.Username, baseCtx.Reponame)
+ ctx := NewAPITestContext(t, baseCtx.Username, baseCtx.Reponame, auth_model.AccessTokenScopeRepo)
t.Run("CheckoutProtected", doGitCheckoutBranch(dstPath, "protected"))
t.Run("PullProtected", doGitPull(dstPath, "origin", "protected"))
diff --git a/tests/integration/gpg_git_test.go b/tests/integration/gpg_git_test.go
index 669212ff14..36095694b0 100644
--- a/tests/integration/gpg_git_test.go
+++ b/tests/integration/gpg_git_test.go
@@ -10,6 +10,7 @@ import (
"os"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/process"
@@ -69,7 +70,7 @@ func TestGPGGit(t *testing.T) {
t.Run("Unsigned-Initial", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
- testCtx := NewAPITestContext(t, username, "initial-unsigned")
+ testCtx := NewAPITestContext(t, username, "initial-unsigned", auth_model.AccessTokenScopeRepo)
t.Run("CreateRepository", doAPICreateRepository(testCtx, false))
t.Run("CheckMasterBranchUnsigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) {
assert.NotNil(t, branch.Commit)
@@ -93,7 +94,7 @@ func TestGPGGit(t *testing.T) {
t.Run("Unsigned-Initial-CRUD-ParentSigned", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
- testCtx := NewAPITestContext(t, username, "initial-unsigned")
+ testCtx := NewAPITestContext(t, username, "initial-unsigned", auth_model.AccessTokenScopeRepo)
t.Run("CreateCRUDFile-ParentSigned", crudActionCreateFile(
t, testCtx, user, "master", "parentsigned", "signed-parent.txt", func(t *testing.T, response api.FileResponse) {
assert.False(t, response.Verification.Verified)
@@ -110,7 +111,7 @@ func TestGPGGit(t *testing.T) {
t.Run("Unsigned-Initial-CRUD-Never", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
- testCtx := NewAPITestContext(t, username, "initial-unsigned")
+ testCtx := NewAPITestContext(t, username, "initial-unsigned", auth_model.AccessTokenScopeRepo)
t.Run("CreateCRUDFile-Never", crudActionCreateFile(
t, testCtx, user, "parentsigned", "parentsigned-never", "unsigned-never2.txt", func(t *testing.T, response api.FileResponse) {
assert.False(t, response.Verification.Verified)
@@ -123,7 +124,7 @@ func TestGPGGit(t *testing.T) {
t.Run("Unsigned-Initial-CRUD-Always", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
- testCtx := NewAPITestContext(t, username, "initial-unsigned")
+ testCtx := NewAPITestContext(t, username, "initial-unsigned", auth_model.AccessTokenScopeRepo)
t.Run("CreateCRUDFile-Always", crudActionCreateFile(
t, testCtx, user, "master", "always", "signed-always.txt", func(t *testing.T, response api.FileResponse) {
assert.NotNil(t, response.Verification)
@@ -160,7 +161,7 @@ func TestGPGGit(t *testing.T) {
t.Run("Unsigned-Initial-CRUD-ParentSigned", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
- testCtx := NewAPITestContext(t, username, "initial-unsigned")
+ testCtx := NewAPITestContext(t, username, "initial-unsigned", auth_model.AccessTokenScopeRepo)
t.Run("CreateCRUDFile-Always-ParentSigned", crudActionCreateFile(
t, testCtx, user, "always", "always-parentsigned", "signed-always-parentsigned.txt", func(t *testing.T, response api.FileResponse) {
assert.NotNil(t, response.Verification)
@@ -183,7 +184,7 @@ func TestGPGGit(t *testing.T) {
t.Run("AlwaysSign-Initial", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
- testCtx := NewAPITestContext(t, username, "initial-always")
+ testCtx := NewAPITestContext(t, username, "initial-always", auth_model.AccessTokenScopeRepo)
t.Run("CreateRepository", doAPICreateRepository(testCtx, false))
t.Run("CheckMasterBranchSigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) {
assert.NotNil(t, branch.Commit)
@@ -211,7 +212,7 @@ func TestGPGGit(t *testing.T) {
t.Run("AlwaysSign-Initial-CRUD-Never", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
- testCtx := NewAPITestContext(t, username, "initial-always-never")
+ testCtx := NewAPITestContext(t, username, "initial-always-never", auth_model.AccessTokenScopeRepo)
t.Run("CreateRepository", doAPICreateRepository(testCtx, false))
t.Run("CreateCRUDFile-Never", crudActionCreateFile(
t, testCtx, user, "master", "never", "unsigned-never.txt", func(t *testing.T, response api.FileResponse) {
@@ -224,7 +225,7 @@ func TestGPGGit(t *testing.T) {
u.Path = baseAPITestContext.GitPath()
t.Run("AlwaysSign-Initial-CRUD-ParentSigned-On-Always", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
- testCtx := NewAPITestContext(t, username, "initial-always-parent")
+ testCtx := NewAPITestContext(t, username, "initial-always-parent", auth_model.AccessTokenScopeRepo)
t.Run("CreateRepository", doAPICreateRepository(testCtx, false))
t.Run("CreateCRUDFile-ParentSigned", crudActionCreateFile(
t, testCtx, user, "master", "parentsigned", "signed-parent.txt", func(t *testing.T, response api.FileResponse) {
@@ -243,7 +244,7 @@ func TestGPGGit(t *testing.T) {
t.Run("AlwaysSign-Initial-CRUD-Always", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
- testCtx := NewAPITestContext(t, username, "initial-always-always")
+ testCtx := NewAPITestContext(t, username, "initial-always-always", auth_model.AccessTokenScopeRepo)
t.Run("CreateRepository", doAPICreateRepository(testCtx, false))
t.Run("CreateCRUDFile-Always", crudActionCreateFile(
t, testCtx, user, "master", "always", "signed-always.txt", func(t *testing.T, response api.FileResponse) {
@@ -263,7 +264,7 @@ func TestGPGGit(t *testing.T) {
t.Run("UnsignedMerging", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
- testCtx := NewAPITestContext(t, username, "initial-unsigned")
+ testCtx := NewAPITestContext(t, username, "initial-unsigned", auth_model.AccessTokenScopeRepo)
var err error
t.Run("CreatePullRequest", func(t *testing.T) {
pr, err = doAPICreatePullRequest(testCtx, testCtx.Username, testCtx.Reponame, "master", "never2")(t)
@@ -284,7 +285,7 @@ func TestGPGGit(t *testing.T) {
t.Run("BaseSignedMerging", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
- testCtx := NewAPITestContext(t, username, "initial-unsigned")
+ testCtx := NewAPITestContext(t, username, "initial-unsigned", auth_model.AccessTokenScopeRepo)
var err error
t.Run("CreatePullRequest", func(t *testing.T) {
pr, err = doAPICreatePullRequest(testCtx, testCtx.Username, testCtx.Reponame, "master", "parentsigned2")(t)
@@ -305,7 +306,7 @@ func TestGPGGit(t *testing.T) {
t.Run("CommitsSignedMerging", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
- testCtx := NewAPITestContext(t, username, "initial-unsigned")
+ testCtx := NewAPITestContext(t, username, "initial-unsigned", auth_model.AccessTokenScopeRepo)
var err error
t.Run("CreatePullRequest", func(t *testing.T) {
pr, err = doAPICreatePullRequest(testCtx, testCtx.Username, testCtx.Reponame, "master", "always-parentsigned")(t)
diff --git a/tests/integration/integration_test.go b/tests/integration/integration_test.go
index 911d9ddf4c..fbb6322785 100644
--- a/tests/integration/integration_test.go
+++ b/tests/integration/integration_test.go
@@ -21,6 +21,7 @@ import (
"testing"
"time"
+ "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/json"
@@ -217,8 +218,8 @@ func emptyTestSession(t testing.TB) *TestSession {
return &TestSession{jar: jar}
}
-func getUserToken(t testing.TB, userName string) string {
- return getTokenForLoggedInUser(t, loginUser(t, userName))
+func getUserToken(t testing.TB, userName string, scope ...auth.AccessTokenScope) string {
+ return getTokenForLoggedInUser(t, loginUser(t, userName), scope...)
}
func loginUser(t testing.TB, userName string) *TestSession {
@@ -256,7 +257,10 @@ func loginUserWithPassword(t testing.TB, userName, password string) *TestSession
// token has to be unique this counter take care of
var tokenCounter int64
-func getTokenForLoggedInUser(t testing.TB, session *TestSession) string {
+// getTokenForLoggedInUser returns a token for a logged in user.
+// The scope is an optional list of snake_case strings like the frontend form fields,
+// but without the "scope_" prefix.
+func getTokenForLoggedInUser(t testing.TB, session *TestSession, scopes ...auth.AccessTokenScope) string {
t.Helper()
var token string
req := NewRequest(t, "GET", "/user/settings/applications")
@@ -274,10 +278,13 @@ func getTokenForLoggedInUser(t testing.TB, session *TestSession) string {
csrf = doc.GetCSRF()
}
assert.NotEmpty(t, csrf)
- req = NewRequestWithValues(t, "POST", "/user/settings/applications", map[string]string{
- "_csrf": csrf,
- "name": fmt.Sprintf("api-testing-token-%d", atomic.AddInt64(&tokenCounter, 1)),
- })
+ urlValues := url.Values{}
+ urlValues.Add("_csrf", csrf)
+ urlValues.Add("name", fmt.Sprintf("api-testing-token-%d", atomic.AddInt64(&tokenCounter, 1)))
+ for _, scope := range scopes {
+ urlValues.Add("scope", string(scope))
+ }
+ req = NewRequestWithURLValues(t, "POST", "/user/settings/applications", urlValues)
resp = session.MakeRequest(t, req, http.StatusSeeOther)
// Log the flash values on failure
@@ -317,6 +324,11 @@ func NewRequestWithValues(t testing.TB, method, urlStr string, values map[string
for key, value := range values {
urlValues[key] = []string{value}
}
+ return NewRequestWithURLValues(t, method, urlStr, urlValues)
+}
+
+func NewRequestWithURLValues(t testing.TB, method, urlStr string, urlValues url.Values) *http.Request {
+ t.Helper()
req := NewRequestWithBody(t, method, urlStr, bytes.NewBufferString(urlValues.Encode()))
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
return req
diff --git a/tests/integration/migrate_test.go b/tests/integration/migrate_test.go
index 9eca69cfcf..a925493d7c 100644
--- a/tests/integration/migrate_test.go
+++ b/tests/integration/migrate_test.go
@@ -11,6 +11,7 @@ import (
"path/filepath"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@@ -66,7 +67,7 @@ func TestMigrateGiteaForm(t *testing.T) {
repoName := "repo1"
repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: ownerName})
session := loginUser(t, ownerName)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
// Step 0: verify the repo is available
req := NewRequestf(t, "GET", fmt.Sprintf("/%s/%s", ownerName, repoName))
diff --git a/tests/integration/org_count_test.go b/tests/integration/org_count_test.go
index a6fe7f188e..8f850a170f 100644
--- a/tests/integration/org_count_test.go
+++ b/tests/integration/org_count_test.go
@@ -8,6 +8,7 @@ import (
"strings"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@@ -24,7 +25,7 @@ func testOrgCounts(t *testing.T, u *url.URL) {
orgOwner := "user2"
orgName := "testOrg"
orgCollaborator := "user4"
- ctx := NewAPITestContext(t, orgOwner, "repo1")
+ ctx := NewAPITestContext(t, orgOwner, "repo1", auth_model.AccessTokenScopeAdminOrg)
var ownerCountRepos map[string]int
var collabCountRepos map[string]int
diff --git a/tests/integration/org_test.go b/tests/integration/org_test.go
index 09a5f42082..bfa6380e8a 100644
--- a/tests/integration/org_test.go
+++ b/tests/integration/org_test.go
@@ -9,6 +9,7 @@ import (
"strings"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
api "code.gitea.io/gitea/modules/structs"
@@ -158,7 +159,7 @@ func TestOrgRestrictedUser(t *testing.T) {
// Therefore create a read-only team
adminSession := loginUser(t, "user1")
- token := getTokenForLoggedInUser(t, adminSession)
+ token := getTokenForLoggedInUser(t, adminSession, auth_model.AccessTokenScopeAdminOrg)
teamToCreate := &api.CreateTeamOption{
Name: "codereader",
diff --git a/tests/integration/privateactivity_test.go b/tests/integration/privateactivity_test.go
index 06019406d7..6e1377ae1f 100644
--- a/tests/integration/privateactivity_test.go
+++ b/tests/integration/privateactivity_test.go
@@ -9,6 +9,7 @@ import (
"testing"
activities_model "code.gitea.io/gitea/models/activities"
+ auth_model "code.gitea.io/gitea/models/auth"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@@ -33,7 +34,7 @@ func testPrivateActivityDoSomethingForActionEntries(t *testing.T) {
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID})
session := loginUser(t, privateActivityTestUser)
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues?state=all&token=%s", owner.Name, repoBefore.Name, token)
req := NewRequestWithJSON(t, "POST", urlStr, &api.CreateIssueOption{
Body: "test",
diff --git a/tests/integration/pull_merge_test.go b/tests/integration/pull_merge_test.go
index e72d00ffb3..491fc0e0aa 100644
--- a/tests/integration/pull_merge_test.go
+++ b/tests/integration/pull_merge_test.go
@@ -17,6 +17,7 @@ import (
"time"
"code.gitea.io/gitea/models"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
@@ -217,7 +218,7 @@ func TestCantMergeConflict(t *testing.T) {
testEditFileToNewBranch(t, session, "user1", "repo1", "master", "base", "README.md", "Hello, World (Edited Twice)\n")
// Use API to create a conflicting pr
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls?token=%s", "user1", "repo1", token), &api.CreatePullRequestOption{
Head: "conflict",
Base: "base",
@@ -325,7 +326,7 @@ func TestCantMergeUnrelated(t *testing.T) {
testEditFileToNewBranch(t, session, "user1", "repo1", "master", "conflict", "README.md", "Hello, World (Edited Once)\n")
// Use API to create a conflicting pr
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls?token=%s", "user1", "repo1", token), &api.CreatePullRequestOption{
Head: "unrelated",
Base: "base",
diff --git a/tests/integration/pull_status_test.go b/tests/integration/pull_status_test.go
index bca8ec848b..e60d17edc0 100644
--- a/tests/integration/pull_status_test.go
+++ b/tests/integration/pull_status_test.go
@@ -11,6 +11,7 @@ import (
"strings"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
api "code.gitea.io/gitea/modules/structs"
"github.com/stretchr/testify/assert"
@@ -63,7 +64,7 @@ func TestPullCreate_CommitStatus(t *testing.T) {
api.CommitStatusWarning: "gitea-exclamation",
}
- testCtx := NewAPITestContext(t, "user1", "repo1")
+ testCtx := NewAPITestContext(t, "user1", "repo1", auth_model.AccessTokenScopeRepo)
// Update commit status, and check if icon is updated as well
for _, status := range statusList {
diff --git a/tests/integration/pull_update_test.go b/tests/integration/pull_update_test.go
index 1e20a63e66..bd416e5bcf 100644
--- a/tests/integration/pull_update_test.go
+++ b/tests/integration/pull_update_test.go
@@ -9,6 +9,7 @@ import (
"testing"
"time"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/unittest"
@@ -38,7 +39,7 @@ func TestAPIPullUpdate(t *testing.T) {
assert.NoError(t, pr.LoadIssue(db.DefaultContext))
session := loginUser(t, "user2")
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
req := NewRequestf(t, "POST", "/api/v1/repos/%s/%s/pulls/%d/update?token="+token, pr.BaseRepo.OwnerName, pr.BaseRepo.Name, pr.Issue.Index)
session.MakeRequest(t, req, http.StatusOK)
@@ -66,7 +67,7 @@ func TestAPIPullUpdateByRebase(t *testing.T) {
assert.NoError(t, pr.LoadIssue(db.DefaultContext))
session := loginUser(t, "user2")
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo)
req := NewRequestf(t, "POST", "/api/v1/repos/%s/%s/pulls/%d/update?style=rebase&token="+token, pr.BaseRepo.OwnerName, pr.BaseRepo.Name, pr.Issue.Index)
session.MakeRequest(t, req, http.StatusOK)
diff --git a/tests/integration/repo_commits_test.go b/tests/integration/repo_commits_test.go
index ab90e72877..cbd83c6deb 100644
--- a/tests/integration/repo_commits_test.go
+++ b/tests/integration/repo_commits_test.go
@@ -11,6 +11,7 @@ import (
"sync"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
@@ -50,7 +51,8 @@ func doTestRepoCommitWithStatus(t *testing.T, state string, classes ...string) {
assert.NotEmpty(t, commitURL)
// Call API to add status for commit
- t.Run("CreateStatus", doAPICreateCommitStatus(NewAPITestContext(t, "user2", "repo1"), path.Base(commitURL), api.CommitStatusState(state)))
+ ctx := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeRepo)
+ t.Run("CreateStatus", doAPICreateCommitStatus(ctx, path.Base(commitURL), api.CommitStatusState(state)))
req = NewRequest(t, "GET", "/user2/repo1/commits/branch/master")
resp = session.MakeRequest(t, req, http.StatusOK)
@@ -142,7 +144,8 @@ func TestRepoCommitsStatusParallel(t *testing.T) {
wg.Add(1)
go func(parentT *testing.T, i int) {
parentT.Run(fmt.Sprintf("ParallelCreateStatus_%d", i), func(t *testing.T) {
- runBody := doAPICreateCommitStatus(NewAPITestContext(t, "user2", "repo1"), path.Base(commitURL), api.CommitStatusState("pending"))
+ ctx := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeRepoStatus)
+ runBody := doAPICreateCommitStatus(ctx, path.Base(commitURL), api.CommitStatusState("pending"))
runBody(t)
wg.Done()
})
diff --git a/tests/integration/ssh_key_test.go b/tests/integration/ssh_key_test.go
index 89a2774303..1e9dc264a6 100644
--- a/tests/integration/ssh_key_test.go
+++ b/tests/integration/ssh_key_test.go
@@ -12,6 +12,7 @@ import (
"testing"
"time"
+ auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/modules/git"
api "code.gitea.io/gitea/modules/structs"
@@ -47,7 +48,9 @@ func TestPushDeployKeyOnEmptyRepo(t *testing.T) {
func testPushDeployKeyOnEmptyRepo(t *testing.T, u *url.URL) {
// OK login
- ctx := NewAPITestContext(t, "user2", "deploy-key-empty-repo-1")
+ ctx := NewAPITestContext(t, "user2", "deploy-key-empty-repo-1", auth_model.AccessTokenScopeRepo)
+ ctxWithDeleteRepo := NewAPITestContext(t, "user2", "deploy-key-empty-repo-1", auth_model.AccessTokenScopeRepo, auth_model.AccessTokenScopeDeleteRepo)
+
keyname := fmt.Sprintf("%s-push", ctx.Reponame)
u.Path = ctx.GitPath()
@@ -72,7 +75,7 @@ func testPushDeployKeyOnEmptyRepo(t *testing.T, u *url.URL) {
t.Run("CheckIsNotEmpty", doCheckRepositoryEmptyStatus(ctx, false))
- t.Run("DeleteRepository", doAPIDeleteRepository(ctx))
+ t.Run("DeleteRepository", doAPIDeleteRepository(ctxWithDeleteRepo))
})
}
@@ -89,10 +92,13 @@ func testKeyOnlyOneType(t *testing.T, u *url.URL) {
keyname := fmt.Sprintf("%s-push", reponame)
// OK login
- ctx := NewAPITestContext(t, username, reponame)
+ ctx := NewAPITestContext(t, username, reponame, auth_model.AccessTokenScopeRepo, auth_model.AccessTokenScopeAdminPublicKey)
+ ctxWithDeleteRepo := NewAPITestContext(t, username, reponame, auth_model.AccessTokenScopeRepo, auth_model.AccessTokenScopeAdminPublicKey, auth_model.AccessTokenScopeDeleteRepo)
otherCtx := ctx
otherCtx.Reponame = "ssh-key-test-repo-2"
+ otherCtxWithDeleteRepo := ctxWithDeleteRepo
+ otherCtxWithDeleteRepo.Reponame = otherCtx.Reponame
failCtx := ctx
failCtx.ExpectedCode = http.StatusUnprocessableEntity
@@ -160,7 +166,7 @@ func testKeyOnlyOneType(t *testing.T, u *url.URL) {
otherSSHURL := createSSHUrl(otherCtx.GitPath(), u)
dstOtherPath := t.TempDir()
- t.Run("DeleteRepository", doAPIDeleteRepository(ctx))
+ t.Run("DeleteRepository", doAPIDeleteRepository(ctxWithDeleteRepo))
t.Run("FailToCreateUserKeyAsStillDeploy", doAPICreateUserKey(failCtx, keyname, keyFile))
@@ -170,9 +176,9 @@ func testKeyOnlyOneType(t *testing.T, u *url.URL) {
t.Run("PushToOther", doGitPushTestRepository(dstOtherPath, "origin", "master"))
- t.Run("DeleteOtherRepository", doAPIDeleteRepository(otherCtx))
+ t.Run("DeleteOtherRepository", doAPIDeleteRepository(otherCtxWithDeleteRepo))
- t.Run("RecreateRepository", doAPICreateRepository(ctx, false))
+ t.Run("RecreateRepository", doAPICreateRepository(ctxWithDeleteRepo, false))
t.Run("CreateUserKey", doAPICreateUserKey(ctx, keyname, keyFile, func(t *testing.T, publicKey api.PublicKey) {
userKeyPublicKeyID = publicKey.ID
diff --git a/tests/integration/user_test.go b/tests/integration/user_test.go
index eeaa6d6e00..febfe576cf 100644
--- a/tests/integration/user_test.go
+++ b/tests/integration/user_test.go
@@ -7,6 +7,7 @@ import (
"net/http"
"testing"
+ auth_model "code.gitea.io/gitea/models/auth"
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
@@ -165,7 +166,7 @@ Note: This user hasn't uploaded any GPG keys.
// Import key
// User1 <user1@example.com>
session := loginUser(t, "user1")
- token := getTokenForLoggedInUser(t, session)
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteGPGKey)
testCreateGPGKey(t, session.MakeRequest, token, http.StatusCreated, `-----BEGIN PGP PUBLIC KEY BLOCK-----
mQENBFyy/VUBCADJ7zbM20Z1RWmFoVgp5WkQfI2rU1Vj9cQHes9i42wVLLtcbPeo