فهرست منبع

Remove user form org now completely removes the user from the system if the user is orphaned

Torkel Ödegaard 7 سال پیش
والد
کامیت
5b5cb6622d
5فایلهای تغییر یافته به همراه71 افزوده شده و 37 حذف شده
  1. 11 9
      pkg/api/org_users.go
  2. 3 2
      pkg/models/org_user.go
  3. 14 0
      pkg/services/sqlstore/org_test.go
  4. 23 10
      pkg/services/sqlstore/org_users.go
  5. 20 16
      pkg/services/sqlstore/user.go

+ 11 - 9
pkg/api/org_users.go

@@ -102,21 +102,23 @@ func updateOrgUserHelper(cmd m.UpdateOrgUserCommand) Response {
 
 // DELETE /api/org/users/:userId
 func RemoveOrgUserForCurrentOrg(c *m.ReqContext) Response {
-	userID := c.ParamsInt64(":userId")
-	return removeOrgUserHelper(c.OrgId, userID)
+	return removeOrgUserHelper(&m.RemoveOrgUserCommand{
+		UserId:                   c.ParamsInt64(":userId"),
+		OrgId:                    c.OrgId,
+		ShouldDeleteOrphanedUser: true,
+	})
 }
 
 // DELETE /api/orgs/:orgId/users/:userId
 func RemoveOrgUser(c *m.ReqContext) Response {
-	userID := c.ParamsInt64(":userId")
-	orgID := c.ParamsInt64(":orgId")
-	return removeOrgUserHelper(orgID, userID)
+	return removeOrgUserHelper(&m.RemoveOrgUserCommand{
+		UserId: c.ParamsInt64(":userId"),
+		OrgId:  c.ParamsInt64(":orgId"),
+	})
 }
 
-func removeOrgUserHelper(orgID int64, userID int64) Response {
-	cmd := m.RemoveOrgUserCommand{OrgId: orgID, UserId: userID}
-
-	if err := bus.Dispatch(&cmd); err != nil {
+func removeOrgUserHelper(cmd *m.RemoveOrgUserCommand) Response {
+	if err := bus.Dispatch(cmd); err != nil {
 		if err == m.ErrLastOrgAdmin {
 			return Error(400, "Cannot remove last organization admin", nil)
 		}

+ 3 - 2
pkg/models/org_user.go

@@ -72,8 +72,9 @@ type OrgUser struct {
 // COMMANDS
 
 type RemoveOrgUserCommand struct {
-	UserId int64
-	OrgId  int64
+	UserId                   int64
+	OrgId                    int64
+	ShouldDeleteOrphanedUser bool
 }
 
 type AddOrgUserCommand struct {

+ 14 - 0
pkg/services/sqlstore/org_test.go

@@ -182,6 +182,20 @@ func TestAccountDataAccess(t *testing.T) {
 					})
 				})
 
+				Convey("Removing user from org should delete user completely if in no other org", func() {
+					// make sure ac2 has no org
+					err := DeleteOrg(&m.DeleteOrgCommand{Id: ac2.OrgId})
+					So(err, ShouldBeNil)
+
+					// remove frome ac2 from ac1 org
+					remCmd := m.RemoveOrgUserCommand{OrgId: ac1.OrgId, UserId: ac2.Id, ShouldDeleteOrphanedUser: true}
+					err = RemoveOrgUser(&remCmd)
+					So(err, ShouldBeNil)
+
+					err = GetSignedInUser(&m.GetSignedInUserQuery{UserId: ac2.Id})
+					So(err, ShouldEqual, m.ErrUserNotFound)
+				})
+
 				Convey("Cannot delete last admin org user", func() {
 					cmd := m.RemoveOrgUserCommand{OrgId: ac1.OrgId, UserId: ac1.Id}
 					err := RemoveOrgUser(&cmd)

+ 23 - 10
pkg/services/sqlstore/org_users.go

@@ -157,6 +157,12 @@ func RemoveOrgUser(cmd *m.RemoveOrgUserCommand) error {
 			}
 		}
 
+		// validate that after delete there is at least one user with admin role in org
+		if err := validateOneAdminLeftInOrg(cmd.OrgId, sess); err != nil {
+			return err
+		}
+
+		// check user other orgs and update user current org
 		var userOrgs []*m.UserOrgDTO
 		sess.Table("org_user")
 		sess.Join("INNER", "org", "org_user.org_id=org.id")
@@ -168,22 +174,29 @@ func RemoveOrgUser(cmd *m.RemoveOrgUserCommand) error {
 			return err
 		}
 
-		hasCurrentOrgSet := false
-		for _, userOrg := range userOrgs {
-			if user.OrgId == userOrg.OrgId {
-				hasCurrentOrgSet = true
-				break
+		if len(userOrgs) > 0 {
+			hasCurrentOrgSet := false
+			for _, userOrg := range userOrgs {
+				if user.OrgId == userOrg.OrgId {
+					hasCurrentOrgSet = true
+					break
+				}
 			}
-		}
 
-		if !hasCurrentOrgSet && len(userOrgs) > 0 {
-			err = setUsingOrgInTransaction(sess, user.Id, userOrgs[0].OrgId)
-			if err != nil {
+			if !hasCurrentOrgSet {
+				err = setUsingOrgInTransaction(sess, user.Id, userOrgs[0].OrgId)
+				if err != nil {
+					return err
+				}
+			}
+		} else if cmd.ShouldDeleteOrphanedUser {
+			// no other orgs, delete the full user
+			if err := deleteUserInTransaction(sess, &m.DeleteUserCommand{UserId: user.Id}); err != nil {
 				return err
 			}
 		}
 
-		return validateOneAdminLeftInOrg(cmd.OrgId, sess)
+		return nil
 	})
 }
 

+ 20 - 16
pkg/services/sqlstore/user.go

@@ -445,25 +445,29 @@ func SearchUsers(query *m.SearchUsersQuery) error {
 
 func DeleteUser(cmd *m.DeleteUserCommand) error {
 	return inTransaction(func(sess *DBSession) error {
-		deletes := []string{
-			"DELETE FROM star WHERE user_id = ?",
-			"DELETE FROM " + dialect.Quote("user") + " WHERE id = ?",
-			"DELETE FROM org_user WHERE user_id = ?",
-			"DELETE FROM dashboard_acl WHERE user_id = ?",
-			"DELETE FROM preferences WHERE user_id = ?",
-			"DELETE FROM team_member WHERE user_id = ?",
-			"DELETE FROM user_auth WHERE user_id = ?",
-		}
+		return deleteUserInTransaction(sess, cmd)
+	})
+}
 
-		for _, sql := range deletes {
-			_, err := sess.Exec(sql, cmd.UserId)
-			if err != nil {
-				return err
-			}
+func deleteUserInTransaction(sess *DBSession, cmd *m.DeleteUserCommand) error {
+	deletes := []string{
+		"DELETE FROM star WHERE user_id = ?",
+		"DELETE FROM " + dialect.Quote("user") + " WHERE id = ?",
+		"DELETE FROM org_user WHERE user_id = ?",
+		"DELETE FROM dashboard_acl WHERE user_id = ?",
+		"DELETE FROM preferences WHERE user_id = ?",
+		"DELETE FROM team_member WHERE user_id = ?",
+		"DELETE FROM user_auth WHERE user_id = ?",
+	}
+
+	for _, sql := range deletes {
+		_, err := sess.Exec(sql, cmd.UserId)
+		if err != nil {
+			return err
 		}
+	}
 
-		return nil
-	})
+	return nil
 }
 
 func UpdateUserPermissions(cmd *m.UpdateUserPermissionsCommand) error {