fix(login): ignore domain suffix for email / phone check (#7446)

Co-authored-by: Tim Möhlmann <tim+github@zitadel.com>
This commit is contained in:
Livio Spring 2024-02-26 15:05:18 +01:00 committed by GitHub
parent 0542b29517
commit b877abd7a2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -724,10 +724,10 @@ func (repo *AuthRequestRepo) tryUsingOnlyUserSession(ctx context.Context, reques
return nil
}
func (repo *AuthRequestRepo) checkLoginName(ctx context.Context, request *domain.AuthRequest, loginName string) (err error) {
func (repo *AuthRequestRepo) checkLoginName(ctx context.Context, request *domain.AuthRequest, loginNameInput string) (err error) {
var user *user_view_model.UserView
loginName = strings.TrimSpace(loginName)
preferredLoginName := loginName
loginNameInput = strings.TrimSpace(loginNameInput)
preferredLoginName := loginNameInput
if request.RequestedOrgID != "" {
if request.RequestedOrgDomain {
domainPolicy, err := repo.getDomainPolicy(ctx, request.RequestedOrgID)
@ -738,9 +738,9 @@ func (repo *AuthRequestRepo) checkLoginName(ctx context.Context, request *domain
preferredLoginName += "@" + request.RequestedPrimaryDomain
}
}
user, err = repo.checkLoginNameInputForResourceOwner(ctx, request, preferredLoginName)
user, err = repo.checkLoginNameInputForResourceOwner(ctx, request, loginNameInput, preferredLoginName)
} else {
user, err = repo.checkLoginNameInput(ctx, request, preferredLoginName)
user, err = repo.checkLoginNameInput(ctx, request, loginNameInput, preferredLoginName)
}
// return any error apart from not found ones directly
if err != nil && !zerrors.IsNotFound(err) {
@ -748,12 +748,12 @@ func (repo *AuthRequestRepo) checkLoginName(ctx context.Context, request *domain
}
// if there's an active (human) user, let's use it
if user != nil && !user.HumanView.IsZero() && domain.UserState(user.State).NotDisabled() {
request.SetUserInfo(user.ID, loginName, user.PreferredLoginName, "", "", user.ResourceOwner)
request.SetUserInfo(user.ID, loginNameInput, user.PreferredLoginName, "", "", user.ResourceOwner)
return nil
}
// the user was either not found or not active
// so check if the loginname suffix matches a verified org domain
ok, errDomainDiscovery := repo.checkDomainDiscovery(ctx, request, loginName)
ok, errDomainDiscovery := repo.checkDomainDiscovery(ctx, request, loginNameInput)
if errDomainDiscovery != nil || ok {
return errDomainDiscovery
}
@ -768,7 +768,7 @@ func (repo *AuthRequestRepo) checkLoginName(ctx context.Context, request *domain
// let's just check if unknown usernames are ignored
if request.LoginPolicy != nil && request.LoginPolicy.IgnoreUnknownUsernames {
if request.LabelPolicy != nil && request.LabelPolicy.HideLoginNameSuffix {
preferredLoginName = loginName
preferredLoginName = loginNameInput
}
request.SetUserInfo(unknownUserID, preferredLoginName, preferredLoginName, preferredLoginName, "", request.RequestedOrgID)
return nil
@ -783,7 +783,7 @@ func (repo *AuthRequestRepo) checkLoginName(ctx context.Context, request *domain
return zerrors.ThrowPreconditionFailed(nil, "AUTH-DGV4g", "Errors.User.NotHuman")
}
// everything should be handled by now
logging.WithFields("authRequest", request.ID, "loginName", loginName).Error("unhandled state for checkLoginName")
logging.WithFields("authRequest", request.ID, "loginName", loginNameInput).Error("unhandled state for checkLoginName")
return zerrors.ThrowInternal(nil, "AUTH-asf3df", "Errors.Internal")
}
@ -817,13 +817,14 @@ func (repo *AuthRequestRepo) checkDomainDiscovery(ctx context.Context, request *
return true, nil
}
func (repo *AuthRequestRepo) checkLoginNameInput(ctx context.Context, request *domain.AuthRequest, loginNameInput string) (*user_view_model.UserView, error) {
// always check the loginname first
user, err := repo.View.UserByLoginName(ctx, loginNameInput, request.InstanceID)
func (repo *AuthRequestRepo) checkLoginNameInput(ctx context.Context, request *domain.AuthRequest, loginNameInput, preferredLoginName string) (*user_view_model.UserView, error) {
// always check the preferred / suffixed loginname first
user, err := repo.View.UserByLoginName(ctx, preferredLoginName, request.InstanceID)
if err == nil {
// and take the user regardless if there would be a user with that email or phone
return user, repo.checkLoginPolicyWithResourceOwner(ctx, request, user.ResourceOwner)
}
// for email and phone check we will use the loginname as provided by the user (without computed suffix)
user, emailErr := repo.View.UserByEmail(ctx, loginNameInput, request.InstanceID)
if emailErr == nil {
// if there was a single user with the specified email
@ -855,13 +856,14 @@ func (repo *AuthRequestRepo) checkLoginNameInput(ctx context.Context, request *d
return nil, err
}
func (repo *AuthRequestRepo) checkLoginNameInputForResourceOwner(ctx context.Context, request *domain.AuthRequest, loginNameInput string) (*user_view_model.UserView, error) {
// always check the loginname first
user, err := repo.View.UserByLoginNameAndResourceOwner(ctx, loginNameInput, request.RequestedOrgID, request.InstanceID)
func (repo *AuthRequestRepo) checkLoginNameInputForResourceOwner(ctx context.Context, request *domain.AuthRequest, loginNameInput, preferredLoginName string) (*user_view_model.UserView, error) {
// always check the preferred / suffixed loginname first
user, err := repo.View.UserByLoginNameAndResourceOwner(ctx, preferredLoginName, request.RequestedOrgID, request.InstanceID)
if err == nil {
// and take the user regardless if there would be a user with that email or phone
return user, nil
}
// for email and phone check we will use the loginname as provided by the user (without computed suffix)
if request.LoginPolicy != nil && !request.LoginPolicy.DisableLoginWithEmail {
// if login by email is allowed and there was a single user with the specified email
// take that user (and ignore possible phone number matches)