@@ -16,6 +16,7 @@ import (
1616 repo_model "code.gitea.io/gitea/models/repo"
1717 "code.gitea.io/gitea/models/unit"
1818 user_model "code.gitea.io/gitea/models/user"
19+ "code.gitea.io/gitea/modules/container"
1920 "code.gitea.io/gitea/modules/log"
2021 "code.gitea.io/gitea/modules/setting"
2122 "code.gitea.io/gitea/modules/util"
@@ -498,54 +499,44 @@ func HasAnyUnitAccess(ctx context.Context, userID int64, repo *repo_model.Reposi
498499 return perm .HasAnyUnitAccess (), nil
499500}
500501
501- // getUsersWithAccessMode returns users that have at least given access mode to the repository.
502- func getUsersWithAccessMode (ctx context. Context , repo * repo_model. Repository , mode perm_model. AccessMode ) ( _ [] * user_model. User , err error ) {
503- if err = repo . LoadOwner ( ctx ); err != nil {
502+ func GetUsersWithUnitAccess ( ctx context. Context , repo * repo_model. Repository , mode perm_model. AccessMode , unitType unit. Type ) ( users [] * user_model. User , err error ) {
503+ userIDs , err := GetUserIDsWithUnitAccess (ctx , repo , mode , unitType )
504+ if err != nil {
504505 return nil , err
505506 }
507+ if len (userIDs ) == 0 {
508+ return users , nil
509+ }
510+ if err = db .GetEngine (ctx ).In ("id" , userIDs .Values ()).OrderBy ("`name`" ).Find (& users ); err != nil {
511+ return nil , err
512+ }
513+ return users , nil
514+ }
506515
516+ func GetUserIDsWithUnitAccess (ctx context.Context , repo * repo_model.Repository , mode perm_model.AccessMode , unitType unit.Type ) (container.Set [int64 ], error ) {
517+ userIDs := container.Set [int64 ]{}
507518 e := db .GetEngine (ctx )
508519 accesses := make ([]* Access , 0 , 10 )
509- if err = e .Where ("repo_id = ? AND mode >= ?" , repo .ID , mode ).Find (& accesses ); err != nil {
520+ if err : = e .Where ("repo_id = ? AND mode >= ?" , repo .ID , mode ).Find (& accesses ); err != nil {
510521 return nil , err
511522 }
523+ for _ , a := range accesses {
524+ userIDs .Add (a .UserID )
525+ }
512526
513- // Leave a seat for owner itself to append later, but if owner is an organization
514- // and just waste 1 unit is cheaper than re-allocate memory once.
515- users := make ([]* user_model.User , 0 , len (accesses )+ 1 )
516- if len (accesses ) > 0 {
517- userIDs := make ([]int64 , len (accesses ))
518- for i := 0 ; i < len (accesses ); i ++ {
519- userIDs [i ] = accesses [i ].UserID
520- }
521-
522- if err = e .In ("id" , userIDs ).Find (& users ); err != nil {
523- return nil , err
524- }
527+ if err := repo .LoadOwner (ctx ); err != nil {
528+ return nil , err
525529 }
526530 if ! repo .Owner .IsOrganization () {
527- users = append (users , repo .Owner )
528- }
529-
530- return users , nil
531- }
532-
533- // GetRepoReaders returns all users that have explicit read access or higher to the repository.
534- func GetRepoReaders (ctx context.Context , repo * repo_model.Repository ) (_ []* user_model.User , err error ) {
535- return getUsersWithAccessMode (ctx , repo , perm_model .AccessModeRead )
536- }
537-
538- // GetRepoWriters returns all users that have write access to the repository.
539- func GetRepoWriters (ctx context.Context , repo * repo_model.Repository ) (_ []* user_model.User , err error ) {
540- return getUsersWithAccessMode (ctx , repo , perm_model .AccessModeWrite )
541- }
542-
543- // IsRepoReader returns true if user has explicit read access or higher to the repository.
544- func IsRepoReader (ctx context.Context , repo * repo_model.Repository , userID int64 ) (bool , error ) {
545- if repo .OwnerID == userID {
546- return true , nil
531+ userIDs .Add (repo .Owner .ID )
532+ } else {
533+ teamUserIDs , err := organization .GetTeamUserIDsWithAccessToAnyRepoUnit (ctx , repo .OwnerID , repo .ID , mode , unitType )
534+ if err != nil {
535+ return nil , err
536+ }
537+ userIDs .AddMultiple (teamUserIDs ... )
547538 }
548- return db . GetEngine ( ctx ). Where ( "repo_id = ? AND user_id = ? AND mode >= ?" , repo . ID , userID , perm_model . AccessModeRead ). Get ( & Access {})
539+ return userIDs , nil
549540}
550541
551542// CheckRepoUnitUser check whether user could visit the unit of this repository
0 commit comments