diff --git a/pkg/services/sqlstore/team.go b/pkg/services/sqlstore/team.go index 7b18920cfb2..fce5578761a 100644 --- a/pkg/services/sqlstore/team.go +++ b/pkg/services/sqlstore/team.go @@ -433,12 +433,6 @@ func updateTeamMember(sess *DBSession, orgID, teamID, userID int64, permission m if permission != models.PERMISSION_ADMIN { permission = 0 // make sure we don't get invalid permission levels in store - - // protect the last team admin - _, err := isLastAdmin(sess, orgID, teamID, userID) - if err != nil { - return err - } } member.Permission = permission @@ -464,11 +458,6 @@ func removeTeamMember(sess *DBSession, cmd *models.RemoveTeamMemberCommand) erro return err } - _, err := isLastAdmin(sess, cmd.OrgId, cmd.TeamId, cmd.UserId) - if err != nil { - return err - } - var rawSQL = "DELETE FROM team_member WHERE org_id=? and team_id=? and user_id=?" res, err := sess.Exec(rawSQL, cmd.OrgId, cmd.TeamId, cmd.UserId) if err != nil { @@ -482,29 +471,6 @@ func removeTeamMember(sess *DBSession, cmd *models.RemoveTeamMemberCommand) erro return err } -func isLastAdmin(sess *DBSession, orgId int64, teamId int64, userId int64) (bool, error) { - rawSQL := "SELECT user_id FROM team_member WHERE org_id=? and team_id=? and permission=?" - userIds := []*int64{} - err := sess.SQL(rawSQL, orgId, teamId, models.PERMISSION_ADMIN).Find(&userIds) - if err != nil { - return false, err - } - - isAdmin := false - for _, adminId := range userIds { - if userId == *adminId { - isAdmin = true - break - } - } - - if isAdmin && len(userIds) == 1 { - return true, models.ErrLastTeamAdmin - } - - return false, err -} - // 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. diff --git a/pkg/services/sqlstore/team_test.go b/pkg/services/sqlstore/team_test.go index 9737a15a82f..6ffaf7aa0c7 100644 --- a/pkg/services/sqlstore/team_test.go +++ b/pkg/services/sqlstore/team_test.go @@ -251,25 +251,18 @@ func TestIntegrationTeamCommandsAndQueries(t *testing.T) { require.Equal(t, len(q2.Result), 0) }) - t.Run("Should never remove the last admin of a team", func(t *testing.T) { + t.Run("Should have empty teams", func(t *testing.T) { err = sqlStore.AddTeamMember(userIds[0], testOrgID, team1.Id, false, models.PERMISSION_ADMIN) require.NoError(t, err) - t.Run("A user should not be able to remove the last admin", func(t *testing.T) { - err = sqlStore.RemoveTeamMember(context.Background(), &models.RemoveTeamMemberCommand{OrgId: testOrgID, TeamId: team1.Id, UserId: userIds[0]}) - require.Equal(t, err, models.ErrLastTeamAdmin) - }) - - t.Run("A user should be able to remove an admin if there are other admins", func(t *testing.T) { - err = sqlStore.AddTeamMember(userIds[1], testOrgID, team1.Id, false, models.PERMISSION_ADMIN) - require.NoError(t, err) - err = sqlStore.RemoveTeamMember(context.Background(), &models.RemoveTeamMemberCommand{OrgId: testOrgID, TeamId: team1.Id, UserId: userIds[1]}) - require.NoError(t, err) - }) - - t.Run("A user should not be able to remove the admin permission for the last admin", func(t *testing.T) { + t.Run("A user should be able to remove the admin permission for the last admin", func(t *testing.T) { err = sqlStore.UpdateTeamMember(context.Background(), &models.UpdateTeamMemberCommand{OrgId: testOrgID, TeamId: team1.Id, UserId: userIds[0], Permission: 0}) - require.Error(t, err, models.ErrLastTeamAdmin) + require.NoError(t, err) + }) + + t.Run("A user should be able to remove the last member", func(t *testing.T) { + err = sqlStore.RemoveTeamMember(context.Background(), &models.RemoveTeamMemberCommand{OrgId: testOrgID, TeamId: team1.Id, UserId: userIds[0]}) + require.NoError(t, err) }) t.Run("A user should be able to remove the admin permission if there are other admins", func(t *testing.T) { diff --git a/public/app/core/components/AccessControl/Permissions.tsx b/public/app/core/components/AccessControl/Permissions.tsx index e6c918de65c..058ee98daac 100644 --- a/public/app/core/components/AccessControl/Permissions.tsx +++ b/public/app/core/components/AccessControl/Permissions.tsx @@ -26,6 +26,7 @@ type Type = 'users' | 'teams' | 'builtInRoles'; export type Props = { title?: string; buttonLabel?: string; + emptyLabel?: string; addPermissionTitle?: string; resource: string; resourceId: ResourceId; @@ -35,6 +36,7 @@ export type Props = { export const Permissions = ({ title = 'Permissions', buttonLabel = 'Add a permission', + emptyLabel = 'There are no permissions', resource, resourceId, canSetPermissions, @@ -145,6 +147,15 @@ export const Permissions = ({ onCancel={() => setIsAdding(false)} /> + {items.length === 0 && ( + + + + + + +
{emptyLabel}
+ )} { title="" addPermissionTitle="Add member" buttonLabel="Add member" + emptyLabel="There are no members in this team or you do not have the permissions to list the current members." resource="teams" resourceId={props.team.id} canSetPermissions={canSetPermissions}