diff --git a/pkg/services/accesscontrol/accesscontrol.go b/pkg/services/accesscontrol/accesscontrol.go index 14bfa63e55c..1e036468068 100644 --- a/pkg/services/accesscontrol/accesscontrol.go +++ b/pkg/services/accesscontrol/accesscontrol.go @@ -2,6 +2,7 @@ package accesscontrol import ( "context" + "fmt" "strings" "github.com/grafana/grafana/pkg/models" @@ -192,3 +193,15 @@ func GetResourcesMetadata(ctx context.Context, permissions map[string][]string, return result } + +func ManagedUserRoleName(userID int64) string { + return fmt.Sprintf("managed:users:%d:permissions", userID) +} + +func ManagedTeamRoleName(teamID int64) string { + return fmt.Sprintf("managed:teams:%d:permissions", teamID) +} + +func ManagedBuiltInRoleName(builtInRole string) string { + return fmt.Sprintf("managed:builtins:%s:permissions", strings.ToLower(builtInRole)) +} diff --git a/pkg/services/accesscontrol/database/resource_permissions.go b/pkg/services/accesscontrol/database/resource_permissions.go index 7625ab408df..bcfef8c6c09 100644 --- a/pkg/services/accesscontrol/database/resource_permissions.go +++ b/pkg/services/accesscontrol/database/resource_permissions.go @@ -56,7 +56,7 @@ func (s *AccessControlStore) setUserResourcePermission( cmd types.SetResourcePermissionCommand, hook types.UserResourceHookFunc, ) (*accesscontrol.ResourcePermission, error) { - permission, err := s.setResourcePermission(sess, orgID, managedUserRoleName(user.ID), s.userAdder(sess, orgID, user.ID), cmd) + permission, err := s.setResourcePermission(sess, orgID, accesscontrol.ManagedUserRoleName(user.ID), s.userAdder(sess, orgID, user.ID), cmd) if err != nil { return nil, err } @@ -95,7 +95,7 @@ func (s *AccessControlStore) setTeamResourcePermission( cmd types.SetResourcePermissionCommand, hook types.TeamResourceHookFunc, ) (*accesscontrol.ResourcePermission, error) { - permission, err := s.setResourcePermission(sess, orgID, managedTeamRoleName(teamID), s.teamAdder(sess, orgID, teamID), cmd) + permission, err := s.setResourcePermission(sess, orgID, accesscontrol.ManagedTeamRoleName(teamID), s.teamAdder(sess, orgID, teamID), cmd) if err != nil { return nil, err } @@ -138,7 +138,7 @@ func (s *AccessControlStore) setBuiltInResourcePermission( cmd types.SetResourcePermissionCommand, hook types.BuiltinResourceHookFunc, ) (*accesscontrol.ResourcePermission, error) { - permission, err := s.setResourcePermission(sess, orgID, managedBuiltInRoleName(builtInRole), s.builtInRoleAdder(sess, orgID, builtInRole), cmd) + permission, err := s.setResourcePermission(sess, orgID, accesscontrol.ManagedBuiltInRoleName(builtInRole), s.builtInRoleAdder(sess, orgID, builtInRole), cmd) if err != nil { return nil, err } @@ -628,15 +628,3 @@ func managedPermission(action, resource string, resourceID string) accesscontrol Scope: accesscontrol.GetResourceScope(resource, resourceID), } } - -func managedUserRoleName(userID int64) string { - return fmt.Sprintf("managed:users:%d:permissions", userID) -} - -func managedTeamRoleName(teamID int64) string { - return fmt.Sprintf("managed:teams:%d:permissions", teamID) -} - -func managedBuiltInRoleName(builtInRole string) string { - return fmt.Sprintf("managed:builtins:%s:permissions", strings.ToLower(builtInRole)) -} diff --git a/pkg/services/sqlstore/user.go b/pkg/services/sqlstore/user.go index 72314b1ba76..04e86b36771 100644 --- a/pkg/services/sqlstore/user.go +++ b/pkg/services/sqlstore/user.go @@ -11,6 +11,7 @@ import ( "github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/events" "github.com/grafana/grafana/pkg/models" + ac "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/util" ) @@ -757,6 +758,47 @@ func deleteUserInTransaction(ss *SQLStore, sess *DBSession, cmd *models.DeleteUs return err } } + + return deleteUserAccessControl(sess, cmd.UserId) +} + +func deleteUserAccessControl(sess *DBSession, userID int64) error { + // Delete user role assignments + if _, err := sess.Exec("DELETE FROM user_role WHERE user_id = ?", userID); err != nil { + return err + } + + // Delete permissions that are scoped to user + if _, err := sess.Exec("DELETE FROM permission WHERE scope = ?", ac.Scope("users", "id", strconv.FormatInt(userID, 10))); err != nil { + return err + } + + var roleIDs []int64 + if err := sess.SQL("SELECT id FROM role WHERE name = ?", ac.ManagedUserRoleName(userID)).Find(&roleIDs); err != nil { + return err + } + + if len(roleIDs) == 0 { + return nil + } + + query := "DELETE FROM permission WHERE role_id IN(? " + strings.Repeat(",?", len(roleIDs)-1) + ")" + args := make([]interface{}, 0, len(roleIDs)+1) + args = append(args, query) + for _, id := range roleIDs { + args = append(args, id) + } + + // Delete managed user permissions + if _, err := sess.Exec(args...); err != nil { + return err + } + + // Delete managed user roles + if _, err := sess.Exec("DELETE FROM role WHERE name = ?", ac.ManagedUserRoleName(userID)); err != nil { + return err + } + return nil }