rename files

This commit is contained in:
eleijonmarck
2022-07-19 15:31:37 +01:00
parent 8f7a8c02e7
commit 4eaab95ff3
3 changed files with 142 additions and 25 deletions
@@ -1,8 +1,12 @@
package commands
import (
"bufio"
"context"
"fmt"
"os"
"strconv"
"strings"
"github.com/fatih/color"
"github.com/grafana/grafana/pkg/bus"
@@ -51,8 +55,6 @@ new word for Conflicting : conflicting (prefered now) / multiple
if len(users) == 0 {
return "no users found"
}
// present all users
showUsers()
// ask if user want to start merging
for u in := range (users) {
@@ -79,14 +81,11 @@ func runConflictingUsersCommand() func(context *cli.Context) error {
if err != nil {
return fmt.Errorf("%v: %w", "failed to load configuration", err)
}
tracer, err := tracing.ProvideService(cfg)
if err != nil {
return fmt.Errorf("%v: %w", "failed to initialize tracer service", err)
}
bus := bus.ProvideBus(tracer)
sqlStore, err := sqlstore.ProvideService(cfg, nil, &migrations.OSSMigrations{}, bus, tracer)
if err != nil {
return fmt.Errorf("%v: %w", "failed to initialize SQL store", err)
@@ -96,39 +95,133 @@ func runConflictingUsersCommand() func(context *cli.Context) error {
if err != nil {
return fmt.Errorf("%v: %w", "failed to get users with conflicting logins", err)
}
if len(users) < 1 {
logger.Info(color.GreenString("No Conflicting users found.\n\n"))
return nil
}
// present all users
showUsers()
for _, u := range users {
logger.Infof("id: %v version: %s\n", u.UserIdentifier, u.Ids)
for _, cUser := range users {
logger.Infof("A user conflict found. \n")
cType := cUser.Conflict()
switch cType {
case Merge:
// pretty print conflicting users
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)
if err != nil {
return fmt.Errorf("could not parse id from string")
}
otherUsers := cUser.Ids
logger.Infof("this will merge users %d into the choosen user %s\n\n", otherUsers, choosenUserToMergeInto)
if confirm() {
err = mergeUser(v, cUser, sqlStore)
if err != nil {
return fmt.Errorf("couldnt merge user with error %w", err)
}
}
case SameIdentification:
return fmt.Errorf("have not implemented ways to deal with non mergeable users")
default:
logger.Infof("could not identify the conflict resolution for found users %s", cUser.Ids)
continue
}
}
return nil
}
}
func showUsers() {
// TODO: present users elegantly :D
logger.Info(color.GreenString("users here"))
// confirm function asks for user input
// returns bool
func confirm() bool {
var input string
fmt.Printf("Do you want to continue with this operation? [y|n]: ")
_, err := fmt.Scanln(&input)
if err != nil {
panic(err)
}
input = strings.ToLower(input)
if input == "y" || input == "yes" {
return true
}
return false
}
type conflictUser struct {
func (c ConflictingUsers) Print() {
ids := strings.Split(c.Ids, ",")
emails := strings.Split(c.ConflictEmails, ",")
logins := strings.Split(c.ConflictLogins, ",")
fmt.Printf("\n")
for i := 0; i < len(ids); i++ {
s := fmt.Sprintf("Id: %s, Email: %s, Login: %s\n---\n", ids[i], emails[i], logins[i])
logger.Info(color.HiYellowString((s)))
}
}
type conflictType string
const (
Merge conflictType = "merge"
SameIdentification conflictType = "same_identification"
)
func (cUser ConflictingUsers) Conflict() conflictType {
// FIXME:
// need to make sure that we get sameidentification when that happens instead of email/logins cased
var cType conflictType
if cUser.SameIdentificationConflictIds {
cType = SameIdentification
} else if cUser.ConflictEmails != "" || cUser.ConflictLogins != "" {
cType = Merge
}
return cType
}
func mergeUser(mergeIntoUser int64, cUser ConflictingUsers, sqlStore *sqlstore.SQLStore) error {
stringIds := strings.Split(cUser.Ids, ",")
fromUserIds := make([]int64, 0, len(stringIds))
for _, raw := range stringIds {
v, err := strconv.ParseInt(raw, 10, 64)
if err != nil {
return fmt.Errorf("could not parse id from string")
}
fromUserIds = append(fromUserIds, v)
}
return sqlStore.MergeUser(mergeIntoUser, fromUserIds)
}
type ConflictingUsers struct {
Ids string `xorm:"ids"`
// IDENTIFIER
// userIdentifier = login + email
UserIdentifier string `xorm:"user_identification"`
ConflictEmails string `xorm:"conflicting_emails"`
ConflictLogins string `xorm:"conflicting_logins"`
UserIdentifier string `xorm:"user_identification"`
ConflictEmails string `xorm:"conflicting_emails"`
ConflictLogins string `xorm:"conflicting_logins"`
SameIdentificationConflictIds bool `xorm:"same_identification_conflict_ids"`
}
type conflictUsers []conflictUser
type allConflictingUserAggregates []ConflictingUsers
func GetUsersWithConflictingEmailsOrLogins(ctx context.Context, s *sqlstore.SQLStore) (conflictUsers, error) {
var stats conflictUsers
func GetUsersWithConflictingEmailsOrLogins(ctx context.Context, s *sqlstore.SQLStore) (allConflictingUserAggregates, error) {
var stats allConflictingUserAggregates
outerErr := s.WithDbSession(ctx, func(dbSession *sqlstore.DBSession) error {
rawSQL := conflictingUserEntriesSQL(s)
err := dbSession.SQL(rawSQL).Find(&stats)
@@ -156,24 +249,24 @@ func conflictingUserEntriesSQL(s *sqlstore.SQLStore) string {
FROM
` + userDialect + `
WHERE (LOWER(u1.email) = LOWER(u2.email))
AND(u1.email != u2.email)) AS dup_email, (
AND(u1.email != u2.email)) AS conflict_email, (
SELECT
u1.login
FROM
` + userDialect + `
WHERE (LOWER(u1.login) = LOWER(u2.login)
AND(u1.login != u2.login))) AS dup_login, (
AND(u1.login != u2.login))) AS conflict_login, (
SELECT
u1.id
FROM
` + userDialect + `
WHERE ((u1.login = u2.login)
AND(u1.email = u2.email)
AND(u1.id != u2.id))) AS dup_ids
AND(u1.id != u2.id))) AS same_identification_conflict_ids
FROM
` + userDialect + ` AS u1, ` + userDialect + ` AS u2
WHERE (dup_email IS NOT NULL
OR dup_login IS NOT NULL OR dup_ids IS NOT NULL)
WHERE (conflict_email IS NOT NULL
OR conflict_login IS NOT NULL OR same_identification_conflict_ids IS NOT NULL)
GROUP BY
LOWER(user_identification);
`
+24
View File
@@ -818,6 +818,30 @@ func UserDeletions() []string {
return deletes
}
func updateAllTablesForFromUser(intoUser user.User, fromUserId int64) error {
// TODO:
fmt.Printf("merging user %d into user %d", fromUserId, intoUser.ID)
return nil
}
// UpdateUserPermissions sets the user Server Admin flag
func (ss *SQLStore) MergeUser(intoUserId int64, fromUserIds []int64) error {
return ss.WithTransactionalDbSession(context.Background(), func(sess *DBSession) error {
var intoUser user.User
if _, err := sess.ID(intoUserId).Where(notServiceAccountFilter(ss)).Get(&intoUser); err != nil {
return err
}
for _, fromUserId := range fromUserIds {
// update all tables fromUserIds to intoUserIds
updateAllTablesForFromUser(intoUser, fromUserId)
}
return nil
})
}
// UpdateUserPermissions sets the user Server Admin flag
func (ss *SQLStore) UpdateUserPermissions(userID int64, isAdmin bool) error {
return ss.WithTransactionalDbSession(context.Background(), func(sess *DBSession) error {