diff --git a/pkg/services/user/userimpl/store.go b/pkg/services/user/userimpl/store.go index f26cf95158f..6ada365b1b0 100644 --- a/pkg/services/user/userimpl/store.go +++ b/pkg/services/user/userimpl/store.go @@ -2,11 +2,15 @@ package userimpl import ( "context" + "errors" "fmt" "strconv" "strings" "time" + "github.com/go-sql-driver/mysql" + "github.com/mattn/go-sqlite3" + "github.com/grafana/grafana/pkg/events" "github.com/grafana/grafana/pkg/infra/db" "github.com/grafana/grafana/pkg/infra/log" @@ -72,7 +76,7 @@ func (ss *sqlStore) Insert(ctx context.Context, cmd *user.User) (int64, error) { return nil }) if err != nil { - return 0, err + return 0, handleSQLError(err) } return cmd.ID, nil @@ -580,3 +584,30 @@ func setOptional[T any](v *T, add func(v T)) { add(*v) } } + +func handleSQLError(err error) error { + if isUniqueConstraintError(err) { + return user.ErrUserAlreadyExists + } + return err +} + +func isUniqueConstraintError(err error) bool { + // check mysql error code + var me *mysql.MySQLError + if errors.As(err, &me) && me.Number == 1062 { + return true + } + + // for postgres we check the error message + if strings.Contains(err.Error(), "duplicate key value") { + return true + } + + var se sqlite3.Error + if errors.As(err, &se) && se.ExtendedCode == sqlite3.ErrConstraintUnique { + return true + } + + return false +} diff --git a/pkg/services/user/userimpl/store_test.go b/pkg/services/user/userimpl/store_test.go index 9d84d64cf17..bca7ac13a49 100644 --- a/pkg/services/user/userimpl/store_test.go +++ b/pkg/services/user/userimpl/store_test.go @@ -68,6 +68,19 @@ func TestIntegrationUserDataAccess(t *testing.T) { require.NoError(t, err) }) + t.Run("error on duplicated user", func(t *testing.T) { + _, err := userStore.Insert(context.Background(), + &user.User{ + Email: "test@email.com", + Name: "test1", + Login: "test1", + Created: time.Now(), + Updated: time.Now(), + }, + ) + require.ErrorIs(t, err, user.ErrUserAlreadyExists) + }) + t.Run("get user", func(t *testing.T) { _, err := userStore.GetByEmail(context.Background(), &user.GetUserByEmailQuery{Email: "test@email.com"},