@@ -14,6 +14,7 @@ import (
1414 repo_model "code.gitea.io/gitea/models/repo"
1515 "code.gitea.io/gitea/models/unit"
1616 user_model "code.gitea.io/gitea/models/user"
17+ "code.gitea.io/gitea/modules/container"
1718 "code.gitea.io/gitea/modules/log"
1819 "code.gitea.io/gitea/modules/setting"
1920 "code.gitea.io/gitea/modules/util"
@@ -458,54 +459,44 @@ func HasAnyUnitAccess(ctx context.Context, userID int64, repo *repo_model.Reposi
458459 return perm .HasAnyUnitAccess (), nil
459460}
460461
461- // getUsersWithAccessMode returns users that have at least given access mode to the repository.
462- func getUsersWithAccessMode (ctx context. Context , repo * repo_model. Repository , mode perm_model. AccessMode ) ( _ [] * user_model. User , err error ) {
463- if err = repo . LoadOwner ( ctx ); err != nil {
462+ func GetUsersWithUnitAccess ( ctx context. Context , repo * repo_model. Repository , mode perm_model. AccessMode , unitType unit. Type ) ( users [] * user_model. User , err error ) {
463+ userIDs , err := GetUserIDsWithUnitAccess (ctx , repo , mode , unitType )
464+ if err != nil {
464465 return nil , err
465466 }
467+ if len (userIDs ) == 0 {
468+ return users , nil
469+ }
470+ if err = db .GetEngine (ctx ).In ("id" , userIDs .Values ()).OrderBy ("`name`" ).Find (& users ); err != nil {
471+ return nil , err
472+ }
473+ return users , nil
474+ }
466475
476+ func GetUserIDsWithUnitAccess (ctx context.Context , repo * repo_model.Repository , mode perm_model.AccessMode , unitType unit.Type ) (container.Set [int64 ], error ) {
477+ userIDs := container.Set [int64 ]{}
467478 e := db .GetEngine (ctx )
468479 accesses := make ([]* Access , 0 , 10 )
469- if err = e .Where ("repo_id = ? AND mode >= ?" , repo .ID , mode ).Find (& accesses ); err != nil {
480+ if err : = e .Where ("repo_id = ? AND mode >= ?" , repo .ID , mode ).Find (& accesses ); err != nil {
470481 return nil , err
471482 }
483+ for _ , a := range accesses {
484+ userIDs .Add (a .UserID )
485+ }
472486
473- // Leave a seat for owner itself to append later, but if owner is an organization
474- // and just waste 1 unit is cheaper than re-allocate memory once.
475- users := make ([]* user_model.User , 0 , len (accesses )+ 1 )
476- if len (accesses ) > 0 {
477- userIDs := make ([]int64 , len (accesses ))
478- for i := 0 ; i < len (accesses ); i ++ {
479- userIDs [i ] = accesses [i ].UserID
480- }
481-
482- if err = e .In ("id" , userIDs ).Find (& users ); err != nil {
483- return nil , err
484- }
487+ if err := repo .LoadOwner (ctx ); err != nil {
488+ return nil , err
485489 }
486490 if ! repo .Owner .IsOrganization () {
487- users = append (users , repo .Owner )
488- }
489-
490- return users , nil
491- }
492-
493- // GetRepoReaders returns all users that have explicit read access or higher to the repository.
494- func GetRepoReaders (ctx context.Context , repo * repo_model.Repository ) (_ []* user_model.User , err error ) {
495- return getUsersWithAccessMode (ctx , repo , perm_model .AccessModeRead )
496- }
497-
498- // GetRepoWriters returns all users that have write access to the repository.
499- func GetRepoWriters (ctx context.Context , repo * repo_model.Repository ) (_ []* user_model.User , err error ) {
500- return getUsersWithAccessMode (ctx , repo , perm_model .AccessModeWrite )
501- }
502-
503- // IsRepoReader returns true if user has explicit read access or higher to the repository.
504- func IsRepoReader (ctx context.Context , repo * repo_model.Repository , userID int64 ) (bool , error ) {
505- if repo .OwnerID == userID {
506- return true , nil
491+ userIDs .Add (repo .Owner .ID )
492+ } else {
493+ teamUserIDs , err := organization .GetTeamUserIDsWithAccessToAnyRepoUnit (ctx , repo .OwnerID , repo .ID , mode , unitType )
494+ if err != nil {
495+ return nil , err
496+ }
497+ userIDs .AddMultiple (teamUserIDs ... )
507498 }
508- return db . GetEngine ( ctx ). Where ( "repo_id = ? AND user_id = ? AND mode >= ?" , repo . ID , userID , perm_model . AccessModeRead ). Get ( & Access {})
499+ return userIDs , nil
509500}
510501
511502// CheckRepoUnitUser check whether user could visit the unit of this repository
0 commit comments