AccessControl: Implement SQL filters for team members filtering (#44898)

* AccessControl: Filter team members

* Modify GetTeamMembersByUser comment

* Fix postgres failing test due to quoting

* Rename GetTeamMembersByUser to GetUserTeamMemberships

* Update TeamStore interface
This commit is contained in:
Gabriel MABILLE
2022-02-09 17:46:37 +01:00
committed by GitHub
parent 3fbe4801b7
commit 78fc0258b1
9 changed files with 252 additions and 35 deletions

View File

@@ -34,6 +34,7 @@ type TeamStore interface {
UpdateTeamMember(ctx context.Context, cmd *models.UpdateTeamMemberCommand) error
RemoveTeamMember(ctx context.Context, cmd *models.RemoveTeamMemberCommand) error
GetTeamMembers(ctx context.Context, cmd *models.GetTeamMembersQuery) error
GetUserTeamMemberships(ctx context.Context, orgID, userID int64, external bool) ([]*models.TeamMemberDTO, error)
AddOrUpdateTeamMember(userID, orgID, teamID int64, isExternal bool, permission models.PermissionType) error
}
@@ -492,11 +493,52 @@ func isLastAdmin(sess *DBSession, orgId int64, teamId int64, userId int64) (bool
return false, err
}
// GetTeamMembers return a list of members for the specified team
// GetUserTeamMemberships return a list of memberships to teams granted to a user
// If external is specified, only memberships provided by an external auth provider will be listed
// This function doesn't perform any accesscontrol filtering.
func (ss *SQLStore) GetUserTeamMemberships(ctx context.Context, orgID, userID int64, external bool) ([]*models.TeamMemberDTO, error) {
query := &models.GetTeamMembersQuery{
OrgId: orgID,
UserId: userID,
External: external,
Result: []*models.TeamMemberDTO{},
}
err := ss.getTeamMembers(ctx, query, nil)
return query.Result, err
}
// GetTeamMembers return a list of members for the specified team filtered based on the user's permissions
func (ss *SQLStore) GetTeamMembers(ctx context.Context, query *models.GetTeamMembersQuery) error {
acFilter := &ac.SQLFilter{}
var err error
// With accesscontrol we filter out users based on the SignedInUser's permissions
// Note we assume that checking SignedInUser is allowed to see team members for this team has already been performed
// If the signed in user is not set no member will be returned
if ss.Cfg.IsFeatureToggleEnabled(featuremgmt.FlagAccesscontrol) {
*acFilter, err = ac.Filter(ctx,
fmt.Sprintf("%s.%s", x.Dialect().Quote("user"), x.Dialect().Quote("id")),
"users", ac.ActionOrgUsersRead, query.SignedInUser,
)
if err != nil {
return err
}
}
return ss.getTeamMembers(ctx, query, acFilter)
}
// getTeamMembers return a list of members for the specified team
func (ss *SQLStore) getTeamMembers(ctx context.Context, query *models.GetTeamMembersQuery, acUserFilter *ac.SQLFilter) error {
query.Result = make([]*models.TeamMemberDTO, 0)
sess := x.Table("team_member")
sess.Join("INNER", x.Dialect().Quote("user"), fmt.Sprintf("team_member.user_id=%s.id", x.Dialect().Quote("user")))
sess.Join("INNER", x.Dialect().Quote("user"),
fmt.Sprintf("team_member.user_id=%s.%s", x.Dialect().Quote("user"), x.Dialect().Quote("id")),
)
if acUserFilter != nil {
sess.Where(acUserFilter.Where, acUserFilter.Args...)
}
// Join with only most recent auth module
authJoinCondition := `(