@@ -22,6 +22,7 @@ import (
2222 "code.gitea.io/gitea/modules/util"
2323
2424 "xorm.io/builder"
25+ "xorm.io/xorm"
2526)
2627
2728// ________ .__ __ .__
@@ -141,8 +142,9 @@ func (org *Organization) LoadTeams(ctx context.Context) ([]*Team, error) {
141142}
142143
143144// GetMembers returns all members of organization.
144- func (org * Organization ) GetMembers (ctx context.Context ) (user_model.UserList , map [int64 ]bool , error ) {
145+ func (org * Organization ) GetMembers (ctx context.Context , doer * user_model. User ) (user_model.UserList , map [int64 ]bool , error ) {
145146 return FindOrgMembers (ctx , & FindOrgMembersOpts {
147+ Doer : doer ,
146148 OrgID : org .ID ,
147149 })
148150}
@@ -195,16 +197,39 @@ func (org *Organization) CanCreateRepo() bool {
195197// FindOrgMembersOpts represensts find org members conditions
196198type FindOrgMembersOpts struct {
197199 db.ListOptions
198- OrgID int64
199- PublicOnly bool
200+ Doer * user_model.User
201+ IsDoerMember bool
202+ OrgID int64
203+ }
204+
205+ func (opts FindOrgMembersOpts ) PublicOnly () bool {
206+ return opts .Doer == nil || ! (opts .IsDoerMember || opts .Doer .IsAdmin )
207+ }
208+
209+ // applyTeamMatesOnlyFilter make sure restricted users only see public team members and there own team mates
210+ func (opts FindOrgMembersOpts ) applyTeamMatesOnlyFilter (sess * xorm.Session ) {
211+ if opts .Doer != nil && opts .IsDoerMember && opts .Doer .IsRestricted {
212+ teamMates := builder .Select ("DISTINCT team_user.uid" ).
213+ From ("team_user" ).
214+ Where (builder .In ("team_user.team_id" , getUserTeamIDsQueryBuilder (opts .OrgID , opts .Doer .ID ))).
215+ And (builder.Eq {"team_user.org_id" : opts .OrgID })
216+
217+ sess .And (
218+ builder .In ("org_user.uid" , teamMates ).
219+ Or (builder.Eq {"org_user.is_public" : true }),
220+ )
221+ }
200222}
201223
202224// CountOrgMembers counts the organization's members
203225func CountOrgMembers (ctx context.Context , opts * FindOrgMembersOpts ) (int64 , error ) {
204226 sess := db .GetEngine (ctx ).Where ("org_id=?" , opts .OrgID )
205- if opts .PublicOnly {
206- sess .And ("is_public = ?" , true )
227+ if opts .PublicOnly () {
228+ sess = sess .And ("is_public = ?" , true )
229+ } else {
230+ opts .applyTeamMatesOnlyFilter (sess )
207231 }
232+
208233 return sess .Count (new (OrgUser ))
209234}
210235
@@ -525,9 +550,12 @@ func GetOrgsCanCreateRepoByUserID(ctx context.Context, userID int64) ([]*Organiz
525550// GetOrgUsersByOrgID returns all organization-user relations by organization ID.
526551func GetOrgUsersByOrgID (ctx context.Context , opts * FindOrgMembersOpts ) ([]* OrgUser , error ) {
527552 sess := db .GetEngine (ctx ).Where ("org_id=?" , opts .OrgID )
528- if opts .PublicOnly {
529- sess .And ("is_public = ?" , true )
553+ if opts .PublicOnly () {
554+ sess = sess .And ("is_public = ?" , true )
555+ } else {
556+ opts .applyTeamMatesOnlyFilter (sess )
530557 }
558+
531559 if opts .ListOptions .PageSize > 0 {
532560 sess = db .SetSessionPagination (sess , opts )
533561
@@ -656,6 +684,15 @@ func (org *Organization) getUserTeamIDs(ctx context.Context, userID int64) ([]in
656684 Find (& teamIDs )
657685}
658686
687+ func getUserTeamIDsQueryBuilder (orgID , userID int64 ) * builder.Builder {
688+ return builder .Select ("team.id" ).From ("team" ).
689+ InnerJoin ("team_user" , "team_user.team_id = team.id" ).
690+ Where (builder.Eq {
691+ "team_user.org_id" : orgID ,
692+ "team_user.uid" : userID ,
693+ })
694+ }
695+
659696// TeamsWithAccessToRepo returns all teams that have given access level to the repository.
660697func (org * Organization ) TeamsWithAccessToRepo (ctx context.Context , repoID int64 , mode perm.AccessMode ) ([]* Team , error ) {
661698 return GetTeamsWithAccessToRepo (ctx , org .ID , repoID , mode )
0 commit comments