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
Этот коммит содержится в:
Harrison Healey
2016-05-03 14:10:36 -04:00
коммит произвёл Christopher Speller
родитель e76a30bca0
Коммит 87989b8afd
36 изменённых файлов: 630 добавлений и 1049 удалений

Просмотреть файл

@@ -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)

Просмотреть файл

@@ -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()

Просмотреть файл

@@ -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