rename files
This commit is contained in:
+118
-25
@@ -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);
|
||||
`
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user