diff --git a/internal/cmd/serv.go b/internal/cmd/serv.go index c8af87649..6120b93ea 100644 --- a/internal/cmd/serv.go +++ b/internal/cmd/serv.go @@ -210,7 +210,7 @@ func runServ(c *cli.Context) error { fail("Internal error", "Failed to get user by key ID '%d': %v", key.ID, err) } - mode := database.Perms.AccessMode(ctx, user.ID, repo.ID, + mode := database.Handle.Permissions().AccessMode(ctx, user.ID, repo.ID, database.AccessModeOptions{ OwnerID: repo.OwnerID, Private: repo.IsPrivate, diff --git a/internal/context/repo.go b/internal/context/repo.go index ccbbdbe75..2123df1d6 100644 --- a/internal/context/repo.go +++ b/internal/context/repo.go @@ -171,7 +171,7 @@ func RepoAssignment(pages ...bool) macaron.Handler { if c.IsLogged && c.User.IsAdmin { c.Repo.AccessMode = database.AccessModeOwner } else { - c.Repo.AccessMode = database.Perms.AccessMode(c.Req.Context(), c.UserID(), repo.ID, + c.Repo.AccessMode = database.Handle.Permissions().AccessMode(c.Req.Context(), c.UserID(), repo.ID, database.AccessModeOptions{ OwnerID: repo.OwnerID, Private: repo.IsPrivate, @@ -182,7 +182,7 @@ func RepoAssignment(pages ...bool) macaron.Handler { // If the authenticated user has no direct access, see if the repository is a fork // and whether the user has access to the base repository. if c.Repo.AccessMode == database.AccessModeNone && repo.BaseRepo != nil { - mode := database.Perms.AccessMode(c.Req.Context(), c.UserID(), repo.BaseRepo.ID, + mode := database.Handle.Permissions().AccessMode(c.Req.Context(), c.UserID(), repo.BaseRepo.ID, database.AccessModeOptions{ OwnerID: repo.BaseRepo.OwnerID, Private: repo.BaseRepo.IsPrivate, diff --git a/internal/database/database.go b/internal/database/database.go index ea28dab1a..fc313aa7f 100644 --- a/internal/database/database.go +++ b/internal/database/database.go @@ -123,7 +123,6 @@ func NewConnection(w logger.Writer) (*gorm.DB, error) { } // Initialize stores, sorted in alphabetical order. - Perms = NewPermsStore(db) Repos = NewReposStore(db) TwoFactors = &twoFactorsStore{DB: db} Users = NewUsersStore(db) @@ -176,3 +175,7 @@ func (db *DB) Notices() *NoticesStore { func (db *DB) Organizations() *OrganizationsStore { return newOrganizationsStoreStore(db.db) } + +func (db *DB) Permissions() *PermissionsStore { + return newPermissionsStore(db.db) +} diff --git a/internal/database/mocks.go b/internal/database/mocks.go index 762788043..abc607151 100644 --- a/internal/database/mocks.go +++ b/internal/database/mocks.go @@ -8,14 +8,6 @@ import ( "testing" ) -func SetMockPermsStore(t *testing.T, mock PermsStore) { - before := Perms - Perms = mock - t.Cleanup(func() { - Perms = before - }) -} - func SetMockReposStore(t *testing.T, mock ReposStore) { before := Repos Repos = mock diff --git a/internal/database/perms.go b/internal/database/permissions.go similarity index 63% rename from internal/database/perms.go rename to internal/database/permissions.go index ec6662704..70990a1fa 100644 --- a/internal/database/perms.go +++ b/internal/database/permissions.go @@ -7,24 +7,11 @@ package database import ( "context" + "github.com/pkg/errors" "gorm.io/gorm" log "unknwon.dev/clog/v2" ) -// PermsStore is the persistent interface for permissions. -type PermsStore interface { - // AccessMode returns the access mode of given user has to the repository. - AccessMode(ctx context.Context, userID, repoID int64, opts AccessModeOptions) AccessMode - // Authorize returns true if the user has as good as desired access mode to the - // repository. - Authorize(ctx context.Context, userID, repoID int64, desired AccessMode, opts AccessModeOptions) bool - // SetRepoPerms does a full update to which users have which level of access to - // given repository. Keys of the "accessMap" are user IDs. - SetRepoPerms(ctx context.Context, repoID int64, accessMap map[int64]AccessMode) error -} - -var Perms PermsStore - // Access represents the highest access level of a user has to a repository. The // only access type that is not in this table is the real owner of a repository. // In case of an organization repository, the members of the owners team are in @@ -74,16 +61,13 @@ func ParseAccessMode(permission string) AccessMode { } } -var _ PermsStore = (*permsStore)(nil) - -type permsStore struct { - *gorm.DB +// PermissionsStore is the storage layer for repository permissions. +type PermissionsStore struct { + db *gorm.DB } -// NewPermsStore returns a persistent interface for permissions with given -// database connection. -func NewPermsStore(db *gorm.DB) PermsStore { - return &permsStore{DB: db} +func newPermissionsStore(db *gorm.DB) *PermissionsStore { + return &PermissionsStore{db: db} } type AccessModeOptions struct { @@ -91,7 +75,8 @@ type AccessModeOptions struct { Private bool // Whether the repository is private. } -func (s *permsStore) AccessMode(ctx context.Context, userID, repoID int64, opts AccessModeOptions) (mode AccessMode) { +// AccessMode returns the access mode of given user has to the repository. +func (s *PermissionsStore) AccessMode(ctx context.Context, userID, repoID int64, opts AccessModeOptions) (mode AccessMode) { if repoID <= 0 { return AccessModeNone } @@ -111,9 +96,9 @@ func (s *permsStore) AccessMode(ctx context.Context, userID, repoID int64, opts } access := new(Access) - err := s.WithContext(ctx).Where("user_id = ? AND repo_id = ?", userID, repoID).First(access).Error + err := s.db.WithContext(ctx).Where("user_id = ? AND repo_id = ?", userID, repoID).First(access).Error if err != nil { - if err != gorm.ErrRecordNotFound { + if !errors.Is(err, gorm.ErrRecordNotFound) { log.Error("Failed to get access [user_id: %d, repo_id: %d]: %v", userID, repoID, err) } return mode @@ -121,11 +106,15 @@ func (s *permsStore) AccessMode(ctx context.Context, userID, repoID int64, opts return access.Mode } -func (s *permsStore) Authorize(ctx context.Context, userID, repoID int64, desired AccessMode, opts AccessModeOptions) bool { +// Authorize returns true if the user has as good as desired access mode to the +// repository. +func (s *PermissionsStore) Authorize(ctx context.Context, userID, repoID int64, desired AccessMode, opts AccessModeOptions) bool { return desired <= s.AccessMode(ctx, userID, repoID, opts) } -func (s *permsStore) SetRepoPerms(ctx context.Context, repoID int64, accessMap map[int64]AccessMode) error { +// SetRepoPerms does a full update to which users have which level of access to +// given repository. Keys of the "accessMap" are user IDs. +func (s *PermissionsStore) SetRepoPerms(ctx context.Context, repoID int64, accessMap map[int64]AccessMode) error { records := make([]*Access, 0, len(accessMap)) for userID, mode := range accessMap { records = append(records, &Access{ @@ -135,7 +124,7 @@ func (s *permsStore) SetRepoPerms(ctx context.Context, repoID int64, accessMap m }) } - return s.WithContext(ctx).Transaction(func(tx *gorm.DB) error { + return s.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error { err := tx.Where("repo_id = ?", repoID).Delete(new(Access)).Error if err != nil { return err diff --git a/internal/database/perms_test.go b/internal/database/permissions_test.go similarity index 88% rename from internal/database/perms_test.go rename to internal/database/permissions_test.go index 9304b71f2..bb4bd2b7b 100644 --- a/internal/database/perms_test.go +++ b/internal/database/permissions_test.go @@ -19,13 +19,13 @@ func TestPerms(t *testing.T) { t.Parallel() ctx := context.Background() - db := &permsStore{ - DB: newTestDB(t, "permsStore"), + s := &PermissionsStore{ + db: newTestDB(t, "PermissionsStore"), } for _, tc := range []struct { name string - test func(t *testing.T, ctx context.Context, db *permsStore) + test func(t *testing.T, ctx context.Context, s *PermissionsStore) }{ {"AccessMode", permsAccessMode}, {"Authorize", permsAuthorize}, @@ -33,10 +33,10 @@ func TestPerms(t *testing.T) { } { t.Run(tc.name, func(t *testing.T) { t.Cleanup(func() { - err := clearTables(t, db.DB) + err := clearTables(t, s.db) require.NoError(t, err) }) - tc.test(t, ctx, db) + tc.test(t, ctx, s) }) if t.Failed() { break @@ -44,16 +44,16 @@ func TestPerms(t *testing.T) { } } -func permsAccessMode(t *testing.T, ctx context.Context, db *permsStore) { +func permsAccessMode(t *testing.T, ctx context.Context, s *PermissionsStore) { // Set up permissions - err := db.SetRepoPerms(ctx, 1, + err := s.SetRepoPerms(ctx, 1, map[int64]AccessMode{ 2: AccessModeWrite, 3: AccessModeAdmin, }, ) require.NoError(t, err) - err = db.SetRepoPerms(ctx, 2, + err = s.SetRepoPerms(ctx, 2, map[int64]AccessMode{ 1: AccessModeRead, }, @@ -149,15 +149,15 @@ func permsAccessMode(t *testing.T, ctx context.Context, db *permsStore) { } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - mode := db.AccessMode(ctx, test.userID, test.repoID, test.opts) + mode := s.AccessMode(ctx, test.userID, test.repoID, test.opts) assert.Equal(t, test.wantAccessMode, mode) }) } } -func permsAuthorize(t *testing.T, ctx context.Context, db *permsStore) { +func permsAuthorize(t *testing.T, ctx context.Context, s *PermissionsStore) { // Set up permissions - err := db.SetRepoPerms(ctx, 1, + err := s.SetRepoPerms(ctx, 1, map[int64]AccessMode{ 1: AccessModeRead, 2: AccessModeWrite, @@ -230,7 +230,7 @@ func permsAuthorize(t *testing.T, ctx context.Context, db *permsStore) { } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - authorized := db.Authorize(ctx, test.userID, repo.ID, test.desired, + authorized := s.Authorize(ctx, test.userID, repo.ID, test.desired, AccessModeOptions{ OwnerID: repo.OwnerID, Private: repo.IsPrivate, @@ -241,7 +241,7 @@ func permsAuthorize(t *testing.T, ctx context.Context, db *permsStore) { } } -func permsSetRepoPerms(t *testing.T, ctx context.Context, db *permsStore) { +func permsSetRepoPerms(t *testing.T, ctx context.Context, s *PermissionsStore) { for _, update := range []struct { repoID int64 accessMap map[int64]AccessMode @@ -280,14 +280,14 @@ func permsSetRepoPerms(t *testing.T, ctx context.Context, db *permsStore) { }, }, } { - err := db.SetRepoPerms(ctx, update.repoID, update.accessMap) + err := s.SetRepoPerms(ctx, update.repoID, update.accessMap) if err != nil { t.Fatal(err) } } var accesses []*Access - err := db.Order("user_id, repo_id").Find(&accesses).Error + err := s.db.Order("user_id, repo_id").Find(&accesses).Error require.NoError(t, err) // Ignore ID fields diff --git a/internal/database/repo.go b/internal/database/repo.go index aaf9be26a..3400d83c9 100644 --- a/internal/database/repo.go +++ b/internal/database/repo.go @@ -392,7 +392,7 @@ func (repo *Repository) APIFormatLegacy(permission *api.Permission, user ...*Use if repo.IsFork { p := &api.Permission{Pull: true} if len(user) != 0 { - accessMode := Perms.AccessMode( + accessMode := Handle.Permissions().AccessMode( context.TODO(), user[0].ID, repo.ID, @@ -530,7 +530,7 @@ func (repo *Repository) GetAssignees() (_ []*User, err error) { // GetAssigneeByID returns the user that has write access of repository by given ID. func (repo *Repository) GetAssigneeByID(userID int64) (*User, error) { ctx := context.TODO() - if !Perms.Authorize( + if !Handle.Permissions().Authorize( ctx, userID, repo.ID, @@ -592,7 +592,7 @@ func (repo *Repository) ComposeCompareURL(oldCommitID, newCommitID string) strin } func (repo *Repository) HasAccess(userID int64) bool { - return Perms.Authorize(context.TODO(), userID, repo.ID, AccessModeRead, + return Handle.Permissions().Authorize(context.TODO(), userID, repo.ID, AccessModeRead, AccessModeOptions{ OwnerID: repo.OwnerID, Private: repo.IsPrivate, diff --git a/internal/database/repo_branch.go b/internal/database/repo_branch.go index cbf00294d..817337bf9 100644 --- a/internal/database/repo_branch.go +++ b/internal/database/repo_branch.go @@ -176,7 +176,7 @@ func UpdateOrgProtectBranch(repo *Repository, protectBranch *ProtectBranch, whit userIDs := tool.StringsToInt64s(strings.Split(whitelistUserIDs, ",")) validUserIDs = make([]int64, 0, len(userIDs)) for _, userID := range userIDs { - if !Perms.Authorize(context.TODO(), userID, repo.ID, AccessModeWrite, + if !Handle.Permissions().Authorize(context.TODO(), userID, repo.ID, AccessModeWrite, AccessModeOptions{ OwnerID: repo.OwnerID, Private: repo.IsPrivate, diff --git a/internal/database/repos_test.go b/internal/database/repos_test.go index f9cba6ea9..da069460e 100644 --- a/internal/database/repos_test.go +++ b/internal/database/repos_test.go @@ -165,10 +165,10 @@ func reposGetByCollaboratorID(t *testing.T, ctx context.Context, db *reposStore) repo2, err := db.Create(ctx, 2, CreateRepoOptions{Name: "repo2"}) require.NoError(t, err) - permsStore := NewPermsStore(db.DB) - err = permsStore.SetRepoPerms(ctx, repo1.ID, map[int64]AccessMode{3: AccessModeRead}) + permissionsStore := newPermissionsStore(db.DB) + err = permissionsStore.SetRepoPerms(ctx, repo1.ID, map[int64]AccessMode{3: AccessModeRead}) require.NoError(t, err) - err = permsStore.SetRepoPerms(ctx, repo2.ID, map[int64]AccessMode{4: AccessModeAdmin}) + err = permissionsStore.SetRepoPerms(ctx, repo2.ID, map[int64]AccessMode{4: AccessModeAdmin}) require.NoError(t, err) t.Run("user 3 is a collaborator of repo1", func(t *testing.T) { @@ -193,12 +193,12 @@ func reposGetByCollaboratorIDWithAccessMode(t *testing.T, ctx context.Context, d repo3, err := db.Create(ctx, 2, CreateRepoOptions{Name: "repo3"}) require.NoError(t, err) - permsStore := NewPermsStore(db.DB) - err = permsStore.SetRepoPerms(ctx, repo1.ID, map[int64]AccessMode{3: AccessModeRead}) + permissionsStore := newPermissionsStore(db.DB) + err = permissionsStore.SetRepoPerms(ctx, repo1.ID, map[int64]AccessMode{3: AccessModeRead}) require.NoError(t, err) - err = permsStore.SetRepoPerms(ctx, repo2.ID, map[int64]AccessMode{3: AccessModeAdmin, 4: AccessModeWrite}) + err = permissionsStore.SetRepoPerms(ctx, repo2.ID, map[int64]AccessMode{3: AccessModeAdmin, 4: AccessModeWrite}) require.NoError(t, err) - err = permsStore.SetRepoPerms(ctx, repo3.ID, map[int64]AccessMode{4: AccessModeWrite}) + err = permissionsStore.SetRepoPerms(ctx, repo3.ID, map[int64]AccessMode{4: AccessModeWrite}) require.NoError(t, err) got, err := db.GetByCollaboratorIDWithAccessMode(ctx, 3) diff --git a/internal/database/ssh_key.go b/internal/database/ssh_key.go index 4b3902ab0..40f03afea 100644 --- a/internal/database/ssh_key.go +++ b/internal/database/ssh_key.go @@ -754,7 +754,7 @@ func DeleteDeployKey(doer *User, id int64) error { if err != nil { return fmt.Errorf("GetRepositoryByID: %v", err) } - if !Perms.Authorize(context.TODO(), doer.ID, repo.ID, AccessModeAdmin, + if !Handle.Permissions().Authorize(context.TODO(), doer.ID, repo.ID, AccessModeAdmin, AccessModeOptions{ OwnerID: repo.OwnerID, Private: repo.IsPrivate, diff --git a/internal/route/api/v1/api.go b/internal/route/api/v1/api.go index 5503c41ee..8c355d12a 100644 --- a/internal/route/api/v1/api.go +++ b/internal/route/api/v1/api.go @@ -57,7 +57,7 @@ func repoAssignment() macaron.Handler { if c.IsTokenAuth && c.User.IsAdmin { c.Repo.AccessMode = database.AccessModeOwner } else { - c.Repo.AccessMode = database.Perms.AccessMode(c.Req.Context(), c.UserID(), repo.ID, + c.Repo.AccessMode = database.Handle.Permissions().AccessMode(c.Req.Context(), c.UserID(), repo.ID, database.AccessModeOptions{ OwnerID: repo.OwnerID, Private: repo.IsPrivate, diff --git a/internal/route/api/v1/repo/repo.go b/internal/route/api/v1/repo/repo.go index 364d087ac..d5b1f5848 100644 --- a/internal/route/api/v1/repo/repo.go +++ b/internal/route/api/v1/repo/repo.go @@ -353,7 +353,7 @@ func ListForks(c *context.APIContext) { return } - accessMode := database.Perms.AccessMode( + accessMode := database.Handle.Permissions().AccessMode( c.Req.Context(), c.User.ID, forks[i].ID, diff --git a/internal/route/lfs/mocks_test.go b/internal/route/lfs/mocks_test.go index acf65dc5f..b028fd66d 100644 --- a/internal/route/lfs/mocks_test.go +++ b/internal/route/lfs/mocks_test.go @@ -14,413 +14,6 @@ import ( lfsutil "gogs.io/gogs/internal/lfsutil" ) -// MockPermsStore is a mock implementation of the PermsStore interface (from -// the package gogs.io/gogs/internal/database) used for unit testing. -type MockPermsStore struct { - // AccessModeFunc is an instance of a mock function object controlling - // the behavior of the method AccessMode. - AccessModeFunc *PermsStoreAccessModeFunc - // AuthorizeFunc is an instance of a mock function object controlling - // the behavior of the method Authorize. - AuthorizeFunc *PermsStoreAuthorizeFunc - // SetRepoPermsFunc is an instance of a mock function object controlling - // the behavior of the method SetRepoPerms. - SetRepoPermsFunc *PermsStoreSetRepoPermsFunc -} - -// NewMockPermsStore creates a new mock of the PermsStore interface. All -// methods return zero values for all results, unless overwritten. -func NewMockPermsStore() *MockPermsStore { - return &MockPermsStore{ - AccessModeFunc: &PermsStoreAccessModeFunc{ - defaultHook: func(context.Context, int64, int64, database.AccessModeOptions) (r0 database.AccessMode) { - return - }, - }, - AuthorizeFunc: &PermsStoreAuthorizeFunc{ - defaultHook: func(context.Context, int64, int64, database.AccessMode, database.AccessModeOptions) (r0 bool) { - return - }, - }, - SetRepoPermsFunc: &PermsStoreSetRepoPermsFunc{ - defaultHook: func(context.Context, int64, map[int64]database.AccessMode) (r0 error) { - return - }, - }, - } -} - -// NewStrictMockPermsStore creates a new mock of the PermsStore interface. -// All methods panic on invocation, unless overwritten. -func NewStrictMockPermsStore() *MockPermsStore { - return &MockPermsStore{ - AccessModeFunc: &PermsStoreAccessModeFunc{ - defaultHook: func(context.Context, int64, int64, database.AccessModeOptions) database.AccessMode { - panic("unexpected invocation of MockPermsStore.AccessMode") - }, - }, - AuthorizeFunc: &PermsStoreAuthorizeFunc{ - defaultHook: func(context.Context, int64, int64, database.AccessMode, database.AccessModeOptions) bool { - panic("unexpected invocation of MockPermsStore.Authorize") - }, - }, - SetRepoPermsFunc: &PermsStoreSetRepoPermsFunc{ - defaultHook: func(context.Context, int64, map[int64]database.AccessMode) error { - panic("unexpected invocation of MockPermsStore.SetRepoPerms") - }, - }, - } -} - -// NewMockPermsStoreFrom creates a new mock of the MockPermsStore interface. -// All methods delegate to the given implementation, unless overwritten. -func NewMockPermsStoreFrom(i database.PermsStore) *MockPermsStore { - return &MockPermsStore{ - AccessModeFunc: &PermsStoreAccessModeFunc{ - defaultHook: i.AccessMode, - }, - AuthorizeFunc: &PermsStoreAuthorizeFunc{ - defaultHook: i.Authorize, - }, - SetRepoPermsFunc: &PermsStoreSetRepoPermsFunc{ - defaultHook: i.SetRepoPerms, - }, - } -} - -// PermsStoreAccessModeFunc describes the behavior when the AccessMode -// method of the parent MockPermsStore instance is invoked. -type PermsStoreAccessModeFunc struct { - defaultHook func(context.Context, int64, int64, database.AccessModeOptions) database.AccessMode - hooks []func(context.Context, int64, int64, database.AccessModeOptions) database.AccessMode - history []PermsStoreAccessModeFuncCall - mutex sync.Mutex -} - -// AccessMode delegates to the next hook function in the queue and stores -// the parameter and result values of this invocation. -func (m *MockPermsStore) AccessMode(v0 context.Context, v1 int64, v2 int64, v3 database.AccessModeOptions) database.AccessMode { - r0 := m.AccessModeFunc.nextHook()(v0, v1, v2, v3) - m.AccessModeFunc.appendCall(PermsStoreAccessModeFuncCall{v0, v1, v2, v3, r0}) - return r0 -} - -// SetDefaultHook sets function that is called when the AccessMode method of -// the parent MockPermsStore instance is invoked and the hook queue is -// empty. -func (f *PermsStoreAccessModeFunc) SetDefaultHook(hook func(context.Context, int64, int64, database.AccessModeOptions) database.AccessMode) { - f.defaultHook = hook -} - -// PushHook adds a function to the end of hook queue. Each invocation of the -// AccessMode method of the parent MockPermsStore instance invokes the hook -// at the front of the queue and discards it. After the queue is empty, the -// default hook function is invoked for any future action. -func (f *PermsStoreAccessModeFunc) PushHook(hook func(context.Context, int64, int64, database.AccessModeOptions) database.AccessMode) { - f.mutex.Lock() - f.hooks = append(f.hooks, hook) - f.mutex.Unlock() -} - -// SetDefaultReturn calls SetDefaultHook with a function that returns the -// given values. -func (f *PermsStoreAccessModeFunc) SetDefaultReturn(r0 database.AccessMode) { - f.SetDefaultHook(func(context.Context, int64, int64, database.AccessModeOptions) database.AccessMode { - return r0 - }) -} - -// PushReturn calls PushHook with a function that returns the given values. -func (f *PermsStoreAccessModeFunc) PushReturn(r0 database.AccessMode) { - f.PushHook(func(context.Context, int64, int64, database.AccessModeOptions) database.AccessMode { - return r0 - }) -} - -func (f *PermsStoreAccessModeFunc) nextHook() func(context.Context, int64, int64, database.AccessModeOptions) database.AccessMode { - f.mutex.Lock() - defer f.mutex.Unlock() - - if len(f.hooks) == 0 { - return f.defaultHook - } - - hook := f.hooks[0] - f.hooks = f.hooks[1:] - return hook -} - -func (f *PermsStoreAccessModeFunc) appendCall(r0 PermsStoreAccessModeFuncCall) { - f.mutex.Lock() - f.history = append(f.history, r0) - f.mutex.Unlock() -} - -// History returns a sequence of PermsStoreAccessModeFuncCall objects -// describing the invocations of this function. -func (f *PermsStoreAccessModeFunc) History() []PermsStoreAccessModeFuncCall { - f.mutex.Lock() - history := make([]PermsStoreAccessModeFuncCall, len(f.history)) - copy(history, f.history) - f.mutex.Unlock() - - return history -} - -// PermsStoreAccessModeFuncCall is an object that describes an invocation of -// method AccessMode on an instance of MockPermsStore. -type PermsStoreAccessModeFuncCall struct { - // Arg0 is the value of the 1st argument passed to this method - // invocation. - Arg0 context.Context - // Arg1 is the value of the 2nd argument passed to this method - // invocation. - Arg1 int64 - // Arg2 is the value of the 3rd argument passed to this method - // invocation. - Arg2 int64 - // Arg3 is the value of the 4th argument passed to this method - // invocation. - Arg3 database.AccessModeOptions - // Result0 is the value of the 1st result returned from this method - // invocation. - Result0 database.AccessMode -} - -// Args returns an interface slice containing the arguments of this -// invocation. -func (c PermsStoreAccessModeFuncCall) Args() []interface{} { - return []interface{}{c.Arg0, c.Arg1, c.Arg2, c.Arg3} -} - -// Results returns an interface slice containing the results of this -// invocation. -func (c PermsStoreAccessModeFuncCall) Results() []interface{} { - return []interface{}{c.Result0} -} - -// PermsStoreAuthorizeFunc describes the behavior when the Authorize method -// of the parent MockPermsStore instance is invoked. -type PermsStoreAuthorizeFunc struct { - defaultHook func(context.Context, int64, int64, database.AccessMode, database.AccessModeOptions) bool - hooks []func(context.Context, int64, int64, database.AccessMode, database.AccessModeOptions) bool - history []PermsStoreAuthorizeFuncCall - mutex sync.Mutex -} - -// Authorize delegates to the next hook function in the queue and stores the -// parameter and result values of this invocation. -func (m *MockPermsStore) Authorize(v0 context.Context, v1 int64, v2 int64, v3 database.AccessMode, v4 database.AccessModeOptions) bool { - r0 := m.AuthorizeFunc.nextHook()(v0, v1, v2, v3, v4) - m.AuthorizeFunc.appendCall(PermsStoreAuthorizeFuncCall{v0, v1, v2, v3, v4, r0}) - return r0 -} - -// SetDefaultHook sets function that is called when the Authorize method of -// the parent MockPermsStore instance is invoked and the hook queue is -// empty. -func (f *PermsStoreAuthorizeFunc) SetDefaultHook(hook func(context.Context, int64, int64, database.AccessMode, database.AccessModeOptions) bool) { - f.defaultHook = hook -} - -// PushHook adds a function to the end of hook queue. Each invocation of the -// Authorize method of the parent MockPermsStore instance invokes the hook -// at the front of the queue and discards it. After the queue is empty, the -// default hook function is invoked for any future action. -func (f *PermsStoreAuthorizeFunc) PushHook(hook func(context.Context, int64, int64, database.AccessMode, database.AccessModeOptions) bool) { - f.mutex.Lock() - f.hooks = append(f.hooks, hook) - f.mutex.Unlock() -} - -// SetDefaultReturn calls SetDefaultHook with a function that returns the -// given values. -func (f *PermsStoreAuthorizeFunc) SetDefaultReturn(r0 bool) { - f.SetDefaultHook(func(context.Context, int64, int64, database.AccessMode, database.AccessModeOptions) bool { - return r0 - }) -} - -// PushReturn calls PushHook with a function that returns the given values. -func (f *PermsStoreAuthorizeFunc) PushReturn(r0 bool) { - f.PushHook(func(context.Context, int64, int64, database.AccessMode, database.AccessModeOptions) bool { - return r0 - }) -} - -func (f *PermsStoreAuthorizeFunc) nextHook() func(context.Context, int64, int64, database.AccessMode, database.AccessModeOptions) bool { - f.mutex.Lock() - defer f.mutex.Unlock() - - if len(f.hooks) == 0 { - return f.defaultHook - } - - hook := f.hooks[0] - f.hooks = f.hooks[1:] - return hook -} - -func (f *PermsStoreAuthorizeFunc) appendCall(r0 PermsStoreAuthorizeFuncCall) { - f.mutex.Lock() - f.history = append(f.history, r0) - f.mutex.Unlock() -} - -// History returns a sequence of PermsStoreAuthorizeFuncCall objects -// describing the invocations of this function. -func (f *PermsStoreAuthorizeFunc) History() []PermsStoreAuthorizeFuncCall { - f.mutex.Lock() - history := make([]PermsStoreAuthorizeFuncCall, len(f.history)) - copy(history, f.history) - f.mutex.Unlock() - - return history -} - -// PermsStoreAuthorizeFuncCall is an object that describes an invocation of -// method Authorize on an instance of MockPermsStore. -type PermsStoreAuthorizeFuncCall struct { - // Arg0 is the value of the 1st argument passed to this method - // invocation. - Arg0 context.Context - // Arg1 is the value of the 2nd argument passed to this method - // invocation. - Arg1 int64 - // Arg2 is the value of the 3rd argument passed to this method - // invocation. - Arg2 int64 - // Arg3 is the value of the 4th argument passed to this method - // invocation. - Arg3 database.AccessMode - // Arg4 is the value of the 5th argument passed to this method - // invocation. - Arg4 database.AccessModeOptions - // Result0 is the value of the 1st result returned from this method - // invocation. - Result0 bool -} - -// Args returns an interface slice containing the arguments of this -// invocation. -func (c PermsStoreAuthorizeFuncCall) Args() []interface{} { - return []interface{}{c.Arg0, c.Arg1, c.Arg2, c.Arg3, c.Arg4} -} - -// Results returns an interface slice containing the results of this -// invocation. -func (c PermsStoreAuthorizeFuncCall) Results() []interface{} { - return []interface{}{c.Result0} -} - -// PermsStoreSetRepoPermsFunc describes the behavior when the SetRepoPerms -// method of the parent MockPermsStore instance is invoked. -type PermsStoreSetRepoPermsFunc struct { - defaultHook func(context.Context, int64, map[int64]database.AccessMode) error - hooks []func(context.Context, int64, map[int64]database.AccessMode) error - history []PermsStoreSetRepoPermsFuncCall - mutex sync.Mutex -} - -// SetRepoPerms delegates to the next hook function in the queue and stores -// the parameter and result values of this invocation. -func (m *MockPermsStore) SetRepoPerms(v0 context.Context, v1 int64, v2 map[int64]database.AccessMode) error { - r0 := m.SetRepoPermsFunc.nextHook()(v0, v1, v2) - m.SetRepoPermsFunc.appendCall(PermsStoreSetRepoPermsFuncCall{v0, v1, v2, r0}) - return r0 -} - -// SetDefaultHook sets function that is called when the SetRepoPerms method -// of the parent MockPermsStore instance is invoked and the hook queue is -// empty. -func (f *PermsStoreSetRepoPermsFunc) SetDefaultHook(hook func(context.Context, int64, map[int64]database.AccessMode) error) { - f.defaultHook = hook -} - -// PushHook adds a function to the end of hook queue. Each invocation of the -// SetRepoPerms method of the parent MockPermsStore instance invokes the -// hook at the front of the queue and discards it. After the queue is empty, -// the default hook function is invoked for any future action. -func (f *PermsStoreSetRepoPermsFunc) PushHook(hook func(context.Context, int64, map[int64]database.AccessMode) error) { - f.mutex.Lock() - f.hooks = append(f.hooks, hook) - f.mutex.Unlock() -} - -// SetDefaultReturn calls SetDefaultHook with a function that returns the -// given values. -func (f *PermsStoreSetRepoPermsFunc) SetDefaultReturn(r0 error) { - f.SetDefaultHook(func(context.Context, int64, map[int64]database.AccessMode) error { - return r0 - }) -} - -// PushReturn calls PushHook with a function that returns the given values. -func (f *PermsStoreSetRepoPermsFunc) PushReturn(r0 error) { - f.PushHook(func(context.Context, int64, map[int64]database.AccessMode) error { - return r0 - }) -} - -func (f *PermsStoreSetRepoPermsFunc) nextHook() func(context.Context, int64, map[int64]database.AccessMode) error { - f.mutex.Lock() - defer f.mutex.Unlock() - - if len(f.hooks) == 0 { - return f.defaultHook - } - - hook := f.hooks[0] - f.hooks = f.hooks[1:] - return hook -} - -func (f *PermsStoreSetRepoPermsFunc) appendCall(r0 PermsStoreSetRepoPermsFuncCall) { - f.mutex.Lock() - f.history = append(f.history, r0) - f.mutex.Unlock() -} - -// History returns a sequence of PermsStoreSetRepoPermsFuncCall objects -// describing the invocations of this function. -func (f *PermsStoreSetRepoPermsFunc) History() []PermsStoreSetRepoPermsFuncCall { - f.mutex.Lock() - history := make([]PermsStoreSetRepoPermsFuncCall, len(f.history)) - copy(history, f.history) - f.mutex.Unlock() - - return history -} - -// PermsStoreSetRepoPermsFuncCall is an object that describes an invocation -// of method SetRepoPerms on an instance of MockPermsStore. -type PermsStoreSetRepoPermsFuncCall struct { - // Arg0 is the value of the 1st argument passed to this method - // invocation. - Arg0 context.Context - // Arg1 is the value of the 2nd argument passed to this method - // invocation. - Arg1 int64 - // Arg2 is the value of the 3rd argument passed to this method - // invocation. - Arg2 map[int64]database.AccessMode - // Result0 is the value of the 1st result returned from this method - // invocation. - Result0 error -} - -// Args returns an interface slice containing the arguments of this -// invocation. -func (c PermsStoreSetRepoPermsFuncCall) Args() []interface{} { - return []interface{}{c.Arg0, c.Arg1, c.Arg2} -} - -// Results returns an interface slice containing the results of this -// invocation. -func (c PermsStoreSetRepoPermsFuncCall) Results() []interface{} { - return []interface{}{c.Result0} -} - // MockReposStore is a mock implementation of the ReposStore interface (from // the package gogs.io/gogs/internal/database) used for unit testing. type MockReposStore struct { @@ -5634,6 +5227,10 @@ func (c UsersStoreUseCustomAvatarFuncCall) Results() []interface{} { // MockStore is a mock implementation of the Store interface (from the // package gogs.io/gogs/internal/route/lfs) used for unit testing. type MockStore struct { + // AuthorizeRepositoryAccessFunc is an instance of a mock function + // object controlling the behavior of the method + // AuthorizeRepositoryAccess. + AuthorizeRepositoryAccessFunc *StoreAuthorizeRepositoryAccessFunc // CreateLFSObjectFunc is an instance of a mock function object // controlling the behavior of the method CreateLFSObject. CreateLFSObjectFunc *StoreCreateLFSObjectFunc @@ -5655,6 +5252,11 @@ type MockStore struct { // return zero values for all results, unless overwritten. func NewMockStore() *MockStore { return &MockStore{ + AuthorizeRepositoryAccessFunc: &StoreAuthorizeRepositoryAccessFunc{ + defaultHook: func(context.Context, int64, int64, database.AccessMode, database.AccessModeOptions) (r0 bool) { + return + }, + }, CreateLFSObjectFunc: &StoreCreateLFSObjectFunc{ defaultHook: func(context.Context, int64, lfsutil.OID, int64, lfsutil.Storage) (r0 error) { return @@ -5687,6 +5289,11 @@ func NewMockStore() *MockStore { // panic on invocation, unless overwritten. func NewStrictMockStore() *MockStore { return &MockStore{ + AuthorizeRepositoryAccessFunc: &StoreAuthorizeRepositoryAccessFunc{ + defaultHook: func(context.Context, int64, int64, database.AccessMode, database.AccessModeOptions) bool { + panic("unexpected invocation of MockStore.AuthorizeRepositoryAccess") + }, + }, CreateLFSObjectFunc: &StoreCreateLFSObjectFunc{ defaultHook: func(context.Context, int64, lfsutil.OID, int64, lfsutil.Storage) error { panic("unexpected invocation of MockStore.CreateLFSObject") @@ -5719,6 +5326,9 @@ func NewStrictMockStore() *MockStore { // methods delegate to the given implementation, unless overwritten. func NewMockStoreFrom(i Store) *MockStore { return &MockStore{ + AuthorizeRepositoryAccessFunc: &StoreAuthorizeRepositoryAccessFunc{ + defaultHook: i.AuthorizeRepositoryAccess, + }, CreateLFSObjectFunc: &StoreCreateLFSObjectFunc{ defaultHook: i.CreateLFSObject, }, @@ -5737,6 +5347,122 @@ func NewMockStoreFrom(i Store) *MockStore { } } +// StoreAuthorizeRepositoryAccessFunc describes the behavior when the +// AuthorizeRepositoryAccess method of the parent MockStore instance is +// invoked. +type StoreAuthorizeRepositoryAccessFunc struct { + defaultHook func(context.Context, int64, int64, database.AccessMode, database.AccessModeOptions) bool + hooks []func(context.Context, int64, int64, database.AccessMode, database.AccessModeOptions) bool + history []StoreAuthorizeRepositoryAccessFuncCall + mutex sync.Mutex +} + +// AuthorizeRepositoryAccess delegates to the next hook function in the +// queue and stores the parameter and result values of this invocation. +func (m *MockStore) AuthorizeRepositoryAccess(v0 context.Context, v1 int64, v2 int64, v3 database.AccessMode, v4 database.AccessModeOptions) bool { + r0 := m.AuthorizeRepositoryAccessFunc.nextHook()(v0, v1, v2, v3, v4) + m.AuthorizeRepositoryAccessFunc.appendCall(StoreAuthorizeRepositoryAccessFuncCall{v0, v1, v2, v3, v4, r0}) + return r0 +} + +// SetDefaultHook sets function that is called when the +// AuthorizeRepositoryAccess method of the parent MockStore instance is +// invoked and the hook queue is empty. +func (f *StoreAuthorizeRepositoryAccessFunc) SetDefaultHook(hook func(context.Context, int64, int64, database.AccessMode, database.AccessModeOptions) bool) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// AuthorizeRepositoryAccess method of the parent MockStore instance invokes +// the hook at the front of the queue and discards it. After the queue is +// empty, the default hook function is invoked for any future action. +func (f *StoreAuthorizeRepositoryAccessFunc) PushHook(hook func(context.Context, int64, int64, database.AccessMode, database.AccessModeOptions) bool) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *StoreAuthorizeRepositoryAccessFunc) SetDefaultReturn(r0 bool) { + f.SetDefaultHook(func(context.Context, int64, int64, database.AccessMode, database.AccessModeOptions) bool { + return r0 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *StoreAuthorizeRepositoryAccessFunc) PushReturn(r0 bool) { + f.PushHook(func(context.Context, int64, int64, database.AccessMode, database.AccessModeOptions) bool { + return r0 + }) +} + +func (f *StoreAuthorizeRepositoryAccessFunc) nextHook() func(context.Context, int64, int64, database.AccessMode, database.AccessModeOptions) bool { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *StoreAuthorizeRepositoryAccessFunc) appendCall(r0 StoreAuthorizeRepositoryAccessFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of StoreAuthorizeRepositoryAccessFuncCall +// objects describing the invocations of this function. +func (f *StoreAuthorizeRepositoryAccessFunc) History() []StoreAuthorizeRepositoryAccessFuncCall { + f.mutex.Lock() + history := make([]StoreAuthorizeRepositoryAccessFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// StoreAuthorizeRepositoryAccessFuncCall is an object that describes an +// invocation of method AuthorizeRepositoryAccess on an instance of +// MockStore. +type StoreAuthorizeRepositoryAccessFuncCall struct { + // Arg0 is the value of the 1st argument passed to this method + // invocation. + Arg0 context.Context + // Arg1 is the value of the 2nd argument passed to this method + // invocation. + Arg1 int64 + // Arg2 is the value of the 3rd argument passed to this method + // invocation. + Arg2 int64 + // Arg3 is the value of the 4th argument passed to this method + // invocation. + Arg3 database.AccessMode + // Arg4 is the value of the 5th argument passed to this method + // invocation. + Arg4 database.AccessModeOptions + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 bool +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c StoreAuthorizeRepositoryAccessFuncCall) Args() []interface{} { + return []interface{}{c.Arg0, c.Arg1, c.Arg2, c.Arg3, c.Arg4} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c StoreAuthorizeRepositoryAccessFuncCall) Results() []interface{} { + return []interface{}{c.Result0} +} + // StoreCreateLFSObjectFunc describes the behavior when the CreateLFSObject // method of the parent MockStore instance is invoked. type StoreCreateLFSObjectFunc struct { diff --git a/internal/route/lfs/route.go b/internal/route/lfs/route.go index cdac39e6c..21e5b0f41 100644 --- a/internal/route/lfs/route.go +++ b/internal/route/lfs/route.go @@ -28,7 +28,7 @@ func RegisterRoutes(r *macaron.Router) { store := NewStore() r.Group("", func() { - r.Post("/objects/batch", authorize(database.AccessModeRead), verifyAccept, verifyContentTypeJSON, serveBatch(store)) + r.Post("/objects/batch", authorize(store, database.AccessModeRead), verifyAccept, verifyContentTypeJSON, serveBatch(store)) r.Group("/objects/basic", func() { basic := &basicHandler{ store: store, @@ -38,9 +38,9 @@ func RegisterRoutes(r *macaron.Router) { }, } r.Combo("/:oid", verifyOID()). - Get(authorize(database.AccessModeRead), basic.serveDownload). - Put(authorize(database.AccessModeWrite), verifyContentTypeStream, basic.serveUpload) - r.Post("/verify", authorize(database.AccessModeWrite), verifyAccept, verifyContentTypeJSON, basic.serveVerify) + Get(authorize(store, database.AccessModeRead), basic.serveDownload). + Put(authorize(store, database.AccessModeWrite), verifyContentTypeStream, basic.serveUpload) + r.Post("/verify", authorize(store, database.AccessModeWrite), verifyAccept, verifyContentTypeJSON, basic.serveVerify) }) }, authenticate(store)) } @@ -104,7 +104,7 @@ func authenticate(store Store) macaron.Handler { } // authorize tries to authorize the user to the context repository with given access mode. -func authorize(mode database.AccessMode) macaron.Handler { +func authorize(store Store, mode database.AccessMode) macaron.Handler { return func(c *macaron.Context, actor *database.User) { username := c.Params(":username") reponame := strings.TrimSuffix(c.Params(":reponame"), ".git") @@ -131,7 +131,7 @@ func authorize(mode database.AccessMode) macaron.Handler { return } - if !database.Perms.Authorize(c.Req.Context(), actor.ID, repo.ID, mode, + if !store.AuthorizeRepositoryAccess(c.Req.Context(), actor.ID, repo.ID, mode, database.AccessModeOptions{ OwnerID: repo.OwnerID, Private: repo.IsPrivate, diff --git a/internal/route/lfs/route_test.go b/internal/route/lfs/route_test.go index 60e21876f..1cd93672a 100644 --- a/internal/route/lfs/route_test.go +++ b/internal/route/lfs/route_test.go @@ -187,19 +187,19 @@ func TestAuthenticate(t *testing.T) { } } -func Test_authorize(t *testing.T) { +func TestAuthorize(t *testing.T) { tests := []struct { name string - authroize macaron.Handler + accessMode database.AccessMode mockUsersStore func() database.UsersStore mockReposStore func() database.ReposStore - mockPermsStore func() database.PermsStore + mockStore func() *MockStore expStatusCode int expBody string }{ { - name: "user does not exist", - authroize: authorize(database.AccessModeNone), + name: "user does not exist", + accessMode: database.AccessModeNone, mockUsersStore: func() database.UsersStore { mock := NewMockUsersStore() mock.GetByUsernameFunc.SetDefaultReturn(nil, database.ErrUserNotExist{}) @@ -208,8 +208,8 @@ func Test_authorize(t *testing.T) { expStatusCode: http.StatusNotFound, }, { - name: "repository does not exist", - authroize: authorize(database.AccessModeNone), + name: "repository does not exist", + accessMode: database.AccessModeNone, mockUsersStore: func() database.UsersStore { mock := NewMockUsersStore() mock.GetByUsernameFunc.SetDefaultHook(func(ctx context.Context, username string) (*database.User, error) { @@ -225,8 +225,8 @@ func Test_authorize(t *testing.T) { expStatusCode: http.StatusNotFound, }, { - name: "actor is not authorized", - authroize: authorize(database.AccessModeWrite), + name: "actor is not authorized", + accessMode: database.AccessModeWrite, mockUsersStore: func() database.UsersStore { mock := NewMockUsersStore() mock.GetByUsernameFunc.SetDefaultHook(func(ctx context.Context, username string) (*database.User, error) { @@ -241,19 +241,19 @@ func Test_authorize(t *testing.T) { }) return mock }, - mockPermsStore: func() database.PermsStore { - mock := NewMockPermsStore() - mock.AuthorizeFunc.SetDefaultHook(func(ctx context.Context, userID int64, repoID int64, desired database.AccessMode, opts database.AccessModeOptions) bool { + mockStore: func() *MockStore { + mockStore := NewMockStore() + mockStore.AuthorizeRepositoryAccessFunc.SetDefaultHook(func(_ context.Context, _ int64, _ int64, desired database.AccessMode, _ database.AccessModeOptions) bool { return desired <= database.AccessModeRead }) - return mock + return mockStore }, expStatusCode: http.StatusNotFound, }, { - name: "actor is authorized", - authroize: authorize(database.AccessModeRead), + name: "actor is authorized", + accessMode: database.AccessModeRead, mockUsersStore: func() database.UsersStore { mock := NewMockUsersStore() mock.GetByUsernameFunc.SetDefaultHook(func(ctx context.Context, username string) (*database.User, error) { @@ -268,12 +268,12 @@ func Test_authorize(t *testing.T) { }) return mock }, - mockPermsStore: func() database.PermsStore { - mock := NewMockPermsStore() - mock.AuthorizeFunc.SetDefaultHook(func(ctx context.Context, userID int64, repoID int64, desired database.AccessMode, opts database.AccessModeOptions) bool { + mockStore: func() *MockStore { + mockStore := NewMockStore() + mockStore.AuthorizeRepositoryAccessFunc.SetDefaultHook(func(_ context.Context, _ int64, _ int64, desired database.AccessMode, _ database.AccessModeOptions) bool { return desired <= database.AccessModeRead }) - return mock + return mockStore }, expStatusCode: http.StatusOK, expBody: "owner.Name: owner, repo.Name: repo", @@ -287,8 +287,9 @@ func Test_authorize(t *testing.T) { if test.mockReposStore != nil { database.SetMockReposStore(t, test.mockReposStore()) } - if test.mockPermsStore != nil { - database.SetMockPermsStore(t, test.mockPermsStore()) + mockStore := NewMockStore() + if test.mockStore != nil { + mockStore = test.mockStore() } m := macaron.New() @@ -296,9 +297,13 @@ func Test_authorize(t *testing.T) { m.Use(func(c *macaron.Context) { c.Map(&database.User{}) }) - m.Get("/:username/:reponame", test.authroize, func(w http.ResponseWriter, owner *database.User, repo *database.Repository) { - fmt.Fprintf(w, "owner.Name: %s, repo.Name: %s", owner.Name, repo.Name) - }) + m.Get( + "/:username/:reponame", + authorize(mockStore, test.accessMode), + func(w http.ResponseWriter, owner *database.User, repo *database.Repository) { + _, _ = fmt.Fprintf(w, "owner.Name: %s, repo.Name: %s", owner.Name, repo.Name) + }, + ) r, err := http.NewRequest("GET", "/owner/repo", nil) if err != nil { diff --git a/internal/route/lfs/store.go b/internal/route/lfs/store.go index ffd9ae5e2..e7e498d39 100644 --- a/internal/route/lfs/store.go +++ b/internal/route/lfs/store.go @@ -26,6 +26,10 @@ type Store interface { // GetLFSObjectsByOIDs returns LFS objects found within "oids". The returned // list could have fewer elements if some oids were not found. GetLFSObjectsByOIDs(ctx context.Context, repoID int64, oids ...lfsutil.OID) ([]*database.LFSObject, error) + + // AuthorizeRepositoryAccess returns true if the user has as good as desired + // access mode to the repository. + AuthorizeRepositoryAccess(ctx context.Context, userID, repoID int64, desired database.AccessMode, opts database.AccessModeOptions) bool } type store struct{} @@ -54,3 +58,7 @@ func (*store) GetLFSObjectByOID(ctx context.Context, repoID int64, oid lfsutil.O func (*store) GetLFSObjectsByOIDs(ctx context.Context, repoID int64, oids ...lfsutil.OID) ([]*database.LFSObject, error) { return database.Handle.LFS().GetObjectsByOIDs(ctx, repoID, oids...) } + +func (*store) AuthorizeRepositoryAccess(ctx context.Context, userID, repoID int64, desired database.AccessMode, opts database.AccessModeOptions) bool { + return database.Handle.Permissions().Authorize(ctx, userID, repoID, desired, opts) +} diff --git a/internal/route/repo/http.go b/internal/route/repo/http.go index 8ba30399b..291479612 100644 --- a/internal/route/repo/http.go +++ b/internal/route/repo/http.go @@ -164,7 +164,7 @@ Please create and use personal access token on user settings page`) if isPull { mode = database.AccessModeRead } - if !database.Perms.Authorize(c.Req.Context(), authUser.ID, repo.ID, mode, + if !database.Handle.Permissions().Authorize(c.Req.Context(), authUser.ID, repo.ID, mode, database.AccessModeOptions{ OwnerID: repo.OwnerID, Private: repo.IsPrivate, diff --git a/internal/route/repo/issue.go b/internal/route/repo/issue.go index 213b661e9..8696d522c 100644 --- a/internal/route/repo/issue.go +++ b/internal/route/repo/issue.go @@ -596,7 +596,7 @@ func viewIssue(c *context.Context, isPullList bool) { participants = make([]*database.User, 1, 10) ) - // Render comments and and fetch participants. + // Render comments and fetch participants. participants[0] = issue.Poster for _, comment = range issue.Comments { if comment.Type == database.COMMENT_TYPE_COMMENT { @@ -612,7 +612,7 @@ func viewIssue(c *context.Context, isPullList bool) { if repo.IsOwnedBy(comment.PosterID) || (repo.Owner.IsOrganization() && repo.Owner.IsOwnedBy(comment.PosterID)) { comment.ShowTag = database.COMMENT_TAG_OWNER - } else if database.Perms.Authorize( + } else if database.Handle.Permissions().Authorize( c.Req.Context(), comment.PosterID, repo.ID, diff --git a/internal/route/repo/pull.go b/internal/route/repo/pull.go index 1859a6fa9..c6bd09d26 100644 --- a/internal/route/repo/pull.go +++ b/internal/route/repo/pull.go @@ -517,7 +517,7 @@ func ParseCompareInfo(c *context.Context) (*database.User, *database.Repository, headGitRepo = c.Repo.GitRepo } - if !database.Perms.Authorize( + if !database.Handle.Permissions().Authorize( c.Req.Context(), c.User.ID, headRepo.ID, diff --git a/mockgen.yaml b/mockgen.yaml index a4f172965..f74d2ea48 100644 --- a/mockgen.yaml +++ b/mockgen.yaml @@ -39,7 +39,6 @@ mocks: - UsersStore - TwoFactorsStore - ReposStore - - PermsStore - path: gogs.io/gogs/internal/route/lfs interfaces: - Store