diff options
author | Harrison Healey <harrisonmhealey@gmail.com> | 2016-05-03 14:10:36 -0400 |
---|---|---|
committer | Christopher Speller <crspeller@gmail.com> | 2016-05-03 14:10:36 -0400 |
commit | 87989b8afd4666a72940389db716b6500d0a9ec3 (patch) | |
tree | d4b0270eb4a9adbff0dd1b6f527ddcccbc9a83d9 /store | |
parent | e76a30bca0690bad53a4cabd6c7c629e89c17268 (diff) | |
download | chat-87989b8afd4666a72940389db716b6500d0a9ec3.tar.gz chat-87989b8afd4666a72940389db716b6500d0a9ec3.tar.bz2 chat-87989b8afd4666a72940389db716b6500d0a9ec3.zip |
PLT-2258 Unified login screen and related APIs (#2820)
* Unified login screen and related APIs
* Refactored login API call to be less convoluted
* Removed LDAP login prompt from invite process
* Fixed existing LDAP users being able to log in if LDAP was configured, but disabled
* Gofmt
* Future proofed login API
* Updated login APIs based on feedback
* Added additional auditing to login API
* Actually removed loginById
Diffstat (limited to 'store')
-rw-r--r-- | store/sql_user_store.go | 41 | ||||
-rw-r--r-- | store/sql_user_store_test.go | 76 | ||||
-rw-r--r-- | store/store.go | 1 |
3 files changed, 118 insertions, 0 deletions
diff --git a/store/sql_user_store.go b/store/sql_user_store.go index 4d18aabd1..37bc148e1 100644 --- a/store/sql_user_store.go +++ b/store/sql_user_store.go @@ -716,6 +716,47 @@ func (us SqlUserStore) GetByUsername(username string) StoreChannel { return storeChannel } +func (us SqlUserStore) GetForLogin(loginId string, allowSignInWithUsername, allowSignInWithEmail, ldapEnabled bool) StoreChannel { + storeChannel := make(StoreChannel) + + go func() { + result := StoreResult{} + + params := map[string]interface{}{ + "LoginId": loginId, + "AllowSignInWithUsername": allowSignInWithUsername, + "AllowSignInWithEmail": allowSignInWithEmail, + "LdapEnabled": ldapEnabled, + } + + users := []*model.User{} + if _, err := us.GetReplica().Select( + &users, + `SELECT + * + FROM + Users + WHERE + (:AllowSignInWithUsername AND Username = :LoginId) + OR (:AllowSignInWithEmail AND Email = :LoginId) + OR (:LdapEnabled AND AuthService = '`+model.USER_AUTH_SERVICE_LDAP+`' AND AuthData = :LoginId)`, + params); err != nil { + result.Err = model.NewLocAppError("SqlUserStore.GetForLogin", "store.sql_user.get_for_login.app_error", nil, err.Error()) + } else if len(users) == 1 { + result.Data = users[0] + } else if len(users) > 1 { + result.Err = model.NewLocAppError("SqlUserStore.GetForLogin", "store.sql_user.get_for_login.multiple_users", nil, "") + } else { + result.Err = model.NewLocAppError("SqlUserStore.GetForLogin", "store.sql_user.get_for_login.app_error", nil, "") + } + + storeChannel <- result + close(storeChannel) + }() + + return storeChannel +} + func (us SqlUserStore) VerifyEmail(userId string) StoreChannel { storeChannel := make(StoreChannel) diff --git a/store/sql_user_store_test.go b/store/sql_user_store_test.go index 9fed32dc8..fbe2285a9 100644 --- a/store/sql_user_store_test.go +++ b/store/sql_user_store_test.go @@ -469,6 +469,82 @@ func TestUserStoreGetByUsername(t *testing.T) { } } +func TestUserStoreGetForLogin(t *testing.T) { + Setup() + + u1 := &model.User{ + Email: model.NewId(), + Username: model.NewId(), + AuthService: model.USER_AUTH_SERVICE_GITLAB, + AuthData: model.NewId(), + } + Must(store.User().Save(u1)) + + u2 := &model.User{ + Email: model.NewId(), + Username: model.NewId(), + AuthService: model.USER_AUTH_SERVICE_LDAP, + AuthData: model.NewId(), + } + Must(store.User().Save(u2)) + + if result := <-store.User().GetForLogin(u1.Username, true, true, true); result.Err != nil { + t.Fatal("Should have gotten user by username", result.Err) + } else if result.Data.(*model.User).Id != u1.Id { + t.Fatal("Should have gotten user1 by username") + } + + if result := <-store.User().GetForLogin(u1.Email, true, true, true); result.Err != nil { + t.Fatal("Should have gotten user by email", result.Err) + } else if result.Data.(*model.User).Id != u1.Id { + t.Fatal("Should have gotten user1 by email") + } + + if result := <-store.User().GetForLogin(u2.AuthData, true, true, true); result.Err != nil { + t.Fatal("Should have gotten user by LDAP AuthData", result.Err) + } else if result.Data.(*model.User).Id != u2.Id { + t.Fatal("Should have gotten user2 by LDAP AuthData") + } + + // prevent getting user by AuthData when they're not an LDAP user + if result := <-store.User().GetForLogin(u1.AuthData, true, true, true); result.Err == nil { + t.Fatal("Should not have gotten user by non-LDAP AuthData") + } + + // prevent getting user when different login methods are disabled + if result := <-store.User().GetForLogin(u1.Username, false, true, true); result.Err == nil { + t.Fatal("Should have failed to get user1 by username") + } + + if result := <-store.User().GetForLogin(u1.Email, true, false, true); result.Err == nil { + t.Fatal("Should have failed to get user1 by email") + } + + if result := <-store.User().GetForLogin(u2.AuthData, true, true, false); result.Err == nil { + t.Fatal("Should have failed to get user3 by LDAP AuthData") + } + + // test a special case where two users will have conflicting login information so we throw a special error + u3 := &model.User{ + Email: model.NewId(), + Username: model.NewId(), + AuthService: model.USER_AUTH_SERVICE_LDAP, + AuthData: model.NewId(), + } + Must(store.User().Save(u3)) + u4 := &model.User{ + Email: model.NewId(), + Username: model.NewId(), + AuthService: model.USER_AUTH_SERVICE_LDAP, + AuthData: u3.Username, + } + Must(store.User().Save(u4)) + + if err := (<-store.User().GetForLogin(u3.Username, true, true, true)).Err; err == nil { + t.Fatal("Should have failed to get users with conflicting login information") + } +} + func TestUserStoreUpdatePassword(t *testing.T) { Setup() diff --git a/store/store.go b/store/store.go index f5c440721..8097fd8e8 100644 --- a/store/store.go +++ b/store/store.go @@ -137,6 +137,7 @@ type UserStore interface { GetByEmail(email string) StoreChannel GetByAuth(authData string, authService string) StoreChannel GetByUsername(username string) StoreChannel + GetForLogin(loginId string, allowSignInWithUsername, allowSignInWithEmail, ldapEnabled bool) StoreChannel VerifyEmail(userId string) StoreChannel GetEtagForProfiles(teamId string) StoreChannel GetEtagForDirectProfiles(userId string) StoreChannel |