Blame SOURCES/0010-v9.0.x-Login-email-before-username-57406.patch

05d305
From 74f3c59f7096b5c31d5c218310b20775eb111d0f Mon Sep 17 00:00:00 2001
05d305
From: Karl Persson <kalle.persson@grafana.com>
05d305
Date: Fri, 21 Oct 2022 14:15:21 +0200
05d305
Subject: [PATCH] [v9.0.x] Login email before username (#57406)
05d305
05d305
* Add test for username/login field conflict
05d305
05d305
* Swap order of login fields
05d305
05d305
Co-authored-by: linoman <2051016+linoman@users.noreply.github.com>
05d305
05d305
diff --git a/pkg/services/sqlstore/user.go b/pkg/services/sqlstore/user.go
05d305
index 9cd80da396..00e3ddc2df 100644
05d305
--- a/pkg/services/sqlstore/user.go
05d305
+++ b/pkg/services/sqlstore/user.go
05d305
@@ -170,20 +170,24 @@ func (ss *SQLStore) GetUserByLogin(ctx context.Context, query *models.GetUserByL
05d305
 			return models.ErrUserNotFound
05d305
 		}
05d305
 
05d305
-		// Try and find the user by login first.
05d305
-		// It's not sufficient to assume that a LoginOrEmail with an "@" is an email.
05d305
+		var has bool
05d305
+		var err error
05d305
 		user := &models.User{Login: query.LoginOrEmail}
05d305
-		has, err := sess.Where(notServiceAccountFilter(ss)).Get(user)
05d305
-
05d305
-		if err != nil {
05d305
-			return err
05d305
-		}
05d305
 
05d305
-		if !has && strings.Contains(query.LoginOrEmail, "@") {
05d305
-			// If the user wasn't found, and it contains an "@" fallback to finding the
05d305
-			// user by email.
05d305
+		// Since username can be an email address, attempt login with email address
05d305
+		// first if the login field has the "@" symbol.
05d305
+		if strings.Contains(query.LoginOrEmail, "@") {
05d305
 			user = &models.User{Email: query.LoginOrEmail}
05d305
 			has, err = sess.Get(user)
05d305
+
05d305
+			if err != nil {
05d305
+				return err
05d305
+			}
05d305
+		}
05d305
+
05d305
+		// Lookup the login field instead of email field
05d305
+		if !has {
05d305
+			has, err = sess.Where(notServiceAccountFilter(ss)).Get(user)
05d305
 		}
05d305
 
05d305
 		if err != nil {
05d305
diff --git a/pkg/services/sqlstore/user_test.go b/pkg/services/sqlstore/user_test.go
05d305
index d3803fa0c9..da23a7cca9 100644
05d305
--- a/pkg/services/sqlstore/user_test.go
05d305
+++ b/pkg/services/sqlstore/user_test.go
05d305
@@ -51,6 +51,45 @@ func TestIntegrationUserDataAccess(t *testing.T) {
05d305
 		require.False(t, query.Result.IsDisabled)
05d305
 	})
05d305
 
05d305
+	t.Run("Get User by login - user_2 uses user_1.email as login", func(t *testing.T) {
05d305
+		ss = InitTestDB(t)
05d305
+
05d305
+		// create user_1
05d305
+		cmd := models.CreateUserCommand{
05d305
+			Email:      "user_1@mail.com",
05d305
+			Name:       "user_1",
05d305
+			Login:      "user_1",
05d305
+			Password:   "user_1_password",
05d305
+			IsDisabled: true,
05d305
+		}
05d305
+		user_1, err := ss.CreateUser(context.Background(), cmd)
05d305
+		require.Nil(t, err)
05d305
+
05d305
+		// create user_2
05d305
+		cmd = models.CreateUserCommand{
05d305
+			Email:      "user_2@mail.com",
05d305
+			Name:       "user_2",
05d305
+			Login:      "user_1@mail.com",
05d305
+			Password:   "user_2_password",
05d305
+			IsDisabled: true,
05d305
+		}
05d305
+		user_2, err := ss.CreateUser(context.Background(), cmd)
05d305
+		require.Nil(t, err)
05d305
+
05d305
+		// query user database for user_1 email
05d305
+		query := models.GetUserByLoginQuery{LoginOrEmail: "user_1@mail.com"}
05d305
+		err = ss.GetUserByLogin(context.Background(), &query)
05d305
+		require.Nil(t, err)
05d305
+
05d305
+		// expect user_1 as result
05d305
+		require.Equal(t, user_1.Email, query.Result.Email)
05d305
+		require.Equal(t, user_1.Login, query.Result.Login)
05d305
+		require.Equal(t, user_1.Name, query.Result.Name)
05d305
+		require.NotEqual(t, user_2.Email, query.Result.Email)
05d305
+		require.NotEqual(t, user_2.Login, query.Result.Login)
05d305
+		require.NotEqual(t, user_2.Name, query.Result.Name)
05d305
+	})
05d305
+
05d305
 	t.Run("Testing DB - creates and loads disabled user", func(t *testing.T) {
05d305
 		ss = InitTestDB(t)
05d305
 		cmd := models.CreateUserCommand{