From ce18b9af09d86da141e5c6db84536f6efb3578c4 Mon Sep 17 00:00:00 2001 From: jackHay22 Date: Tue, 9 May 2023 15:43:24 -0400 Subject: [PATCH 01/67] update scopes, replace in tests, api route definitions, WIP on tests, migration --- models/auth/token_scope.go | 349 ++++++++------ models/auth/token_scope_test.go | 94 ++-- modules/context/permission.go | 28 +- public/serviceworker.js | 6 + routers/api/v1/api.go | 452 +++++++++--------- routers/web/auth/oauth.go | 3 +- routers/web/repo/http.go | 2 +- services/forms/user_form_test.go | 8 +- services/lfs/locks.go | 9 +- services/lfs/server.go | 8 +- tests/integration/api_admin_org_test.go | 4 +- tests/integration/api_admin_test.go | 22 +- tests/integration/api_branch_test.go | 16 +- .../api_comment_attachment_test.go | 6 +- tests/integration/api_comment_test.go | 10 +- tests/integration/api_gpg_keys_test.go | 4 +- tests/integration/api_httpsig_test.go | 2 +- .../integration/api_issue_attachment_test.go | 6 +- tests/integration/api_issue_label_test.go | 8 +- tests/integration/api_issue_milestone_test.go | 2 +- tests/integration/api_issue_pin_test.go | 8 +- tests/integration/api_issue_reaction_test.go | 4 +- tests/integration/api_issue_stopwatch_test.go | 8 +- .../api_issue_subscription_test.go | 2 +- tests/integration/api_issue_test.go | 6 +- .../api_issue_tracked_time_test.go | 6 +- tests/integration/api_keys_test.go | 8 +- tests/integration/api_notification_test.go | 4 +- tests/integration/api_oauth2_apps_test.go | 6 +- tests/integration/api_org_test.go | 10 +- tests/integration/api_packages_npm_test.go | 2 +- tests/integration/api_packages_nuget_test.go | 2 +- tests/integration/api_packages_pub_test.go | 2 +- .../integration/api_packages_vagrant_test.go | 2 +- tests/integration/api_pull_review_test.go | 6 +- tests/integration/api_pull_test.go | 12 +- tests/integration/api_releases_test.go | 10 +- tests/integration/api_repo_archive_test.go | 2 +- .../integration/api_repo_collaborator_test.go | 8 +- tests/integration/api_repo_edit_test.go | 4 +- .../integration/api_repo_file_create_test.go | 6 +- .../integration/api_repo_file_delete_test.go | 4 +- tests/integration/api_repo_file_get_test.go | 2 +- .../integration/api_repo_file_update_test.go | 4 +- tests/integration/api_repo_git_hook_test.go | 18 +- tests/integration/api_repo_git_tags_test.go | 2 +- tests/integration/api_repo_hook_test.go | 2 +- .../integration/api_repo_lfs_migrate_test.go | 2 +- tests/integration/api_repo_lfs_test.go | 2 +- tests/integration/api_repo_raw_test.go | 2 +- tests/integration/api_repo_tags_test.go | 2 +- tests/integration/api_repo_teams_test.go | 4 +- tests/integration/api_repo_test.go | 34 +- tests/integration/api_repo_topic_test.go | 4 +- tests/integration/api_team_test.go | 14 +- tests/integration/api_team_user_test.go | 2 +- tests/integration/api_user_email_test.go | 4 +- tests/integration/api_user_follow_test.go | 2 +- tests/integration/api_user_org_perm_test.go | 6 +- tests/integration/api_user_orgs_test.go | 4 +- tests/integration/api_user_star_test.go | 12 +- tests/integration/api_user_watch_test.go | 2 +- tests/integration/api_wiki_test.go | 4 +- tests/integration/dump_restore_test.go | 2 +- tests/integration/empty_repo_test.go | 2 +- tests/integration/eventsource_test.go | 2 +- tests/integration/git_test.go | 8 +- tests/integration/gpg_git_test.go | 24 +- tests/integration/lfs_getobject_test.go | 8 +- tests/integration/migrate_test.go | 2 +- tests/integration/org_count_test.go | 2 +- tests/integration/org_test.go | 2 +- tests/integration/privateactivity_test.go | 2 +- tests/integration/pull_merge_test.go | 4 +- tests/integration/pull_status_test.go | 2 +- tests/integration/pull_update_test.go | 4 +- tests/integration/repo_commits_test.go | 6 +- tests/integration/ssh_key_test.go | 8 +- tests/integration/user_test.go | 2 +- 79 files changed, 746 insertions(+), 623 deletions(-) create mode 100644 public/serviceworker.js diff --git a/models/auth/token_scope.go b/models/auth/token_scope.go index 06c89fecc2e4d..1cb9633277105 100644 --- a/models/auth/token_scope.go +++ b/models/auth/token_scope.go @@ -6,113 +6,129 @@ package auth import ( "fmt" "strings" + + "code.gitea.io/gitea/models/perm" ) -// AccessTokenScope represents the scope for an access token. -type AccessTokenScope string +// AccessTokenScopeCategory represents the scope category for an access token +type AccessTokenScopeCategory int const ( - AccessTokenScopeAll AccessTokenScope = "all" + NoCategory AccessTokenScopeCategory = iota + AccessTokenScopeCategoryActivityPub + AccessTokenScopeCategoryAdmin + AccessTokenScopeCategoryMisc + AccessTokenScopeCategoryNotification + AccessTokenScopeCategoryOrganization + AccessTokenScopeCategoryPackage + AccessTokenScopeCategoryIssue + AccessTokenScopeCategoryRepository + AccessTokenScopeCategoryUser +) - AccessTokenScopeRepo AccessTokenScope = "repo" - AccessTokenScopeRepoStatus AccessTokenScope = "repo:status" - AccessTokenScopePublicRepo AccessTokenScope = "public_repo" +// AccessTokenScopeLevel represents the access levels without a given scope category +type AccessTokenScopeLevel int - AccessTokenScopeAdminOrg AccessTokenScope = "admin:org" - AccessTokenScopeWriteOrg AccessTokenScope = "write:org" - AccessTokenScopeReadOrg AccessTokenScope = "read:org" +const ( + NoAccess AccessTokenScopeLevel = iota + Read + Write + Delete +) - AccessTokenScopeAdminPublicKey AccessTokenScope = "admin:public_key" - AccessTokenScopeWritePublicKey AccessTokenScope = "write:public_key" - AccessTokenScopeReadPublicKey AccessTokenScope = "read:public_key" +// AccessTokenScope represents the scope for an access token. +type AccessTokenScope string - AccessTokenScopeAdminRepoHook AccessTokenScope = "admin:repo_hook" - AccessTokenScopeWriteRepoHook AccessTokenScope = "write:repo_hook" - AccessTokenScopeReadRepoHook AccessTokenScope = "read:repo_hook" +// for all categories, delete implies write, write implies read +const ( + AccessTokenScopeAll AccessTokenScope = "all" + AccessTokenScopePublicOnly AccessTokenScope = "public" // limited to public orgs/repos - AccessTokenScopeAdminOrgHook AccessTokenScope = "admin:org_hook" + AccessTokenScopeReadActivityPub AccessTokenScope = "read:activitypub" + AccessTokenScopeWriteActivityPub AccessTokenScope = "write:activitypub" + AccessTokenScopeDeleteActivityPub AccessTokenScope = "delete:activitypub" - AccessTokenScopeAdminUserHook AccessTokenScope = "admin:user_hook" + AccessTokenScopeReadAdmin AccessTokenScope = "read:admin" + AccessTokenScopeWriteAdmin AccessTokenScope = "write:admin" + AccessTokenScopeDeleteAdmin AccessTokenScope = "delete:admin" - AccessTokenScopeNotification AccessTokenScope = "notification" + AccessTokenScopeReadMisc AccessTokenScope = "read:misc" + AccessTokenScopeWriteMisc AccessTokenScope = "write:misc" + AccessTokenScopeDeleteMisc AccessTokenScope = "delete:misc" - AccessTokenScopeUser AccessTokenScope = "user" - AccessTokenScopeReadUser AccessTokenScope = "read:user" - AccessTokenScopeUserEmail AccessTokenScope = "user:email" - AccessTokenScopeUserFollow AccessTokenScope = "user:follow" + AccessTokenScopeReadNotification AccessTokenScope = "read:notification" + AccessTokenScopeWriteNotification AccessTokenScope = "write:notification" + AccessTokenScopeDeleteNotification AccessTokenScope = "delete:notification" - AccessTokenScopeDeleteRepo AccessTokenScope = "delete_repo" + AccessTokenScopeReadOrganization AccessTokenScope = "read:organization" + AccessTokenScopeWriteOrganization AccessTokenScope = "write:organization" + AccessTokenScopeDeleteOrganization AccessTokenScope = "delete:organization" - AccessTokenScopePackage AccessTokenScope = "package" - AccessTokenScopeWritePackage AccessTokenScope = "write:package" AccessTokenScopeReadPackage AccessTokenScope = "read:package" + AccessTokenScopeWritePackage AccessTokenScope = "write:package" AccessTokenScopeDeletePackage AccessTokenScope = "delete:package" - AccessTokenScopeAdminGPGKey AccessTokenScope = "admin:gpg_key" - AccessTokenScopeWriteGPGKey AccessTokenScope = "write:gpg_key" - AccessTokenScopeReadGPGKey AccessTokenScope = "read:gpg_key" + AccessTokenScopeReadIssue AccessTokenScope = "read:issue" + AccessTokenScopeWriteIssue AccessTokenScope = "write:issue" + AccessTokenScopeDeleteIssue AccessTokenScope = "delete:issue" - AccessTokenScopeAdminApplication AccessTokenScope = "admin:application" - AccessTokenScopeWriteApplication AccessTokenScope = "write:application" - AccessTokenScopeReadApplication AccessTokenScope = "read:application" + AccessTokenScopeReadRepository AccessTokenScope = "read:repository" + AccessTokenScopeWriteRepository AccessTokenScope = "write:repository" + AccessTokenScopeDeleteRepository AccessTokenScope = "delete:repository" - AccessTokenScopeSudo AccessTokenScope = "sudo" + AccessTokenScopeReadUser AccessTokenScope = "read:user" + AccessTokenScopeWriteUser AccessTokenScope = "write:user" + AccessTokenScopeDeleteUser AccessTokenScope = "delete:user" ) -// AccessTokenScopeBitmap represents a bitmap of access token scopes. -type AccessTokenScopeBitmap uint64 +// 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 | AccessTokenScopeAdminUserHookBits | - AccessTokenScopeNotificationBits | AccessTokenScopeUserBits | AccessTokenScopeDeleteRepoBits | - AccessTokenScopePackageBits | AccessTokenScopeAdminGPGKeyBits | AccessTokenScopeAdminApplicationBits - - AccessTokenScopeRepoBits AccessTokenScopeBitmap = 1< 64 scopes, @@ -120,61 +136,116 @@ const ( ) // allAccessTokenScopes contains all access token scopes. -// The order is important: parent scope must precedes child scopes. +// The order is important: parent scope must precede child scopes. var allAccessTokenScopes = []AccessTokenScope{ - AccessTokenScopeRepo, AccessTokenScopeRepoStatus, AccessTokenScopePublicRepo, - AccessTokenScopeAdminOrg, AccessTokenScopeWriteOrg, AccessTokenScopeReadOrg, - AccessTokenScopeAdminPublicKey, AccessTokenScopeWritePublicKey, AccessTokenScopeReadPublicKey, - AccessTokenScopeAdminRepoHook, AccessTokenScopeWriteRepoHook, AccessTokenScopeReadRepoHook, - AccessTokenScopeAdminOrgHook, - AccessTokenScopeAdminUserHook, - AccessTokenScopeNotification, - AccessTokenScopeUser, AccessTokenScopeReadUser, AccessTokenScopeUserEmail, AccessTokenScopeUserFollow, - AccessTokenScopeDeleteRepo, - AccessTokenScopePackage, AccessTokenScopeWritePackage, AccessTokenScopeReadPackage, AccessTokenScopeDeletePackage, - AccessTokenScopeAdminGPGKey, AccessTokenScopeWriteGPGKey, AccessTokenScopeReadGPGKey, - AccessTokenScopeAdminApplication, AccessTokenScopeWriteApplication, AccessTokenScopeReadApplication, - AccessTokenScopeSudo, + AccessTokenScopePublicOnly, + AccessTokenScopeDeleteActivityPub, AccessTokenScopeWriteActivityPub, AccessTokenScopeReadActivityPub, + AccessTokenScopeDeleteAdmin, AccessTokenScopeWriteAdmin, AccessTokenScopeReadAdmin, + AccessTokenScopeDeleteMisc, AccessTokenScopeWriteMisc, AccessTokenScopeReadMisc, + AccessTokenScopeDeleteNotification, AccessTokenScopeWriteNotification, AccessTokenScopeReadNotification, + AccessTokenScopeDeleteOrganization, AccessTokenScopeWriteOrganization, AccessTokenScopeReadOrganization, + AccessTokenScopeDeletePackage, AccessTokenScopeWritePackage, AccessTokenScopeReadPackage, + AccessTokenScopeDeleteIssue, AccessTokenScopeWriteIssue, AccessTokenScopeReadIssue, + AccessTokenScopeDeleteRepository, AccessTokenScopeWriteRepository, AccessTokenScopeReadRepository, + AccessTokenScopeDeleteUser, AccessTokenScopeWriteUser, AccessTokenScopeReadUser, } // 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, - AccessTokenScopeAdminUserHook: AccessTokenScopeAdminUserHookBits, - 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, +var allAccessTokenScopeBits = map[AccessTokenScope]accessTokenScopeBitmap{ + AccessTokenScopeAll: accessTokenScopeAllBits, + AccessTokenScopePublicOnly: accessTokenScopePublicOnlyBits, + AccessTokenScopeReadActivityPub: accessTokenScopeReadActivityPubBits, + AccessTokenScopeWriteActivityPub: accessTokenScopeWriteActivityPubBits, + AccessTokenScopeDeleteActivityPub: accessTokenScopeDeleteActivityPubBits, + AccessTokenScopeReadAdmin: accessTokenScopeReadAdminBits, + AccessTokenScopeWriteAdmin: accessTokenScopeWriteAdminBits, + AccessTokenScopeDeleteAdmin: accessTokenScopeDeleteAdminBits, + AccessTokenScopeReadMisc: accessTokenScopeReadMiscBits, + AccessTokenScopeWriteMisc: accessTokenScopeWriteMiscBits, + AccessTokenScopeDeleteMisc: accessTokenScopeDeleteMiscBits, + AccessTokenScopeReadNotification: accessTokenScopeReadNotificationBits, + AccessTokenScopeWriteNotification: accessTokenScopeWriteNotificationBits, + AccessTokenScopeDeleteNotification: accessTokenScopeDeleteNotificationBits, + AccessTokenScopeReadOrganization: accessTokenScopeReadOrganizationBits, + AccessTokenScopeWriteOrganization: accessTokenScopeWriteOrganizationBits, + AccessTokenScopeDeleteOrganization: accessTokenScopeDeleteOrganizationBits, + AccessTokenScopeReadPackage: accessTokenScopeReadPackageBits, + AccessTokenScopeWritePackage: accessTokenScopeWritePackageBits, + AccessTokenScopeDeletePackage: accessTokenScopeDeletePackageBits, + AccessTokenScopeReadIssue: accessTokenScopeReadIssueBits, + AccessTokenScopeWriteIssue: accessTokenScopeWriteIssueBits, + AccessTokenScopeDeleteIssue: accessTokenScopeDeleteIssueBits, + AccessTokenScopeReadRepository: accessTokenScopeReadRepositoryBits, + AccessTokenScopeWriteRepository: accessTokenScopeWriteRepositoryBits, + AccessTokenScopeDeleteRepository: accessTokenScopeDeleteRepositoryBits, + AccessTokenScopeReadUser: accessTokenScopeReadUserBits, + AccessTokenScopeWriteUser: accessTokenScopeWriteUserBits, + AccessTokenScopeDeleteUser: accessTokenScopeDeleteUserBits, +} + +// readAccessTokenScopes maps a scope category to the read permission scope +var accessTokenScopes = map[AccessTokenScopeLevel]map[AccessTokenScopeCategory]AccessTokenScope{ + Read: { + AccessTokenScopeCategoryActivityPub: AccessTokenScopeReadActivityPub, + AccessTokenScopeCategoryAdmin: AccessTokenScopeReadAdmin, + AccessTokenScopeCategoryMisc: AccessTokenScopeReadMisc, + AccessTokenScopeCategoryNotification: AccessTokenScopeReadNotification, + AccessTokenScopeCategoryOrganization: AccessTokenScopeReadOrganization, + AccessTokenScopeCategoryPackage: AccessTokenScopeReadPackage, + AccessTokenScopeCategoryIssue: AccessTokenScopeReadIssue, + AccessTokenScopeCategoryRepository: AccessTokenScopeReadRepository, + AccessTokenScopeCategoryUser: AccessTokenScopeReadUser, + }, + Write: { + AccessTokenScopeCategoryActivityPub: AccessTokenScopeWriteActivityPub, + AccessTokenScopeCategoryAdmin: AccessTokenScopeWriteAdmin, + AccessTokenScopeCategoryMisc: AccessTokenScopeWriteMisc, + AccessTokenScopeCategoryNotification: AccessTokenScopeWriteNotification, + AccessTokenScopeCategoryOrganization: AccessTokenScopeWriteOrganization, + AccessTokenScopeCategoryPackage: AccessTokenScopeWritePackage, + AccessTokenScopeCategoryIssue: AccessTokenScopeWriteIssue, + AccessTokenScopeCategoryRepository: AccessTokenScopeWriteRepository, + AccessTokenScopeCategoryUser: AccessTokenScopeWriteUser, + }, + Delete: { + AccessTokenScopeCategoryActivityPub: AccessTokenScopeDeleteActivityPub, + AccessTokenScopeCategoryAdmin: AccessTokenScopeDeleteAdmin, + AccessTokenScopeCategoryMisc: AccessTokenScopeDeleteMisc, + AccessTokenScopeCategoryNotification: AccessTokenScopeDeleteNotification, + AccessTokenScopeCategoryOrganization: AccessTokenScopeDeleteOrganization, + AccessTokenScopeCategoryPackage: AccessTokenScopeDeletePackage, + AccessTokenScopeCategoryIssue: AccessTokenScopeDeleteIssue, + AccessTokenScopeCategoryRepository: AccessTokenScopeDeleteRepository, + AccessTokenScopeCategoryUser: AccessTokenScopeDeleteUser, + }, +} + +// GetRequiredScope gets the specific scope for a given level and category +func GetRequiredScope(level AccessTokenScopeLevel, scopeCategory AccessTokenScopeCategory) AccessTokenScope { + return accessTokenScopes[level][scopeCategory] +} + +// GetScopeLevelFromAccessMode converts permission access mode to scope level +func GetScopeLevelFromAccessMode(mode perm.AccessMode) AccessTokenScopeLevel { + switch mode { + case perm.AccessModeNone: + return NoAccess + case perm.AccessModeRead: + return Read + case perm.AccessModeWrite: + return Write + case perm.AccessModeAdmin: + return Delete + case perm.AccessModeOwner: + return Delete + default: + return NoAccess + } } -// Parse parses the scope string into a bitmap, thus removing possible duplicates. -func (s AccessTokenScope) Parse() (AccessTokenScopeBitmap, error) { - var bitmap AccessTokenScopeBitmap +// parse the scope string into a bitmap, thus removing possible duplicates. +func (s AccessTokenScope) parse() (accessTokenScopeBitmap, error) { + var bitmap accessTokenScopeBitmap // The following is the more performant equivalent of 'for _, v := range strings.Split(remainingScope, ",")' as this is hot code remainingScopes := string(s) @@ -196,7 +267,7 @@ func (s AccessTokenScope) Parse() (AccessTokenScopeBitmap, error) { continue } if singleScope == AccessTokenScopeAll { - bitmap |= AccessTokenScopeAllBits + bitmap |= accessTokenScopeAllBits continue } @@ -217,26 +288,36 @@ func (s AccessTokenScope) StringSlice() []string { // Normalize returns a normalized scope string without any duplicates. func (s AccessTokenScope) Normalize() (AccessTokenScope, error) { - bitmap, err := s.Parse() + bitmap, err := s.parse() if err != nil { return "", err } - return bitmap.ToScope(), nil + return bitmap.toScope(), nil +} + +// PublicOnly checks if this token scope is limited to public resources +func (s AccessTokenScope) PublicOnly() (bool, error) { + bitmap, err := s.parse() + if err != nil { + return false, err + } + + return bitmap.hasScope(AccessTokenScopePublicOnly) } // HasScope returns true if the string has the given scope func (s AccessTokenScope) HasScope(scope AccessTokenScope) (bool, error) { - bitmap, err := s.Parse() + bitmap, err := s.parse() if err != nil { return false, err } - return bitmap.HasScope(scope) + return bitmap.hasScope(scope) } -// HasScope returns true if the string has the given scope -func (bitmap AccessTokenScopeBitmap) HasScope(scope AccessTokenScope) (bool, error) { +// 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) @@ -245,17 +326,17 @@ func (bitmap AccessTokenScopeBitmap) HasScope(scope AccessTokenScope) (bool, err return bitmap&expectedBits == expectedBits, nil } -// ToScope returns a normalized scope string without any duplicates. -func (bitmap AccessTokenScopeBitmap) ToScope() AccessTokenScope { +// 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 + 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 { + if ok, _ := bitmap.hasScope(singleScope); ok { current := reconstruct | allAccessTokenScopeBits[singleScope] if current == reconstruct { continue @@ -269,7 +350,7 @@ func (bitmap AccessTokenScopeBitmap) ToScope() AccessTokenScope { scope := AccessTokenScope(strings.Join(scopes, ",")) scope = AccessTokenScope(strings.ReplaceAll( string(scope), - "repo,admin:org,admin:public_key,admin:org_hook,admin:user_hook,notification,user,delete_repo,package,admin:gpg_key,admin:application", + "delete:activitypub,delete:admin,delete:misc,delete:notification,delete:organization,delete:package,delete:issue,delete:repository,delete:user", "all", )) return scope diff --git a/models/auth/token_scope_test.go b/models/auth/token_scope_test.go index b96a5fd469479..4c6c273b34cf7 100644 --- a/models/auth/token_scope_test.go +++ b/models/auth/token_scope_test.go @@ -4,44 +4,35 @@ package auth import ( + "fmt" "testing" "github.com/stretchr/testify/assert" ) +type scopeTestNormalize struct { + in AccessTokenScope + out AccessTokenScope + err error +} + func TestAccessTokenScope_Normalize(t *testing.T) { - tests := []struct { - in AccessTokenScope - out AccessTokenScope - err error - }{ + tests := []scopeTestNormalize{ {"", "", 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}, + {"write:misc,delete:notification,read:package,write:notification,public", "public,write:misc,delete:notification,read:package", nil}, {"all", "all", nil}, - {"repo,admin:org,admin:public_key,admin:repo_hook,admin:org_hook,admin:user_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,admin:user_hook,notification,user,delete_repo,package,admin:gpg_key,admin:application,sudo", "all,sudo", nil}, + {"delete:activitypub,delete:admin,delete:misc,delete:notification,delete:organization,delete:package,delete:issue,delete:repository,delete:user", "all", nil}, + {"delete:activitypub,delete:admin,delete:misc,delete:notification,delete:organization,delete:package,delete:issue,delete:repository,delete:user,public", "public,all", nil}, + } + + for _, scope := range []string{"activitypub", "admin", "misc", "notification", "organization", "package", "issue", "repository", "user"} { + tests = append(tests, + scopeTestNormalize{AccessTokenScope(fmt.Sprintf("read:%s", scope)), AccessTokenScope(fmt.Sprintf("read:%s", scope)), nil}, + scopeTestNormalize{AccessTokenScope(fmt.Sprintf("write:%s", scope)), AccessTokenScope(fmt.Sprintf("write:%s", scope)), nil}, + scopeTestNormalize{AccessTokenScope(fmt.Sprintf("write:%[1]s,read:%[1]s", scope)), AccessTokenScope(fmt.Sprintf("write:%s", scope)), nil}, + scopeTestNormalize{AccessTokenScope(fmt.Sprintf("read:%[1]s,write:%[1]s", scope)), AccessTokenScope(fmt.Sprintf("write:%s", scope)), nil}, + scopeTestNormalize{AccessTokenScope(fmt.Sprintf("read:%[1]s,delete:%[1]s,write:%[1]s", scope)), AccessTokenScope(fmt.Sprintf("delete:%s", scope)), nil}, + ) } for _, test := range tests { @@ -53,25 +44,32 @@ func TestAccessTokenScope_Normalize(t *testing.T) { } } +type scopeTestHasScope struct { + in AccessTokenScope + scope AccessTokenScope + out bool + err error +} + 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}, + tests := []scopeTestHasScope{ + {"read:admin", "delete:package", false, nil}, + {"all", "delete:package", true, nil}, + {"delete:package", "all", false, nil}, + {"public", "read:issue", false, nil}, + } + + for _, scope := range []string{"activitypub", "admin", "misc", "notification", "organization", "package", "issue", "repository", "user"} { + tests = append(tests, + scopeTestHasScope{AccessTokenScope(fmt.Sprintf("read:%s", scope)), AccessTokenScope(fmt.Sprintf("read:%s", scope)), true, nil}, + scopeTestHasScope{AccessTokenScope(fmt.Sprintf("write:%s", scope)), AccessTokenScope(fmt.Sprintf("write:%s", scope)), true, nil}, + scopeTestHasScope{AccessTokenScope(fmt.Sprintf("delete:%s", scope)), AccessTokenScope(fmt.Sprintf("delete:%s", scope)), true, nil}, + scopeTestHasScope{AccessTokenScope(fmt.Sprintf("write:%s", scope)), AccessTokenScope(fmt.Sprintf("read:%s", scope)), true, nil}, + scopeTestHasScope{AccessTokenScope(fmt.Sprintf("delete:%s", scope)), AccessTokenScope(fmt.Sprintf("write:%s", scope)), true, nil}, + scopeTestHasScope{AccessTokenScope(fmt.Sprintf("read:%s", scope)), AccessTokenScope(fmt.Sprintf("write:%s", scope)), false, nil}, + scopeTestHasScope{AccessTokenScope(fmt.Sprintf("read:%s", scope)), AccessTokenScope(fmt.Sprintf("delete:%s", scope)), false, nil}, + scopeTestHasScope{AccessTokenScope(fmt.Sprintf("write:%s", scope)), AccessTokenScope(fmt.Sprintf("delete:%s", scope)), false, nil}, + ) } for _, test := range tests { diff --git a/modules/context/permission.go b/modules/context/permission.go index cc53fb99ed747..bc687db616353 100644 --- a/modules/context/permission.go +++ b/modules/context/permission.go @@ -111,28 +111,36 @@ func RequireRepoReaderOr(unitTypes ...unit.Type) func(ctx *Context) { } } -// RequireRepoScopedToken check whether personal access token has repo scope -func CheckRepoScopedToken(ctx *Context, repo *repo_model.Repository) { +// CheckRepoScopedToken check whether personal access token has repo scope +func CheckRepoScopedToken(ctx *Context, repo *repo_model.Repository, level auth_model.AccessTokenScopeLevel) { if !ctx.IsBasicAuth || ctx.Data["IsApiToken"] != true { return } - var err error scope, ok := ctx.Data["ApiTokenScope"].(auth_model.AccessTokenScope) if ok { // it's a personal access token but not oauth2 token var scopeMatched bool - scopeMatched, err = scope.HasScope(auth_model.AccessTokenScopeRepo) + + requiredScope := auth_model.GetRequiredScope(level, auth_model.AccessTokenScopeCategoryRepository) + + // check if scope only applies to public resources + publicOnly, err := scope.PublicOnly() if err != nil { ctx.ServerError("HasScope", err) return } - if !scopeMatched && !repo.IsPrivate { - scopeMatched, err = scope.HasScope(auth_model.AccessTokenScopePublicRepo) - if err != nil { - ctx.ServerError("HasScope", err) - return - } + + if publicOnly && repo.IsPrivate { + ctx.Error(http.StatusForbidden) + return } + + scopeMatched, err = scope.HasScope(requiredScope) + if err != nil { + ctx.ServerError("HasScope", err) + return + } + if !scopeMatched { ctx.Error(http.StatusForbidden) return diff --git a/public/serviceworker.js b/public/serviceworker.js new file mode 100644 index 0000000000000..104e9adc86cb3 --- /dev/null +++ b/public/serviceworker.js @@ -0,0 +1,6 @@ +/******/ (function() { // webpackBootstrap +/******/ "use strict"; +/******/ +/******/ +/******/ })() +; \ No newline at end of file diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 45e36e84fe788..da677a5903d4f 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -80,6 +80,7 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/activitypub" @@ -237,7 +238,7 @@ func reqPackageAccess(accessMode perm.AccessMode) func(ctx *context.APIContext) } // Contexter middleware already checks token for user sign in process. -func reqToken(requiredScope auth_model.AccessTokenScope) func(ctx *context.APIContext) { +func reqToken(requiredScopeCategory auth_model.AccessTokenScopeCategory) func(ctx *context.APIContext) { return func(ctx *context.APIContext) { // If actions token is present if true == ctx.Data["IsActionsToken"] { @@ -247,28 +248,51 @@ func reqToken(requiredScope auth_model.AccessTokenScope) func(ctx *context.APICo // If OAuth2 token is present if _, ok := ctx.Data["ApiTokenScope"]; ctx.Data["IsApiToken"] == true && ok { // no scope required - if requiredScope == "" { + if requiredScopeCategory == auth_model.NoCategory { return } - // check scope + // get the scope from the request scope := ctx.Data["ApiTokenScope"].(auth_model.AccessTokenScope) - allow, err := scope.HasScope(requiredScope) + + // use the http method to determine the access level + requiredScopeLevel := auth_model.Read + if ctx.Req.Method == "POST" || ctx.Req.Method == "PUT" || ctx.Req.Method == "PATCH" { + requiredScopeLevel = auth_model.Write + } else if ctx.Req.Method == "DELETE" { + requiredScopeLevel = auth_model.Delete + } + + // get the required scope for the given access level and category + requiredScope := auth_model.GetRequiredScope(requiredScopeLevel, requiredScopeCategory) + + // check if scope only applies to public resources + publicOnly, err := scope.PublicOnly() if err != nil { - ctx.Error(http.StatusForbidden, "reqToken", "parsing token failed: "+err.Error()) + ctx.Error(http.StatusForbidden, "reqToken", "parsing public resource scope failed: "+err.Error()) return } - if allow { + + if publicOnly && (requiredScopeCategory == auth_model.AccessTokenScopeCategoryRepository) && + ctx.Repo.Repository != nil && ctx.Repo.Repository.IsPrivate { + ctx.Error(http.StatusForbidden, "reqToken", "token scope is limited to public repos: "+requiredScope) 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 - } - } + if publicOnly && (requiredScopeCategory == auth_model.AccessTokenScopeCategoryOrganization) && + ctx.Org.Organization != nil && ctx.Org.Organization.Visibility != structs.VisibleTypePublic { + ctx.Error(http.StatusForbidden, "reqToken", "token scope is limited to public orgs: "+requiredScope) + return + } + + allow, err := scope.HasScope(requiredScope) + if err != nil { + ctx.Error(http.StatusForbidden, "reqToken", "checking scope failed: "+err.Error()) + return + } + + if allow { + return } ctx.Error(http.StatusForbidden, "reqToken", "token does not have required scope: "+requiredScope) @@ -713,24 +737,28 @@ func Routes(ctx gocontext.Context) *web.Route { m.Get("", activitypub.Person) m.Post("/inbox", activitypub.ReqHTTPSignature(), activitypub.PersonInbox) }, context_service.UserIDAssignmentAPI()) - }) + }, reqToken(auth_model.AccessTokenScopeCategoryActivityPub)) } - m.Get("/signing-key.gpg", misc.SigningKey) - m.Post("/markup", bind(api.MarkupOption{}), misc.Markup) - m.Post("/markdown", bind(api.MarkdownOption{}), misc.Markdown) - m.Post("/markdown/raw", misc.MarkdownRaw) - m.Get("/gitignore/templates", misc.ListGitignoresTemplates) - m.Get("/gitignore/templates/{name}", misc.GetGitignoreTemplateInfo) - m.Get("/licenses", misc.ListLicenseTemplates) - m.Get("/licenses/{name}", misc.GetLicenseTemplateInfo) - m.Get("/label/templates", misc.ListLabelTemplates) - m.Get("/label/templates/{name}", misc.GetLabelTemplate) + + m.Group("", func() { + m.Get("/signing-key.gpg", misc.SigningKey) + m.Post("/markup", bind(api.MarkupOption{}), misc.Markup) + m.Post("/markdown", bind(api.MarkdownOption{}), misc.Markdown) + m.Post("/markdown/raw", misc.MarkdownRaw) + m.Get("/gitignore/templates", misc.ListGitignoresTemplates) + m.Get("/gitignore/templates/{name}", misc.GetGitignoreTemplateInfo) + m.Get("/licenses", misc.ListLicenseTemplates) + m.Get("/licenses/{name}", misc.GetLicenseTemplateInfo) + m.Get("/label/templates", misc.ListLabelTemplates) + m.Get("/label/templates/{name}", misc.GetLabelTemplate) + }, reqToken(auth_model.AccessTokenScopeCategoryMisc)) + m.Group("/settings", func() { m.Get("/ui", settings.GetGeneralUISettings) m.Get("/api", settings.GetGeneralAPISettings) m.Get("/attachment", settings.GetGeneralAttachmentSettings) m.Get("/repository", settings.GetGeneralRepoSettings) - }) + }) // TODO scope? (Is this misc?) // Notifications (requires 'notification' scope) m.Group("/notifications", func() { @@ -741,7 +769,7 @@ func Routes(ctx gocontext.Context) *web.Route { m.Combo("/threads/{id}"). Get(notify.GetThread). Patch(notify.ReadThread) - }, reqToken(auth_model.AccessTokenScopeNotification)) + }, reqToken(auth_model.AccessTokenScopeCategoryNotification)) // Users (no scope required) m.Group("/users", func() { @@ -763,7 +791,7 @@ func Routes(ctx gocontext.Context) *web.Route { m.Get("/activities/feeds", user.ListUserActivityFeeds) }, context_service.UserAssignmentAPI()) - }) + }, reqToken(auth_model.NoCategory)) // TODO add scope here? // (no scope required) m.Group("/users", func() { @@ -781,62 +809,57 @@ func Routes(ctx gocontext.Context) *web.Route { m.Get("/subscriptions", user.GetWatchedRepos) }, context_service.UserAssignmentAPI()) - }, reqToken("")) + }, reqToken(auth_model.NoCategory)) // TODO add scope here? m.Group("/user", func() { m.Get("", user.GetAuthenticatedUser) m.Group("/settings", func() { - m.Get("", reqToken(auth_model.AccessTokenScopeReadUser), user.GetUserSettings) - m.Patch("", reqToken(auth_model.AccessTokenScopeUser), bind(api.UserSettingsOptions{}), user.UpdateUserSettings) + m.Get("", user.GetUserSettings) + m.Patch("", 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.Combo("/emails").Get(user.ListEmails). + Post(bind(api.CreateEmailOption{}), user.AddEmail). + Delete(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("", reqToken(auth_model.AccessTokenScopeUserFollow), user.Follow) // requires 'user:follow' scope - m.Delete("", reqToken(auth_model.AccessTokenScopeUserFollow), user.Unfollow) // requires 'user:follow' scope + m.Put("", user.Follow) + m.Delete("", user.Unfollow) }, context_service.UserAssignmentAPI()) }) - // (admin:public_key scope) m.Group("/keys", func() { - 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) + m.Combo("").Get(user.ListMyPublicKeys). + Post(bind(api.CreateKeyOption{}), user.CreatePublicKey) + m.Combo("/{id}").Get(user.GetPublicKey). + Delete(user.DeletePublicKey) }) - // (admin:application scope) m.Group("/applications", func() { m.Combo("/oauth2"). - Get(reqToken(auth_model.AccessTokenScopeReadApplication), user.ListOauth2Applications). - Post(reqToken(auth_model.AccessTokenScopeWriteApplication), bind(api.CreateOAuth2ApplicationOptions{}), user.CreateOauth2Application) + Get(user.ListOauth2Applications). + Post(bind(api.CreateOAuth2ApplicationOptions{}), user.CreateOauth2Application) m.Combo("/oauth2/{id}"). - Delete(reqToken(auth_model.AccessTokenScopeWriteApplication), user.DeleteOauth2Application). - Patch(reqToken(auth_model.AccessTokenScopeWriteApplication), bind(api.CreateOAuth2ApplicationOptions{}), user.UpdateOauth2Application). - Get(reqToken(auth_model.AccessTokenScopeReadApplication), user.GetOauth2Application) + Delete(user.DeleteOauth2Application). + Patch(bind(api.CreateOAuth2ApplicationOptions{}), user.UpdateOauth2Application). + Get(user.GetOauth2Application) }) - // (admin:gpg_key scope) m.Group("/gpg_keys", func() { - 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.Combo("").Get(user.ListMyGPGKeys). + Post(bind(api.CreateGPGKeyOption{}), user.CreateGPGKey) + m.Combo("/{id}").Get(user.GetGPGKey). + Delete(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) - // (repo scope) - m.Combo("/repos", reqToken(auth_model.AccessTokenScopeRepo)).Get(user.ListMyRepos). + m.Combo("/repos", reqToken(auth_model.AccessTokenScopeCategoryRepository)).Get(user.ListMyRepos). Post(bind(api.CreateRepoOption{}), repo.Create) - // (repo scope) m.Group("/starred", func() { m.Get("", user.GetMyStarredRepos) m.Group("/{username}/{reponame}", func() { @@ -844,62 +867,61 @@ func Routes(ctx gocontext.Context) *web.Route { m.Put("", user.Star) m.Delete("", user.Unstar) }, repoAssignment()) - }, 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(auth_model.AccessTokenScopeCategoryRepository)) + m.Get("/times", reqToken(auth_model.AccessTokenScopeCategoryRepository), repo.ListMyTrackedTimes) + m.Get("/stopwatches", reqToken(auth_model.AccessTokenScopeCategoryRepository), repo.GetStopwatches) + m.Get("/subscriptions", reqToken(auth_model.AccessTokenScopeCategoryRepository), user.GetMyWatchedRepos) + m.Get("/teams", reqToken(auth_model.AccessTokenScopeCategoryRepository), org.ListUserTeams) m.Group("/hooks", func() { m.Combo("").Get(user.ListHooks). Post(bind(api.CreateHookOption{}), user.CreateHook) m.Combo("/{id}").Get(user.GetHook). Patch(bind(api.EditHookOption{}), user.EditHook). Delete(user.DeleteHook) - }, reqToken(auth_model.AccessTokenScopeAdminUserHook), reqWebhooksEnabled()) - }, reqToken("")) + }, reqWebhooksEnabled()) + }, reqToken(auth_model.AccessTokenScopeCategoryUser)) // Repositories - m.Post("/org/{org}/repos", reqToken(auth_model.AccessTokenScopeAdminOrg), bind(api.CreateRepoOption{}), repo.CreateOrgRepoDeprecated) + m.Post("/org/{org}/repos", reqToken(auth_model.AccessTokenScopeCategoryOrganization), bind(api.CreateRepoOption{}), repo.CreateOrgRepoDeprecated) - m.Combo("/repositories/{id}", reqToken(auth_model.AccessTokenScopeRepo)).Get(repo.GetByID) + m.Combo("/repositories/{id}", reqToken(auth_model.AccessTokenScopeCategoryRepository)).Get(repo.GetByID) m.Group("/repos", func() { m.Get("/search", repo.Search) - m.Get("/issues/search", repo.SearchIssues) + m.Get("/issues/search", reqToken(auth_model.AccessTokenScopeCategoryIssue), repo.SearchIssues) - // (repo scope) - m.Post("/migrate", reqToken(auth_model.AccessTokenScopeRepo), bind(api.MigrateRepoOptions{}), repo.Migrate) + m.Post("/migrate", reqToken(auth_model.AccessTokenScopeCategoryRepository), bind(api.MigrateRepoOptions{}), repo.Migrate) m.Group("/{username}/{reponame}", func() { m.Combo("").Get(reqAnyRepoReader(), repo.Get). - 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) + Delete(reqOwner(), repo.Delete). + Patch(reqAdmin(), bind(api.EditRepoOption{}), repo.Edit) + m.Post("/generate", 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)). + }) + m.Combo("/notifications", reqToken(auth_model.AccessTokenScopeCategoryNotification)). Get(notify.ListRepoNotifications). Put(notify.ReadRepoNotifications) m.Group("/hooks/git", func() { - m.Combo("").Get(reqToken(auth_model.AccessTokenScopeReadRepoHook), repo.ListGitHooks) + m.Combo("").Get(repo.ListGitHooks) m.Group("/{id}", func() { - 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) + m.Combo("").Get(repo.GetGitHook). + Patch(bind(api.EditGitHookOption{}), repo.EditGitHook). + Delete(repo.DeleteGitHook) }) }, reqAdmin(), reqGitHook(), context.ReferencesGitRepo(true)) m.Group("/hooks", func() { - m.Combo("").Get(reqToken(auth_model.AccessTokenScopeReadRepoHook), repo.ListHooks). - Post(reqToken(auth_model.AccessTokenScopeWriteRepoHook), bind(api.CreateHookOption{}), repo.CreateHook) + m.Combo("").Get(repo.ListHooks). + Post(bind(api.CreateHookOption{}), repo.CreateHook) m.Group("/{id}", func() { - 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) + m.Combo("").Get(repo.GetHook). + Patch(bind(api.EditHookOption{}), repo.EditHook). + Delete(repo.DeleteHook) + m.Post("/tests", context.ReferencesGitRepo(), context.RepoRefForAPI, repo.TestHook) }) }, reqAdmin(), reqWebhooksEnabled()) m.Group("/collaborators", func() { @@ -910,25 +932,25 @@ func Routes(ctx gocontext.Context) *web.Route { Delete(reqAdmin(), repo.DeleteCollaborator) m.Get("/permission", repo.GetRepoPermissions) }) - }, 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.Get("/assignees", reqAnyRepoReader(), repo.GetAssignees) + m.Get("/reviewers", 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(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(auth_model.AccessTokenScopeRepo), reqRepoReader(unit.TypeCode), bind(api.CreateForkOption{}), repo.CreateFork) + Post(reqRepoReader(unit.TypeCode), bind(api.CreateForkOption{}), repo.CreateFork) m.Group("/branches", func() { m.Get("", repo.ListBranches) m.Get("/*", repo.GetBranch) - 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) + m.Delete("/*", reqRepoWriter(unit.TypeCode), repo.DeleteBranch) + m.Post("", reqRepoWriter(unit.TypeCode), bind(api.CreateBranchRepoOption{}), repo.CreateBranch) }, context.ReferencesGitRepo(), reqRepoReader(unit.TypeCode)) m.Group("/branch_protections", func() { m.Get("", repo.ListBranchProtections) @@ -938,75 +960,75 @@ func Routes(ctx gocontext.Context) *web.Route { m.Patch("", bind(api.EditBranchProtectionOption{}), repo.EditBranchProtection) m.Delete("", repo.DeleteBranchProtection) }) - }, reqToken(auth_model.AccessTokenScopeRepo), reqAdmin()) + }, reqAdmin()) m.Group("/tags", func() { m.Get("", repo.ListTags) m.Get("/*", repo.GetTag) - m.Post("", reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeCode), bind(api.CreateTagOption{}), repo.CreateTag) - m.Delete("/*", reqToken(auth_model.AccessTokenScopeRepo), repo.DeleteTag) + m.Post("", reqRepoWriter(unit.TypeCode), bind(api.CreateTagOption{}), repo.CreateTag) + m.Delete("/*", 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(auth_model.AccessTokenScopeRepo), reqAdmin()) + }, reqAdmin()) m.Group("/times", func() { m.Combo("").Get(repo.ListTrackedTimesByRepository) m.Combo("/{timetrackingusername}").Get(repo.ListTrackedTimesByUser) - }, mustEnableIssues, reqToken(auth_model.AccessTokenScopeRepo)) + }, mustEnableIssues) m.Group("/wiki", func() { m.Combo("/page/{pageName}"). Get(repo.GetWikiPage). - 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) + Patch(mustNotBeArchived, reqRepoWriter(unit.TypeWiki), bind(api.CreateWikiPageOptions{}), repo.EditWikiPage). + Delete(mustNotBeArchived, reqRepoWriter(unit.TypeWiki), repo.DeleteWikiPage) m.Get("/revisions/{pageName}", repo.ListPageRevisions) - m.Post("/new", mustNotBeArchived, reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeWiki), bind(api.CreateWikiPageOptions{}), repo.NewWikiPage) + m.Post("/new", mustNotBeArchived, 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(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.CreateIssueOption{}), repo.CreateIssue) + Post(mustNotBeArchived, bind(api.CreateIssueOption{}), repo.CreateIssue) m.Get("/pinned", repo.ListPinnedIssues) m.Group("/comments", func() { m.Get("", repo.ListRepoIssueComments) m.Group("/{id}", func() { m.Combo(""). Get(repo.GetIssueComment). - Patch(mustNotBeArchived, reqToken(auth_model.AccessTokenScopeRepo), bind(api.EditIssueCommentOption{}), repo.EditIssueComment). - Delete(reqToken(auth_model.AccessTokenScopeRepo), repo.DeleteIssueComment) + Patch(mustNotBeArchived, bind(api.EditIssueCommentOption{}), repo.EditIssueComment). + Delete(repo.DeleteIssueComment) m.Combo("/reactions"). Get(repo.GetIssueCommentReactions). - Post(reqToken(auth_model.AccessTokenScopeRepo), bind(api.EditReactionOption{}), repo.PostIssueCommentReaction). - Delete(reqToken(auth_model.AccessTokenScopeRepo), bind(api.EditReactionOption{}), repo.DeleteIssueCommentReaction) + Post(bind(api.EditReactionOption{}), repo.PostIssueCommentReaction). + Delete(bind(api.EditReactionOption{}), repo.DeleteIssueCommentReaction) m.Group("/assets", func() { m.Combo(""). Get(repo.ListIssueCommentAttachments). - Post(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, repo.CreateIssueCommentAttachment) + Post(mustNotBeArchived, repo.CreateIssueCommentAttachment) m.Combo("/{asset}"). Get(repo.GetIssueCommentAttachment). - Patch(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.EditAttachmentOptions{}), repo.EditIssueCommentAttachment). - Delete(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, repo.DeleteIssueCommentAttachment) + Patch(mustNotBeArchived, bind(api.EditAttachmentOptions{}), repo.EditIssueCommentAttachment). + Delete(mustNotBeArchived, repo.DeleteIssueCommentAttachment) }, mustEnableAttachments) }) }) m.Group("/{index}", func() { m.Combo("").Get(repo.GetIssue). - Patch(reqToken(auth_model.AccessTokenScopeRepo), bind(api.EditIssueOption{}), repo.EditIssue). - Delete(reqToken(auth_model.AccessTokenScopeRepo), reqAdmin(), context.ReferencesGitRepo(), repo.DeleteIssue) + Patch(bind(api.EditIssueOption{}), repo.EditIssue). + Delete(reqAdmin(), context.ReferencesGitRepo(), repo.DeleteIssue) m.Group("/comments", func() { m.Combo("").Get(repo.ListIssueComments). - Post(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.CreateIssueCommentOption{}), repo.CreateIssueComment) - m.Combo("/{id}", reqToken(auth_model.AccessTokenScopeRepo)).Patch(bind(api.EditIssueCommentOption{}), repo.EditIssueCommentDeprecated). + Post(mustNotBeArchived, bind(api.CreateIssueCommentOption{}), repo.CreateIssueComment) + m.Combo("/{id}").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(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) + Post(bind(api.IssueLabelsOption{}), repo.AddIssueLabels). + Put(bind(api.IssueLabelsOption{}), repo.ReplaceIssueLabels). + Delete(repo.ClearIssueLabels) + m.Delete("/{id}", repo.DeleteIssueLabel) }) m.Group("/times", func() { m.Combo(""). @@ -1014,142 +1036,142 @@ func Routes(ctx gocontext.Context) *web.Route { Post(bind(api.AddTimeOption{}), repo.AddTime). Delete(repo.ResetIssueTime) m.Delete("/{id}", repo.DeleteTime) - }, reqToken(auth_model.AccessTokenScopeRepo)) - m.Combo("/deadline").Post(reqToken(auth_model.AccessTokenScopeRepo), bind(api.EditDeadlineOption{}), repo.UpdateIssueDeadline) + }) + m.Combo("/deadline").Post(bind(api.EditDeadlineOption{}), repo.UpdateIssueDeadline) m.Group("/stopwatch", func() { - 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.Post("/start", repo.StartIssueStopwatch) + m.Post("/stop", repo.StopIssueStopwatch) + m.Delete("/delete", repo.DeleteIssueStopwatch) }) m.Group("/subscriptions", func() { m.Get("", repo.GetIssueSubscribers) - 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.Get("/check", repo.CheckIssueSubscription) + m.Put("/{user}", repo.AddIssueSubscription) + m.Delete("/{user}", repo.DelIssueSubscription) }) m.Combo("/reactions"). Get(repo.GetIssueReactions). - Post(reqToken(auth_model.AccessTokenScopeRepo), bind(api.EditReactionOption{}), repo.PostIssueReaction). - Delete(reqToken(auth_model.AccessTokenScopeRepo), bind(api.EditReactionOption{}), repo.DeleteIssueReaction) + Post(bind(api.EditReactionOption{}), repo.PostIssueReaction). + Delete(bind(api.EditReactionOption{}), repo.DeleteIssueReaction) m.Group("/assets", func() { m.Combo(""). Get(repo.ListIssueAttachments). - Post(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, repo.CreateIssueAttachment) + Post(mustNotBeArchived, repo.CreateIssueAttachment) m.Combo("/{asset}"). Get(repo.GetIssueAttachment). - Patch(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.EditAttachmentOptions{}), repo.EditIssueAttachment). - Delete(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, repo.DeleteIssueAttachment) + Patch(mustNotBeArchived, bind(api.EditAttachmentOptions{}), repo.EditIssueAttachment). + Delete(mustNotBeArchived, repo.DeleteIssueAttachment) }, mustEnableAttachments) m.Combo("/dependencies"). Get(repo.GetIssueDependencies). - Post(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.IssueMeta{}), repo.CreateIssueDependency). - Delete(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.IssueMeta{}), repo.RemoveIssueDependency) + Post(mustNotBeArchived, bind(api.IssueMeta{}), repo.CreateIssueDependency). + Delete(mustNotBeArchived, bind(api.IssueMeta{}), repo.RemoveIssueDependency) m.Combo("/blocks"). Get(repo.GetIssueBlocks). - Post(reqToken(auth_model.AccessTokenScopeRepo), bind(api.IssueMeta{}), repo.CreateIssueBlocking). - Delete(reqToken(auth_model.AccessTokenScopeRepo), bind(api.IssueMeta{}), repo.RemoveIssueBlocking) + Post(bind(api.IssueMeta{}), repo.CreateIssueBlocking). + Delete(bind(api.IssueMeta{}), repo.RemoveIssueBlocking) m.Group("/pin", func() { m.Combo(""). - Post(reqToken(auth_model.AccessTokenScopeRepo), reqAdmin(), repo.PinIssue). - Delete(reqToken(auth_model.AccessTokenScopeRepo), reqAdmin(), repo.UnpinIssue) - m.Patch("/{position}", reqToken(auth_model.AccessTokenScopeRepo), reqAdmin(), repo.MoveIssuePin) + Post(reqAdmin(), repo.PinIssue). + Delete(reqAdmin(), repo.UnpinIssue) + m.Patch("/{position}", reqAdmin(), repo.MoveIssuePin) }) }) }, mustEnableIssuesOrPulls) m.Group("/labels", func() { m.Combo("").Get(repo.ListLabels). - Post(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), bind(api.CreateLabelOption{}), repo.CreateLabel) + Post(reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), bind(api.CreateLabelOption{}), repo.CreateLabel) m.Combo("/{id}").Get(repo.GetLabel). - 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) + Patch(reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), bind(api.EditLabelOption{}), repo.EditLabel). + Delete(reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), repo.DeleteLabel) }) - m.Post("/markup", reqToken(auth_model.AccessTokenScopeRepo), bind(api.MarkupOption{}), misc.Markup) - m.Post("/markdown", reqToken(auth_model.AccessTokenScopeRepo), bind(api.MarkdownOption{}), misc.Markdown) - m.Post("/markdown/raw", reqToken(auth_model.AccessTokenScopeRepo), misc.MarkdownRaw) + m.Post("/markup", bind(api.MarkupOption{}), misc.Markup) + m.Post("/markdown", bind(api.MarkdownOption{}), misc.Markdown) + m.Post("/markdown/raw", misc.MarkdownRaw) m.Group("/milestones", func() { m.Combo("").Get(repo.ListMilestones). - Post(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), bind(api.CreateMilestoneOption{}), repo.CreateMilestone) + Post(reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), bind(api.CreateMilestoneOption{}), repo.CreateMilestone) m.Combo("/{id}").Get(repo.GetMilestone). - 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) + Patch(reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), bind(api.EditMilestoneOption{}), repo.EditMilestone). + Delete(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(auth_model.AccessTokenScopeRepo), user.Watch) - m.Delete("", reqToken(auth_model.AccessTokenScopeRepo), user.Unwatch) + m.Put("", user.Watch) + m.Delete("", user.Unwatch) }) m.Group("/releases", func() { m.Combo("").Get(repo.ListReleases). - Post(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeReleases), context.ReferencesGitRepo(), bind(api.CreateReleaseOption{}), repo.CreateRelease) + Post(reqRepoWriter(unit.TypeReleases), context.ReferencesGitRepo(), bind(api.CreateReleaseOption{}), repo.CreateRelease) m.Combo("/latest").Get(repo.GetLatestRelease) m.Group("/{id}", func() { m.Combo("").Get(repo.GetRelease). - 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) + Patch(reqRepoWriter(unit.TypeReleases), context.ReferencesGitRepo(), bind(api.EditReleaseOption{}), repo.EditRelease). + Delete(reqRepoWriter(unit.TypeReleases), repo.DeleteRelease) m.Group("/assets", func() { m.Combo("").Get(repo.ListReleaseAttachments). - Post(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeReleases), repo.CreateReleaseAttachment) + Post(reqRepoWriter(unit.TypeReleases), repo.CreateReleaseAttachment) m.Combo("/{asset}").Get(repo.GetReleaseAttachment). - Patch(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeReleases), bind(api.EditAttachmentOptions{}), repo.EditReleaseAttachment). - Delete(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeReleases), repo.DeleteReleaseAttachment) + Patch(reqRepoWriter(unit.TypeReleases), bind(api.EditAttachmentOptions{}), repo.EditReleaseAttachment). + Delete(reqRepoWriter(unit.TypeReleases), repo.DeleteReleaseAttachment) }) }) m.Group("/tags", func() { m.Combo("/{tag}"). Get(repo.GetReleaseByTag). - Delete(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeReleases), repo.DeleteReleaseByTag) + Delete(reqRepoWriter(unit.TypeReleases), repo.DeleteReleaseByTag) }) }, reqRepoReader(unit.TypeReleases)) - 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.Post("/mirror-sync", reqToken(auth_model.AccessTokenScopeCategoryRepository), reqRepoWriter(unit.TypeCode), repo.MirrorSync) + m.Post("/push_mirrors-sync", reqAdmin(), reqToken(auth_model.AccessTokenScopeCategoryRepository), 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(), reqToken(auth_model.AccessTokenScopeRepo)) + }, reqAdmin()) m.Get("/editorconfig/{filename}", context.ReferencesGitRepo(), context.RepoRefForAPI, reqRepoReader(unit.TypeCode), repo.GetEditorconfig) m.Group("/pulls", func() { m.Combo("").Get(repo.ListPullRequests). - Post(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.CreatePullRequestOption{}), repo.CreatePullRequest) + Post(mustNotBeArchived, bind(api.CreatePullRequestOption{}), repo.CreatePullRequest) m.Get("/pinned", repo.ListPinnedPullRequests) m.Group("/{index}", func() { m.Combo("").Get(repo.GetPullRequest). - Patch(reqToken(auth_model.AccessTokenScopeRepo), bind(api.EditPullRequestOption{}), repo.EditPullRequest) + Patch(bind(api.EditPullRequestOption{}), repo.EditPullRequest) m.Get(".{diffType:diff|patch}", repo.DownloadPullDiffOrPatch) - m.Post("/update", reqToken(auth_model.AccessTokenScopeRepo), repo.UpdatePullRequest) + m.Post("/update", repo.UpdatePullRequest) m.Get("/commits", repo.GetPullRequestCommits) m.Get("/files", repo.GetPullRequestFiles) m.Combo("/merge").Get(repo.IsPullRequestMerged). - Post(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(forms.MergePullRequestForm{}), repo.MergePullRequest). - Delete(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, repo.CancelScheduledAutoMerge) + Post(mustNotBeArchived, bind(forms.MergePullRequestForm{}), repo.MergePullRequest). + Delete(mustNotBeArchived, repo.CancelScheduledAutoMerge) m.Group("/reviews", func() { m.Combo(""). Get(repo.ListPullReviews). - Post(reqToken(auth_model.AccessTokenScopeRepo), bind(api.CreatePullReviewOptions{}), repo.CreatePullReview) + Post(bind(api.CreatePullReviewOptions{}), repo.CreatePullReview) m.Group("/{id}", func() { m.Combo(""). Get(repo.GetPullReview). - Delete(reqToken(auth_model.AccessTokenScopeRepo), repo.DeletePullReview). - Post(reqToken(auth_model.AccessTokenScopeRepo), bind(api.SubmitPullReviewOptions{}), repo.SubmitPullReview) + Delete(repo.DeletePullReview). + Post(bind(api.SubmitPullReviewOptions{}), repo.SubmitPullReview) m.Combo("/comments"). Get(repo.GetPullReviewComments) - m.Post("/dismissals", reqToken(auth_model.AccessTokenScopeRepo), bind(api.DismissPullReviewOptions{}), repo.DismissPullReview) - m.Post("/undismissals", reqToken(auth_model.AccessTokenScopeRepo), repo.UnDismissPullReview) + m.Post("/dismissals", bind(api.DismissPullReviewOptions{}), repo.DismissPullReview) + m.Post("/undismissals", repo.UnDismissPullReview) }) }) - m.Combo("/requested_reviewers", reqToken(auth_model.AccessTokenScopeRepo)). + m.Combo("/requested_reviewers"). 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(auth_model.AccessTokenScopeRepoStatus), reqRepoWriter(unit.TypeCode), bind(api.CreateStatusOption{}), repo.NewCommitStatus) + Post(reqRepoWriter(unit.TypeCode), bind(api.CreateStatusOption{}), repo.NewCommitStatus) }, reqRepoReader(unit.TypeCode)) m.Group("/commits", func() { m.Get("", context.ReferencesGitRepo(), repo.GetAllCommits) @@ -1170,7 +1192,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(auth_model.AccessTokenScopeRepo), bind(api.ApplyDiffPatchFileOptions{}), repo.ApplyDiffPatch) + m.Post("/diffpatch", reqRepoWriter(unit.TypeCode), bind(api.ApplyDiffPatchFileOptions{}), repo.ApplyDiffPatch) m.Group("/contents", func() { m.Get("", repo.GetContentsList) m.Post("", reqToken(auth_model.AccessTokenScopeRepo), bind(api.ChangeFilesOptions{}), reqRepoBranchWriter, repo.ChangeFiles) @@ -1179,15 +1201,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(auth_model.AccessTokenScopeRepo)) + }) }, reqRepoReader(unit.TypeCode)) m.Get("/signing-key.gpg", misc.SigningKey) m.Group("/topics", func() { m.Combo("").Get(repo.ListTopics). - Put(reqToken(auth_model.AccessTokenScopeRepo), reqAdmin(), bind(api.RepoTopicOptions{}), repo.UpdateTopics) + Put(reqAdmin(), bind(api.RepoTopicOptions{}), repo.UpdateTopics) m.Group("/{topic}", func() { - m.Combo("").Put(reqToken(auth_model.AccessTokenScopeRepo), repo.AddTopic). - Delete(reqToken(auth_model.AccessTokenScopeRepo), repo.DeleteTopic) + m.Combo("").Put(repo.AddTopic). + Delete(repo.DeleteTopic) }, reqAdmin()) }, reqAnyRepoReader()) m.Get("/issue_templates", context.ReferencesGitRepo(), repo.GetIssueTemplates) @@ -1197,54 +1219,54 @@ func Routes(ctx gocontext.Context) *web.Route { m.Get("/activities/feeds", repo.ListRepoActivityFeeds) m.Get("/new_pin_allowed", repo.AreNewIssuePinsAllowed) }, repoAssignment()) - }) + }, reqToken(auth_model.AccessTokenScopeCategoryRepository)) // 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("", 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.GetPackage) + m.Delete("", reqPackageAccess(perm.AccessModeWrite), packages.DeletePackage) + m.Get("/files", packages.ListPackageFiles) }) - m.Get("/", reqToken(auth_model.AccessTokenScopeReadPackage), packages.ListPackages) - }, context_service.UserAssignmentAPI(), context.PackageAssignmentAPI(), reqPackageAccess(perm.AccessModeRead)) + m.Get("/", packages.ListPackages) + }, context_service.UserAssignmentAPI(), context.PackageAssignmentAPI(), reqToken(auth_model.AccessTokenScopeCategoryPackage), reqPackageAccess(perm.AccessModeRead)) // Organizations - m.Get("/user/orgs", reqToken(auth_model.AccessTokenScopeReadOrg), org.ListMyOrgs) + m.Get("/user/orgs", reqToken(auth_model.AccessTokenScopeCategoryOrganization), org.ListMyOrgs) m.Group("/users/{username}/orgs", func() { - 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(auth_model.AccessTokenScopeWriteOrg), bind(api.CreateOrgOption{}), org.Create) - m.Get("/orgs", org.GetAll) + m.Get("", org.ListUserOrgs) + m.Get("/{org}/permissions", org.GetUserOrgsPermissions) + }, context_service.UserAssignmentAPI(), reqToken(auth_model.AccessTokenScopeCategoryOrganization)) // TODO does this require user or org scope? + m.Post("/orgs", reqToken(auth_model.AccessTokenScopeCategoryOrganization), bind(api.CreateOrgOption{}), org.Create) + m.Get("/orgs", reqToken(auth_model.AccessTokenScopeCategoryOrganization), org.GetAll) m.Group("/orgs/{org}", func() { m.Combo("").Get(org.Get). - Patch(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgOwnership(), bind(api.EditOrgOption{}), org.Edit). - Delete(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgOwnership(), org.Delete) + Patch(reqOrgOwnership(), bind(api.EditOrgOption{}), org.Edit). + Delete(reqOrgOwnership(), org.Delete) m.Combo("/repos").Get(user.ListOrgRepos). - Post(reqToken(auth_model.AccessTokenScopeWriteOrg), bind(api.CreateRepoOption{}), repo.CreateOrgRepo) + Post(bind(api.CreateRepoOption{}), repo.CreateOrgRepo) m.Group("/members", func() { - 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.Get("", org.ListMembers) + m.Combo("/{username}").Get(org.IsMember). + Delete(reqOrgOwnership(), org.DeleteMember) }) m.Group("/public_members", func() { m.Get("", org.ListPublicMembers) m.Combo("/{username}").Get(org.IsPublicMember). - Put(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgMembership(), org.PublicizeMember). - Delete(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgMembership(), org.ConcealMember) + Put(reqOrgMembership(), org.PublicizeMember). + Delete(reqOrgMembership(), org.ConcealMember) }) m.Group("/teams", func() { - 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) + m.Get("", org.ListTeams) + m.Post("", reqOrgOwnership(), bind(api.CreateTeamOption{}), org.CreateTeam) + m.Get("/search", org.SearchTeam) }, reqOrgMembership()) m.Group("/labels", func() { m.Get("", 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.Post("", reqOrgOwnership(), bind(api.CreateLabelOption{}), org.CreateLabel) + m.Combo("/{id}").Get(org.GetLabel). + Patch(reqOrgOwnership(), bind(api.EditLabelOption{}), org.EditLabel). + Delete(reqOrgOwnership(), org.DeleteLabel) }) m.Group("/hooks", func() { m.Combo("").Get(org.ListHooks). @@ -1252,29 +1274,29 @@ func Routes(ctx gocontext.Context) *web.Route { m.Combo("/{id}").Get(org.GetHook). Patch(bind(api.EditHookOption{}), org.EditHook). Delete(org.DeleteHook) - }, reqToken(auth_model.AccessTokenScopeAdminOrgHook), reqOrgOwnership(), reqWebhooksEnabled()) + }, reqOrgOwnership(), reqWebhooksEnabled()) m.Get("/activities/feeds", org.ListOrgActivityFeeds) - }, orgAssignment(true)) + }, reqToken(auth_model.AccessTokenScopeCategoryOrganization), orgAssignment(true)) m.Group("/teams/{teamid}", func() { - 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.Combo("").Get(org.GetTeam). + Patch(reqOrgOwnership(), bind(api.EditTeamOption{}), org.EditTeam). + Delete(reqOrgOwnership(), org.DeleteTeam) m.Group("/members", func() { - m.Get("", reqToken(auth_model.AccessTokenScopeReadOrg), org.GetTeamMembers) + m.Get("", org.GetTeamMembers) m.Combo("/{username}"). - Get(reqToken(auth_model.AccessTokenScopeReadOrg), org.GetTeamMember). - Put(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgOwnership(), org.AddTeamMember). - Delete(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgOwnership(), org.RemoveTeamMember) + Get(org.GetTeamMember). + Put(reqOrgOwnership(), org.AddTeamMember). + Delete(reqOrgOwnership(), org.RemoveTeamMember) }) m.Group("/repos", func() { - m.Get("", reqToken(auth_model.AccessTokenScopeReadOrg), org.GetTeamRepos) + m.Get("", org.GetTeamRepos) m.Combo("/{org}/{reponame}"). - Put(reqToken(auth_model.AccessTokenScopeWriteOrg), org.AddTeamRepository). - Delete(reqToken(auth_model.AccessTokenScopeWriteOrg), org.RemoveTeamRepository). - Get(reqToken(auth_model.AccessTokenScopeReadOrg), org.GetTeamRepo) + Put(org.AddTeamRepository). // TODO repo scope? + Delete(org.RemoveTeamRepository). + Get(org.GetTeamRepo) }) m.Get("/activities/feeds", org.ListTeamActivityFeeds) - }, orgAssignment(false, true), reqToken(""), reqTeamMembership()) + }, orgAssignment(false, true), reqToken(auth_model.AccessTokenScopeCategoryOrganization), reqTeamMembership()) m.Group("/admin", func() { m.Group("/cron", func() { @@ -1314,11 +1336,11 @@ func Routes(ctx gocontext.Context) *web.Route { Patch(bind(api.EditHookOption{}), admin.EditHook). Delete(admin.DeleteHook) }) - }, reqToken(auth_model.AccessTokenScopeSudo), reqSiteAdmin()) + }, reqToken(auth_model.AccessTokenScopeCategoryAdmin), reqSiteAdmin()) m.Group("/topics", func() { m.Get("/search", repo.TopicSearch) - }) + }) // TODO scope? }, sudo()) return m diff --git a/routers/web/auth/oauth.go b/routers/web/auth/oauth.go index 92a06e7c14a03..c0962116b61ce 100644 --- a/routers/web/auth/oauth.go +++ b/routers/web/auth/oauth.go @@ -14,6 +14,8 @@ import ( "net/url" "strings" + "github.com/golang-jwt/jwt/v4" + "code.gitea.io/gitea/models/auth" org_model "code.gitea.io/gitea/models/organization" user_model "code.gitea.io/gitea/models/user" @@ -36,7 +38,6 @@ import ( user_service "code.gitea.io/gitea/services/user" "gitea.com/go-chi/binding" - "github.com/golang-jwt/jwt/v4" "github.com/markbates/goth" "github.com/markbates/goth/gothic" ) diff --git a/routers/web/repo/http.go b/routers/web/repo/http.go index b6ebd25915626..f4e9ac86a1bc3 100644 --- a/routers/web/repo/http.go +++ b/routers/web/repo/http.go @@ -152,7 +152,7 @@ func httpBase(ctx *context.Context) (h *serviceHandler) { return } - context.CheckRepoScopedToken(ctx, repo) + context.CheckRepoScopedToken(ctx, repo, auth_model.GetScopeLevelFromAccessMode(accessMode)) if ctx.Written() { return } diff --git a/services/forms/user_form_test.go b/services/forms/user_form_test.go index 84efa25d535e7..66050187c9f1c 100644 --- a/services/forms/user_form_test.go +++ b/services/forms/user_form_test.go @@ -112,12 +112,12 @@ func TestNewAccessTokenForm_GetScope(t *testing.T) { expectedErr error }{ { - form: NewAccessTokenForm{Name: "test", Scope: []string{"repo"}}, - scope: "repo", + form: NewAccessTokenForm{Name: "test", Scope: []string{"read:repository"}}, + scope: "read:repository", }, { - form: NewAccessTokenForm{Name: "test", Scope: []string{"repo", "user"}}, - scope: "repo,user", + form: NewAccessTokenForm{Name: "test", Scope: []string{"read:repository", "write:user"}}, + scope: "read:repository,write:user", }, } diff --git a/services/lfs/locks.go b/services/lfs/locks.go index 1e5db6bd2014a..f1768cd694804 100644 --- a/services/lfs/locks.go +++ b/services/lfs/locks.go @@ -8,6 +8,7 @@ import ( "strconv" "strings" + auth_model "code.gitea.io/gitea/models/auth" git_model "code.gitea.io/gitea/models/git" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" @@ -58,7 +59,7 @@ func GetListLockHandler(ctx *context.Context) { } repository.MustOwner(ctx) - context.CheckRepoScopedToken(ctx, repository) + context.CheckRepoScopedToken(ctx, repository, auth_model.Read) if ctx.Written() { return } @@ -150,7 +151,7 @@ func PostLockHandler(ctx *context.Context) { } repository.MustOwner(ctx) - context.CheckRepoScopedToken(ctx, repository) + context.CheckRepoScopedToken(ctx, repository, auth_model.Write) if ctx.Written() { return } @@ -222,7 +223,7 @@ func VerifyLockHandler(ctx *context.Context) { } repository.MustOwner(ctx) - context.CheckRepoScopedToken(ctx, repository) + context.CheckRepoScopedToken(ctx, repository, auth_model.Read) if ctx.Written() { return } @@ -293,7 +294,7 @@ func UnLockHandler(ctx *context.Context) { } repository.MustOwner(ctx) - context.CheckRepoScopedToken(ctx, repository) + context.CheckRepoScopedToken(ctx, repository, auth_model.Delete) if ctx.Written() { return } diff --git a/services/lfs/server.go b/services/lfs/server.go index 64e1203394547..1f82aed54b397 100644 --- a/services/lfs/server.go +++ b/services/lfs/server.go @@ -18,6 +18,7 @@ import ( "strings" actions_model "code.gitea.io/gitea/models/actions" + auth_model "code.gitea.io/gitea/models/auth" git_model "code.gitea.io/gitea/models/git" "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" @@ -423,7 +424,12 @@ func getAuthenticatedRepository(ctx *context.Context, rc *requestContext, requir return nil } - context.CheckRepoScopedToken(ctx, repository) + if requireWrite { + context.CheckRepoScopedToken(ctx, repository, auth_model.Write) + } else { + context.CheckRepoScopedToken(ctx, repository, auth_model.Read) + } + if ctx.Written() { return nil } diff --git a/tests/integration/api_admin_org_test.go b/tests/integration/api_admin_org_test.go index 89617f7a2c47b..0bf4b1f7cba03 100644 --- a/tests/integration/api_admin_org_test.go +++ b/tests/integration/api_admin_org_test.go @@ -21,7 +21,7 @@ import ( func TestAPIAdminOrgCreate(t *testing.T) { onGiteaRun(t, func(*testing.T, *url.URL) { session := loginUser(t, "user1") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeSudo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteAdmin) org := api.CreateOrgOption{ UserName: "user2_org", @@ -55,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, auth_model.AccessTokenScopeSudo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteAdmin) org := api.CreateOrgOption{ UserName: "user2_org", diff --git a/tests/integration/api_admin_test.go b/tests/integration/api_admin_test.go index 7cfc3276eebc4..27025c9b9988d 100644 --- a/tests/integration/api_admin_test.go +++ b/tests/integration/api_admin_test.go @@ -25,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, auth_model.AccessTokenScopeSudo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteAdmin) 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", @@ -52,7 +52,7 @@ func TestAPIAdminDeleteMissingSSHKey(t *testing.T) { defer tests.PrepareTestEnv(t)() // user1 is an admin user - token := getUserToken(t, "user1", auth_model.AccessTokenScopeSudo) + token := getUserToken(t, "user1", auth_model.AccessTokenScopeDeleteAdmin) req := NewRequestf(t, "DELETE", "/api/v1/admin/users/user1/keys/%d?token=%s", unittest.NonexistentID, token) MakeRequest(t, req, http.StatusNotFound) } @@ -61,7 +61,7 @@ func TestAPIAdminDeleteUnauthorizedKey(t *testing.T) { defer tests.PrepareTestEnv(t)() adminUsername := "user1" normalUsername := "user2" - token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeSudo) + token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeDeleteAdmin) urlStr := fmt.Sprintf("/api/v1/admin/users/%s/keys?token=%s", adminUsername, token) req := NewRequestWithValues(t, "POST", urlStr, map[string]string{ @@ -82,7 +82,7 @@ func TestAPISudoUser(t *testing.T) { defer tests.PrepareTestEnv(t)() adminUsername := "user1" normalUsername := "user2" - token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeSudo) + token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeReadAdmin) urlStr := fmt.Sprintf("/api/v1/user?sudo=%s&token=%s", normalUsername, token) req := NewRequest(t, "GET", urlStr) @@ -98,7 +98,7 @@ func TestAPISudoUserForbidden(t *testing.T) { adminUsername := "user1" normalUsername := "user2" - token := getUserToken(t, normalUsername, auth_model.AccessTokenScopeSudo) + token := getUserToken(t, normalUsername, auth_model.AccessTokenScopeReadAdmin) urlStr := fmt.Sprintf("/api/v1/user?sudo=%s&token=%s", adminUsername, token) req := NewRequest(t, "GET", urlStr) MakeRequest(t, req, http.StatusForbidden) @@ -107,7 +107,7 @@ func TestAPISudoUserForbidden(t *testing.T) { func TestAPIListUsers(t *testing.T) { defer tests.PrepareTestEnv(t)() adminUsername := "user1" - token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeSudo) + token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeReadAdmin) urlStr := fmt.Sprintf("/api/v1/admin/users?token=%s", token) req := NewRequest(t, "GET", urlStr) @@ -143,7 +143,7 @@ func TestAPIListUsersNonAdmin(t *testing.T) { func TestAPICreateUserInvalidEmail(t *testing.T) { defer tests.PrepareTestEnv(t)() adminUsername := "user1" - token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeSudo) + token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeWriteAdmin) 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", @@ -161,7 +161,7 @@ func TestAPICreateUserInvalidEmail(t *testing.T) { func TestAPICreateAndDeleteUser(t *testing.T) { defer tests.PrepareTestEnv(t)() adminUsername := "user1" - token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeSudo) + token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeWriteAdmin) req := NewRequestWithValues( t, @@ -187,7 +187,7 @@ func TestAPICreateAndDeleteUser(t *testing.T) { func TestAPIEditUser(t *testing.T) { defer tests.PrepareTestEnv(t)() adminUsername := "user1" - token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeSudo) + token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeWriteAdmin) urlStr := fmt.Sprintf("/api/v1/admin/users/%s?token=%s", "user2", token) req := NewRequestWithValues(t, "PATCH", urlStr, map[string]string{ @@ -229,7 +229,7 @@ func TestAPIEditUser(t *testing.T) { func TestAPICreateRepoForUser(t *testing.T) { defer tests.PrepareTestEnv(t)() adminUsername := "user1" - token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeSudo) + token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeWriteAdmin) req := NewRequestWithJSON( t, @@ -245,7 +245,7 @@ func TestAPICreateRepoForUser(t *testing.T) { func TestAPIRenameUser(t *testing.T) { defer tests.PrepareTestEnv(t)() adminUsername := "user1" - token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeSudo) + token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeWriteAdmin) urlStr := fmt.Sprintf("/api/v1/admin/users/%s/rename?token=%s", "user2", token) req := NewRequestWithValues(t, "POST", urlStr, map[string]string{ // required diff --git a/tests/integration/api_branch_test.go b/tests/integration/api_branch_test.go index 6616399a8add0..384ea77365d75 100644 --- a/tests/integration/api_branch_test.go +++ b/tests/integration/api_branch_test.go @@ -16,7 +16,7 @@ import ( ) func testAPIGetBranch(t *testing.T, branchName string, exists bool) { - token := getUserToken(t, "user2", auth_model.AccessTokenScopeRepo) + token := getUserToken(t, "user2", auth_model.AccessTokenScopeReadRepository) req := NewRequestf(t, "GET", "/api/v1/repos/user2/repo1/branches/%s?token=%s", branchName, token) resp := MakeRequest(t, req, NoExpectedStatus) if !exists { @@ -32,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", auth_model.AccessTokenScopeRepo) + token := getUserToken(t, "user2", auth_model.AccessTokenScopeReadRepository) req := NewRequestf(t, "GET", "/api/v1/repos/user2/repo1/branch_protections/%s?token=%s", branchName, token) resp := MakeRequest(t, req, expectedHTTPStatus) @@ -44,7 +44,7 @@ func testAPIGetBranchProtection(t *testing.T, branchName string, expectedHTTPSta } func testAPICreateBranchProtection(t *testing.T, branchName string, expectedHTTPStatus int) { - token := getUserToken(t, "user2", auth_model.AccessTokenScopeRepo) + token := getUserToken(t, "user2", auth_model.AccessTokenScopeWriteRepository) req := NewRequestWithJSON(t, "POST", "/api/v1/repos/user2/repo1/branch_protections?token="+token, &api.BranchProtection{ RuleName: branchName, }) @@ -58,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", auth_model.AccessTokenScopeRepo) + token := getUserToken(t, "user2", auth_model.AccessTokenScopeWriteRepository) req := NewRequestWithJSON(t, "PATCH", "/api/v1/repos/user2/repo1/branch_protections/"+branchName+"?token="+token, body) resp := MakeRequest(t, req, expectedHTTPStatus) @@ -70,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", auth_model.AccessTokenScopeRepo) + token := getUserToken(t, "user2", auth_model.AccessTokenScopeDeleteRepository) 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", auth_model.AccessTokenScopeRepo) + token := getUserToken(t, "user2", auth_model.AccessTokenScopeDeleteRepository) req := NewRequestf(t, "DELETE", "/api/v1/repos/user2/repo1/branches/%s?token=%s", branchName, token) MakeRequest(t, req, expectedHTTPStatus) } @@ -102,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", auth_model.AccessTokenScopeRepo) + ctx := NewAPITestContext(t, username, "my-noo-repo", auth_model.AccessTokenScopeWriteRepository) giteaURL.Path = ctx.GitPath() t.Run("CreateRepo", doAPICreateRepository(ctx, false)) @@ -149,7 +149,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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 1d0b902b39347..5a14a3217621a 100644 --- a/tests/integration/api_comment_attachment_test.go +++ b/tests/integration/api_comment_attachment_test.go @@ -82,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d/assets?token=%s", repoOwner.Name, repo.Name, comment.ID, token) @@ -121,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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{ @@ -144,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteRepository) 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 56de8b59093e5..ee6369eca056d 100644 --- a/tests/integration/api_comment_test.go +++ b/tests/integration/api_comment_test.go @@ -76,7 +76,7 @@ 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}) - token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeRepo) + token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeReadRepository) 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) @@ -96,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, auth_model.AccessTokenScopeRepo) + token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeWriteRepository) 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{ @@ -118,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, auth_model.AccessTokenScopeRepo) + token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeReadRepository) 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) @@ -146,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, auth_model.AccessTokenScopeRepo) + token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeWriteRepository) 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{ @@ -170,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, auth_model.AccessTokenScopeRepo) + token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeDeleteRepository) 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 f66961786fff0..7ec9d8fe129d4 100644 --- a/tests/integration/api_gpg_keys_test.go +++ b/tests/integration/api_gpg_keys_test.go @@ -21,8 +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, auth_model.AccessTokenScopeRepo) - tokenWithGPGKeyScope := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAdminGPGKey, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) + tokenWithGPGKeyScope := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteRepository, auth_model.AccessTokenScopeWriteRepository) tt := []struct { name string diff --git a/tests/integration/api_httpsig_test.go b/tests/integration/api_httpsig_test.go index 57f83490dcc9c..08fbe8eae2465 100644 --- a/tests/integration/api_httpsig_test.go +++ b/tests/integration/api_httpsig_test.go @@ -53,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, auth_model.AccessTokenScopeAdminPublicKey, auth_model.AccessTokenScopeSudo)) + token := url.QueryEscape(getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteAdmin)) 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 b4d6dab42a184..3d728e9f4034b 100644 --- a/tests/integration/api_issue_attachment_test.go +++ b/tests/integration/api_issue_attachment_test.go @@ -73,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/assets?token=%s", repoOwner.Name, repo.Name, issue.Index, token) @@ -111,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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{ @@ -133,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteRepository) 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 18240159834a7..10c7997f5e38d 100644 --- a/tests/integration/api_issue_label_test.go +++ b/tests/integration/api_issue_label_test.go @@ -25,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/labels?token=%s", owner.Name, repo.Name, token) // CreateLabel @@ -97,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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{ @@ -120,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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{ @@ -144,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, auth_model.AccessTokenScopeRepo, auth_model.AccessTokenScopeAdminOrg) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteOrganization) 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 cbce795bc9a6b..b194f4f95c386 100644 --- a/tests/integration/api_issue_milestone_test.go +++ b/tests/integration/api_issue_milestone_test.go @@ -29,7 +29,7 @@ func TestAPIIssuesMilestone(t *testing.T) { assert.Equal(t, structs.StateOpen, milestone.State()) session := loginUser(t, owner.Name) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) // update values of issue milestoneState := "closed" diff --git a/tests/integration/api_issue_pin_test.go b/tests/integration/api_issue_pin_test.go index 65be1d74f2d33..40040797d52e4 100644 --- a/tests/integration/api_issue_pin_test.go +++ b/tests/integration/api_issue_pin_test.go @@ -29,7 +29,7 @@ func TestAPIPinIssue(t *testing.T) { owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, owner.Name) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) // Pin the Issue urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/pin?token=%s", @@ -56,7 +56,7 @@ func TestAPIUnpinIssue(t *testing.T) { owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, owner.Name) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteRepository) // Pin the Issue urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/pin?token=%s", @@ -97,7 +97,7 @@ func TestAPIMoveIssuePin(t *testing.T) { owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, owner.Name) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) // Pin the first Issue urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/pin?token=%s", @@ -152,7 +152,7 @@ func TestAPIListPinnedIssues(t *testing.T) { owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, owner.Name) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) // Pin the Issue urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/pin?token=%s", diff --git a/tests/integration/api_issue_reaction_test.go b/tests/integration/api_issue_reaction_test.go index 42793c66cfbf7..666bea4b4c55e 100644 --- a/tests/integration/api_issue_reaction_test.go +++ b/tests/integration/api_issue_reaction_test.go @@ -29,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteRepository) user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/reactions?token=%s", @@ -88,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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 a8a832414d353..d3cc16e2a9eeb 100644 --- a/tests/integration/api_issue_stopwatch_test.go +++ b/tests/integration/api_issue_stopwatch_test.go @@ -26,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) req := NewRequestf(t, "GET", "/api/v1/user/stopwatches?token=%s", token) resp := MakeRequest(t, req, http.StatusOK) var apiWatches []*api.StopWatch @@ -52,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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) @@ -68,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteRepository) 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) @@ -84,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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 473e720754091..8907017272148 100644 --- a/tests/integration/api_issue_subscription_test.go +++ b/tests/integration/api_issue_subscription_test.go @@ -31,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteRepository) 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 4344c15ea45f3..566bce3a76ea4 100644 --- a/tests/integration/api_issue_test.go +++ b/tests/integration/api_issue_test.go @@ -30,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) link, _ := url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/issues", owner.Name, repo.Name)) link.RawQuery = url.Values{"token": {token}, "state": {"all"}}.Encode() @@ -81,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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, @@ -117,7 +117,7 @@ func TestAPIEditIssue(t *testing.T) { assert.Equal(t, api.StateOpen, issueBefore.State()) session := loginUser(t, owner.Name) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) // 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 7d9c785474014..ad37677e1b81b 100644 --- a/tests/integration/api_issue_tracked_time_test.go +++ b/tests/integration/api_issue_tracked_time_test.go @@ -28,7 +28,7 @@ func TestAPIGetTrackedTimes(t *testing.T) { assert.NoError(t, issue2.LoadRepo(db.DefaultContext)) session := loginUser(t, user2.Name) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) 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) @@ -71,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteRepository) // 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) @@ -106,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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 dc25cbfc1a7c6..238c3cb823230 100644 --- a/tests/integration/api_keys_test.go +++ b/tests/integration/api_keys_test.go @@ -54,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) keysURL := fmt.Sprintf("/api/v1/repos/%s/%s/keys?token=%s", repoOwner.Name, repo.Name, token) rawKeyBody := api.CreateKeyOption{ Title: "read-only", @@ -80,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) keysURL := fmt.Sprintf("/api/v1/repos/%s/%s/keys?token=%s", repoOwner.Name, repo.Name, token) rawKeyBody := api.CreateKeyOption{ Title: "read-write", @@ -104,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, auth_model.AccessTokenScopeAdminPublicKey)) + token := url.QueryEscape(getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser)) 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=" @@ -168,7 +168,7 @@ func TestCreateUserKey(t *testing.T) { // Now login as user 2 session2 := loginUser(t, "user2") - token2 := url.QueryEscape(getTokenForLoggedInUser(t, session2, auth_model.AccessTokenScopeAdminPublicKey)) + token2 := url.QueryEscape(getTokenForLoggedInUser(t, session2, auth_model.AccessTokenScopeWriteUser)) // 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 0ff13704cf69d..3167f6adaeae1 100644 --- a/tests/integration/api_notification_test.go +++ b/tests/integration/api_notification_test.go @@ -28,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, auth_model.AccessTokenScopeNotification) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteNotification) // -- GET /notifications -- // test filter @@ -146,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, auth_model.AccessTokenScopeNotification) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteNotification) // 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 c320efb391ed7..72cdba2ea2f6e 100644 --- a/tests/integration/api_oauth2_apps_test.go +++ b/tests/integration/api_oauth2_apps_test.go @@ -55,7 +55,7 @@ func testAPICreateOAuth2Application(t *testing.T) { func testAPIListOAuth2Applications(t *testing.T) { user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) session := loginUser(t, user.Name) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadApplication) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser) existApp := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ UID: user.ID, @@ -86,7 +86,7 @@ func testAPIListOAuth2Applications(t *testing.T) { func testAPIDeleteOAuth2Application(t *testing.T) { user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) session := loginUser(t, user.Name) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteApplication) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser) oldApp := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ UID: user.ID, @@ -107,7 +107,7 @@ 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, auth_model.AccessTokenScopeReadApplication) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser) existApp := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ UID: user.ID, diff --git a/tests/integration/api_org_test.go b/tests/integration/api_org_test.go index 4b79b32c59486..edbf576b9ecf3 100644 --- a/tests/integration/api_org_test.go +++ b/tests/integration/api_org_test.go @@ -26,7 +26,7 @@ import ( func TestAPIOrgCreate(t *testing.T) { onGiteaRun(t, func(*testing.T, *url.URL) { - token := getUserToken(t, "user1", auth_model.AccessTokenScopeWriteOrg) + token := getUserToken(t, "user1", auth_model.AccessTokenScopeWriteOrganization) org := api.CreateOrgOption{ UserName: "user1_org", @@ -100,7 +100,7 @@ func TestAPIOrgEdit(t *testing.T) { onGiteaRun(t, func(*testing.T, *url.URL) { session := loginUser(t, "user1") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrg) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization) org := api.EditOrgOption{ FullName: "User3 organization new full name", Description: "A new description", @@ -127,7 +127,7 @@ func TestAPIOrgEditBadVisibility(t *testing.T) { onGiteaRun(t, func(*testing.T, *url.URL) { session := loginUser(t, "user1") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrg) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization) org := api.EditOrgOption{ FullName: "User3 organization new full name", Description: "A new description", @@ -162,7 +162,7 @@ func TestAPIOrgDeny(t *testing.T) { func TestAPIGetAll(t *testing.T) { defer tests.PrepareTestEnv(t)() - token := getUserToken(t, "user1", auth_model.AccessTokenScopeReadOrg) + token := getUserToken(t, "user1", auth_model.AccessTokenScopeReadOrganization) // accessing with a token will return all orgs req := NewRequestf(t, "GET", "/api/v1/orgs?token=%s", token) @@ -186,7 +186,7 @@ func TestAPIGetAll(t *testing.T) { func TestAPIOrgSearchEmptyTeam(t *testing.T) { onGiteaRun(t, func(*testing.T, *url.URL) { - token := getUserToken(t, "user1", auth_model.AccessTokenScopeAdminOrg) + token := getUserToken(t, "user1", auth_model.AccessTokenScopeWriteOrganization) orgName := "org_with_empty_team" // create org diff --git a/tests/integration/api_packages_npm_test.go b/tests/integration/api_packages_npm_test.go index 78389b5740af3..eb17c91f36613 100644 --- a/tests/integration/api_packages_npm_test.go +++ b/tests/integration/api_packages_npm_test.go @@ -28,7 +28,7 @@ func TestPackageNpm(t *testing.T) { user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - token := fmt.Sprintf("Bearer %s", getTokenForLoggedInUser(t, loginUser(t, user.Name), auth_model.AccessTokenScopePackage)) + token := fmt.Sprintf("Bearer %s", getTokenForLoggedInUser(t, loginUser(t, user.Name), auth_model.AccessTokenScopeDeletePackage)) packageName := "@scope/test-package" packageVersion := "1.0.1-pre" diff --git a/tests/integration/api_packages_nuget_test.go b/tests/integration/api_packages_nuget_test.go index 2240d2a5d4a67..a6c4090f0efac 100644 --- a/tests/integration/api_packages_nuget_test.go +++ b/tests/integration/api_packages_nuget_test.go @@ -75,7 +75,7 @@ func TestPackageNuGet(t *testing.T) { } user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - token := getUserToken(t, user.Name, auth_model.AccessTokenScopePackage) + token := getUserToken(t, user.Name, auth_model.AccessTokenScopeWritePackage) packageName := "test.package" packageVersion := "1.0.3" diff --git a/tests/integration/api_packages_pub_test.go b/tests/integration/api_packages_pub_test.go index 5c1cc6052f179..df0c7aa21b7e4 100644 --- a/tests/integration/api_packages_pub_test.go +++ b/tests/integration/api_packages_pub_test.go @@ -31,7 +31,7 @@ func TestPackagePub(t *testing.T) { user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - token := "Bearer " + getUserToken(t, user.Name, auth_model.AccessTokenScopePackage) + token := "Bearer " + getUserToken(t, user.Name, auth_model.AccessTokenScopeWritePackage) packageName := "test_package" packageVersion := "1.0.1" diff --git a/tests/integration/api_packages_vagrant_test.go b/tests/integration/api_packages_vagrant_test.go index b28bfca6f08d9..cbfc362f32d51 100644 --- a/tests/integration/api_packages_vagrant_test.go +++ b/tests/integration/api_packages_vagrant_test.go @@ -28,7 +28,7 @@ func TestPackageVagrant(t *testing.T) { defer tests.PrepareTestEnv(t)() user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - token := "Bearer " + getUserToken(t, user.Name, auth_model.AccessTokenScopePackage) + token := "Bearer " + getUserToken(t, user.Name, auth_model.AccessTokenScopeWritePackage) packageName := "test_package" packageVersion := "1.0.1" diff --git a/tests/integration/api_pull_review_test.go b/tests/integration/api_pull_review_test.go index e0abf34f5e30a..92059d022dab9 100644 --- a/tests/integration/api_pull_review_test.go +++ b/tests/integration/api_pull_review_test.go @@ -28,7 +28,7 @@ func TestAPIPullReview(t *testing.T) { // test ListPullReviews session := loginUser(t, "user2") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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) @@ -231,7 +231,7 @@ func TestAPIPullReviewRequest(t *testing.T) { // Test add Review Request session := loginUser(t, "user2") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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"}, }) @@ -251,7 +251,7 @@ func TestAPIPullReviewRequest(t *testing.T) { // Test Remove Review Request session2 := loginUser(t, "user4") - token2 := getTokenForLoggedInUser(t, session2, auth_model.AccessTokenScopeRepo) + token2 := getTokenForLoggedInUser(t, session2, auth_model.AccessTokenScopeDeleteRepository) 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 cf675f9740a2d..9d590630e4510 100644 --- a/tests/integration/api_pull_test.go +++ b/tests/integration/api_pull_test.go @@ -29,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, auth_model.AccessTokenScopeRepo) + ctx := NewAPITestContext(t, "user2", repo.Name, auth_model.AccessTokenScopeReadRepository) 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) @@ -75,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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), @@ -94,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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", @@ -114,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) opts := &api.CreatePullRequestOption{ Head: fmt.Sprintf("%s:master", owner11.Name), @@ -151,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) opts := &api.CreatePullRequestOption{ Head: fmt.Sprintf("%s:master", owner11.Name), @@ -181,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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 aa5816ad02944..7a7e822de9d88 100644 --- a/tests/integration/api_releases_test.go +++ b/tests/integration/api_releases_test.go @@ -25,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, auth_model.AccessTokenScopeRepo) + token := getUserToken(t, user2.LowerName, auth_model.AccessTokenScopeReadRepository) link, _ := url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/releases", user2.Name, repo.Name)) link.RawQuery = url.Values{"token": {token}}.Encode() @@ -101,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) gitRepo, err := git.OpenRepository(git.DefaultContext, repo.RepoPath()) assert.NoError(t, err) @@ -153,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) createNewReleaseUsingAPI(t, session, token, owner, repo, "v0.0.1", "", "v0.0.1", "test") } @@ -164,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) gitRepo, err := git.OpenRepository(git.DefaultContext, repo.RepoPath()) assert.NoError(t, err) @@ -232,7 +232,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteRepository) 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 699d7a436c08a..5d1db1b09b785 100644 --- a/tests/integration/api_repo_archive_test.go +++ b/tests/integration/api_repo_archive_test.go @@ -25,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) 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 ed015384772b2..7a07067113f29 100644 --- a/tests/integration/api_repo_collaborator_test.go +++ b/tests/integration/api_repo_collaborator_test.go @@ -28,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, auth_model.AccessTokenScopeRepo) + testCtx := NewAPITestContext(t, repo2Owner.Name, repo2.Name, auth_model.AccessTokenScopeReadRepository) 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) @@ -85,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, auth_model.AccessTokenScopeRepo) + _testCtx := NewAPITestContext(t, user5.Name, repo2.Name, auth_model.AccessTokenScopeReadRepository) 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) @@ -100,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, auth_model.AccessTokenScopeRepo) + _testCtx := NewAPITestContext(t, user5.Name, repo2.Name, auth_model.AccessTokenScopeReadRepository) 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) @@ -116,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, auth_model.AccessTokenScopeRepo) + _testCtx := NewAPITestContext(t, user10.Name, repo2.Name, auth_model.AccessTokenScopeReadRepository) 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 30dc73ef1b74d..b7242fb3166d7 100644 --- a/tests/integration/api_repo_edit_test.go +++ b/tests/integration/api_repo_edit_test.go @@ -147,10 +147,10 @@ func TestAPIRepoEdit(t *testing.T) { // Get user2's token session := loginUser(t, user2.Name) - token2 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token2 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) // Get user4's token session = loginUser(t, user4.Name) - token4 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token4 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) // 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 a3a5422154199..a2829b276440c 100644 --- a/tests/integration/api_repo_file_create_test.go +++ b/tests/integration/api_repo_file_create_test.go @@ -151,10 +151,10 @@ func TestAPICreateFile(t *testing.T) { // Get user2's token session := loginUser(t, user2.Name) - token2 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token2 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) // Get user4's token session = loginUser(t, user4.Name) - token4 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token4 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) // Test creating a file in repo1 which user2 owns, try both with branch and empty branch for _, branch := range [...]string{ @@ -280,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", auth_model.AccessTokenScopeRepo), true)(t) + doAPICreateRepository(NewAPITestContext(t, "user2", "empty-repo", auth_model.AccessTokenScopeWriteRepository), 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 ae28c97002db7..71c8f74ed0e34 100644 --- a/tests/integration/api_repo_file_delete_test.go +++ b/tests/integration/api_repo_file_delete_test.go @@ -49,10 +49,10 @@ func TestAPIDeleteFile(t *testing.T) { // Get user2's token session := loginUser(t, user2.Name) - token2 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token2 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteRepository) // Get user4's token session = loginUser(t, user4.Name) - token4 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token4 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteRepository) // 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 a6a1e634396e2..4f7cb249f21d2 100644 --- a/tests/integration/api_repo_file_get_test.go +++ b/tests/integration/api_repo_file_get_test.go @@ -25,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", auth_model.AccessTokenScopeRepo, auth_model.AccessTokenScopeDeleteRepo) + httpContext := NewAPITestContext(t, "user2", "repo-lfs-test", auth_model.AccessTokenScopeDeleteRepository) 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 177d7282cabe3..5bcb531fc13be 100644 --- a/tests/integration/api_repo_file_update_test.go +++ b/tests/integration/api_repo_file_update_test.go @@ -117,10 +117,10 @@ func TestAPIUpdateFile(t *testing.T) { // Get user2's token session := loginUser(t, user2.Name) - token2 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token2 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) // Get user4's token session = loginUser(t, user4.Name) - token4 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token4 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) // 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 e1c4682e6d6e6..50a27b27b431f 100644 --- a/tests/integration/api_repo_git_hook_test.go +++ b/tests/integration/api_repo_git_hook_test.go @@ -31,7 +31,7 @@ func TestAPIListGitHooks(t *testing.T) { // user1 is an admin user session := loginUser(t, "user1") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepoHook) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/hooks/git?token=%s", owner.Name, repo.Name, token) resp := MakeRequest(t, req, http.StatusOK) @@ -57,7 +57,7 @@ func TestAPIListGitHooksNoHooks(t *testing.T) { // user1 is an admin user session := loginUser(t, "user1") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepoHook) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/hooks/git?token=%s", owner.Name, repo.Name, token) resp := MakeRequest(t, req, http.StatusOK) @@ -77,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, auth_model.AccessTokenScopeReadRepoHook) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/hooks/git?token=%s", owner.Name, repo.Name, token) MakeRequest(t, req, http.StatusForbidden) @@ -91,7 +91,7 @@ func TestAPIGetGitHook(t *testing.T) { // user1 is an admin user session := loginUser(t, "user1") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepoHook) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) 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) @@ -108,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, auth_model.AccessTokenScopeReadRepoHook) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) 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) @@ -122,7 +122,7 @@ func TestAPIEditGitHook(t *testing.T) { // user1 is an admin user session := loginUser(t, "user1") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAdminRepoHook) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteAdmin) urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/hooks/git/pre-receive?token=%s", owner.Name, repo.Name, token) @@ -151,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, auth_model.AccessTokenScopeWriteRepoHook) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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{ @@ -168,7 +168,7 @@ func TestAPIDeleteGitHook(t *testing.T) { // user1 is an admin user session := loginUser(t, "user1") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAdminRepoHook) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteRepository) req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/hooks/git/pre-receive?token=%s", owner.Name, repo.Name, token) @@ -190,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, auth_model.AccessTokenScopeWriteRepoHook) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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 b29fc45cf5531..29e0642971b6e 100644 --- a/tests/integration/api_repo_git_tags_test.go +++ b/tests/integration/api_repo_git_tags_test.go @@ -70,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteRepository) 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 0fa2402992fc6..18b12597dbdb2 100644 --- a/tests/integration/api_repo_hook_test.go +++ b/tests/integration/api_repo_hook_test.go @@ -26,7 +26,7 @@ func TestAPICreateHook(t *testing.T) { // user1 is an admin user session := loginUser(t, "user1") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepoHook) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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 e66ca6b1474b4..2cd7132b76ccf 100644 --- a/tests/integration/api_repo_lfs_migrate_test.go +++ b/tests/integration/api_repo_lfs_migrate_test.go @@ -31,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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 a7a70baeefa29..0d44d2446441c 100644 --- a/tests/integration/api_repo_lfs_test.go +++ b/tests/integration/api_repo_lfs_test.go @@ -60,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", auth_model.AccessTokenScopeRepo) + ctx := NewAPITestContext(t, "user2", "lfs-"+name+"-repo", auth_model.AccessTokenScopeWriteRepository) 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 60e9eeed6bc14..ccb20a939ee62 100644 --- a/tests/integration/api_repo_raw_test.go +++ b/tests/integration/api_repo_raw_test.go @@ -20,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) 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 d4fd9097ddf3c..1a9b599fb7050 100644 --- a/tests/integration/api_repo_tags_test.go +++ b/tests/integration/api_repo_tags_test.go @@ -23,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteRepository) repoName := "repo1" diff --git a/tests/integration/api_repo_teams_test.go b/tests/integration/api_repo_teams_test.go index 1f444e31414c1..28fe18e0acddb 100644 --- a/tests/integration/api_repo_teams_test.go +++ b/tests/integration/api_repo_teams_test.go @@ -28,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) // ListTeams url := fmt.Sprintf("/api/v1/repos/%s/teams?token=%s", publicOrgRepo.FullName(), token) @@ -68,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, auth_model.AccessTokenScopeRepo) + token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteRepository) 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 aa4e6742063e3..2fb65f2451f90 100644 --- a/tests/integration/api_repo_test.go +++ b/tests/integration/api_repo_test.go @@ -295,7 +295,7 @@ func TestAPIOrgRepos(t *testing.T) { for userToLogin, expected := range expectedResults { testName := fmt.Sprintf("LoggedUser%d", userToLogin.ID) session := loginUser(t, userToLogin.Name) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrg) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrganization) t.Run(testName, func(t *testing.T) { req := NewRequestf(t, "GET", "/api/v1/orgs/%s/repos?token="+token, sourceOrg.Name) @@ -317,7 +317,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) req := NewRequestf(t, "GET", "/api/v1/repositories/2?token="+token) MakeRequest(t, req, http.StatusNotFound) } @@ -341,7 +341,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) req := NewRequestWithJSON(t, "POST", "/api/v1/repos/migrate?token="+token, &api.MigrateRepoOptions{ CloneAddr: testCase.cloneURL, RepoOwnerID: testCase.userID, @@ -371,7 +371,7 @@ func TestAPIRepoMigrateConflict(t *testing.T) { func testAPIRepoMigrateConflict(t *testing.T, u *url.URL) { username := "user2" - baseAPITestContext := NewAPITestContext(t, username, "repo1", auth_model.AccessTokenScopeRepo) + baseAPITestContext := NewAPITestContext(t, username, "repo1", auth_model.AccessTokenScopeWriteRepository) u.Path = baseAPITestContext.GitPath() @@ -406,7 +406,7 @@ func TestAPIMirrorSyncNonMirrorRepo(t *testing.T) { defer tests.PrepareTestEnv(t)() session := loginUser(t, "user2") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) var repo api.Repository req := NewRequest(t, "GET", "/api/v1/repos/user2/repo1") @@ -438,7 +438,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, auth_model.AccessTokenScopeAdminOrg) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization) req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/org/%s/repos?token="+token, testCase.orgName), &api.CreateRepoOption{ Name: testCase.repoName, }) @@ -452,7 +452,7 @@ func TestAPIRepoCreateConflict(t *testing.T) { func testAPIRepoCreateConflict(t *testing.T, u *url.URL) { username := "user2" - baseAPITestContext := NewAPITestContext(t, username, "repo1", auth_model.AccessTokenScopeRepo) + baseAPITestContext := NewAPITestContext(t, username, "repo1", auth_model.AccessTokenScopeWriteRepository) u.Path = baseAPITestContext.GitPath() @@ -502,7 +502,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) repoName := "moveME" apiRepo := new(api.Repository) req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/user/repos?token=%s", token), &api.CreateRepoOption{ @@ -520,7 +520,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, auth_model.AccessTokenScopeRepo) + token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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, @@ -537,7 +537,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) repoName := "moveME" apiRepo := new(api.Repository) req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/user/repos?token=%s", token), &api.CreateRepoOption{ @@ -567,7 +567,7 @@ func TestAPIAcceptTransfer(t *testing.T) { // try to accept with not authorized user session := loginUser(t, "user2") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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) @@ -577,7 +577,7 @@ func TestAPIAcceptTransfer(t *testing.T) { // accept transfer session = loginUser(t, "user4") - token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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) @@ -593,7 +593,7 @@ func TestAPIRejectTransfer(t *testing.T) { // try to reject with not authorized user session := loginUser(t, "user2") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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) @@ -603,7 +603,7 @@ func TestAPIRejectTransfer(t *testing.T) { // reject transfer session = loginUser(t, "user4") - token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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) @@ -617,7 +617,7 @@ func TestAPIGenerateRepo(t *testing.T) { user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) session := loginUser(t, user.Name) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) templateRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 44}) @@ -653,7 +653,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) 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) @@ -667,7 +667,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) 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 ab9fd9bb96c58..275d8181ab419 100644 --- a/tests/integration/api_repo_topic_test.go +++ b/tests/integration/api_repo_topic_test.go @@ -60,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, auth_model.AccessTokenScopeRepo) + token2 := getUserToken(t, user2.Name, auth_model.AccessTokenScopeDeleteRepository) // Test read topics using login url := fmt.Sprintf("/api/v1/repos/%s/%s/topics", user2.Name, repo2.Name) @@ -140,7 +140,7 @@ func TestAPIRepoTopic(t *testing.T) { MakeRequest(t, req, http.StatusNotFound) // Get user4's token - token4 := getUserToken(t, user4.Name, auth_model.AccessTokenScopeRepo) + token4 := getUserToken(t, user4.Name, auth_model.AccessTokenScopeWriteRepository) // 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 60c61394d4533..c1093348dd8eb 100644 --- a/tests/integration/api_team_test.go +++ b/tests/integration/api_team_test.go @@ -33,7 +33,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, auth_model.AccessTokenScopeAdminOrg) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrganization) req := NewRequestf(t, "GET", "/api/v1/teams/%d?token="+token, teamUser.TeamID) resp := MakeRequest(t, req, http.StatusOK) @@ -48,7 +48,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, auth_model.AccessTokenScopeReadOrg) + token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrganization) req = NewRequestf(t, "GET", "/api/v1/teams/%d?token="+token, teamUser.TeamID) _ = MakeRequest(t, req, http.StatusForbidden) @@ -58,7 +58,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, auth_model.AccessTokenScopeAdminOrg) + token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteOrganization) org = unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 6}) @@ -262,7 +262,7 @@ func TestAPITeamSearch(t *testing.T) { var results TeamSearchResults - token := getUserToken(t, user.Name, auth_model.AccessTokenScopeReadOrg) + token := getUserToken(t, user.Name, auth_model.AccessTokenScopeReadOrganization) 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) @@ -272,7 +272,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, auth_model.AccessTokenScopeReadOrg) + token5 := getUserToken(t, user5.Name, auth_model.AccessTokenScopeReadOrganization) req = NewRequestf(t, "GET", "/api/v1/orgs/%s/teams/search?q=%s&token=%s", org.Name, "team", token5) MakeRequest(t, req, http.StatusForbidden) @@ -287,7 +287,7 @@ func TestAPIGetTeamRepo(t *testing.T) { var results api.Repository - token := getUserToken(t, user.Name, auth_model.AccessTokenScopeReadOrg) + token := getUserToken(t, user.Name, auth_model.AccessTokenScopeReadOrganization) 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) @@ -295,7 +295,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, auth_model.AccessTokenScopeReadOrg) + token5 := getUserToken(t, user5.Name, auth_model.AccessTokenScopeReadOrganization) 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 468697a393056..aa33c690413b9 100644 --- a/tests/integration/api_team_user_test.go +++ b/tests/integration/api_team_user_test.go @@ -24,7 +24,7 @@ func TestAPITeamUser(t *testing.T) { normalUsername := "user2" session := loginUser(t, normalUsername) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrg) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrganization) 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 09083d9ce8cdc..fee2f1b960301 100644 --- a/tests/integration/api_user_email_test.go +++ b/tests/integration/api_user_email_test.go @@ -46,7 +46,7 @@ func TestAPIAddEmail(t *testing.T) { normalUsername := "user2" session := loginUser(t, normalUsername) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeUser) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser) opts := api.CreateEmailOption{ Emails: []string{"user101@example.com"}, @@ -83,7 +83,7 @@ func TestAPIDeleteEmail(t *testing.T) { normalUsername := "user2" session := loginUser(t, normalUsername) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeUser) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteUser) 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 c7ad62e649487..66a826d36dbc8 100644 --- a/tests/integration/api_user_follow_test.go +++ b/tests/integration/api_user_follow_test.go @@ -25,7 +25,7 @@ func TestAPIFollow(t *testing.T) { token1 := getTokenForLoggedInUser(t, session1) session2 := loginUser(t, user2) - token2 := getTokenForLoggedInUser(t, session2, auth_model.AccessTokenScopeUserFollow) + token2 := getTokenForLoggedInUser(t, session2, auth_model.AccessTokenScopeWriteUser) 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 ac575b1f012db..3c3e6540f714a 100644 --- a/tests/integration/api_user_org_perm_test.go +++ b/tests/integration/api_user_org_perm_test.go @@ -33,7 +33,7 @@ func sampleTest(t *testing.T, auoptc apiUserOrgPermTestCase) { defer tests.PrepareTestEnv(t)() session := loginUser(t, auoptc.LoginUser) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrg) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrganization) 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) @@ -126,7 +126,7 @@ func TestUnknowUser(t *testing.T) { defer tests.PrepareTestEnv(t)() session := loginUser(t, "user1") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrg) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrganization) req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/unknow/orgs/org25/permissions?token=%s", token)) resp := MakeRequest(t, req, http.StatusNotFound) @@ -140,7 +140,7 @@ func TestUnknowOrganization(t *testing.T) { defer tests.PrepareTestEnv(t)() session := loginUser(t, "user1") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrg) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrganization) 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 8f914b4875f73..f0a7e4f86edac 100644 --- a/tests/integration/api_user_orgs_test.go +++ b/tests/integration/api_user_orgs_test.go @@ -70,7 +70,7 @@ func TestUserOrgs(t *testing.T) { func getUserOrgs(t *testing.T, userDoer, userCheck string) (orgs []*api.Organization) { token := "" if len(userDoer) != 0 { - token = getUserToken(t, userDoer, auth_model.AccessTokenScopeReadOrg) + token = getUserToken(t, userDoer, auth_model.AccessTokenScopeReadOrganization) } urlStr := fmt.Sprintf("/api/v1/users/%s/orgs?token=%s", userCheck, token) req := NewRequest(t, "GET", urlStr) @@ -92,7 +92,7 @@ func TestMyOrgs(t *testing.T) { MakeRequest(t, req, http.StatusUnauthorized) normalUsername := "user2" - token := getUserToken(t, normalUsername, auth_model.AccessTokenScopeReadOrg) + token := getUserToken(t, normalUsername, auth_model.AccessTokenScopeReadOrganization) 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 6a486c19a8826..71be29dd49ebe 100644 --- a/tests/integration/api_user_star_test.go +++ b/tests/integration/api_user_star_test.go @@ -23,12 +23,12 @@ func TestAPIStar(t *testing.T) { session := loginUser(t, user) token := getTokenForLoggedInUser(t, session) - tokenWithRepoScope := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + tokenWithUserScope := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteUser) 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, tokenWithRepoScope)) + req := NewRequest(t, "PUT", fmt.Sprintf("/api/v1/user/starred/%s?token=%s", repo, tokenWithUserScope)) MakeRequest(t, req, http.StatusNoContent) }) @@ -49,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", tokenWithRepoScope)) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/starred?token=%s", tokenWithUserScope)) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, "1", resp.Header().Get("X-Total-Count")) @@ -63,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, tokenWithRepoScope)) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/starred/%s?token=%s", repo, tokenWithUserScope)) MakeRequest(t, req, http.StatusNoContent) - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/starred/%s?token=%s", repo+"notexisting", tokenWithRepoScope)) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/starred/%s?token=%s", repo+"notexisting", tokenWithUserScope)) 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, tokenWithRepoScope)) + req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/user/starred/%s?token=%s", repo, tokenWithUserScope)) MakeRequest(t, req, http.StatusNoContent) }) } diff --git a/tests/integration/api_user_watch_test.go b/tests/integration/api_user_watch_test.go index 5702962573967..9a4a9ad7da8ab 100644 --- a/tests/integration/api_user_watch_test.go +++ b/tests/integration/api_user_watch_test.go @@ -23,7 +23,7 @@ func TestAPIWatch(t *testing.T) { session := loginUser(t, user) token := getTokenForLoggedInUser(t, session) - tokenWithRepoScope := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + tokenWithRepoScope := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) t.Run("Watch", func(t *testing.T) { defer tests.PrintCurrentTest(t)() diff --git a/tests/integration/api_wiki_test.go b/tests/integration/api_wiki_test.go index 3f85074c8aa77..f598982555b3a 100644 --- a/tests/integration/api_wiki_test.go +++ b/tests/integration/api_wiki_test.go @@ -180,7 +180,7 @@ func TestAPINewWikiPage(t *testing.T) { defer tests.PrepareTestEnv(t)() username := "user2" session := loginUser(t, username) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/wiki/new?token=%s", username, "repo1", token) @@ -197,7 +197,7 @@ func TestAPIEditWikiPage(t *testing.T) { defer tests.PrepareTestEnv(t)() username := "user2" session := loginUser(t, username) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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 9ad795d53a41c..11d07e1f9841d 100644 --- a/tests/integration/dump_restore_test.go +++ b/tests/integration/dump_restore_test.go @@ -51,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) // // Phase 1: dump repo1 from the Gitea instance to the filesystem diff --git a/tests/integration/empty_repo_test.go b/tests/integration/empty_repo_test.go index cfb2456223d52..f0022f4db3a32 100644 --- a/tests/integration/empty_repo_test.go +++ b/tests/integration/empty_repo_test.go @@ -117,7 +117,7 @@ func TestEmptyRepoAddFileByAPI(t *testing.T) { assert.NoError(t, err) session := loginUser(t, "user30") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) url := fmt.Sprintf("/api/v1/repos/user30/empty/contents/new-file.txt?token=%s", token) req := NewRequestWithJSON(t, "POST", url, &api.CreateFileOptions{ diff --git a/tests/integration/eventsource_test.go b/tests/integration/eventsource_test.go index 4fdb8cd6f52d8..4eb92bcbafb64 100644 --- a/tests/integration/eventsource_test.go +++ b/tests/integration/eventsource_test.go @@ -60,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, auth_model.AccessTokenScopeNotification) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteNotification) var apiNL []api.NotificationThread diff --git a/tests/integration/git_test.go b/tests/integration/git_test.go index 8d5c0fc3902b0..e26a51487e42a 100644 --- a/tests/integration/git_test.go +++ b/tests/integration/git_test.go @@ -44,11 +44,11 @@ func TestGit(t *testing.T) { func testGit(t *testing.T, u *url.URL) { username := "user2" - baseAPITestContext := NewAPITestContext(t, username, "repo1", auth_model.AccessTokenScopeRepo, auth_model.AccessTokenScopeWritePublicKey, auth_model.AccessTokenScopeDeleteRepo) + baseAPITestContext := NewAPITestContext(t, username, "repo1", auth_model.AccessTokenScopeDeleteRepository) u.Path = baseAPITestContext.GitPath() - forkedUserCtx := NewAPITestContext(t, "user4", "repo1", auth_model.AccessTokenScopeRepo) + forkedUserCtx := NewAPITestContext(t, "user4", "repo1", auth_model.AccessTokenScopeReadRepository) t.Run("HTTP", func(t *testing.T) { defer tests.PrintCurrentTest(t)() @@ -359,7 +359,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, auth_model.AccessTokenScopeRepo) + ctx := NewAPITestContext(t, baseCtx.Username, baseCtx.Reponame, auth_model.AccessTokenScopeWriteRepository) 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-") @@ -603,7 +603,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, auth_model.AccessTokenScopeRepo) + ctx := NewAPITestContext(t, baseCtx.Username, baseCtx.Reponame, auth_model.AccessTokenScopeWriteRepository) 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 36095694b0e89..95a06021834a4 100644 --- a/tests/integration/gpg_git_test.go +++ b/tests/integration/gpg_git_test.go @@ -70,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", auth_model.AccessTokenScopeRepo) + testCtx := NewAPITestContext(t, username, "initial-unsigned", auth_model.AccessTokenScopeWriteRepository) t.Run("CreateRepository", doAPICreateRepository(testCtx, false)) t.Run("CheckMasterBranchUnsigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) { assert.NotNil(t, branch.Commit) @@ -94,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", auth_model.AccessTokenScopeRepo) + testCtx := NewAPITestContext(t, username, "initial-unsigned", auth_model.AccessTokenScopeWriteRepository) 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) @@ -111,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", auth_model.AccessTokenScopeRepo) + testCtx := NewAPITestContext(t, username, "initial-unsigned", auth_model.AccessTokenScopeWriteRepository) 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) @@ -124,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", auth_model.AccessTokenScopeRepo) + testCtx := NewAPITestContext(t, username, "initial-unsigned", auth_model.AccessTokenScopeWriteRepository) 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) @@ -161,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", auth_model.AccessTokenScopeRepo) + testCtx := NewAPITestContext(t, username, "initial-unsigned", auth_model.AccessTokenScopeWriteRepository) 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) @@ -184,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", auth_model.AccessTokenScopeRepo) + testCtx := NewAPITestContext(t, username, "initial-always", auth_model.AccessTokenScopeWriteRepository) t.Run("CreateRepository", doAPICreateRepository(testCtx, false)) t.Run("CheckMasterBranchSigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) { assert.NotNil(t, branch.Commit) @@ -212,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", auth_model.AccessTokenScopeRepo) + testCtx := NewAPITestContext(t, username, "initial-always-never", auth_model.AccessTokenScopeWriteRepository) 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) { @@ -225,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", auth_model.AccessTokenScopeRepo) + testCtx := NewAPITestContext(t, username, "initial-always-parent", auth_model.AccessTokenScopeWriteRepository) 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) { @@ -244,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", auth_model.AccessTokenScopeRepo) + testCtx := NewAPITestContext(t, username, "initial-always-always", auth_model.AccessTokenScopeWriteRepository) 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) { @@ -264,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", auth_model.AccessTokenScopeRepo) + testCtx := NewAPITestContext(t, username, "initial-unsigned", auth_model.AccessTokenScopeWriteRepository) var err error t.Run("CreatePullRequest", func(t *testing.T) { pr, err = doAPICreatePullRequest(testCtx, testCtx.Username, testCtx.Reponame, "master", "never2")(t) @@ -285,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", auth_model.AccessTokenScopeRepo) + testCtx := NewAPITestContext(t, username, "initial-unsigned", auth_model.AccessTokenScopeWriteRepository) var err error t.Run("CreatePullRequest", func(t *testing.T) { pr, err = doAPICreatePullRequest(testCtx, testCtx.Username, testCtx.Reponame, "master", "parentsigned2")(t) @@ -306,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", auth_model.AccessTokenScopeRepo) + testCtx := NewAPITestContext(t, username, "initial-unsigned", auth_model.AccessTokenScopeWriteRepository) 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/lfs_getobject_test.go b/tests/integration/lfs_getobject_test.go index ba236d355f12d..fe070c62d5cea 100644 --- a/tests/integration/lfs_getobject_test.go +++ b/tests/integration/lfs_getobject_test.go @@ -41,13 +41,13 @@ func storeObjectInRepo(t *testing.T, repositoryID int64, content *[]byte) string return pointer.Oid } -func storeAndGetLfsToken(t *testing.T, ts auth.AccessTokenScope, content *[]byte, extraHeader *http.Header, expectedStatus int) *httptest.ResponseRecorder { +func storeAndGetLfsToken(t *testing.T, content *[]byte, extraHeader *http.Header, expectedStatus int, ts ...auth.AccessTokenScope) *httptest.ResponseRecorder { repo, err := repo_model.GetRepositoryByOwnerAndName(db.DefaultContext, "user2", "repo1") assert.NoError(t, err) oid := storeObjectInRepo(t, repo.ID, content) defer git_model.RemoveLFSMetaObjectByOid(db.DefaultContext, repo.ID, oid) - token := getUserToken(t, "user2", ts) + token := getUserToken(t, "user2", ts...) // Request OID req := NewRequest(t, "GET", "/user2/repo1.git/info/lfs/objects/"+oid+"/test") @@ -119,7 +119,7 @@ func TestGetLFSSmallToken(t *testing.T) { defer tests.PrepareTestEnv(t)() content := []byte("A very small file\n") - resp := storeAndGetLfsToken(t, auth.AccessTokenScopePublicRepo, &content, nil, http.StatusOK) + resp := storeAndGetLfsToken(t, &content, nil, http.StatusOK, auth.AccessTokenScopePublicOnly, auth.AccessTokenScopeReadRepository) checkResponseTestContentEncoding(t, &content, resp, false) } @@ -127,7 +127,7 @@ func TestGetLFSSmallTokenFail(t *testing.T) { defer tests.PrepareTestEnv(t)() content := []byte("A very small file\n") - storeAndGetLfsToken(t, auth.AccessTokenScopeNotification, &content, nil, http.StatusForbidden) + storeAndGetLfsToken(t, &content, nil, http.StatusForbidden, auth.AccessTokenScopeReadNotification) } func TestGetLFSLarge(t *testing.T) { diff --git a/tests/integration/migrate_test.go b/tests/integration/migrate_test.go index a925493d7c9e8..9a6edb7d70d6d 100644 --- a/tests/integration/migrate_test.go +++ b/tests/integration/migrate_test.go @@ -67,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) // 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 8f850a170f116..e46b83169b7f9 100644 --- a/tests/integration/org_count_test.go +++ b/tests/integration/org_count_test.go @@ -25,7 +25,7 @@ func testOrgCounts(t *testing.T, u *url.URL) { orgOwner := "user2" orgName := "testOrg" orgCollaborator := "user4" - ctx := NewAPITestContext(t, orgOwner, "repo1", auth_model.AccessTokenScopeAdminOrg) + ctx := NewAPITestContext(t, orgOwner, "repo1", auth_model.AccessTokenScopeWriteOrganization) 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 bfa6380e8a983..64d93e40836d0 100644 --- a/tests/integration/org_test.go +++ b/tests/integration/org_test.go @@ -159,7 +159,7 @@ func TestOrgRestrictedUser(t *testing.T) { // Therefore create a read-only team adminSession := loginUser(t, "user1") - token := getTokenForLoggedInUser(t, adminSession, auth_model.AccessTokenScopeAdminOrg) + token := getTokenForLoggedInUser(t, adminSession, auth_model.AccessTokenScopeWriteOrganization) teamToCreate := &api.CreateTeamOption{ Name: "codereader", diff --git a/tests/integration/privateactivity_test.go b/tests/integration/privateactivity_test.go index 6e1377ae1f2fb..04e03ab26bcc6 100644 --- a/tests/integration/privateactivity_test.go +++ b/tests/integration/privateactivity_test.go @@ -34,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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 f6a36f60af2be..8890347c3678b 100644 --- a/tests/integration/pull_merge_test.go +++ b/tests/integration/pull_merge_test.go @@ -218,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls?token=%s", "user1", "repo1", token), &api.CreatePullRequestOption{ Head: "conflict", Base: "base", @@ -326,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, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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 736d1ee4f0eec..0bdb80ecbf44d 100644 --- a/tests/integration/pull_status_test.go +++ b/tests/integration/pull_status_test.go @@ -64,7 +64,7 @@ func TestPullCreate_CommitStatus(t *testing.T) { api.CommitStatusWarning: "gitea-exclamation", } - testCtx := NewAPITestContext(t, "user1", "repo1", auth_model.AccessTokenScopeRepo) + testCtx := NewAPITestContext(t, "user1", "repo1", auth_model.AccessTokenScopeWriteRepository) // 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 b94731002f164..fa56cec4853f9 100644 --- a/tests/integration/pull_update_test.go +++ b/tests/integration/pull_update_test.go @@ -39,7 +39,7 @@ func TestAPIPullUpdate(t *testing.T) { assert.NoError(t, pr.LoadIssue(db.DefaultContext)) session := loginUser(t, "user2") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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) @@ -67,7 +67,7 @@ func TestAPIPullUpdateByRebase(t *testing.T) { assert.NoError(t, pr.LoadIssue(db.DefaultContext)) session := loginUser(t, "user2") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeRepo) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 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 0cfd21485d19e..ccd2eff5ef43d 100644 --- a/tests/integration/repo_commits_test.go +++ b/tests/integration/repo_commits_test.go @@ -52,7 +52,7 @@ func doTestRepoCommitWithStatus(t *testing.T, state string, classes ...string) { assert.NotEmpty(t, commitURL) // Call API to add status for commit - ctx := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeRepo) + ctx := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeWriteRepository) t.Run("CreateStatus", doAPICreateCommitStatus(ctx, path.Base(commitURL), api.CreateStatusOption{ State: api.CommitStatusState(state), TargetURL: "http://test.ci/", @@ -157,7 +157,7 @@ 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) { - ctx := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeRepoStatus) + ctx := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeReadRepository) runBody := doAPICreateCommitStatus(ctx, path.Base(commitURL), api.CreateStatusOption{ State: api.CommitStatusPending, TargetURL: "http://test.ci/", @@ -188,7 +188,7 @@ func TestRepoCommitsStatusMultiple(t *testing.T) { assert.NotEmpty(t, commitURL) // Call API to add status for commit - ctx := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeRepo) + ctx := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeWriteRepository) t.Run("CreateStatus", doAPICreateCommitStatus(ctx, path.Base(commitURL), api.CreateStatusOption{ State: api.CommitStatusSuccess, TargetURL: "http://test.ci/", diff --git a/tests/integration/ssh_key_test.go b/tests/integration/ssh_key_test.go index 1e9dc264a64c6..59db581e0e4f1 100644 --- a/tests/integration/ssh_key_test.go +++ b/tests/integration/ssh_key_test.go @@ -48,8 +48,8 @@ func TestPushDeployKeyOnEmptyRepo(t *testing.T) { func testPushDeployKeyOnEmptyRepo(t *testing.T, u *url.URL) { // OK login - 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) + ctx := NewAPITestContext(t, "user2", "deploy-key-empty-repo-1", auth_model.AccessTokenScopeWriteRepository) + ctxWithDeleteRepo := NewAPITestContext(t, "user2", "deploy-key-empty-repo-1", auth_model.AccessTokenScopeDeleteRepository) keyname := fmt.Sprintf("%s-push", ctx.Reponame) u.Path = ctx.GitPath() @@ -92,8 +92,8 @@ func testKeyOnlyOneType(t *testing.T, u *url.URL) { keyname := fmt.Sprintf("%s-push", reponame) // OK login - 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) + ctx := NewAPITestContext(t, username, reponame, auth_model.AccessTokenScopeWriteRepository) + ctxWithDeleteRepo := NewAPITestContext(t, username, reponame, auth_model.AccessTokenScopeDeleteRepository) otherCtx := ctx otherCtx.Reponame = "ssh-key-test-repo-2" diff --git a/tests/integration/user_test.go b/tests/integration/user_test.go index 65cba1dee3e31..3e4d967686f11 100644 --- a/tests/integration/user_test.go +++ b/tests/integration/user_test.go @@ -166,7 +166,7 @@ Note: This user hasn't uploaded any GPG keys. // Import key // User1 session := loginUser(t, "user1") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteGPGKey) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser) testCreateGPGKey(t, session.MakeRequest, token, http.StatusCreated, `-----BEGIN PGP PUBLIC KEY BLOCK----- mQENBFyy/VUBCADJ7zbM20Z1RWmFoVgp5WkQfI2rU1Vj9cQHes9i42wVLLtcbPeo From 17663a4d0b473dfb2ba04b7f4ff2b0793a2568c6 Mon Sep 17 00:00:00 2001 From: jackHay22 Date: Tue, 9 May 2023 16:32:52 -0400 Subject: [PATCH 02/67] fix some tests --- routers/api/v1/api.go | 6 +++--- tests/integration/api_admin_test.go | 6 +++--- tests/integration/api_branch_test.go | 2 +- tests/integration/api_comment_attachment_test.go | 9 +++++---- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index da677a5903d4f..4a745f6054600 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -737,7 +737,7 @@ func Routes(ctx gocontext.Context) *web.Route { m.Get("", activitypub.Person) m.Post("/inbox", activitypub.ReqHTTPSignature(), activitypub.PersonInbox) }, context_service.UserIDAssignmentAPI()) - }, reqToken(auth_model.AccessTokenScopeCategoryActivityPub)) + }) // TODO reqToken(auth_model.AccessTokenScopeCategoryActivityPub) } m.Group("", func() { @@ -791,7 +791,7 @@ func Routes(ctx gocontext.Context) *web.Route { m.Get("/activities/feeds", user.ListUserActivityFeeds) }, context_service.UserAssignmentAPI()) - }, reqToken(auth_model.NoCategory)) // TODO add scope here? + }) // (no scope required) m.Group("/users", func() { @@ -809,7 +809,7 @@ func Routes(ctx gocontext.Context) *web.Route { m.Get("/subscriptions", user.GetWatchedRepos) }, context_service.UserAssignmentAPI()) - }, reqToken(auth_model.NoCategory)) // TODO add scope here? + }, reqToken(auth_model.NoCategory)) m.Group("/user", func() { m.Get("", user.GetAuthenticatedUser) diff --git a/tests/integration/api_admin_test.go b/tests/integration/api_admin_test.go index 27025c9b9988d..20a7bc896f3d0 100644 --- a/tests/integration/api_admin_test.go +++ b/tests/integration/api_admin_test.go @@ -25,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, auth_model.AccessTokenScopeWriteAdmin) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteAdmin) 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", @@ -82,7 +82,7 @@ func TestAPISudoUser(t *testing.T) { defer tests.PrepareTestEnv(t)() adminUsername := "user1" normalUsername := "user2" - token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeReadAdmin) + token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeReadUser) urlStr := fmt.Sprintf("/api/v1/user?sudo=%s&token=%s", normalUsername, token) req := NewRequest(t, "GET", urlStr) @@ -161,7 +161,7 @@ func TestAPICreateUserInvalidEmail(t *testing.T) { func TestAPICreateAndDeleteUser(t *testing.T) { defer tests.PrepareTestEnv(t)() adminUsername := "user1" - token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeWriteAdmin) + token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeDeleteAdmin) req := NewRequestWithValues( t, diff --git a/tests/integration/api_branch_test.go b/tests/integration/api_branch_test.go index 384ea77365d75..602d5f603bc53 100644 --- a/tests/integration/api_branch_test.go +++ b/tests/integration/api_branch_test.go @@ -102,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", auth_model.AccessTokenScopeWriteRepository) + ctx := NewAPITestContext(t, username, "my-noo-repo", auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) giteaURL.Path = ctx.GitPath() t.Run("CreateRepo", doAPICreateRepository(ctx, false)) diff --git a/tests/integration/api_comment_attachment_test.go b/tests/integration/api_comment_attachment_test.go index 5a14a3217621a..d268876fd9ae2 100644 --- a/tests/integration/api_comment_attachment_test.go +++ b/tests/integration/api_comment_attachment_test.go @@ -36,8 +36,8 @@ func TestAPIGetCommentAttachment(t *testing.T) { repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, repoOwner.Name) - token := getTokenForLoggedInUser(t, session) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d/assets/%d", repoOwner.Name, repo.Name, comment.ID, attachment.ID) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d/assets/%d?token=%s", repoOwner.Name, repo.Name, comment.ID, attachment.ID, token) session.MakeRequest(t, req, http.StatusOK) req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d/assets/%d?token=%s", repoOwner.Name, repo.Name, comment.ID, attachment.ID, token) resp := session.MakeRequest(t, req, http.StatusOK) @@ -61,8 +61,9 @@ func TestAPIListCommentAttachments(t *testing.T) { repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, repoOwner.Name) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d/assets", - repoOwner.Name, repo.Name, comment.ID) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d/assets?token=%s", + repoOwner.Name, repo.Name, comment.ID, token) resp := session.MakeRequest(t, req, http.StatusOK) var apiAttachments []*api.Attachment From 2b2cdc9b587a9769627ccd934ca4e2717e7c17d0 Mon Sep 17 00:00:00 2001 From: jackHay22 Date: Tue, 9 May 2023 17:09:50 -0400 Subject: [PATCH 03/67] revert token scope reorg --- routers/api/v1/api.go | 400 +++++++++++++++++++++--------------------- 1 file changed, 201 insertions(+), 199 deletions(-) diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 4a745f6054600..c096251785d3b 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -737,28 +737,24 @@ func Routes(ctx gocontext.Context) *web.Route { m.Get("", activitypub.Person) m.Post("/inbox", activitypub.ReqHTTPSignature(), activitypub.PersonInbox) }, context_service.UserIDAssignmentAPI()) - }) // TODO reqToken(auth_model.AccessTokenScopeCategoryActivityPub) + }) } - - m.Group("", func() { - m.Get("/signing-key.gpg", misc.SigningKey) - m.Post("/markup", bind(api.MarkupOption{}), misc.Markup) - m.Post("/markdown", bind(api.MarkdownOption{}), misc.Markdown) - m.Post("/markdown/raw", misc.MarkdownRaw) - m.Get("/gitignore/templates", misc.ListGitignoresTemplates) - m.Get("/gitignore/templates/{name}", misc.GetGitignoreTemplateInfo) - m.Get("/licenses", misc.ListLicenseTemplates) - m.Get("/licenses/{name}", misc.GetLicenseTemplateInfo) - m.Get("/label/templates", misc.ListLabelTemplates) - m.Get("/label/templates/{name}", misc.GetLabelTemplate) - }, reqToken(auth_model.AccessTokenScopeCategoryMisc)) - + m.Get("/signing-key.gpg", misc.SigningKey) + m.Post("/markup", bind(api.MarkupOption{}), misc.Markup) + m.Post("/markdown", bind(api.MarkdownOption{}), misc.Markdown) + m.Post("/markdown/raw", misc.MarkdownRaw) + m.Get("/gitignore/templates", misc.ListGitignoresTemplates) + m.Get("/gitignore/templates/{name}", misc.GetGitignoreTemplateInfo) + m.Get("/licenses", misc.ListLicenseTemplates) + m.Get("/licenses/{name}", misc.GetLicenseTemplateInfo) + m.Get("/label/templates", misc.ListLabelTemplates) + m.Get("/label/templates/{name}", misc.GetLabelTemplate) m.Group("/settings", func() { m.Get("/ui", settings.GetGeneralUISettings) m.Get("/api", settings.GetGeneralAPISettings) m.Get("/attachment", settings.GetGeneralAttachmentSettings) m.Get("/repository", settings.GetGeneralRepoSettings) - }) // TODO scope? (Is this misc?) + }) // Notifications (requires 'notification' scope) m.Group("/notifications", func() { @@ -769,7 +765,7 @@ func Routes(ctx gocontext.Context) *web.Route { m.Combo("/threads/{id}"). Get(notify.GetThread). Patch(notify.ReadThread) - }, reqToken(auth_model.AccessTokenScopeCategoryNotification)) + }, reqToken(auth_model.AccessTokenScopeNotification)) // Users (no scope required) m.Group("/users", func() { @@ -809,57 +805,62 @@ func Routes(ctx gocontext.Context) *web.Route { m.Get("/subscriptions", user.GetWatchedRepos) }, context_service.UserAssignmentAPI()) - }, reqToken(auth_model.NoCategory)) + }, reqToken("")) m.Group("/user", func() { m.Get("", user.GetAuthenticatedUser) m.Group("/settings", func() { - m.Get("", user.GetUserSettings) - m.Patch("", bind(api.UserSettingsOptions{}), user.UpdateUserSettings) + m.Get("", reqToken(auth_model.AccessTokenScopeReadUser), user.GetUserSettings) + m.Patch("", reqToken(auth_model.AccessTokenScopeUser), bind(api.UserSettingsOptions{}), user.UpdateUserSettings) }) - m.Combo("/emails").Get(user.ListEmails). - Post(bind(api.CreateEmailOption{}), user.AddEmail). - Delete(bind(api.DeleteEmailOption{}), user.DeleteEmail) + 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) + 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", user.GetVerificationToken) - m.Post("/gpg_key_verify", bind(api.VerifyGPGKeyOption{}), user.VerifyUserGPGKey) + 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.Combo("/repos", reqToken(auth_model.AccessTokenScopeCategoryRepository)).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() { @@ -867,61 +868,62 @@ func Routes(ctx gocontext.Context) *web.Route { m.Put("", user.Star) m.Delete("", user.Unstar) }, repoAssignment()) - }, reqToken(auth_model.AccessTokenScopeCategoryRepository)) - m.Get("/times", reqToken(auth_model.AccessTokenScopeCategoryRepository), repo.ListMyTrackedTimes) - m.Get("/stopwatches", reqToken(auth_model.AccessTokenScopeCategoryRepository), repo.GetStopwatches) - m.Get("/subscriptions", reqToken(auth_model.AccessTokenScopeCategoryRepository), user.GetMyWatchedRepos) - m.Get("/teams", reqToken(auth_model.AccessTokenScopeCategoryRepository), org.ListUserTeams) + }, 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) m.Group("/hooks", func() { m.Combo("").Get(user.ListHooks). Post(bind(api.CreateHookOption{}), user.CreateHook) m.Combo("/{id}").Get(user.GetHook). Patch(bind(api.EditHookOption{}), user.EditHook). Delete(user.DeleteHook) - }, reqWebhooksEnabled()) - }, reqToken(auth_model.AccessTokenScopeCategoryUser)) + }, reqToken(auth_model.AccessTokenScopeAdminUserHook), reqWebhooksEnabled()) + }, reqToken("")) // Repositories - m.Post("/org/{org}/repos", reqToken(auth_model.AccessTokenScopeCategoryOrganization), bind(api.CreateRepoOption{}), repo.CreateOrgRepoDeprecated) + m.Post("/org/{org}/repos", reqToken(auth_model.AccessTokenScopeAdminOrg), bind(api.CreateRepoOption{}), repo.CreateOrgRepoDeprecated) - m.Combo("/repositories/{id}", reqToken(auth_model.AccessTokenScopeCategoryRepository)).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", reqToken(auth_model.AccessTokenScopeCategoryIssue), repo.SearchIssues) + m.Get("/issues/search", repo.SearchIssues) - m.Post("/migrate", reqToken(auth_model.AccessTokenScopeCategoryRepository), 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(reqOwner(), repo.Delete). - Patch(reqAdmin(), bind(api.EditRepoOption{}), repo.Edit) - m.Post("/generate", reqRepoReader(unit.TypeCode), bind(api.GenerateRepoOption{}), repo.Generate) + 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) - }) - m.Combo("/notifications", reqToken(auth_model.AccessTokenScopeCategoryNotification)). + }, 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) }) }, 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) }) }, reqAdmin(), reqWebhooksEnabled()) m.Group("/collaborators", func() { @@ -932,25 +934,25 @@ func Routes(ctx gocontext.Context) *web.Route { Delete(reqAdmin(), repo.DeleteCollaborator) m.Get("/permission", repo.GetRepoPermissions) }) - }) - m.Get("/assignees", reqAnyRepoReader(), repo.GetAssignees) - m.Get("/reviewers", 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(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(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) @@ -960,75 +962,75 @@ func Routes(ctx gocontext.Context) *web.Route { m.Patch("", bind(api.EditBranchProtectionOption{}), repo.EditBranchProtection) m.Delete("", repo.DeleteBranchProtection) }) - }, 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) - }, reqAdmin()) + }, reqToken(auth_model.AccessTokenScopeRepo), reqAdmin()) m.Group("/times", func() { m.Combo("").Get(repo.ListTrackedTimesByRepository) m.Combo("/{timetrackingusername}").Get(repo.ListTrackedTimesByUser) - }, mustEnableIssues) + }, 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(mustNotBeArchived, bind(api.CreateIssueOption{}), repo.CreateIssue) + Post(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.CreateIssueOption{}), repo.CreateIssue) m.Get("/pinned", repo.ListPinnedIssues) m.Group("/comments", func() { m.Get("", repo.ListRepoIssueComments) m.Group("/{id}", func() { m.Combo(""). Get(repo.GetIssueComment). - Patch(mustNotBeArchived, bind(api.EditIssueCommentOption{}), repo.EditIssueComment). - Delete(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(bind(api.EditReactionOption{}), repo.PostIssueCommentReaction). - Delete(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(mustNotBeArchived, repo.CreateIssueCommentAttachment) + Post(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, repo.CreateIssueCommentAttachment) m.Combo("/{asset}"). Get(repo.GetIssueCommentAttachment). - Patch(mustNotBeArchived, bind(api.EditAttachmentOptions{}), repo.EditIssueCommentAttachment). - Delete(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(bind(api.EditIssueOption{}), repo.EditIssue). - Delete(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(mustNotBeArchived, bind(api.CreateIssueCommentOption{}), repo.CreateIssueComment) - m.Combo("/{id}").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(bind(api.IssueLabelsOption{}), repo.AddIssueLabels). - Put(bind(api.IssueLabelsOption{}), repo.ReplaceIssueLabels). - Delete(repo.ClearIssueLabels) - m.Delete("/{id}", 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(""). @@ -1036,142 +1038,142 @@ func Routes(ctx gocontext.Context) *web.Route { Post(bind(api.AddTimeOption{}), repo.AddTime). Delete(repo.ResetIssueTime) m.Delete("/{id}", repo.DeleteTime) - }) - m.Combo("/deadline").Post(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", repo.StartIssueStopwatch) - m.Post("/stop", repo.StopIssueStopwatch) - m.Delete("/delete", 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", repo.CheckIssueSubscription) - m.Put("/{user}", repo.AddIssueSubscription) - m.Delete("/{user}", 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(bind(api.EditReactionOption{}), repo.PostIssueReaction). - Delete(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(mustNotBeArchived, repo.CreateIssueAttachment) + Post(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, repo.CreateIssueAttachment) m.Combo("/{asset}"). Get(repo.GetIssueAttachment). - Patch(mustNotBeArchived, bind(api.EditAttachmentOptions{}), repo.EditIssueAttachment). - Delete(mustNotBeArchived, repo.DeleteIssueAttachment) + Patch(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.EditAttachmentOptions{}), repo.EditIssueAttachment). + Delete(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, repo.DeleteIssueAttachment) }, mustEnableAttachments) m.Combo("/dependencies"). Get(repo.GetIssueDependencies). - Post(mustNotBeArchived, bind(api.IssueMeta{}), repo.CreateIssueDependency). - Delete(mustNotBeArchived, bind(api.IssueMeta{}), repo.RemoveIssueDependency) + Post(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.IssueMeta{}), repo.CreateIssueDependency). + Delete(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.IssueMeta{}), repo.RemoveIssueDependency) m.Combo("/blocks"). Get(repo.GetIssueBlocks). - Post(bind(api.IssueMeta{}), repo.CreateIssueBlocking). - Delete(bind(api.IssueMeta{}), repo.RemoveIssueBlocking) + Post(reqToken(auth_model.AccessTokenScopeRepo), bind(api.IssueMeta{}), repo.CreateIssueBlocking). + Delete(reqToken(auth_model.AccessTokenScopeRepo), bind(api.IssueMeta{}), repo.RemoveIssueBlocking) m.Group("/pin", func() { m.Combo(""). - Post(reqAdmin(), repo.PinIssue). - Delete(reqAdmin(), repo.UnpinIssue) - m.Patch("/{position}", reqAdmin(), repo.MoveIssuePin) + Post(reqToken(auth_model.AccessTokenScopeRepo), reqAdmin(), repo.PinIssue). + Delete(reqToken(auth_model.AccessTokenScopeRepo), reqAdmin(), repo.UnpinIssue) + m.Patch("/{position}", reqToken(auth_model.AccessTokenScopeRepo), reqAdmin(), repo.MoveIssuePin) }) }) }, mustEnableIssuesOrPulls) m.Group("/labels", func() { m.Combo("").Get(repo.ListLabels). - Post(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(reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), bind(api.EditLabelOption{}), repo.EditLabel). - Delete(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("/markup", bind(api.MarkupOption{}), misc.Markup) - m.Post("/markdown", bind(api.MarkdownOption{}), misc.Markdown) - m.Post("/markdown/raw", misc.MarkdownRaw) + m.Post("/markup", reqToken(auth_model.AccessTokenScopeRepo), bind(api.MarkupOption{}), misc.Markup) + 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(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(reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), bind(api.EditMilestoneOption{}), repo.EditMilestone). - Delete(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("", user.Watch) - m.Delete("", 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(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.Combo("/latest").Get(repo.GetLatestRelease) m.Group("/{id}", func() { m.Combo("").Get(repo.GetRelease). - Patch(reqRepoWriter(unit.TypeReleases), context.ReferencesGitRepo(), bind(api.EditReleaseOption{}), repo.EditRelease). - Delete(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(reqRepoWriter(unit.TypeReleases), repo.CreateReleaseAttachment) + Post(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeReleases), repo.CreateReleaseAttachment) m.Combo("/{asset}").Get(repo.GetReleaseAttachment). - Patch(reqRepoWriter(unit.TypeReleases), bind(api.EditAttachmentOptions{}), repo.EditReleaseAttachment). - Delete(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(reqRepoWriter(unit.TypeReleases), repo.DeleteReleaseByTag) + Delete(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeReleases), repo.DeleteReleaseByTag) }) }, reqRepoReader(unit.TypeReleases)) - m.Post("/mirror-sync", reqToken(auth_model.AccessTokenScopeCategoryRepository), reqRepoWriter(unit.TypeCode), repo.MirrorSync) - m.Post("/push_mirrors-sync", reqAdmin(), reqToken(auth_model.AccessTokenScopeCategoryRepository), 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(mustNotBeArchived, bind(api.CreatePullRequestOption{}), repo.CreatePullRequest) + Post(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.CreatePullRequestOption{}), repo.CreatePullRequest) m.Get("/pinned", repo.ListPinnedPullRequests) m.Group("/{index}", func() { m.Combo("").Get(repo.GetPullRequest). - Patch(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", 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(mustNotBeArchived, bind(forms.MergePullRequestForm{}), repo.MergePullRequest). - Delete(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(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(repo.DeletePullReview). - Post(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", bind(api.DismissPullReviewOptions{}), repo.DismissPullReview) - m.Post("/undismissals", 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"). + 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(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) @@ -1192,7 +1194,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), 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.Post("", reqToken(auth_model.AccessTokenScopeRepo), bind(api.ChangeFilesOptions{}), reqRepoBranchWriter, repo.ChangeFiles) @@ -1201,15 +1203,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(auth_model.AccessTokenScopeRepo)) }, reqRepoReader(unit.TypeCode)) m.Get("/signing-key.gpg", misc.SigningKey) m.Group("/topics", func() { m.Combo("").Get(repo.ListTopics). - Put(reqAdmin(), bind(api.RepoTopicOptions{}), repo.UpdateTopics) + Put(reqToken(auth_model.AccessTokenScopeRepo), reqAdmin(), bind(api.RepoTopicOptions{}), repo.UpdateTopics) m.Group("/{topic}", func() { - m.Combo("").Put(repo.AddTopic). - Delete(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) @@ -1219,54 +1221,54 @@ func Routes(ctx gocontext.Context) *web.Route { m.Get("/activities/feeds", repo.ListRepoActivityFeeds) m.Get("/new_pin_allowed", repo.AreNewIssuePinsAllowed) }, repoAssignment()) - }, reqToken(auth_model.AccessTokenScopeCategoryRepository)) + }) // 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) - }, context_service.UserAssignmentAPI(), context.PackageAssignmentAPI(), reqToken(auth_model.AccessTokenScopeCategoryPackage), reqPackageAccess(perm.AccessModeRead)) + m.Get("/", reqToken(auth_model.AccessTokenScopeReadPackage), packages.ListPackages) + }, context_service.UserAssignmentAPI(), context.PackageAssignmentAPI(), reqPackageAccess(perm.AccessModeRead)) // Organizations - m.Get("/user/orgs", reqToken(auth_model.AccessTokenScopeCategoryOrganization), 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", org.GetUserOrgsPermissions) - }, context_service.UserAssignmentAPI(), reqToken(auth_model.AccessTokenScopeCategoryOrganization)) // TODO does this require user or org scope? - m.Post("/orgs", reqToken(auth_model.AccessTokenScopeCategoryOrganization), bind(api.CreateOrgOption{}), org.Create) - m.Get("/orgs", reqToken(auth_model.AccessTokenScopeCategoryOrganization), org.GetAll) + 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(auth_model.AccessTokenScopeWriteOrg), bind(api.CreateOrgOption{}), org.Create) + m.Get("/orgs", org.GetAll) m.Group("/orgs/{org}", func() { m.Combo("").Get(org.Get). - Patch(reqOrgOwnership(), bind(api.EditOrgOption{}), org.Edit). - Delete(reqOrgOwnership(), org.Delete) + Patch(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgOwnership(), bind(api.EditOrgOption{}), org.Edit). + Delete(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgOwnership(), org.Delete) m.Combo("/repos").Get(user.ListOrgRepos). - Post(bind(api.CreateRepoOption{}), repo.CreateOrgRepo) + 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(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(reqOrgMembership(), org.PublicizeMember). - Delete(reqOrgMembership(), org.ConcealMember) + 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) + 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("", reqOrgOwnership(), bind(api.CreateLabelOption{}), org.CreateLabel) - m.Combo("/{id}").Get(org.GetLabel). - Patch(reqOrgOwnership(), bind(api.EditLabelOption{}), org.EditLabel). - Delete(reqOrgOwnership(), org.DeleteLabel) + 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). @@ -1274,29 +1276,29 @@ func Routes(ctx gocontext.Context) *web.Route { m.Combo("/{id}").Get(org.GetHook). Patch(bind(api.EditHookOption{}), org.EditHook). Delete(org.DeleteHook) - }, reqOrgOwnership(), reqWebhooksEnabled()) + }, reqToken(auth_model.AccessTokenScopeAdminOrgHook), reqOrgOwnership(), reqWebhooksEnabled()) m.Get("/activities/feeds", org.ListOrgActivityFeeds) - }, reqToken(auth_model.AccessTokenScopeCategoryOrganization), orgAssignment(true)) + }, 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). // TODO repo scope? - 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) }) m.Get("/activities/feeds", org.ListTeamActivityFeeds) - }, orgAssignment(false, true), reqToken(auth_model.AccessTokenScopeCategoryOrganization), reqTeamMembership()) + }, orgAssignment(false, true), reqToken(""), reqTeamMembership()) m.Group("/admin", func() { m.Group("/cron", func() { @@ -1336,11 +1338,11 @@ func Routes(ctx gocontext.Context) *web.Route { Patch(bind(api.EditHookOption{}), admin.EditHook). Delete(admin.DeleteHook) }) - }, reqToken(auth_model.AccessTokenScopeCategoryAdmin), reqSiteAdmin()) + }, reqToken(auth_model.AccessTokenScopeSudo), reqSiteAdmin()) m.Group("/topics", func() { m.Get("/search", repo.TopicSearch) - }) // TODO scope? + }) }, sudo()) return m From 8c0e8dcd623dfb58179bf0ef8fe8bd6a613cb4e5 Mon Sep 17 00:00:00 2001 From: jackHay22 Date: Tue, 9 May 2023 17:40:29 -0400 Subject: [PATCH 04/67] split out the token scope check --- routers/api/v1/api.go | 61 ++++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index c096251785d3b..b3b350ab33dbc 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -237,14 +237,10 @@ func reqPackageAccess(accessMode perm.AccessMode) func(ctx *context.APIContext) } } -// Contexter middleware already checks token for user sign in process. -func reqToken(requiredScopeCategory auth_model.AccessTokenScopeCategory) func(ctx *context.APIContext) { +// if a token is being used for auth, we check that it contains the required scope +// if a token is not being used, reqToken will enforce other sign in methods +func tokenRequiresScope(requiredScopeCategory auth_model.AccessTokenScopeCategory) func(ctx *context.APIContext) { return func(ctx *context.APIContext) { - // If actions token is present - if true == ctx.Data["IsActionsToken"] { - return - } - // If OAuth2 token is present if _, ok := ctx.Data["ApiTokenScope"]; ctx.Data["IsApiToken"] == true && ok { // no scope required @@ -269,25 +265,25 @@ func reqToken(requiredScopeCategory auth_model.AccessTokenScopeCategory) func(ct // check if scope only applies to public resources publicOnly, err := scope.PublicOnly() if err != nil { - ctx.Error(http.StatusForbidden, "reqToken", "parsing public resource scope failed: "+err.Error()) + ctx.Error(http.StatusForbidden, "tokenRequiresScope", "parsing public resource scope failed: "+err.Error()) return } if publicOnly && (requiredScopeCategory == auth_model.AccessTokenScopeCategoryRepository) && ctx.Repo.Repository != nil && ctx.Repo.Repository.IsPrivate { - ctx.Error(http.StatusForbidden, "reqToken", "token scope is limited to public repos: "+requiredScope) + ctx.Error(http.StatusForbidden, "tokenRequiresScope", "token scope is limited to public repos: "+requiredScope) return } if publicOnly && (requiredScopeCategory == auth_model.AccessTokenScopeCategoryOrganization) && ctx.Org.Organization != nil && ctx.Org.Organization.Visibility != structs.VisibleTypePublic { - ctx.Error(http.StatusForbidden, "reqToken", "token scope is limited to public orgs: "+requiredScope) + ctx.Error(http.StatusForbidden, "tokenRequiresScope", "token scope is limited to public orgs: "+requiredScope) return } allow, err := scope.HasScope(requiredScope) if err != nil { - ctx.Error(http.StatusForbidden, "reqToken", "checking scope failed: "+err.Error()) + ctx.Error(http.StatusForbidden, "tokenRequiresScope", "checking scope failed: "+err.Error()) return } @@ -295,9 +291,25 @@ func reqToken(requiredScopeCategory auth_model.AccessTokenScopeCategory) func(ct return } - ctx.Error(http.StatusForbidden, "reqToken", "token does not have required scope: "+requiredScope) + ctx.Error(http.StatusForbidden, "tokenRequiresScope", "token does not have required scope: "+requiredScope) return } + } +} + +// Contexter middleware already checks token for user sign in process. +func reqToken() func(ctx *context.APIContext) { + return func(ctx *context.APIContext) { + // If actions token is present + if true == ctx.Data["IsActionsToken"] { + return + } + + if true == ctx.Data["IsApiToken"] { + // token scope checked at by top-level groups + return + } + if ctx.IsBasicAuth { ctx.CheckForOTP() return @@ -765,7 +777,7 @@ func Routes(ctx gocontext.Context) *web.Route { m.Combo("/threads/{id}"). Get(notify.GetThread). Patch(notify.ReadThread) - }, reqToken(auth_model.AccessTokenScopeNotification)) + }, reqToken(auth_model.AccessTokenScopeCategoryNotification)) // Users (no scope required) m.Group("/users", func() { @@ -805,26 +817,27 @@ func Routes(ctx gocontext.Context) *web.Route { m.Get("/subscriptions", user.GetWatchedRepos) }, context_service.UserAssignmentAPI()) - }, reqToken("")) + }, reqToken(auth_model.NoCategory)) m.Group("/user", func() { m.Get("", user.GetAuthenticatedUser) m.Group("/settings", func() { - 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("", user.GetUserSettings) + m.Patch("", bind(api.UserSettingsOptions{}), user.UpdateUserSettings) + }, reqToken(auth_model.AccessTokenScopeCategoryUser)) + m.Combo("/emails", reqToken(auth_model.AccessTokenScopeCategoryUser)). + Get(user.ListEmails). + Post(bind(api.CreateEmailOption{}), user.AddEmail). + Delete(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("", 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()) + m.Put("", user.Follow) + m.Delete("", user.Unfollow) + }, reqToken(auth_model.AccessTokenScopeCategoryUser), context_service.UserAssignmentAPI()) }) // (admin:public_key scope) @@ -833,7 +846,7 @@ func Routes(ctx gocontext.Context) *web.Route { 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) - }) + }, reqToken(auth_model.AccessTokenScopeCategoryUser)) // (admin:application scope) m.Group("/applications", func() { From 0fc8dd1fedc18911c633c12e9cb427f76bc4e454 Mon Sep 17 00:00:00 2001 From: jackHay22 Date: Tue, 16 May 2023 11:48:46 -0400 Subject: [PATCH 05/67] add migration, fix integration tests, updates to scopes --- models/auth/token_scope.go | 33 +- models/migrations/v1_20/v259.go | 143 ++++++ modules/context/permission.go | 4 +- routers/api/v1/api.go | 467 +++++++++--------- tests/integration/api_gpg_keys_test.go | 6 +- tests/integration/api_httpsig_test.go | 5 +- .../integration/api_issue_attachment_test.go | 4 +- tests/integration/api_issue_label_test.go | 4 +- tests/integration/api_issue_milestone_test.go | 2 +- tests/integration/api_issue_reaction_test.go | 2 +- tests/integration/api_issue_stopwatch_test.go | 2 +- tests/integration/api_issue_test.go | 6 +- tests/integration/api_notification_test.go | 2 +- tests/integration/api_oauth2_apps_test.go | 2 +- tests/integration/api_pull_review_test.go | 4 +- .../integration/api_repo_collaborator_test.go | 2 +- .../integration/api_repo_file_create_test.go | 6 +- .../api_repo_get_contents_list_test.go | 5 +- .../integration/api_repo_get_contents_test.go | 5 +- tests/integration/api_repo_git_blobs_test.go | 3 +- .../integration/api_repo_git_commits_test.go | 17 +- tests/integration/api_repo_git_hook_test.go | 2 +- tests/integration/api_repo_git_notes_test.go | 3 +- tests/integration/api_repo_git_ref_test.go | 3 +- tests/integration/api_repo_git_tags_test.go | 2 +- tests/integration/api_repo_git_trees_test.go | 3 +- tests/integration/api_repo_lfs_test.go | 2 +- tests/integration/api_repo_test.go | 16 +- tests/integration/api_user_follow_test.go | 4 +- tests/integration/api_user_heatmap_test.go | 3 +- tests/integration/api_user_info_test.go | 3 +- tests/integration/api_user_org_perm_test.go | 6 +- tests/integration/api_user_orgs_test.go | 4 +- tests/integration/api_user_search_test.go | 5 +- tests/integration/api_user_star_test.go | 4 +- tests/integration/api_user_watch_test.go | 4 +- tests/integration/dump_restore_test.go | 2 +- tests/integration/eventsource_test.go | 2 +- tests/integration/git_test.go | 6 +- tests/integration/migrate_test.go | 2 +- tests/integration/privateactivity_test.go | 2 +- tests/integration/repo_commits_test.go | 2 +- tests/integration/ssh_key_test.go | 8 +- 43 files changed, 499 insertions(+), 313 deletions(-) create mode 100644 models/migrations/v1_20/v259.go diff --git a/models/auth/token_scope.go b/models/auth/token_scope.go index 1cb9633277105..01bc677e3d77b 100644 --- a/models/auth/token_scope.go +++ b/models/auth/token_scope.go @@ -14,8 +14,7 @@ import ( type AccessTokenScopeCategory int const ( - NoCategory AccessTokenScopeCategory = iota - AccessTokenScopeCategoryActivityPub + AccessTokenScopeCategoryActivityPub = iota AccessTokenScopeCategoryAdmin AccessTokenScopeCategoryMisc AccessTokenScopeCategoryNotification @@ -220,9 +219,23 @@ var accessTokenScopes = map[AccessTokenScopeLevel]map[AccessTokenScopeCategory]A }, } -// GetRequiredScope gets the specific scope for a given level and category -func GetRequiredScope(level AccessTokenScopeLevel, scopeCategory AccessTokenScopeCategory) AccessTokenScope { - return accessTokenScopes[level][scopeCategory] +// GetRequiredScopes gets the specific scopes for a given level and categories +func GetRequiredScopes(level AccessTokenScopeLevel, scopeCategories ...AccessTokenScopeCategory) []AccessTokenScope { + scopes := make([]AccessTokenScope, 0) + for _, cat := range scopeCategories { + scopes = append(scopes, accessTokenScopes[level][cat]) + } + return scopes +} + +// ContainsCategory checks if a list of categories contains a specific category +func ContainsCategory(categories []AccessTokenScopeCategory, category AccessTokenScopeCategory) bool { + for _, c := range categories { + if c == category { + return true + } + } + return false } // GetScopeLevelFromAccessMode converts permission access mode to scope level @@ -307,13 +320,19 @@ func (s AccessTokenScope) PublicOnly() (bool, error) { } // HasScope returns true if the string has the given scope -func (s AccessTokenScope) HasScope(scope AccessTokenScope) (bool, error) { +func (s AccessTokenScope) HasScope(scopes ...AccessTokenScope) (bool, error) { bitmap, err := s.parse() if err != nil { return false, err } - return bitmap.hasScope(scope) + for _, s := range scopes { + if has, err := bitmap.hasScope(s); !has || err != nil { + return has, err + } + } + + return true, nil } // hasScope returns true if the string has the given scope diff --git a/models/migrations/v1_20/v259.go b/models/migrations/v1_20/v259.go new file mode 100644 index 0000000000000..ad3c4daa8c849 --- /dev/null +++ b/models/migrations/v1_20/v259.go @@ -0,0 +1,143 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_20 // nolint + +import ( + "fmt" + "strings" + + "xorm.io/xorm" + + auth_model "code.gitea.io/gitea/models/auth" +) + +// OldAccessTokenScope represents the scope for an access token. +type OldAccessTokenScope string + +const ( + OldAccessTokenScopeAll OldAccessTokenScope = "all" + + OldAccessTokenScopeRepo OldAccessTokenScope = "repo" + OldAccessTokenScopeRepoStatus OldAccessTokenScope = "repo:status" + OldAccessTokenScopePublicRepo OldAccessTokenScope = "public_repo" + + OldAccessTokenScopeAdminOrg OldAccessTokenScope = "admin:org" + OldAccessTokenScopeWriteOrg OldAccessTokenScope = "write:org" + OldAccessTokenScopeReadOrg OldAccessTokenScope = "read:org" + + OldAccessTokenScopeAdminPublicKey OldAccessTokenScope = "admin:public_key" + OldAccessTokenScopeWritePublicKey OldAccessTokenScope = "write:public_key" + OldAccessTokenScopeReadPublicKey OldAccessTokenScope = "read:public_key" + + OldAccessTokenScopeAdminRepoHook OldAccessTokenScope = "admin:repo_hook" + OldAccessTokenScopeWriteRepoHook OldAccessTokenScope = "write:repo_hook" + OldAccessTokenScopeReadRepoHook OldAccessTokenScope = "read:repo_hook" + + OldAccessTokenScopeAdminOrgHook OldAccessTokenScope = "admin:org_hook" + + OldAccessTokenScopeNotification OldAccessTokenScope = "notification" + + OldAccessTokenScopeUser OldAccessTokenScope = "user" + OldAccessTokenScopeReadUser OldAccessTokenScope = "read:user" + OldAccessTokenScopeUserEmail OldAccessTokenScope = "user:email" + OldAccessTokenScopeUserFollow OldAccessTokenScope = "user:follow" + + OldAccessTokenScopeDeleteRepo OldAccessTokenScope = "delete_repo" + + OldAccessTokenScopePackage OldAccessTokenScope = "package" + OldAccessTokenScopeWritePackage OldAccessTokenScope = "write:package" + OldAccessTokenScopeReadPackage OldAccessTokenScope = "read:package" + OldAccessTokenScopeDeletePackage OldAccessTokenScope = "delete:package" + + OldAccessTokenScopeAdminGPGKey OldAccessTokenScope = "admin:gpg_key" + OldAccessTokenScopeWriteGPGKey OldAccessTokenScope = "write:gpg_key" + OldAccessTokenScopeReadGPGKey OldAccessTokenScope = "read:gpg_key" + + OldAccessTokenScopeAdminApplication OldAccessTokenScope = "admin:application" + OldAccessTokenScopeWriteApplication OldAccessTokenScope = "write:application" + OldAccessTokenScopeReadApplication OldAccessTokenScope = "read:application" + + OldAccessTokenScopeSudo OldAccessTokenScope = "sudo" +) + +var accessTokenScopeMap = map[OldAccessTokenScope][]auth_model.AccessTokenScope{ + OldAccessTokenScopeAll: {auth_model.AccessTokenScopeAll}, + OldAccessTokenScopeRepo: {auth_model.AccessTokenScopeDeleteRepository}, + OldAccessTokenScopeRepoStatus: {auth_model.AccessTokenScopeWriteRepository}, + OldAccessTokenScopePublicRepo: {auth_model.AccessTokenScopeDeleteRepository, auth_model.AccessTokenScopePublicOnly}, + OldAccessTokenScopeAdminOrg: {auth_model.AccessTokenScopeDeleteOrganization}, + OldAccessTokenScopeWriteOrg: {auth_model.AccessTokenScopeWriteOrganization}, + OldAccessTokenScopeReadOrg: {auth_model.AccessTokenScopeReadOrganization}, + OldAccessTokenScopeAdminPublicKey: {auth_model.AccessTokenScopeDeleteUser}, + OldAccessTokenScopeWritePublicKey: {auth_model.AccessTokenScopeWriteUser}, + OldAccessTokenScopeReadPublicKey: {auth_model.AccessTokenScopeReadUser}, + OldAccessTokenScopeAdminRepoHook: {auth_model.AccessTokenScopeDeleteRepository}, + OldAccessTokenScopeWriteRepoHook: {auth_model.AccessTokenScopeWriteRepository}, + OldAccessTokenScopeReadRepoHook: {auth_model.AccessTokenScopeReadRepository}, + OldAccessTokenScopeAdminOrgHook: {auth_model.AccessTokenScopeWriteOrganization}, + OldAccessTokenScopeNotification: {auth_model.AccessTokenScopeDeleteNotification}, + OldAccessTokenScopeUser: {auth_model.AccessTokenScopeDeleteUser}, + OldAccessTokenScopeReadUser: {auth_model.AccessTokenScopeReadUser}, + OldAccessTokenScopeUserEmail: {auth_model.AccessTokenScopeWriteUser}, + OldAccessTokenScopeUserFollow: {auth_model.AccessTokenScopeWriteUser}, + OldAccessTokenScopeDeleteRepo: {auth_model.AccessTokenScopeDeleteRepository}, + OldAccessTokenScopePackage: {auth_model.AccessTokenScopeDeletePackage}, + OldAccessTokenScopeWritePackage: {auth_model.AccessTokenScopeWritePackage}, + OldAccessTokenScopeReadPackage: {auth_model.AccessTokenScopeReadPackage}, + OldAccessTokenScopeDeletePackage: {auth_model.AccessTokenScopeDeletePackage}, + OldAccessTokenScopeAdminGPGKey: {auth_model.AccessTokenScopeDeleteUser}, + OldAccessTokenScopeWriteGPGKey: {auth_model.AccessTokenScopeWriteUser}, + OldAccessTokenScopeReadGPGKey: {auth_model.AccessTokenScopeReadUser}, + OldAccessTokenScopeAdminApplication: {auth_model.AccessTokenScopeDeleteUser}, + OldAccessTokenScopeWriteApplication: {auth_model.AccessTokenScopeWriteUser}, + OldAccessTokenScopeReadApplication: {auth_model.AccessTokenScopeReadUser}, + OldAccessTokenScopeSudo: {auth_model.AccessTokenScopeDeleteAdmin}, +} + +type AccessToken struct { + ID int64 `xorm:"pk autoincr"` + Scope string +} + +func ConvertScopedAccessTokens(x *xorm.Engine) error { + var tokens []*AccessToken + + if err := x.Find(&tokens); err != nil { + return err + } + + for _, token := range tokens { + allNewScopesMap := make(map[auth_model.AccessTokenScope]bool) + for _, oldScope := range strings.Split(token.Scope, ",") { + if newScopes, exists := accessTokenScopeMap[OldAccessTokenScope(oldScope)]; exists { + for _, newScope := range newScopes { + allNewScopesMap[newScope] = true + } + } else { + return fmt.Errorf("old access token scope %s does not exist", oldScope) + } + } + + scopes := make([]string, 0, len(allNewScopesMap)) + for s := range allNewScopesMap { + scopes = append(scopes, string(s)) + } + scope := auth_model.AccessTokenScope(strings.Join(scopes, ",")) + + // normalize the scope + normScope, err := scope.Normalize() + if err != nil { + return err + } + + token.Scope = string(normScope) + + // update the db entry with the new scope + if _, err = x.Cols("scope").Update(token); err != nil { + return err + } + } + + return nil +} diff --git a/modules/context/permission.go b/modules/context/permission.go index bc687db616353..0f72b8e244d4c 100644 --- a/modules/context/permission.go +++ b/modules/context/permission.go @@ -121,7 +121,7 @@ func CheckRepoScopedToken(ctx *Context, repo *repo_model.Repository, level auth_ if ok { // it's a personal access token but not oauth2 token var scopeMatched bool - requiredScope := auth_model.GetRequiredScope(level, auth_model.AccessTokenScopeCategoryRepository) + requiredScopes := auth_model.GetRequiredScopes(level, auth_model.AccessTokenScopeCategoryRepository) // check if scope only applies to public resources publicOnly, err := scope.PublicOnly() @@ -135,7 +135,7 @@ func CheckRepoScopedToken(ctx *Context, repo *repo_model.Repository, level auth_ return } - scopeMatched, err = scope.HasScope(requiredScope) + scopeMatched, err = scope.HasScope(requiredScopes...) if err != nil { ctx.ServerError("HasScope", err) return diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index b3b350ab33dbc..e42ea6ce183ac 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -239,12 +239,12 @@ func reqPackageAccess(accessMode perm.AccessMode) func(ctx *context.APIContext) // if a token is being used for auth, we check that it contains the required scope // if a token is not being used, reqToken will enforce other sign in methods -func tokenRequiresScope(requiredScopeCategory auth_model.AccessTokenScopeCategory) func(ctx *context.APIContext) { +func tokenRequiresScopes(requiredScopeCategories ...auth_model.AccessTokenScopeCategory) func(ctx *context.APIContext) { return func(ctx *context.APIContext) { // If OAuth2 token is present if _, ok := ctx.Data["ApiTokenScope"]; ctx.Data["IsApiToken"] == true && ok { // no scope required - if requiredScopeCategory == auth_model.NoCategory { + if len(requiredScopeCategories) == 0 { return } @@ -260,7 +260,7 @@ func tokenRequiresScope(requiredScopeCategory auth_model.AccessTokenScopeCategor } // get the required scope for the given access level and category - requiredScope := auth_model.GetRequiredScope(requiredScopeLevel, requiredScopeCategory) + requiredScopes := auth_model.GetRequiredScopes(requiredScopeLevel, requiredScopeCategories...) // check if scope only applies to public resources publicOnly, err := scope.PublicOnly() @@ -269,19 +269,19 @@ func tokenRequiresScope(requiredScopeCategory auth_model.AccessTokenScopeCategor return } - if publicOnly && (requiredScopeCategory == auth_model.AccessTokenScopeCategoryRepository) && + if publicOnly && auth_model.ContainsCategory(requiredScopeCategories, auth_model.AccessTokenScopeCategoryRepository) && ctx.Repo.Repository != nil && ctx.Repo.Repository.IsPrivate { - ctx.Error(http.StatusForbidden, "tokenRequiresScope", "token scope is limited to public repos: "+requiredScope) + ctx.Error(http.StatusForbidden, "tokenRequiresScope", "token scope is limited to public repos: "+scope) return } - if publicOnly && (requiredScopeCategory == auth_model.AccessTokenScopeCategoryOrganization) && + if publicOnly && auth_model.ContainsCategory(requiredScopeCategories, auth_model.AccessTokenScopeCategoryOrganization) && ctx.Org.Organization != nil && ctx.Org.Organization.Visibility != structs.VisibleTypePublic { - ctx.Error(http.StatusForbidden, "tokenRequiresScope", "token scope is limited to public orgs: "+requiredScope) + ctx.Error(http.StatusForbidden, "tokenRequiresScope", "token scope is limited to public orgs: "+scope) return } - allow, err := scope.HasScope(requiredScope) + allow, err := scope.HasScope(requiredScopes...) if err != nil { ctx.Error(http.StatusForbidden, "tokenRequiresScope", "checking scope failed: "+err.Error()) return @@ -291,7 +291,7 @@ func tokenRequiresScope(requiredScopeCategory auth_model.AccessTokenScopeCategor return } - ctx.Error(http.StatusForbidden, "tokenRequiresScope", "token does not have required scope: "+requiredScope) + ctx.Error(http.StatusForbidden, "tokenRequiresScope", fmt.Sprintf("token does not have at least one of required scope(s): %v", requiredScopes)) return } } @@ -306,7 +306,7 @@ func reqToken() func(ctx *context.APIContext) { } if true == ctx.Data["IsApiToken"] { - // token scope checked at by top-level groups + // token scope checked at top level return } @@ -736,50 +736,56 @@ func Routes(ctx gocontext.Context) *web.Route { ctx.Redirect(setting.AppSubURL + "/api/swagger") }) } - m.Get("/version", misc.Version) + if setting.Federation.Enabled { m.Get("/nodeinfo", misc.NodeInfo) m.Group("/activitypub", func() { // deprecated, remove in 1.20, use /user-id/{user-id} instead m.Group("/user/{username}", func() { m.Get("", activitypub.Person) - m.Post("/inbox", activitypub.ReqHTTPSignature(), activitypub.PersonInbox) + m.Post("/inbox", activitypub.ReqHTTPSignature(), activitypub.PersonInbox) // TODO reqToken()? }, context_service.UserAssignmentAPI()) m.Group("/user-id/{user-id}", func() { m.Get("", activitypub.Person) - m.Post("/inbox", activitypub.ReqHTTPSignature(), activitypub.PersonInbox) + m.Post("/inbox", activitypub.ReqHTTPSignature(), activitypub.PersonInbox) // TODO reqToken()? }, context_service.UserIDAssignmentAPI()) - }) + }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryActivityPub)) } - m.Get("/signing-key.gpg", misc.SigningKey) - m.Post("/markup", bind(api.MarkupOption{}), misc.Markup) - m.Post("/markdown", bind(api.MarkdownOption{}), misc.Markdown) - m.Post("/markdown/raw", misc.MarkdownRaw) - m.Get("/gitignore/templates", misc.ListGitignoresTemplates) - m.Get("/gitignore/templates/{name}", misc.GetGitignoreTemplateInfo) - m.Get("/licenses", misc.ListLicenseTemplates) - m.Get("/licenses/{name}", misc.GetLicenseTemplateInfo) - m.Get("/label/templates", misc.ListLabelTemplates) - m.Get("/label/templates/{name}", misc.GetLabelTemplate) - m.Group("/settings", func() { - m.Get("/ui", settings.GetGeneralUISettings) - m.Get("/api", settings.GetGeneralAPISettings) - m.Get("/attachment", settings.GetGeneralAttachmentSettings) - m.Get("/repository", settings.GetGeneralRepoSettings) - }) - // Notifications (requires 'notification' scope) + // Misc (requires 'misc' scope) + m.Group("", func() { + m.Get("/version", misc.Version) + m.Get("/signing-key.gpg", misc.SigningKey) + m.Post("/markup", reqToken(), bind(api.MarkupOption{}), misc.Markup) + m.Post("/markdown", reqToken(), bind(api.MarkdownOption{}), misc.Markdown) + m.Post("/markdown/raw", reqToken(), misc.MarkdownRaw) + m.Get("/gitignore/templates", misc.ListGitignoresTemplates) + m.Get("/gitignore/templates/{name}", misc.GetGitignoreTemplateInfo) + m.Get("/licenses", misc.ListLicenseTemplates) + m.Get("/licenses/{name}", misc.GetLicenseTemplateInfo) + m.Get("/label/templates", misc.ListLabelTemplates) + m.Get("/label/templates/{name}", misc.GetLabelTemplate) + + m.Group("/settings", func() { + m.Get("/ui", settings.GetGeneralUISettings) + m.Get("/api", settings.GetGeneralAPISettings) + m.Get("/attachment", settings.GetGeneralAttachmentSettings) + m.Get("/repository", settings.GetGeneralRepoSettings) + }) + }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryMisc)) + + // Notifications (requires 'notifications' scope) m.Group("/notifications", func() { m.Combo(""). Get(notify.ListNotifications). - Put(notify.ReadNotifications) + Put(notify.ReadNotifications, reqToken()) m.Get("/new", notify.NewAvailable) m.Combo("/threads/{id}"). Get(notify.GetThread). - Patch(notify.ReadThread) - }, reqToken(auth_model.AccessTokenScopeCategoryNotification)) + Patch(notify.ReadThread, reqToken()) + }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryNotification)) - // Users (no scope required) + // Users (requires user scope) m.Group("/users", func() { m.Get("/search", reqExploreSignIn(), user.Search) @@ -790,18 +796,18 @@ func Routes(ctx gocontext.Context) *web.Route { m.Get("/heatmap", user.GetUserHeatmapData) } - m.Get("/repos", reqExploreSignIn(), user.ListUserRepos) + m.Get("/repos", tokenRequiresScopes(auth_model.AccessTokenScopeCategoryRepository), reqExploreSignIn(), user.ListUserRepos) m.Group("/tokens", func() { m.Combo("").Get(user.ListAccessTokens). - Post(bind(api.CreateAccessTokenOption{}), user.CreateAccessToken) - m.Combo("/{id}").Delete(user.DeleteAccessToken) + Post(bind(api.CreateAccessTokenOption{}), reqToken(), user.CreateAccessToken) + m.Combo("/{id}").Delete(reqToken(), user.DeleteAccessToken) }, reqBasicAuth()) m.Get("/activities/feeds", user.ListUserActivityFeeds) }, context_service.UserAssignmentAPI()) - }) + }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser)) - // (no scope required) + // Users (requires user scope) m.Group("/users", func() { m.Group("/{username}", func() { m.Get("/keys", user.ListPublicKeys) @@ -817,17 +823,18 @@ func Routes(ctx gocontext.Context) *web.Route { m.Get("/subscriptions", user.GetWatchedRepos) }, context_service.UserAssignmentAPI()) - }, reqToken(auth_model.NoCategory)) + }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser), reqToken()) + // Users (requires user scope) m.Group("/user", func() { m.Get("", user.GetAuthenticatedUser) m.Group("/settings", func() { m.Get("", user.GetUserSettings) m.Patch("", bind(api.UserSettingsOptions{}), user.UpdateUserSettings) - }, reqToken(auth_model.AccessTokenScopeCategoryUser)) - m.Combo("/emails", reqToken(auth_model.AccessTokenScopeCategoryUser)). + }, reqToken()) + m.Combo("/emails"). Get(user.ListEmails). - Post(bind(api.CreateEmailOption{}), user.AddEmail). + Post(bind(api.CreateEmailOption{}), user.AddEmail). // TODO reqToken? Delete(bind(api.DeleteEmailOption{}), user.DeleteEmail) m.Get("/followers", user.ListMyFollowers) @@ -835,42 +842,42 @@ func Routes(ctx gocontext.Context) *web.Route { m.Get("", user.ListMyFollowing) m.Group("/{username}", func() { m.Get("", user.CheckMyFollowing) - m.Put("", user.Follow) + m.Put("", user.Follow) // TODO reqToken()? m.Delete("", user.Unfollow) - }, reqToken(auth_model.AccessTokenScopeCategoryUser), context_service.UserAssignmentAPI()) + }, context_service.UserAssignmentAPI()) }) // (admin:public_key scope) m.Group("/keys", func() { - 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) - }, reqToken(auth_model.AccessTokenScopeCategoryUser)) + m.Combo("").Get(user.ListMyPublicKeys). + Post(bind(api.CreateKeyOption{}), user.CreatePublicKey) + m.Combo("/{id}").Get(user.GetPublicKey). + Delete(user.DeletePublicKey) + }) // (admin:application scope) m.Group("/applications", func() { m.Combo("/oauth2"). - Get(reqToken(auth_model.AccessTokenScopeReadApplication), user.ListOauth2Applications). - Post(reqToken(auth_model.AccessTokenScopeWriteApplication), bind(api.CreateOAuth2ApplicationOptions{}), user.CreateOauth2Application) + Get(user.ListOauth2Applications). + Post(bind(api.CreateOAuth2ApplicationOptions{}), user.CreateOauth2Application) // TODO reqToken()? m.Combo("/oauth2/{id}"). - Delete(reqToken(auth_model.AccessTokenScopeWriteApplication), user.DeleteOauth2Application). - Patch(reqToken(auth_model.AccessTokenScopeWriteApplication), bind(api.CreateOAuth2ApplicationOptions{}), user.UpdateOauth2Application). - Get(reqToken(auth_model.AccessTokenScopeReadApplication), user.GetOauth2Application) + Delete(user.DeleteOauth2Application). // TODO reqToken()? + Patch(bind(api.CreateOAuth2ApplicationOptions{}), user.UpdateOauth2Application). // TODO reqToken()? + Get(user.GetOauth2Application) }) // (admin:gpg_key scope) m.Group("/gpg_keys", func() { - 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.Combo("").Get(user.ListMyGPGKeys). + Post(bind(api.CreateGPGKeyOption{}), user.CreateGPGKey) + m.Combo("/{id}").Get(user.GetGPGKey). + Delete(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) // (repo scope) - m.Combo("/repos", reqToken(auth_model.AccessTokenScopeRepo)).Get(user.ListMyRepos). + m.Combo("/repos", tokenRequiresScopes(auth_model.AccessTokenScopeCategoryRepository)).Get(user.ListMyRepos). Post(bind(api.CreateRepoOption{}), repo.Create) // (repo scope) @@ -881,64 +888,70 @@ func Routes(ctx gocontext.Context) *web.Route { m.Put("", user.Star) m.Delete("", user.Unstar) }, repoAssignment()) - }, 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) + }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryRepository)) + m.Get("/times", repo.ListMyTrackedTimes) + m.Get("/stopwatches", repo.GetStopwatches) + m.Get("/subscriptions", user.GetMyWatchedRepos) + m.Get("/teams", org.ListUserTeams) m.Group("/hooks", func() { m.Combo("").Get(user.ListHooks). Post(bind(api.CreateHookOption{}), user.CreateHook) m.Combo("/{id}").Get(user.GetHook). Patch(bind(api.EditHookOption{}), user.EditHook). Delete(user.DeleteHook) - }, reqToken(auth_model.AccessTokenScopeAdminUserHook), reqWebhooksEnabled()) - }, reqToken("")) + }, reqWebhooksEnabled()) + }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser), reqToken()) - // Repositories - m.Post("/org/{org}/repos", reqToken(auth_model.AccessTokenScopeAdminOrg), bind(api.CreateRepoOption{}), repo.CreateOrgRepoDeprecated) + // Repositories (requires repo scope, org scope) + m.Post("/org/{org}/repos", + tokenRequiresScopes(auth_model.AccessTokenScopeCategoryOrganization, auth_model.AccessTokenScopeCategoryRepository), + reqToken(), + bind(api.CreateRepoOption{}), + repo.CreateOrgRepoDeprecated) - m.Combo("/repositories/{id}", reqToken(auth_model.AccessTokenScopeRepo)).Get(repo.GetByID) + // requires repo scope + m.Combo("/repositories/{id}", reqToken(), tokenRequiresScopes(auth_model.AccessTokenScopeCategoryRepository)).Get(repo.GetByID) + // Repos (requires repo scope) m.Group("/repos", func() { m.Get("/search", repo.Search) m.Get("/issues/search", repo.SearchIssues) // (repo scope) - m.Post("/migrate", reqToken(auth_model.AccessTokenScopeRepo), bind(api.MigrateRepoOptions{}), repo.Migrate) + m.Post("/migrate", reqToken(), bind(api.MigrateRepoOptions{}), repo.Migrate) m.Group("/{username}/{reponame}", func() { m.Combo("").Get(reqAnyRepoReader(), repo.Get). - 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) + 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.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)). + }, reqToken()) + m.Combo("/notifications", reqToken()). Get(notify.ListRepoNotifications). Put(notify.ReadRepoNotifications) m.Group("/hooks/git", func() { - m.Combo("").Get(reqToken(auth_model.AccessTokenScopeReadRepoHook), repo.ListGitHooks) + m.Combo("").Get(repo.ListGitHooks) m.Group("/{id}", func() { - 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) + m.Combo("").Get(repo.GetGitHook). + Patch(bind(api.EditGitHookOption{}), repo.EditGitHook). + Delete(repo.DeleteGitHook) }) - }, reqAdmin(), reqGitHook(), context.ReferencesGitRepo(true)) + }, reqToken(), reqAdmin(), reqGitHook(), context.ReferencesGitRepo(true)) m.Group("/hooks", func() { - m.Combo("").Get(reqToken(auth_model.AccessTokenScopeReadRepoHook), repo.ListHooks). - Post(reqToken(auth_model.AccessTokenScopeWriteRepoHook), bind(api.CreateHookOption{}), repo.CreateHook) + m.Combo("").Get(repo.ListHooks). + Post(bind(api.CreateHookOption{}), repo.CreateHook) m.Group("/{id}", func() { - 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) + m.Combo("").Get(repo.GetHook). + Patch(bind(api.EditHookOption{}), repo.EditHook). + Delete(repo.DeleteHook) + m.Post("/tests", context.ReferencesGitRepo(), context.RepoRefForAPI, repo.TestHook) }) - }, reqAdmin(), reqWebhooksEnabled()) + }, reqToken(), reqAdmin(), reqWebhooksEnabled()) m.Group("/collaborators", func() { m.Get("", reqAnyRepoReader(), repo.ListCollaborators) m.Group("/{collaborator}", func() { @@ -947,25 +960,25 @@ func Routes(ctx gocontext.Context) *web.Route { Delete(reqAdmin(), repo.DeleteCollaborator) m.Get("/permission", repo.GetRepoPermissions) }) - }, reqToken(auth_model.AccessTokenScopeRepo)) - m.Get("/assignees", reqToken(auth_model.AccessTokenScopeRepo), reqAnyRepoReader(), repo.GetAssignees) - m.Get("/reviewers", reqToken(auth_model.AccessTokenScopeRepo), reqAnyRepoReader(), repo.GetReviewers) + }, reqToken()) + m.Get("/assignees", reqToken(), reqAnyRepoReader(), repo.GetAssignees) + m.Get("/reviewers", reqToken(), 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(auth_model.AccessTokenScopeRepo)) - m.Get("/raw/*", context.ReferencesGitRepo(), context.RepoRefForAPI, reqRepoReader(unit.TypeCode), repo.GetRawFile) + }, reqToken()) + m.Get("/raw/*", context.ReferencesGitRepo(), context.RepoRefForAPI, reqRepoReader(unit.TypeCode), repo.GetRawFile) // TODO should these require a token? 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(auth_model.AccessTokenScopeRepo), reqRepoReader(unit.TypeCode), bind(api.CreateForkOption{}), repo.CreateFork) + Post(reqToken(), reqRepoReader(unit.TypeCode), bind(api.CreateForkOption{}), repo.CreateFork) m.Group("/branches", func() { m.Get("", repo.ListBranches) m.Get("/*", repo.GetBranch) - 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) + m.Delete("/*", reqToken(), reqRepoWriter(unit.TypeCode), repo.DeleteBranch) // TODO reqToken()? + m.Post("", reqToken(), reqRepoWriter(unit.TypeCode), bind(api.CreateBranchRepoOption{}), repo.CreateBranch) }, context.ReferencesGitRepo(), reqRepoReader(unit.TypeCode)) m.Group("/branch_protections", func() { m.Get("", repo.ListBranchProtections) @@ -975,75 +988,75 @@ func Routes(ctx gocontext.Context) *web.Route { m.Patch("", bind(api.EditBranchProtectionOption{}), repo.EditBranchProtection) m.Delete("", repo.DeleteBranchProtection) }) - }, reqToken(auth_model.AccessTokenScopeRepo), reqAdmin()) + }, reqToken(), reqAdmin()) m.Group("/tags", func() { m.Get("", repo.ListTags) m.Get("/*", repo.GetTag) - 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.Post("", reqToken(), reqRepoWriter(unit.TypeCode), bind(api.CreateTagOption{}), repo.CreateTag) + m.Delete("/*", reqToken(), repo.DeleteTag) + }, reqRepoReader(unit.TypeCode), context.ReferencesGitRepo(true)) // TODO reqToken()? 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(auth_model.AccessTokenScopeRepo), reqAdmin()) + }, reqToken(), reqAdmin()) m.Group("/times", func() { m.Combo("").Get(repo.ListTrackedTimesByRepository) m.Combo("/{timetrackingusername}").Get(repo.ListTrackedTimesByUser) - }, mustEnableIssues, reqToken(auth_model.AccessTokenScopeRepo)) + }, mustEnableIssues, reqToken()) m.Group("/wiki", func() { m.Combo("/page/{pageName}"). Get(repo.GetWikiPage). - 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) + Patch(mustNotBeArchived, reqToken(), reqRepoWriter(unit.TypeWiki), bind(api.CreateWikiPageOptions{}), repo.EditWikiPage). + Delete(mustNotBeArchived, reqToken(), reqRepoWriter(unit.TypeWiki), repo.DeleteWikiPage) m.Get("/revisions/{pageName}", repo.ListPageRevisions) - m.Post("/new", mustNotBeArchived, reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeWiki), bind(api.CreateWikiPageOptions{}), repo.NewWikiPage) + m.Post("/new", reqToken(), mustNotBeArchived, reqRepoWriter(unit.TypeWiki), bind(api.CreateWikiPageOptions{}), repo.NewWikiPage) m.Get("/pages", repo.ListWikiPages) - }, mustEnableWiki) + }, mustEnableWiki) // TODO reqToken()? m.Group("/issues", func() { m.Combo("").Get(repo.ListIssues). - Post(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.CreateIssueOption{}), repo.CreateIssue) + Post(reqToken(), mustNotBeArchived, bind(api.CreateIssueOption{}), repo.CreateIssue) m.Get("/pinned", repo.ListPinnedIssues) m.Group("/comments", func() { m.Get("", repo.ListRepoIssueComments) m.Group("/{id}", func() { m.Combo(""). Get(repo.GetIssueComment). - Patch(mustNotBeArchived, reqToken(auth_model.AccessTokenScopeRepo), bind(api.EditIssueCommentOption{}), repo.EditIssueComment). - Delete(reqToken(auth_model.AccessTokenScopeRepo), repo.DeleteIssueComment) + Patch(mustNotBeArchived, reqToken(), bind(api.EditIssueCommentOption{}), repo.EditIssueComment). + Delete(reqToken(), repo.DeleteIssueComment) m.Combo("/reactions"). Get(repo.GetIssueCommentReactions). - Post(reqToken(auth_model.AccessTokenScopeRepo), bind(api.EditReactionOption{}), repo.PostIssueCommentReaction). - Delete(reqToken(auth_model.AccessTokenScopeRepo), bind(api.EditReactionOption{}), repo.DeleteIssueCommentReaction) + Post(reqToken(), bind(api.EditReactionOption{}), repo.PostIssueCommentReaction). + Delete(reqToken(), bind(api.EditReactionOption{}), repo.DeleteIssueCommentReaction) m.Group("/assets", func() { m.Combo(""). Get(repo.ListIssueCommentAttachments). - Post(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, repo.CreateIssueCommentAttachment) + Post(reqToken(), mustNotBeArchived, repo.CreateIssueCommentAttachment) m.Combo("/{asset}"). Get(repo.GetIssueCommentAttachment). - Patch(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.EditAttachmentOptions{}), repo.EditIssueCommentAttachment). - Delete(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, repo.DeleteIssueCommentAttachment) + Patch(reqToken(), mustNotBeArchived, bind(api.EditAttachmentOptions{}), repo.EditIssueCommentAttachment). + Delete(reqToken(), mustNotBeArchived, repo.DeleteIssueCommentAttachment) }, mustEnableAttachments) }) }) m.Group("/{index}", func() { m.Combo("").Get(repo.GetIssue). - Patch(reqToken(auth_model.AccessTokenScopeRepo), bind(api.EditIssueOption{}), repo.EditIssue). - Delete(reqToken(auth_model.AccessTokenScopeRepo), reqAdmin(), context.ReferencesGitRepo(), repo.DeleteIssue) + Patch(reqToken(), bind(api.EditIssueOption{}), repo.EditIssue). + Delete(reqToken(), reqAdmin(), context.ReferencesGitRepo(), repo.DeleteIssue) m.Group("/comments", func() { m.Combo("").Get(repo.ListIssueComments). - Post(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.CreateIssueCommentOption{}), repo.CreateIssueComment) - m.Combo("/{id}", reqToken(auth_model.AccessTokenScopeRepo)).Patch(bind(api.EditIssueCommentOption{}), repo.EditIssueCommentDeprecated). + Post(reqToken(), mustNotBeArchived, bind(api.CreateIssueCommentOption{}), repo.CreateIssueComment) + m.Combo("/{id}", reqToken()).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(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) + Post(reqToken(), bind(api.IssueLabelsOption{}), repo.AddIssueLabels). + Put(reqToken(), bind(api.IssueLabelsOption{}), repo.ReplaceIssueLabels). + Delete(reqToken(), repo.ClearIssueLabels) + m.Delete("/{id}", reqToken(), repo.DeleteIssueLabel) }) m.Group("/times", func() { m.Combo(""). @@ -1051,142 +1064,142 @@ func Routes(ctx gocontext.Context) *web.Route { Post(bind(api.AddTimeOption{}), repo.AddTime). Delete(repo.ResetIssueTime) m.Delete("/{id}", repo.DeleteTime) - }, reqToken(auth_model.AccessTokenScopeRepo)) - m.Combo("/deadline").Post(reqToken(auth_model.AccessTokenScopeRepo), bind(api.EditDeadlineOption{}), repo.UpdateIssueDeadline) + }, reqToken()) + m.Combo("/deadline").Post(reqToken(), bind(api.EditDeadlineOption{}), repo.UpdateIssueDeadline) m.Group("/stopwatch", func() { - 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.Post("/start", repo.StartIssueStopwatch) + m.Post("/stop", repo.StopIssueStopwatch) + m.Delete("/delete", repo.DeleteIssueStopwatch) + }, reqToken()) m.Group("/subscriptions", func() { m.Get("", repo.GetIssueSubscribers) - 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.Get("/check", reqToken(), repo.CheckIssueSubscription) + m.Put("/{user}", reqToken(), repo.AddIssueSubscription) + m.Delete("/{user}", reqToken(), repo.DelIssueSubscription) }) m.Combo("/reactions"). Get(repo.GetIssueReactions). - Post(reqToken(auth_model.AccessTokenScopeRepo), bind(api.EditReactionOption{}), repo.PostIssueReaction). - Delete(reqToken(auth_model.AccessTokenScopeRepo), bind(api.EditReactionOption{}), repo.DeleteIssueReaction) + Post(reqToken(), bind(api.EditReactionOption{}), repo.PostIssueReaction). + Delete(reqToken(), bind(api.EditReactionOption{}), repo.DeleteIssueReaction) m.Group("/assets", func() { m.Combo(""). Get(repo.ListIssueAttachments). - Post(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, repo.CreateIssueAttachment) + Post(reqToken(), mustNotBeArchived, repo.CreateIssueAttachment) m.Combo("/{asset}"). Get(repo.GetIssueAttachment). - Patch(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.EditAttachmentOptions{}), repo.EditIssueAttachment). - Delete(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, repo.DeleteIssueAttachment) + Patch(reqToken(), mustNotBeArchived, bind(api.EditAttachmentOptions{}), repo.EditIssueAttachment). + Delete(reqToken(), mustNotBeArchived, repo.DeleteIssueAttachment) }, mustEnableAttachments) m.Combo("/dependencies"). Get(repo.GetIssueDependencies). - Post(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.IssueMeta{}), repo.CreateIssueDependency). - Delete(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.IssueMeta{}), repo.RemoveIssueDependency) + Post(reqToken(), mustNotBeArchived, bind(api.IssueMeta{}), repo.CreateIssueDependency). + Delete(reqToken(), mustNotBeArchived, bind(api.IssueMeta{}), repo.RemoveIssueDependency) m.Combo("/blocks"). Get(repo.GetIssueBlocks). - Post(reqToken(auth_model.AccessTokenScopeRepo), bind(api.IssueMeta{}), repo.CreateIssueBlocking). - Delete(reqToken(auth_model.AccessTokenScopeRepo), bind(api.IssueMeta{}), repo.RemoveIssueBlocking) + Post(reqToken(), bind(api.IssueMeta{}), repo.CreateIssueBlocking). + Delete(reqToken(), bind(api.IssueMeta{}), repo.RemoveIssueBlocking) m.Group("/pin", func() { m.Combo(""). - Post(reqToken(auth_model.AccessTokenScopeRepo), reqAdmin(), repo.PinIssue). - Delete(reqToken(auth_model.AccessTokenScopeRepo), reqAdmin(), repo.UnpinIssue) - m.Patch("/{position}", reqToken(auth_model.AccessTokenScopeRepo), reqAdmin(), repo.MoveIssuePin) + Post(reqToken(), reqAdmin(), repo.PinIssue). + Delete(reqToken(), reqAdmin(), repo.UnpinIssue) + m.Patch("/{position}", reqToken(), reqAdmin(), repo.MoveIssuePin) }) }) }, mustEnableIssuesOrPulls) m.Group("/labels", func() { m.Combo("").Get(repo.ListLabels). - Post(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), bind(api.CreateLabelOption{}), repo.CreateLabel) + Post(reqToken(), reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), bind(api.CreateLabelOption{}), repo.CreateLabel) m.Combo("/{id}").Get(repo.GetLabel). - 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) + Patch(reqToken(), reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), bind(api.EditLabelOption{}), repo.EditLabel). + Delete(reqToken(), reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), repo.DeleteLabel) }) - m.Post("/markup", reqToken(auth_model.AccessTokenScopeRepo), bind(api.MarkupOption{}), misc.Markup) - m.Post("/markdown", reqToken(auth_model.AccessTokenScopeRepo), bind(api.MarkdownOption{}), misc.Markdown) - m.Post("/markdown/raw", reqToken(auth_model.AccessTokenScopeRepo), misc.MarkdownRaw) + m.Post("/markup", reqToken(), bind(api.MarkupOption{}), misc.Markup) + m.Post("/markdown", reqToken(), bind(api.MarkdownOption{}), misc.Markdown) + m.Post("/markdown/raw", reqToken(), misc.MarkdownRaw) m.Group("/milestones", func() { m.Combo("").Get(repo.ListMilestones). - Post(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), bind(api.CreateMilestoneOption{}), repo.CreateMilestone) + Post(reqToken(), reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), bind(api.CreateMilestoneOption{}), repo.CreateMilestone) m.Combo("/{id}").Get(repo.GetMilestone). - 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) + Patch(reqToken(), reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), bind(api.EditMilestoneOption{}), repo.EditMilestone). + Delete(reqToken(), 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(auth_model.AccessTokenScopeRepo), user.Watch) - m.Delete("", reqToken(auth_model.AccessTokenScopeRepo), user.Unwatch) + m.Put("", reqToken(), user.Watch) + m.Delete("", reqToken(), user.Unwatch) }) m.Group("/releases", func() { m.Combo("").Get(repo.ListReleases). - Post(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeReleases), context.ReferencesGitRepo(), bind(api.CreateReleaseOption{}), repo.CreateRelease) + Post(reqToken(), reqRepoWriter(unit.TypeReleases), context.ReferencesGitRepo(), bind(api.CreateReleaseOption{}), repo.CreateRelease) m.Combo("/latest").Get(repo.GetLatestRelease) m.Group("/{id}", func() { m.Combo("").Get(repo.GetRelease). - 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) + Patch(reqToken(), reqRepoWriter(unit.TypeReleases), context.ReferencesGitRepo(), bind(api.EditReleaseOption{}), repo.EditRelease). + Delete(reqToken(), reqRepoWriter(unit.TypeReleases), repo.DeleteRelease) m.Group("/assets", func() { m.Combo("").Get(repo.ListReleaseAttachments). - Post(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeReleases), repo.CreateReleaseAttachment) + Post(reqToken(), reqRepoWriter(unit.TypeReleases), repo.CreateReleaseAttachment) m.Combo("/{asset}").Get(repo.GetReleaseAttachment). - Patch(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeReleases), bind(api.EditAttachmentOptions{}), repo.EditReleaseAttachment). - Delete(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeReleases), repo.DeleteReleaseAttachment) + Patch(reqToken(), reqRepoWriter(unit.TypeReleases), bind(api.EditAttachmentOptions{}), repo.EditReleaseAttachment). + Delete(reqToken(), reqRepoWriter(unit.TypeReleases), repo.DeleteReleaseAttachment) }) }) m.Group("/tags", func() { m.Combo("/{tag}"). Get(repo.GetReleaseByTag). - Delete(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeReleases), repo.DeleteReleaseByTag) + Delete(reqToken(), reqRepoWriter(unit.TypeReleases), repo.DeleteReleaseByTag) }) }, reqRepoReader(unit.TypeReleases)) - 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.Post("/mirror-sync", reqToken(), reqRepoWriter(unit.TypeCode), repo.MirrorSync) + m.Post("/push_mirrors-sync", reqAdmin(), reqToken(), 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(), reqToken(auth_model.AccessTokenScopeRepo)) + }, reqAdmin(), reqToken()) m.Get("/editorconfig/{filename}", context.ReferencesGitRepo(), context.RepoRefForAPI, reqRepoReader(unit.TypeCode), repo.GetEditorconfig) m.Group("/pulls", func() { m.Combo("").Get(repo.ListPullRequests). - Post(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.CreatePullRequestOption{}), repo.CreatePullRequest) + Post(reqToken(), mustNotBeArchived, bind(api.CreatePullRequestOption{}), repo.CreatePullRequest) m.Get("/pinned", repo.ListPinnedPullRequests) m.Group("/{index}", func() { m.Combo("").Get(repo.GetPullRequest). - Patch(reqToken(auth_model.AccessTokenScopeRepo), bind(api.EditPullRequestOption{}), repo.EditPullRequest) + Patch(reqToken(), bind(api.EditPullRequestOption{}), repo.EditPullRequest) m.Get(".{diffType:diff|patch}", repo.DownloadPullDiffOrPatch) - m.Post("/update", reqToken(auth_model.AccessTokenScopeRepo), repo.UpdatePullRequest) + m.Post("/update", reqToken(), repo.UpdatePullRequest) m.Get("/commits", repo.GetPullRequestCommits) m.Get("/files", repo.GetPullRequestFiles) m.Combo("/merge").Get(repo.IsPullRequestMerged). - Post(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(forms.MergePullRequestForm{}), repo.MergePullRequest). - Delete(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, repo.CancelScheduledAutoMerge) + Post(reqToken(), mustNotBeArchived, bind(forms.MergePullRequestForm{}), repo.MergePullRequest). + Delete(reqToken(), mustNotBeArchived, repo.CancelScheduledAutoMerge) m.Group("/reviews", func() { m.Combo(""). Get(repo.ListPullReviews). - Post(reqToken(auth_model.AccessTokenScopeRepo), bind(api.CreatePullReviewOptions{}), repo.CreatePullReview) + Post(reqToken(), bind(api.CreatePullReviewOptions{}), repo.CreatePullReview) m.Group("/{id}", func() { m.Combo(""). Get(repo.GetPullReview). - Delete(reqToken(auth_model.AccessTokenScopeRepo), repo.DeletePullReview). - Post(reqToken(auth_model.AccessTokenScopeRepo), bind(api.SubmitPullReviewOptions{}), repo.SubmitPullReview) + Delete(reqToken(), repo.DeletePullReview). + Post(reqToken(), bind(api.SubmitPullReviewOptions{}), repo.SubmitPullReview) m.Combo("/comments"). Get(repo.GetPullReviewComments) - m.Post("/dismissals", reqToken(auth_model.AccessTokenScopeRepo), bind(api.DismissPullReviewOptions{}), repo.DismissPullReview) - m.Post("/undismissals", reqToken(auth_model.AccessTokenScopeRepo), repo.UnDismissPullReview) + m.Post("/dismissals", reqToken(), bind(api.DismissPullReviewOptions{}), repo.DismissPullReview) + m.Post("/undismissals", reqToken(), repo.UnDismissPullReview) }) }) - m.Combo("/requested_reviewers", reqToken(auth_model.AccessTokenScopeRepo)). + m.Combo("/requested_reviewers", reqToken()). 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(auth_model.AccessTokenScopeRepoStatus), reqRepoWriter(unit.TypeCode), bind(api.CreateStatusOption{}), repo.NewCommitStatus) + Post(reqToken(), reqRepoWriter(unit.TypeCode), bind(api.CreateStatusOption{}), repo.NewCommitStatus) }, reqRepoReader(unit.TypeCode)) m.Group("/commits", func() { m.Get("", context.ReferencesGitRepo(), repo.GetAllCommits) @@ -1207,7 +1220,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(auth_model.AccessTokenScopeRepo), bind(api.ApplyDiffPatchFileOptions{}), repo.ApplyDiffPatch) + m.Post("/diffpatch", reqRepoWriter(unit.TypeCode), reqToken(), bind(api.ApplyDiffPatchFileOptions{}), repo.ApplyDiffPatch) m.Group("/contents", func() { m.Get("", repo.GetContentsList) m.Post("", reqToken(auth_model.AccessTokenScopeRepo), bind(api.ChangeFilesOptions{}), reqRepoBranchWriter, repo.ChangeFiles) @@ -1216,15 +1229,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(auth_model.AccessTokenScopeRepo)) + }, reqToken()) }, reqRepoReader(unit.TypeCode)) m.Get("/signing-key.gpg", misc.SigningKey) m.Group("/topics", func() { m.Combo("").Get(repo.ListTopics). - Put(reqToken(auth_model.AccessTokenScopeRepo), reqAdmin(), bind(api.RepoTopicOptions{}), repo.UpdateTopics) + Put(reqToken(), reqAdmin(), bind(api.RepoTopicOptions{}), repo.UpdateTopics) m.Group("/{topic}", func() { - m.Combo("").Put(reqToken(auth_model.AccessTokenScopeRepo), repo.AddTopic). - Delete(reqToken(auth_model.AccessTokenScopeRepo), repo.DeleteTopic) + m.Combo("").Put(reqToken(), repo.AddTopic). + Delete(reqToken(), repo.DeleteTopic) }, reqAdmin()) }, reqAnyRepoReader()) m.Get("/issue_templates", context.ReferencesGitRepo(), repo.GetIssueTemplates) @@ -1234,54 +1247,54 @@ func Routes(ctx gocontext.Context) *web.Route { m.Get("/activities/feeds", repo.ListRepoActivityFeeds) m.Get("/new_pin_allowed", repo.AreNewIssuePinsAllowed) }, repoAssignment()) - }) + }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryRepository)) // 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("", 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("", reqToken(), packages.GetPackage) + m.Delete("", reqToken(), reqPackageAccess(perm.AccessModeWrite), packages.DeletePackage) + m.Get("/files", reqToken(), packages.ListPackageFiles) }) - m.Get("/", reqToken(auth_model.AccessTokenScopeReadPackage), packages.ListPackages) - }, context_service.UserAssignmentAPI(), context.PackageAssignmentAPI(), reqPackageAccess(perm.AccessModeRead)) + m.Get("/", reqToken(), packages.ListPackages) + }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryPackage), context_service.UserAssignmentAPI(), context.PackageAssignmentAPI(), reqPackageAccess(perm.AccessModeRead)) // Organizations - m.Get("/user/orgs", reqToken(auth_model.AccessTokenScopeReadOrg), org.ListMyOrgs) + m.Get("/user/orgs", reqToken(), tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser, auth_model.AccessTokenScopeCategoryOrganization), org.ListMyOrgs) m.Group("/users/{username}/orgs", func() { - 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(auth_model.AccessTokenScopeWriteOrg), bind(api.CreateOrgOption{}), org.Create) - m.Get("/orgs", org.GetAll) + m.Get("", reqToken(), org.ListUserOrgs) + m.Get("/{org}/permissions", reqToken(), org.GetUserOrgsPermissions) + }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser, auth_model.AccessTokenScopeCategoryOrganization), context_service.UserAssignmentAPI()) + m.Post("/orgs", tokenRequiresScopes(auth_model.AccessTokenScopeCategoryOrganization), reqToken(), bind(api.CreateOrgOption{}), org.Create) + m.Get("/orgs", org.GetAll, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryOrganization)) m.Group("/orgs/{org}", func() { m.Combo("").Get(org.Get). - Patch(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgOwnership(), bind(api.EditOrgOption{}), org.Edit). - Delete(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgOwnership(), org.Delete) + Patch(reqToken(), reqOrgOwnership(), bind(api.EditOrgOption{}), org.Edit). + Delete(reqToken(), reqOrgOwnership(), org.Delete) m.Combo("/repos").Get(user.ListOrgRepos). - Post(reqToken(auth_model.AccessTokenScopeWriteOrg), bind(api.CreateRepoOption{}), repo.CreateOrgRepo) + Post(reqToken(), bind(api.CreateRepoOption{}), repo.CreateOrgRepo) m.Group("/members", func() { - 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.Get("", reqToken(), org.ListMembers) + m.Combo("/{username}").Get(reqToken(), org.IsMember). + Delete(reqToken(), reqOrgOwnership(), org.DeleteMember) }) m.Group("/public_members", func() { m.Get("", org.ListPublicMembers) m.Combo("/{username}").Get(org.IsPublicMember). - Put(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgMembership(), org.PublicizeMember). - Delete(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgMembership(), org.ConcealMember) + Put(reqToken(), reqOrgMembership(), org.PublicizeMember). + Delete(reqToken(), reqOrgMembership(), org.ConcealMember) }) m.Group("/teams", func() { - 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) + m.Get("", reqToken(), org.ListTeams) + m.Post("", reqToken(), reqOrgOwnership(), bind(api.CreateTeamOption{}), org.CreateTeam) + m.Get("/search", reqToken(), org.SearchTeam) }, reqOrgMembership()) m.Group("/labels", func() { m.Get("", 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.Post("", reqToken(), reqOrgOwnership(), bind(api.CreateLabelOption{}), org.CreateLabel) + m.Combo("/{id}").Get(reqToken(), org.GetLabel). + Patch(reqToken(), reqOrgOwnership(), bind(api.EditLabelOption{}), org.EditLabel). + Delete(reqToken(), reqOrgOwnership(), org.DeleteLabel) }) m.Group("/hooks", func() { m.Combo("").Get(org.ListHooks). @@ -1289,29 +1302,29 @@ func Routes(ctx gocontext.Context) *web.Route { m.Combo("/{id}").Get(org.GetHook). Patch(bind(api.EditHookOption{}), org.EditHook). Delete(org.DeleteHook) - }, reqToken(auth_model.AccessTokenScopeAdminOrgHook), reqOrgOwnership(), reqWebhooksEnabled()) + }, reqToken(), reqOrgOwnership(), reqWebhooksEnabled()) m.Get("/activities/feeds", org.ListOrgActivityFeeds) - }, orgAssignment(true)) + }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryOrganization), orgAssignment(true)) m.Group("/teams/{teamid}", func() { - 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.Combo("").Get(reqToken(), org.GetTeam). + Patch(reqToken(), reqOrgOwnership(), bind(api.EditTeamOption{}), org.EditTeam). + Delete(reqToken(), reqOrgOwnership(), org.DeleteTeam) m.Group("/members", func() { - m.Get("", reqToken(auth_model.AccessTokenScopeReadOrg), org.GetTeamMembers) + m.Get("", reqToken(), org.GetTeamMembers) m.Combo("/{username}"). - Get(reqToken(auth_model.AccessTokenScopeReadOrg), org.GetTeamMember). - Put(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgOwnership(), org.AddTeamMember). - Delete(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgOwnership(), org.RemoveTeamMember) + Get(reqToken(), org.GetTeamMember). + Put(reqToken(), reqOrgOwnership(), org.AddTeamMember). + Delete(reqToken(), reqOrgOwnership(), org.RemoveTeamMember) }) m.Group("/repos", func() { - m.Get("", reqToken(auth_model.AccessTokenScopeReadOrg), org.GetTeamRepos) + m.Get("", reqToken(), org.GetTeamRepos) m.Combo("/{org}/{reponame}"). - Put(reqToken(auth_model.AccessTokenScopeWriteOrg), org.AddTeamRepository). - Delete(reqToken(auth_model.AccessTokenScopeWriteOrg), org.RemoveTeamRepository). - Get(reqToken(auth_model.AccessTokenScopeReadOrg), org.GetTeamRepo) + Put(reqToken(), org.AddTeamRepository). + Delete(reqToken(), org.RemoveTeamRepository). + Get(reqToken(), org.GetTeamRepo) }) m.Get("/activities/feeds", org.ListTeamActivityFeeds) - }, orgAssignment(false, true), reqToken(""), reqTeamMembership()) + }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryOrganization), orgAssignment(false, true), reqToken(), reqTeamMembership()) m.Group("/admin", func() { m.Group("/cron", func() { @@ -1351,11 +1364,11 @@ func Routes(ctx gocontext.Context) *web.Route { Patch(bind(api.EditHookOption{}), admin.EditHook). Delete(admin.DeleteHook) }) - }, reqToken(auth_model.AccessTokenScopeSudo), reqSiteAdmin()) + }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryAdmin), reqToken(), reqSiteAdmin()) m.Group("/topics", func() { m.Get("/search", repo.TopicSearch) - }) + }) // TODO token category }, sudo()) return m diff --git a/tests/integration/api_gpg_keys_test.go b/tests/integration/api_gpg_keys_test.go index 7ec9d8fe129d4..d3e8804460286 100644 --- a/tests/integration/api_gpg_keys_test.go +++ b/tests/integration/api_gpg_keys_test.go @@ -21,8 +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, auth_model.AccessTokenScopeReadRepository) - tokenWithGPGKeyScope := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteRepository, auth_model.AccessTokenScopeWriteRepository) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteRepository) + tokenWithGPGKeyScope := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteRepository, auth_model.AccessTokenScopeDeleteUser) tt := []struct { name string @@ -36,7 +36,7 @@ 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}, + results: []int{http.StatusForbidden, http.StatusForbidden, http.StatusForbidden, http.StatusForbidden, http.StatusForbidden, http.StatusForbidden, http.StatusForbidden, http.StatusForbidden, http.StatusForbidden}, }, { name: "LoggedAsUser2WithScope", makeRequest: session.MakeRequest, token: tokenWithGPGKeyScope, diff --git a/tests/integration/api_httpsig_test.go b/tests/integration/api_httpsig_test.go index 08fbe8eae2465..4520364527f14 100644 --- a/tests/integration/api_httpsig_test.go +++ b/tests/integration/api_httpsig_test.go @@ -53,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, auth_model.AccessTokenScopeWriteAdmin)) + token := url.QueryEscape(getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser)) 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" @@ -69,7 +69,8 @@ func TestHTTPSigPubKey(t *testing.T) { keyID := ssh.FingerprintSHA256(sshSigner.PublicKey()) // create the request - req = NewRequest(t, "GET", "/api/v1/admin/users") + token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadAdmin) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/admin/users?token=%s", token)) signer, _, err := httpsig.NewSSHSigner(sshSigner, httpsig.DigestSha512, []string{httpsig.RequestTarget, "(created)", "(expires)"}, httpsig.Signature, 10) if err != nil { diff --git a/tests/integration/api_issue_attachment_test.go b/tests/integration/api_issue_attachment_test.go index 3d728e9f4034b..2067dfab4523b 100644 --- a/tests/integration/api_issue_attachment_test.go +++ b/tests/integration/api_issue_attachment_test.go @@ -32,7 +32,7 @@ func TestAPIGetIssueAttachment(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.AccessTokenScopeReadRepository) urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/assets/%d?token=%s", repoOwner.Name, repo.Name, issue.Index, attachment.ID, token) @@ -53,7 +53,7 @@ func TestAPIListIssueAttachments(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.AccessTokenScopeReadRepository) urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/assets?token=%s", repoOwner.Name, repo.Name, issue.Index, token) diff --git a/tests/integration/api_issue_label_test.go b/tests/integration/api_issue_label_test.go index 10c7997f5e38d..9db17fb5b538d 100644 --- a/tests/integration/api_issue_label_test.go +++ b/tests/integration/api_issue_label_test.go @@ -25,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, auth_model.AccessTokenScopeWriteRepository) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteRepository) urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/labels?token=%s", owner.Name, repo.Name, token) // CreateLabel @@ -144,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, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteOrganization) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeDeleteOrganization) 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 b194f4f95c386..3ac26062f0e6a 100644 --- a/tests/integration/api_issue_milestone_test.go +++ b/tests/integration/api_issue_milestone_test.go @@ -29,7 +29,7 @@ func TestAPIIssuesMilestone(t *testing.T) { assert.Equal(t, structs.StateOpen, milestone.State()) session := loginUser(t, owner.Name) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteRepository) // 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 666bea4b4c55e..2014447ff0a80 100644 --- a/tests/integration/api_issue_reaction_test.go +++ b/tests/integration/api_issue_reaction_test.go @@ -88,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, auth_model.AccessTokenScopeWriteRepository) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteRepository) 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 d3cc16e2a9eeb..bee966a4398c3 100644 --- a/tests/integration/api_issue_stopwatch_test.go +++ b/tests/integration/api_issue_stopwatch_test.go @@ -26,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, auth_model.AccessTokenScopeReadRepository) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository, auth_model.AccessTokenScopeReadUser) req := NewRequestf(t, "GET", "/api/v1/user/stopwatches?token=%s", token) resp := MakeRequest(t, req, http.StatusOK) var apiWatches []*api.StopWatch diff --git a/tests/integration/api_issue_test.go b/tests/integration/api_issue_test.go index 566bce3a76ea4..ef1cd506f0855 100644 --- a/tests/integration/api_issue_test.go +++ b/tests/integration/api_issue_test.go @@ -171,7 +171,7 @@ func TestAPIEditIssue(t *testing.T) { func TestAPISearchIssues(t *testing.T) { defer tests.PrepareTestEnv(t)() - token := getUserToken(t, "user2") + token := getUserToken(t, "user2", auth_model.AccessTokenScopeReadRepository) // as this API was used in the frontend, it uses UI page size expectedIssueCount := 16 // from the fixtures @@ -180,7 +180,7 @@ func TestAPISearchIssues(t *testing.T) { } link, _ := url.Parse("/api/v1/repos/issues/search") - query := url.Values{"token": {getUserToken(t, "user1")}} + query := url.Values{"token": {getUserToken(t, "user1", auth_model.AccessTokenScopeReadRepository)}} var apiIssues []*api.Issue link.RawQuery = query.Encode() @@ -278,7 +278,7 @@ func TestAPISearchIssuesWithLabels(t *testing.T) { } link, _ := url.Parse("/api/v1/repos/issues/search") - query := url.Values{"token": {getUserToken(t, "user1")}} + query := url.Values{"token": {getUserToken(t, "user1", auth_model.AccessTokenScopeReadRepository)}} var apiIssues []*api.Issue link.RawQuery = query.Encode() diff --git a/tests/integration/api_notification_test.go b/tests/integration/api_notification_test.go index 3167f6adaeae1..52d6e6d84ab2a 100644 --- a/tests/integration/api_notification_test.go +++ b/tests/integration/api_notification_test.go @@ -28,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, auth_model.AccessTokenScopeWriteNotification) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteNotification, auth_model.AccessTokenScopeWriteRepository) // -- GET /notifications -- // test filter diff --git a/tests/integration/api_oauth2_apps_test.go b/tests/integration/api_oauth2_apps_test.go index 72cdba2ea2f6e..30fa289b8a089 100644 --- a/tests/integration/api_oauth2_apps_test.go +++ b/tests/integration/api_oauth2_apps_test.go @@ -86,7 +86,7 @@ func testAPIListOAuth2Applications(t *testing.T) { func testAPIDeleteOAuth2Application(t *testing.T) { user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) session := loginUser(t, user.Name) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteUser) oldApp := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ UID: user.ID, diff --git a/tests/integration/api_pull_review_test.go b/tests/integration/api_pull_review_test.go index 92059d022dab9..261f47988c0aa 100644 --- a/tests/integration/api_pull_review_test.go +++ b/tests/integration/api_pull_review_test.go @@ -28,7 +28,7 @@ func TestAPIPullReview(t *testing.T) { // test ListPullReviews session := loginUser(t, "user2") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteRepository) 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) @@ -231,7 +231,7 @@ func TestAPIPullReviewRequest(t *testing.T) { // Test add Review Request session := loginUser(t, "user2") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteRepository) 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"}, }) diff --git a/tests/integration/api_repo_collaborator_test.go b/tests/integration/api_repo_collaborator_test.go index 7a07067113f29..b7280a4f6c417 100644 --- a/tests/integration/api_repo_collaborator_test.go +++ b/tests/integration/api_repo_collaborator_test.go @@ -28,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, auth_model.AccessTokenScopeReadRepository) + testCtx := NewAPITestContext(t, repo2Owner.Name, repo2.Name, auth_model.AccessTokenScopeWriteRepository) 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) diff --git a/tests/integration/api_repo_file_create_test.go b/tests/integration/api_repo_file_create_test.go index a2829b276440c..cbc164891b820 100644 --- a/tests/integration/api_repo_file_create_test.go +++ b/tests/integration/api_repo_file_create_test.go @@ -151,10 +151,10 @@ func TestAPICreateFile(t *testing.T) { // Get user2's token session := loginUser(t, user2.Name) - token2 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) + token2 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) // Get user4's token session = loginUser(t, user4.Name) - token4 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) + token4 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) // Test creating a file in repo1 which user2 owns, try both with branch and empty branch for _, branch := range [...]string{ @@ -280,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", auth_model.AccessTokenScopeWriteRepository), true)(t) + doAPICreateRepository(NewAPITestContext(t, "user2", "empty-repo", auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser), true)(t) createFileOptions = getCreateFileOptions() fileID++ treePath = fmt.Sprintf("new/file%d.txt", fileID) diff --git a/tests/integration/api_repo_get_contents_list_test.go b/tests/integration/api_repo_get_contents_list_test.go index 2c7b44120c512..f91305abefc92 100644 --- a/tests/integration/api_repo_get_contents_list_test.go +++ b/tests/integration/api_repo_get_contents_list_test.go @@ -9,6 +9,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" @@ -64,10 +65,10 @@ func testAPIGetContentsList(t *testing.T, u *url.URL) { // Get user2's token session := loginUser(t, user2.Name) - token2 := getTokenForLoggedInUser(t, session) + token2 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) // Get user4's token session = loginUser(t, user4.Name) - token4 := getTokenForLoggedInUser(t, session) + token4 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) // Make a new branch in repo1 newBranch := "test_branch" diff --git a/tests/integration/api_repo_get_contents_test.go b/tests/integration/api_repo_get_contents_test.go index 8b193b03c93e0..be091cea4ec43 100644 --- a/tests/integration/api_repo_get_contents_test.go +++ b/tests/integration/api_repo_get_contents_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" @@ -66,10 +67,10 @@ func testAPIGetContents(t *testing.T, u *url.URL) { // Get user2's token session := loginUser(t, user2.Name) - token2 := getTokenForLoggedInUser(t, session) + token2 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) // Get user4's token session = loginUser(t, user4.Name) - token4 := getTokenForLoggedInUser(t, session) + token4 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) // Make a new branch in repo1 newBranch := "test_branch" diff --git a/tests/integration/api_repo_git_blobs_test.go b/tests/integration/api_repo_git_blobs_test.go index 02652e5934843..9a0bb6d0f284a 100644 --- a/tests/integration/api_repo_git_blobs_test.go +++ b/tests/integration/api_repo_git_blobs_test.go @@ -7,6 +7,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" @@ -31,7 +32,7 @@ func TestAPIReposGitBlobs(t *testing.T) { // Login as User2. session := loginUser(t, user2.Name) - token := getTokenForLoggedInUser(t, session) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) // Test a public repo that anyone can GET the blob of req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/git/blobs/%s", user2.Name, repo1.Name, repo1ReadmeSHA) diff --git a/tests/integration/api_repo_git_commits_test.go b/tests/integration/api_repo_git_commits_test.go index 90048a5496245..2b0224a986ded 100644 --- a/tests/integration/api_repo_git_commits_test.go +++ b/tests/integration/api_repo_git_commits_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" api "code.gitea.io/gitea/modules/structs" @@ -28,7 +29,7 @@ func TestAPIReposGitCommits(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.AccessTokenScopeReadRepository) // check invalid requests req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/commits/12345?token="+token, user.Name) @@ -56,7 +57,7 @@ func TestAPIReposGitCommitList(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.AccessTokenScopeReadRepository) // Test getting commits (Page 1) req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo20/commits?token="+token+"¬=master&sha=remove-files-a", user.Name) @@ -79,7 +80,7 @@ func TestAPIReposGitCommitListNotMaster(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.AccessTokenScopeReadRepository) // Test getting commits (Page 1) req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo16/commits?token="+token, user.Name) @@ -104,7 +105,7 @@ func TestAPIReposGitCommitListPage2Empty(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.AccessTokenScopeReadRepository) // Test getting commits (Page=2) req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo16/commits?token="+token+"&page=2", user.Name) @@ -121,7 +122,7 @@ func TestAPIReposGitCommitListDifferentBranch(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.AccessTokenScopeReadRepository) // Test getting commits (Page=1, Branch=good-sign) req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo16/commits?token="+token+"&sha=good-sign", user.Name) @@ -161,7 +162,7 @@ func TestDownloadCommitDiffOrPatch(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.AccessTokenScopeReadRepository) // Test getting diff reqDiff := NewRequestf(t, "GET", "/api/v1/repos/%s/repo16/git/commits/f27c2b2b03dcab38beaf89b0ab4ff61f6de63441.diff?token="+token, user.Name) @@ -183,7 +184,7 @@ func TestGetFileHistory(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.AccessTokenScopeReadRepository) req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo16/commits?path=readme.md&token="+token+"&sha=good-sign", user.Name) resp := MakeRequest(t, req, http.StatusOK) @@ -203,7 +204,7 @@ func TestGetFileHistoryNotOnMaster(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.AccessTokenScopeReadRepository) req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo20/commits?path=test.csv&token="+token+"&sha=add-csv¬=master", user.Name) resp := MakeRequest(t, req, http.StatusOK) diff --git a/tests/integration/api_repo_git_hook_test.go b/tests/integration/api_repo_git_hook_test.go index 50a27b27b431f..a30195645947f 100644 --- a/tests/integration/api_repo_git_hook_test.go +++ b/tests/integration/api_repo_git_hook_test.go @@ -122,7 +122,7 @@ func TestAPIEditGitHook(t *testing.T) { // user1 is an admin user session := loginUser(t, "user1") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteAdmin) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/hooks/git/pre-receive?token=%s", owner.Name, repo.Name, token) diff --git a/tests/integration/api_repo_git_notes_test.go b/tests/integration/api_repo_git_notes_test.go index 1448f405728b6..30846f235fd78 100644 --- a/tests/integration/api_repo_git_notes_test.go +++ b/tests/integration/api_repo_git_notes_test.go @@ -8,6 +8,7 @@ import ( "net/url" "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 @@ func TestAPIReposGitNotes(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.AccessTokenScopeReadRepository) // check invalid requests req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/notes/12345?token=%s", user.Name, token) diff --git a/tests/integration/api_repo_git_ref_test.go b/tests/integration/api_repo_git_ref_test.go index aac01ca9ad429..20900b3241944 100644 --- a/tests/integration/api_repo_git_ref_test.go +++ b/tests/integration/api_repo_git_ref_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" @@ -17,7 +18,7 @@ func TestAPIReposGitRefs(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.AccessTokenScopeReadRepository) for _, ref := range [...]string{ "refs/heads/master", // Branch diff --git a/tests/integration/api_repo_git_tags_test.go b/tests/integration/api_repo_git_tags_test.go index 29e0642971b6e..e263710d00c0e 100644 --- a/tests/integration/api_repo_git_tags_test.go +++ b/tests/integration/api_repo_git_tags_test.go @@ -26,7 +26,7 @@ func TestAPIGitTags(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) // Login as User2. session := loginUser(t, user.Name) - token := getTokenForLoggedInUser(t, session) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) // Set up git config for the tagger _ = git.NewCommand(git.DefaultContext, "config", "user.name").AddDynamicArguments(user.Name).Run(&git.RunOpts{Dir: repo.RepoPath()}) diff --git a/tests/integration/api_repo_git_trees_test.go b/tests/integration/api_repo_git_trees_test.go index d1d49e4627f7e..7a7ece120c931 100644 --- a/tests/integration/api_repo_git_trees_test.go +++ b/tests/integration/api_repo_git_trees_test.go @@ -7,6 +7,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" @@ -28,7 +29,7 @@ func TestAPIReposGitTrees(t *testing.T) { // Login as User2. session := loginUser(t, user2.Name) - token := getTokenForLoggedInUser(t, session) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) // Test a public repo that anyone can GET the tree of for _, ref := range [...]string{ diff --git a/tests/integration/api_repo_lfs_test.go b/tests/integration/api_repo_lfs_test.go index 0d44d2446441c..b0e9269bb86e2 100644 --- a/tests/integration/api_repo_lfs_test.go +++ b/tests/integration/api_repo_lfs_test.go @@ -60,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", auth_model.AccessTokenScopeWriteRepository) + ctx := NewAPITestContext(t, "user2", "lfs-"+name+"-repo", auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) t.Run("CreateRepo", doAPICreateRepository(ctx, false)) repo, err := repo_model.GetRepositoryByOwnerAndName(db.DefaultContext, "user2", "lfs-"+name+"-repo") diff --git a/tests/integration/api_repo_test.go b/tests/integration/api_repo_test.go index 2fb65f2451f90..0f387192eb09c 100644 --- a/tests/integration/api_repo_test.go +++ b/tests/integration/api_repo_test.go @@ -189,7 +189,7 @@ func TestAPISearchRepo(t *testing.T) { if userToLogin != nil && userToLogin.ID > 0 { testName = fmt.Sprintf("LoggedUser%d", userToLogin.ID) session := loginUser(t, userToLogin.Name) - token = getTokenForLoggedInUser(t, session) + token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) userID = userToLogin.ID } else { testName = "AnonymousUser" @@ -371,7 +371,7 @@ func TestAPIRepoMigrateConflict(t *testing.T) { func testAPIRepoMigrateConflict(t *testing.T, u *url.URL) { username := "user2" - baseAPITestContext := NewAPITestContext(t, username, "repo1", auth_model.AccessTokenScopeWriteRepository) + baseAPITestContext := NewAPITestContext(t, username, "repo1", auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) u.Path = baseAPITestContext.GitPath() @@ -438,7 +438,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, auth_model.AccessTokenScopeWriteOrganization) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization, auth_model.AccessTokenScopeWriteRepository) req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/org/%s/repos?token="+token, testCase.orgName), &api.CreateRepoOption{ Name: testCase.repoName, }) @@ -452,7 +452,7 @@ func TestAPIRepoCreateConflict(t *testing.T) { func testAPIRepoCreateConflict(t *testing.T, u *url.URL) { username := "user2" - baseAPITestContext := NewAPITestContext(t, username, "repo1", auth_model.AccessTokenScopeWriteRepository) + baseAPITestContext := NewAPITestContext(t, username, "repo1", auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) u.Path = baseAPITestContext.GitPath() @@ -502,7 +502,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, auth_model.AccessTokenScopeWriteRepository) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) repoName := "moveME" apiRepo := new(api.Repository) req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/user/repos?token=%s", token), &api.CreateRepoOption{ @@ -537,7 +537,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, auth_model.AccessTokenScopeWriteRepository) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) repoName := "moveME" apiRepo := new(api.Repository) req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/user/repos?token=%s", token), &api.CreateRepoOption{ @@ -567,7 +567,7 @@ func TestAPIAcceptTransfer(t *testing.T) { // try to accept with not authorized user session := loginUser(t, "user2") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) 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) @@ -577,7 +577,7 @@ func TestAPIAcceptTransfer(t *testing.T) { // accept transfer session = loginUser(t, "user4") - token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) + token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) 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) diff --git a/tests/integration/api_user_follow_test.go b/tests/integration/api_user_follow_test.go index 66a826d36dbc8..03c7a5a48b2cd 100644 --- a/tests/integration/api_user_follow_test.go +++ b/tests/integration/api_user_follow_test.go @@ -22,10 +22,10 @@ func TestAPIFollow(t *testing.T) { user2 := "user1" session1 := loginUser(t, user1) - token1 := getTokenForLoggedInUser(t, session1) + token1 := getTokenForLoggedInUser(t, session1, auth_model.AccessTokenScopeReadUser) session2 := loginUser(t, user2) - token2 := getTokenForLoggedInUser(t, session2, auth_model.AccessTokenScopeWriteUser) + token2 := getTokenForLoggedInUser(t, session2, auth_model.AccessTokenScopeDeleteUser) t.Run("Follow", func(t *testing.T) { defer tests.PrintCurrentTest(t)() diff --git a/tests/integration/api_user_heatmap_test.go b/tests/integration/api_user_heatmap_test.go index 432306914cd29..5a7e58a02d601 100644 --- a/tests/integration/api_user_heatmap_test.go +++ b/tests/integration/api_user_heatmap_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/modules/timeutil" "code.gitea.io/gitea/tests" @@ -20,7 +21,7 @@ func TestUserHeatmap(t *testing.T) { defer tests.PrepareTestEnv(t)() adminUsername := "user1" normalUsername := "user2" - token := getUserToken(t, adminUsername) + token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeReadUser) fakeNow := time.Date(2011, 10, 20, 0, 0, 0, 0, time.Local) timeutil.Set(fakeNow) diff --git a/tests/integration/api_user_info_test.go b/tests/integration/api_user_info_test.go index 65262792b7fa9..82cd97e904c0d 100644 --- a/tests/integration/api_user_info_test.go +++ b/tests/integration/api_user_info_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" @@ -21,7 +22,7 @@ func TestAPIUserInfo(t *testing.T) { user2 := "user31" session := loginUser(t, user) - token := getTokenForLoggedInUser(t, session) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser) t.Run("GetInfo", 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 3c3e6540f714a..40870f39ff437 100644 --- a/tests/integration/api_user_org_perm_test.go +++ b/tests/integration/api_user_org_perm_test.go @@ -33,7 +33,7 @@ func sampleTest(t *testing.T, auoptc apiUserOrgPermTestCase) { defer tests.PrepareTestEnv(t)() session := loginUser(t, auoptc.LoginUser) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrganization) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrganization, auth_model.AccessTokenScopeReadUser) 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) @@ -126,7 +126,7 @@ func TestUnknowUser(t *testing.T) { defer tests.PrepareTestEnv(t)() session := loginUser(t, "user1") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrganization) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser, auth_model.AccessTokenScopeReadOrganization) req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/unknow/orgs/org25/permissions?token=%s", token)) resp := MakeRequest(t, req, http.StatusNotFound) @@ -140,7 +140,7 @@ func TestUnknowOrganization(t *testing.T) { defer tests.PrepareTestEnv(t)() session := loginUser(t, "user1") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrganization) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser, auth_model.AccessTokenScopeReadOrganization) 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 f0a7e4f86edac..323facaf48ed9 100644 --- a/tests/integration/api_user_orgs_test.go +++ b/tests/integration/api_user_orgs_test.go @@ -70,7 +70,7 @@ func TestUserOrgs(t *testing.T) { func getUserOrgs(t *testing.T, userDoer, userCheck string) (orgs []*api.Organization) { token := "" if len(userDoer) != 0 { - token = getUserToken(t, userDoer, auth_model.AccessTokenScopeReadOrganization) + token = getUserToken(t, userDoer, auth_model.AccessTokenScopeReadOrganization, auth_model.AccessTokenScopeReadUser) } urlStr := fmt.Sprintf("/api/v1/users/%s/orgs?token=%s", userCheck, token) req := NewRequest(t, "GET", urlStr) @@ -92,7 +92,7 @@ func TestMyOrgs(t *testing.T) { MakeRequest(t, req, http.StatusUnauthorized) normalUsername := "user2" - token := getUserToken(t, normalUsername, auth_model.AccessTokenScopeReadOrganization) + token := getUserToken(t, normalUsername, auth_model.AccessTokenScopeReadOrganization, auth_model.AccessTokenScopeReadUser) 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_search_test.go b/tests/integration/api_user_search_test.go index dc11281c46f1b..be14d5a6b2965 100644 --- a/tests/integration/api_user_search_test.go +++ b/tests/integration/api_user_search_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" @@ -26,7 +27,7 @@ func TestAPIUserSearchLoggedIn(t *testing.T) { defer tests.PrepareTestEnv(t)() adminUsername := "user1" session := loginUser(t, adminUsername) - token := getTokenForLoggedInUser(t, session) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser) query := "user2" req := NewRequestf(t, "GET", "/api/v1/users/search?token=%s&q=%s", token, query) resp := MakeRequest(t, req, http.StatusOK) @@ -65,7 +66,7 @@ func TestAPIUserSearchAdminLoggedInUserHidden(t *testing.T) { defer tests.PrepareTestEnv(t)() adminUsername := "user1" session := loginUser(t, adminUsername) - token := getTokenForLoggedInUser(t, session) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser) query := "user31" req := NewRequestf(t, "GET", "/api/v1/users/search?token=%s&q=%s", token, query) req.SetBasicAuth(token, "x-oauth-basic") diff --git a/tests/integration/api_user_star_test.go b/tests/integration/api_user_star_test.go index 71be29dd49ebe..6957dfcef8a80 100644 --- a/tests/integration/api_user_star_test.go +++ b/tests/integration/api_user_star_test.go @@ -22,8 +22,8 @@ func TestAPIStar(t *testing.T) { repo := "user2/repo1" session := loginUser(t, user) - token := getTokenForLoggedInUser(t, session) - tokenWithUserScope := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteUser) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser) + tokenWithUserScope := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteUser, auth_model.AccessTokenScopeDeleteRepository) t.Run("Star", func(t *testing.T) { defer tests.PrintCurrentTest(t)() diff --git a/tests/integration/api_user_watch_test.go b/tests/integration/api_user_watch_test.go index 9a4a9ad7da8ab..dbd6626b10bde 100644 --- a/tests/integration/api_user_watch_test.go +++ b/tests/integration/api_user_watch_test.go @@ -22,8 +22,8 @@ func TestAPIWatch(t *testing.T) { repo := "user2/repo1" session := loginUser(t, user) - token := getTokenForLoggedInUser(t, session) - tokenWithRepoScope := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser) + tokenWithRepoScope := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeDeleteRepository, auth_model.AccessTokenScopeReadUser) t.Run("Watch", func(t *testing.T) { defer tests.PrintCurrentTest(t)() diff --git a/tests/integration/dump_restore_test.go b/tests/integration/dump_restore_test.go index 11d07e1f9841d..b043559a8e9de 100644 --- a/tests/integration/dump_restore_test.go +++ b/tests/integration/dump_restore_test.go @@ -51,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, auth_model.AccessTokenScopeWriteRepository) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeReadMisc) // // 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 4eb92bcbafb64..734f4a6a0a347 100644 --- a/tests/integration/eventsource_test.go +++ b/tests/integration/eventsource_test.go @@ -60,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, auth_model.AccessTokenScopeWriteNotification) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteNotification, auth_model.AccessTokenScopeWriteRepository) var apiNL []api.NotificationThread diff --git a/tests/integration/git_test.go b/tests/integration/git_test.go index e26a51487e42a..1d45df0a47841 100644 --- a/tests/integration/git_test.go +++ b/tests/integration/git_test.go @@ -44,11 +44,11 @@ func TestGit(t *testing.T) { func testGit(t *testing.T, u *url.URL) { username := "user2" - baseAPITestContext := NewAPITestContext(t, username, "repo1", auth_model.AccessTokenScopeDeleteRepository) + baseAPITestContext := NewAPITestContext(t, username, "repo1", auth_model.AccessTokenScopeDeleteRepository, auth_model.AccessTokenScopeWriteUser) u.Path = baseAPITestContext.GitPath() - forkedUserCtx := NewAPITestContext(t, "user4", "repo1", auth_model.AccessTokenScopeReadRepository) + forkedUserCtx := NewAPITestContext(t, "user4", "repo1", auth_model.AccessTokenScopeDeleteRepository, auth_model.AccessTokenScopeWriteUser) t.Run("HTTP", func(t *testing.T) { defer tests.PrintCurrentTest(t)() @@ -603,7 +603,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, auth_model.AccessTokenScopeWriteRepository) + ctx := NewAPITestContext(t, baseCtx.Username, baseCtx.Reponame, auth_model.AccessTokenScopeDeleteRepository) t.Run("CheckoutProtected", doGitCheckoutBranch(dstPath, "protected")) t.Run("PullProtected", doGitPull(dstPath, "origin", "protected")) diff --git a/tests/integration/migrate_test.go b/tests/integration/migrate_test.go index 9a6edb7d70d6d..f25329f66bcee 100644 --- a/tests/integration/migrate_test.go +++ b/tests/integration/migrate_test.go @@ -67,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, auth_model.AccessTokenScopeWriteRepository) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeReadMisc) // Step 0: verify the repo is available req := NewRequestf(t, "GET", fmt.Sprintf("/%s/%s", ownerName, repoName)) diff --git a/tests/integration/privateactivity_test.go b/tests/integration/privateactivity_test.go index 04e03ab26bcc6..5b69e433db226 100644 --- a/tests/integration/privateactivity_test.go +++ b/tests/integration/privateactivity_test.go @@ -125,7 +125,7 @@ func testPrivateActivityHelperHasHeatmapContentFromPublic(t *testing.T) bool { } func testPrivateActivityHelperHasHeatmapContentFromSession(t *testing.T, session *TestSession) bool { - token := getTokenForLoggedInUser(t, session) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser) req := NewRequestf(t, "GET", "/api/v1/users/%s/heatmap?token=%s", privateActivityTestUser, token) resp := session.MakeRequest(t, req, http.StatusOK) diff --git a/tests/integration/repo_commits_test.go b/tests/integration/repo_commits_test.go index ccd2eff5ef43d..99927f1929c5c 100644 --- a/tests/integration/repo_commits_test.go +++ b/tests/integration/repo_commits_test.go @@ -157,7 +157,7 @@ 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) { - ctx := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeReadRepository) + ctx := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeWriteRepository) runBody := doAPICreateCommitStatus(ctx, path.Base(commitURL), api.CreateStatusOption{ State: api.CommitStatusPending, TargetURL: "http://test.ci/", diff --git a/tests/integration/ssh_key_test.go b/tests/integration/ssh_key_test.go index 59db581e0e4f1..b98000bfea55e 100644 --- a/tests/integration/ssh_key_test.go +++ b/tests/integration/ssh_key_test.go @@ -48,8 +48,8 @@ func TestPushDeployKeyOnEmptyRepo(t *testing.T) { func testPushDeployKeyOnEmptyRepo(t *testing.T, u *url.URL) { // OK login - ctx := NewAPITestContext(t, "user2", "deploy-key-empty-repo-1", auth_model.AccessTokenScopeWriteRepository) - ctxWithDeleteRepo := NewAPITestContext(t, "user2", "deploy-key-empty-repo-1", auth_model.AccessTokenScopeDeleteRepository) + ctx := NewAPITestContext(t, "user2", "deploy-key-empty-repo-1", auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) + ctxWithDeleteRepo := NewAPITestContext(t, "user2", "deploy-key-empty-repo-1", auth_model.AccessTokenScopeDeleteRepository, auth_model.AccessTokenScopeWriteUser) keyname := fmt.Sprintf("%s-push", ctx.Reponame) u.Path = ctx.GitPath() @@ -92,8 +92,8 @@ func testKeyOnlyOneType(t *testing.T, u *url.URL) { keyname := fmt.Sprintf("%s-push", reponame) // OK login - ctx := NewAPITestContext(t, username, reponame, auth_model.AccessTokenScopeWriteRepository) - ctxWithDeleteRepo := NewAPITestContext(t, username, reponame, auth_model.AccessTokenScopeDeleteRepository) + ctx := NewAPITestContext(t, username, reponame, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeDeleteUser) + ctxWithDeleteRepo := NewAPITestContext(t, username, reponame, auth_model.AccessTokenScopeDeleteRepository, auth_model.AccessTokenScopeWriteUser) otherCtx := ctx otherCtx.Reponame = "ssh-key-test-repo-2" From 5bb478d7cf8d1e454b9673d062e356a2576a393a Mon Sep 17 00:00:00 2001 From: jackHay22 Date: Tue, 16 May 2023 13:00:41 -0400 Subject: [PATCH 06/67] update access token scope selection --- templates/user/settings/applications.tmpl | 222 ++---------------- .../components/ScopedAccessTokenSelector.vue | 94 ++++++++ web_src/js/index.js | 2 + 3 files changed, 112 insertions(+), 206 deletions(-) create mode 100644 web_src/js/components/ScopedAccessTokenSelector.vue diff --git a/templates/user/settings/applications.tmpl b/templates/user/settings/applications.tmpl index 1c12a0a2b7679..3222ead1c45ae 100644 --- a/templates/user/settings/applications.tmpl +++ b/templates/user/settings/applications.tmpl @@ -18,9 +18,7 @@ {{svg "fontawesome-send" 36}}
- - {{.Name}} -
{{.Name}} +
{{.Name}}

{{$.locale.Tr "settings.scopes_list"}}

    {{range .Scope.StringSlice}} @@ -47,213 +45,25 @@
- -
+
{{.locale.Tr "settings.select_scopes"}} -
+
- - -
-
-
-
-
- - -
-
-
-
- - -
-
-
-
-
- - -
-
-
-
-
- - -
-
-
-
- - -
-
-
-
-
- - -
-
-
-
-
- - -
-
-
-
- - -
-
-
-
-
- - -
-
-
-
-
- - -
-
-
-
- - -
-
-
-
-
- - -
-
-
-
- - -
-
-
-
- - -
-
-
-
- - -
-
-
-
-
- - -
-
-
-
- - -
-
-
-
- - -
-
-
-
-
- - -
-
-
-
- - -
-
-
-
-
- - -
-
-
-
- - -
-
-
-
- - -
-
-
-
-
- - -
-
-
-
-
- - -
-
-
-
- - -
-
-
-
-
- - -
-
-
-
-
- - -
-
-
-
- - -
-
-
-
-
- - -
-
+ + +
+ + + + + + + + + +