@@ -269,8 +269,8 @@ func UserMentionedRepoCond(id string, userID int64) builder.Cond {
269269 )
270270}
271271
272- // UserCollaborationRepoCond returns user as collabrators repositories list
273- func UserCollaborationRepoCond (idStr string , userID int64 ) builder.Cond {
272+ // UserAccessRepoCond returns a condition for selecting all repositories a user has unit independent access to
273+ func UserAccessRepoCond (idStr string , userID int64 ) builder.Cond {
274274 return builder .In (idStr , builder .Select ("repo_id" ).
275275 From ("`access`" ).
276276 Where (builder .And (
@@ -280,8 +280,18 @@ func UserCollaborationRepoCond(idStr string, userID int64) builder.Cond {
280280 )
281281}
282282
283- // userOrgTeamRepoCond selects repos that the given user has access to through team membership
284- func userOrgTeamRepoCond (idStr string , userID int64 ) builder.Cond {
283+ // userCollaborationRepoCond returns a condition for selecting all repositories a user is collaborator in
284+ func UserCollaborationRepoCond (idStr string , userID int64 ) builder.Cond {
285+ return builder .In (idStr , builder .Select ("repo_id" ).
286+ From ("`collaboration`" ).
287+ Where (builder .And (
288+ builder.Eq {"`collaboration`.user_id" : userID },
289+ )),
290+ )
291+ }
292+
293+ // UserOrgTeamRepoCond selects repos that the given user has access to through team membership
294+ func UserOrgTeamRepoCond (idStr string , userID int64 ) builder.Cond {
285295 return builder .In (idStr , userOrgTeamRepoBuilder (userID ))
286296}
287297
@@ -297,7 +307,13 @@ func userOrgTeamRepoBuilder(userID int64) *builder.Builder {
297307func userOrgTeamUnitRepoBuilder (userID int64 , unitType unit.Type ) * builder.Builder {
298308 return userOrgTeamRepoBuilder (userID ).
299309 Join ("INNER" , "team_unit" , "`team_unit`.team_id = `team_repo`.team_id" ).
300- Where (builder.Eq {"`team_unit`.`type`" : unitType })
310+ Where (builder.Eq {"`team_unit`.`type`" : unitType }).
311+ And (builder.Gt {"`team_unit`.`access_mode`" : int (perm .AccessModeNone )})
312+ }
313+
314+ // userOrgTeamUnitRepoCond returns a condition to select repo ids where user's teams can access the special unit.
315+ func userOrgTeamUnitRepoCond (idStr string , userID int64 , unitType unit.Type ) builder.Cond {
316+ return builder .In (idStr , userOrgTeamUnitRepoBuilder (userID , unitType ))
301317}
302318
303319// UserOrgUnitRepoCond selects repos that the given user has access to through org and the special unit
@@ -350,7 +366,7 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond {
350366 if opts .Private {
351367 if opts .Actor != nil && ! opts .Actor .IsAdmin && opts .Actor .ID != opts .OwnerID {
352368 // OK we're in the context of a User
353- cond = cond .And (AccessibleRepositoryCondition (opts .Actor ))
369+ cond = cond .And (AccessibleRepositoryCondition (opts .Actor , unit . TypeInvalid ))
354370 }
355371 } else {
356372 // Not looking at private organisations and users
@@ -395,10 +411,10 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond {
395411 builder.Neq {"owner_id" : opts .OwnerID },
396412 // 2. But we can see because of:
397413 builder .Or (
398- // A. We have access
399- UserCollaborationRepoCond ("`repository`.id" , opts .OwnerID ),
414+ // A. We have unit independent access
415+ UserAccessRepoCond ("`repository`.id" , opts .OwnerID ),
400416 // B. We are in a team for
401- userOrgTeamRepoCond ("`repository`.id" , opts .OwnerID ),
417+ UserOrgTeamRepoCond ("`repository`.id" , opts .OwnerID ),
402418 // C. Public repositories in organizations that we are member of
403419 userOrgPublicRepoCondPrivate (opts .OwnerID ),
404420 ),
@@ -479,7 +495,7 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond {
479495 }
480496
481497 if opts .Actor != nil && opts .Actor .IsRestricted {
482- cond = cond .And (AccessibleRepositoryCondition (opts .Actor ))
498+ cond = cond .And (AccessibleRepositoryCondition (opts .Actor , unit . TypeInvalid ))
483499 }
484500
485501 if opts .Archived != util .OptionalBoolNone {
@@ -574,7 +590,7 @@ func searchRepositoryByCondition(ctx context.Context, opts *SearchRepoOptions, c
574590}
575591
576592// AccessibleRepositoryCondition takes a user a returns a condition for checking if a repository is accessible
577- func AccessibleRepositoryCondition (user * user_model.User ) builder.Cond {
593+ func AccessibleRepositoryCondition (user * user_model.User , unitType unit. Type ) builder.Cond {
578594 cond := builder .NewCond ()
579595
580596 if user == nil || ! user .IsRestricted || user .ID <= 0 {
@@ -594,13 +610,24 @@ func AccessibleRepositoryCondition(user *user_model.User) builder.Cond {
594610 }
595611
596612 if user != nil {
613+ // 2. Be able to see all repositories that we have unit independent access to
614+ // 3. Be able to see all repositories through team membership(s)
615+ if unitType == unit .TypeInvalid {
616+ // Regardless of UnitType
617+ cond = cond .Or (
618+ UserAccessRepoCond ("`repository`.id" , user .ID ),
619+ UserOrgTeamRepoCond ("`repository`.id" , user .ID ),
620+ )
621+ } else {
622+ // For a specific UnitType
623+ cond = cond .Or (
624+ UserCollaborationRepoCond ("`repository`.id" , user .ID ),
625+ userOrgTeamUnitRepoCond ("`repository`.id" , user .ID , unitType ),
626+ )
627+ }
597628 cond = cond .Or (
598- // 2. Be able to see all repositories that we have access to
599- UserCollaborationRepoCond ("`repository`.id" , user .ID ),
600- // 3. Repositories that we directly own
629+ // 4. Repositories that we directly own
601630 builder.Eq {"`repository`.owner_id" : user .ID },
602- // 4. Be able to see all repositories that we are in a team
603- userOrgTeamRepoCond ("`repository`.id" , user .ID ),
604631 // 5. Be able to see all public repos in private organizations that we are an org_user of
605632 userOrgPublicRepoCond (user .ID ),
606633 )
@@ -645,18 +672,18 @@ func SearchRepositoryIDs(opts *SearchRepoOptions) ([]int64, int64, error) {
645672// AccessibleRepoIDsQuery queries accessible repository ids. Usable as a subquery wherever repo ids need to be filtered.
646673func AccessibleRepoIDsQuery (user * user_model.User ) * builder.Builder {
647674 // NB: Please note this code needs to still work if user is nil
648- return builder .Select ("id" ).From ("repository" ).Where (AccessibleRepositoryCondition (user ))
675+ return builder .Select ("id" ).From ("repository" ).Where (AccessibleRepositoryCondition (user , unit . TypeInvalid ))
649676}
650677
651- // FindUserAccessibleRepoIDs find all accessible repositories' ID by user's id
652- func FindUserAccessibleRepoIDs (user * user_model.User ) ([]int64 , error ) {
678+ // FindUserCodeAccessibleRepoIDs finds all at Code level accessible repositories' ID by the user's id
679+ func FindUserCodeAccessibleRepoIDs (user * user_model.User ) ([]int64 , error ) {
653680 repoIDs := make ([]int64 , 0 , 10 )
654681 if err := db .GetEngine (db .DefaultContext ).
655682 Table ("repository" ).
656683 Cols ("id" ).
657- Where (AccessibleRepositoryCondition (user )).
684+ Where (AccessibleRepositoryCondition (user , unit . TypeCode )).
658685 Find (& repoIDs ); err != nil {
659- return nil , fmt .Errorf ("FindUserAccesibleRepoIDs : %v" , err )
686+ return nil , fmt .Errorf ("FindUserCodeAccesibleRepoIDs : %v" , err )
660687 }
661688 return repoIDs , nil
662689}
0 commit comments