Command: add conflict merge user command
- MergeUser will - replace all user_ids from conflicting users to the chosen userId - delete users whose user_ids are not the chosen user - SameIdentification will - update chosen user with chosen email,login details - delete users whose user_ids are not the chosen user
This commit is contained in:
1 parent
3838a59fa1
commit
29adcd4e48
3 files changed
+145
-30
No files matched your search
@@ -111,32 +111,40 @@ func runConflictingUsersCommand() func(context *cli.Context) error {
|
||||
cUser.Print()
|
||||
|
||||
// waiting for user to choose which user to merge to
|
||||
logger.Infof("Choose which user to merge into:")
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
if ok := scanner.Scan(); !ok {
|
||||
if err := scanner.Err(); err != nil {
|
||||
return fmt.Errorf("can't read conflict option from stdin: %w", err)
|
||||
}
|
||||
return fmt.Errorf("can't read conflict option from stdin")
|
||||
}
|
||||
choosenUserToMergeInto := scanner.Text()
|
||||
if !strings.Contains(cUser.Ids, choosenUserToMergeInto) {
|
||||
return fmt.Errorf("not a conflicting user id")
|
||||
}
|
||||
v, err := strconv.ParseInt(choosenUserToMergeInto, 10, 64)
|
||||
chosenUser, err := promptToMerge(cUser)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse id from string")
|
||||
return err
|
||||
}
|
||||
|
||||
otherUsers := cUser.Ids
|
||||
logger.Infof("this will merge users %d into the choosen user %s\n\n", otherUsers, choosenUserToMergeInto)
|
||||
logger.Infof("this will merge users %s into the chosen user %d\n\n", otherUsers, chosenUser)
|
||||
if confirm() {
|
||||
err = mergeUser(v, cUser, sqlStore)
|
||||
err = mergeUser(context.Context, chosenUser, cUser, sqlStore)
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldnt merge user with error %w", err)
|
||||
return fmt.Errorf("could not merge user with error %w", err)
|
||||
}
|
||||
}
|
||||
case SameIdentification:
|
||||
return fmt.Errorf("have not implemented ways to deal with non mergeable users")
|
||||
// waiting for user to choose which user to merge to
|
||||
chosenUser, err := promptToMerge(cUser)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = sqlStore.UpdateUser(context.Context, &models.UpdateUserCommand{UserId: chosenUser})
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not update user with details %w", err)
|
||||
}
|
||||
otherUsers := strings.Split(cUser.Ids, ",")
|
||||
for _, oUser := range otherUsers {
|
||||
oUser, err := strconv.ParseInt(oUser, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = sqlStore.DeleteUser(context.Context, &models.DeleteUserCommand{UserId: oUser})
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not update user with details %w", err)
|
||||
}
|
||||
}
|
||||
default:
|
||||
logger.Infof("could not identify the conflict resolution for found users %s", cUser.Ids)
|
||||
continue
|
||||
@@ -237,7 +245,7 @@ func (cUser ConflictingUsers) Conflict() conflictType {
|
||||
return cType
|
||||
}
|
||||
|
||||
func mergeUser(mergeIntoUser int64, cUser ConflictingUsers, sqlStore *sqlstore.SQLStore) error {
|
||||
func mergeUser(ctx context.Context, mergeIntoUser int64, cUser ConflictingUsers, sqlStore *sqlstore.SQLStore) error {
|
||||
stringIds := strings.Split(cUser.Ids, ",")
|
||||
fromUserIds := make([]int64, 0, len(stringIds))
|
||||
for _, raw := range stringIds {
|
||||
@@ -247,7 +255,7 @@ func mergeUser(mergeIntoUser int64, cUser ConflictingUsers, sqlStore *sqlstore.S
|
||||
}
|
||||
fromUserIds = append(fromUserIds, v)
|
||||
}
|
||||
return sqlStore.MergeUser(mergeIntoUser, fromUserIds)
|
||||
return sqlStore.MergeUser(ctx, mergeIntoUser, fromUserIds)
|
||||
}
|
||||
|
||||
type ConflictingUsers struct {
|
||||
|
||||
@@ -46,11 +46,74 @@ func TestUserManagerListConflictingUsers(t *testing.T) {
|
||||
}
|
||||
_, err = sqlStore.CreateUser(context.Background(), dupUserLogincmd)
|
||||
require.NoError(t, err)
|
||||
// require metrics and statistics to be 2
|
||||
m, err := GetUsersWithConflictingEmailsOrLogins(context.Background(), sqlStore)
|
||||
t.Logf("%v+", m)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(m))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestMergeUser(t *testing.T) {
|
||||
t.Run("should be able to merge user", func(t *testing.T) {
|
||||
// Restore after destructive operation
|
||||
sqlStore := sqlstore.InitTestDB(t)
|
||||
|
||||
const testOrgID int64 = 1
|
||||
// "Skipping conflicting users test for mysql as it does make unique constraint case insensitive by default
|
||||
if sqlStore.GetDialect().DriverName() != "mysql" {
|
||||
|
||||
// setup
|
||||
dupUserEmailcmd := user.CreateUserCommand{
|
||||
Email: "USERDUPLICATETEST1@TEST.COM",
|
||||
Name: "user name 1",
|
||||
Login: "USER_DUPLICATE_TEST_1_LOGIN",
|
||||
OrgID: testOrgID,
|
||||
}
|
||||
userWithUpperCase, err := sqlStore.CreateUser(context.Background(), dupUserEmailcmd)
|
||||
require.NoError(t, err)
|
||||
|
||||
// add additional user with conflicting login where DOMAIN is upper case
|
||||
dupUserLogincmd := user.CreateUserCommand{
|
||||
Email: "userduplicatetest1@test.com",
|
||||
Name: "user name 1",
|
||||
Login: "user_duplicate_test_1_login",
|
||||
OrgID: testOrgID,
|
||||
}
|
||||
userWithLowerCase, err := sqlStore.CreateUser(context.Background(), dupUserLogincmd)
|
||||
require.NoError(t, err)
|
||||
// fromUser should be replaced by userWithLowerCase
|
||||
team1, err := sqlStore.CreateTeam("group1 name", "test1@test.com", testOrgID)
|
||||
require.NoError(t, err)
|
||||
err = sqlStore.AddTeamMember(userWithUpperCase.ID, testOrgID, team1.Id, false, 0)
|
||||
require.NoError(t, err)
|
||||
// setup finished
|
||||
|
||||
m, err := GetUsersWithConflictingEmailsOrLogins(context.Background(), sqlStore)
|
||||
require.NoError(t, err)
|
||||
mergeErr := mergeUser(context.Background(), userWithLowerCase.ID, m[0], sqlStore)
|
||||
require.NoError(t, mergeErr)
|
||||
|
||||
// start test
|
||||
// fromUser should be deleted after merger
|
||||
t.Logf("testing getting user")
|
||||
query := &models.GetUserByIdQuery{Id: userWithUpperCase.ID}
|
||||
err = sqlStore.GetUserById(context.Background(), query)
|
||||
require.Error(t, models.ErrUserNotFound, err)
|
||||
|
||||
testUser := &models.SignedInUser{
|
||||
OrgId: testOrgID,
|
||||
Permissions: map[int64]map[string][]string{
|
||||
1: {
|
||||
ac.ActionTeamsRead: []string{ac.ScopeTeamsAll},
|
||||
ac.ActionOrgUsersRead: []string{ac.ScopeUsersAll},
|
||||
},
|
||||
},
|
||||
}
|
||||
t.Logf("testing getting team member")
|
||||
q1 := &models.GetTeamMembersQuery{OrgId: testOrgID, TeamId: team1.Id, SignedInUser: testUser}
|
||||
err = sqlStore.GetTeamMembers(context.Background(), q1)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, len(q1.Result))
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user