fix: improvements for login flow (incl. webauthn) (#1026)

* fix: typo ZITADEL uppercase for OTP Issuer

* fix: password validation after change in current user agent

* fix: otp validation after setup in current user agent

* add waiting

* add waiting

* show u2f state

* regenerate css

* add useragentID to webauthn verify

* return mfa attribute in mgmt

* switch between providers

* use preferredLoginName for webauthn display

* some fixes

* correct translations for login

* add some missing event translations

* fix usersession test

* remove unnecessary cancel button on password change done
This commit is contained in:
Livio Amstutz
2020-12-07 12:09:10 +01:00
committed by GitHub
parent 8b88a0ab86
commit 077a9a628e
48 changed files with 451 additions and 123 deletions

View File

@@ -786,7 +786,7 @@ func userSessionByIDs(ctx context.Context, provider userSessionViewProvider, eve
if !errors.IsNotFound(err) {
return nil, err
}
session = &user_view_model.UserSessionView{}
session = &user_view_model.UserSessionView{UserAgentID: agentID, UserID: user.ID}
}
events, err := eventProvider.UserEventsByID(ctx, user.ID, session.Sequence)
if err != nil {
@@ -824,7 +824,9 @@ func userSessionByIDs(ctx context.Context, provider userSessionViewProvider, eve
case es_model.UserRemoved:
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dG2fe", "Errors.User.NotActive")
}
sessionCopy.AppendEvent(event)
if err := sessionCopy.AppendEvent(event); err != nil {
return user_view_model.UserSessionToModel(&sessionCopy), nil
}
}
return user_view_model.UserSessionToModel(&sessionCopy), nil
}

View File

@@ -1208,7 +1208,7 @@ func Test_userSessionByIDs(t *testing.T) {
eventProvider: &mockEventErrUser{},
user: &user_model.UserView{ID: "id"},
},
&user_model.UserSessionView{},
&user_model.UserSessionView{UserID: "id"},
nil,
},
{

View File

@@ -234,11 +234,11 @@ func (repo *UserRepo) ChangeMyPassword(ctx context.Context, old, new string) err
return err
}
pwPolicyView := iam_es_model.PasswordComplexityViewToModel(policy)
_, err = repo.UserEvents.ChangePassword(ctx, pwPolicyView, authz.GetCtxData(ctx).UserID, old, new)
_, err = repo.UserEvents.ChangePassword(ctx, pwPolicyView, authz.GetCtxData(ctx).UserID, old, new, "")
return err
}
func (repo *UserRepo) ChangePassword(ctx context.Context, userID, old, new string) (err error) {
func (repo *UserRepo) ChangePassword(ctx context.Context, userID, old, new, userAgentID string) (err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
policy, err := repo.View.PasswordComplexityPolicyByAggregateID(authz.GetCtxData(ctx).OrgID)
@@ -249,7 +249,7 @@ func (repo *UserRepo) ChangePassword(ctx context.Context, userID, old, new strin
return err
}
pwPolicyView := iam_es_model.PasswordComplexityViewToModel(policy)
_, err = repo.UserEvents.ChangePassword(ctx, pwPolicyView, userID, old, new)
_, err = repo.UserEvents.ChangePassword(ctx, pwPolicyView, userID, old, new, userAgentID)
return err
}
@@ -290,12 +290,12 @@ func (repo *UserRepo) AddMyMFAOTP(ctx context.Context) (*model.OTP, error) {
return repo.UserEvents.AddOTP(ctx, authz.GetCtxData(ctx).UserID, accountName)
}
func (repo *UserRepo) VerifyMFAOTPSetup(ctx context.Context, userID, code string) error {
return repo.UserEvents.CheckMFAOTPSetup(ctx, userID, code)
func (repo *UserRepo) VerifyMFAOTPSetup(ctx context.Context, userID, code, userAgentID string) error {
return repo.UserEvents.CheckMFAOTPSetup(ctx, userID, code, userAgentID)
}
func (repo *UserRepo) VerifyMyMFAOTPSetup(ctx context.Context, code string) error {
return repo.UserEvents.CheckMFAOTPSetup(ctx, authz.GetCtxData(ctx).UserID, code)
return repo.UserEvents.CheckMFAOTPSetup(ctx, authz.GetCtxData(ctx).UserID, code, "")
}
func (repo *UserRepo) RemoveMyMFAOTP(ctx context.Context) error {
@@ -310,12 +310,12 @@ func (repo *UserRepo) AddMyMFAU2F(ctx context.Context) (*model.WebAuthNToken, er
return repo.UserEvents.AddU2F(ctx, authz.GetCtxData(ctx).UserID)
}
func (repo *UserRepo) VerifyMFAU2FSetup(ctx context.Context, userID, tokenName string, credentialData []byte) error {
return repo.UserEvents.VerifyU2FSetup(ctx, userID, tokenName, credentialData)
func (repo *UserRepo) VerifyMFAU2FSetup(ctx context.Context, userID, tokenName, userAgentID string, credentialData []byte) error {
return repo.UserEvents.VerifyU2FSetup(ctx, userID, tokenName, userAgentID, credentialData)
}
func (repo *UserRepo) VerifyMyMFAU2FSetup(ctx context.Context, tokenName string, credentialData []byte) error {
return repo.UserEvents.VerifyU2FSetup(ctx, authz.GetCtxData(ctx).UserID, tokenName, credentialData)
return repo.UserEvents.VerifyU2FSetup(ctx, authz.GetCtxData(ctx).UserID, tokenName, "", credentialData)
}
func (repo *UserRepo) RemoveMFAU2F(ctx context.Context, userID, webAuthNTokenID string) error {
@@ -334,12 +334,12 @@ func (repo *UserRepo) AddMyPasswordless(ctx context.Context) (*model.WebAuthNTok
return repo.UserEvents.AddPasswordless(ctx, authz.GetCtxData(ctx).UserID)
}
func (repo *UserRepo) VerifyPasswordlessSetup(ctx context.Context, userID, tokenName string, credentialData []byte) error {
return repo.UserEvents.VerifyPasswordlessSetup(ctx, userID, tokenName, credentialData)
func (repo *UserRepo) VerifyPasswordlessSetup(ctx context.Context, userID, tokenName, userAgentID string, credentialData []byte) error {
return repo.UserEvents.VerifyPasswordlessSetup(ctx, userID, tokenName, userAgentID, credentialData)
}
func (repo *UserRepo) VerifyMyPasswordlessSetup(ctx context.Context, tokenName string, credentialData []byte) error {
return repo.UserEvents.VerifyPasswordlessSetup(ctx, authz.GetCtxData(ctx).UserID, tokenName, credentialData)
return repo.UserEvents.VerifyPasswordlessSetup(ctx, authz.GetCtxData(ctx).UserID, tokenName, "", credentialData)
}
func (repo *UserRepo) RemovePasswordless(ctx context.Context, userID, webAuthNTokenID string) error {
@@ -391,7 +391,7 @@ func (repo *UserRepo) RequestPasswordReset(ctx context.Context, loginname string
return repo.UserEvents.RequestSetPassword(ctx, user.ID, model.NotificationTypeEmail)
}
func (repo *UserRepo) SetPassword(ctx context.Context, userID, code, password string) error {
func (repo *UserRepo) SetPassword(ctx context.Context, userID, code, password, userAgentID string) error {
policy, err := repo.View.PasswordComplexityPolicyByAggregateID(authz.GetCtxData(ctx).OrgID)
if errors.IsNotFound(err) {
policy, err = repo.View.PasswordComplexityPolicyByAggregateID(repo.SystemDefaults.IamID)
@@ -400,7 +400,7 @@ func (repo *UserRepo) SetPassword(ctx context.Context, userID, code, password st
return err
}
pwPolicyView := iam_es_model.PasswordComplexityViewToModel(policy)
return repo.UserEvents.SetPassword(ctx, pwPolicyView, userID, code, password)
return repo.UserEvents.SetPassword(ctx, pwPolicyView, userID, code, password, userAgentID)
}
func (repo *UserRepo) SignOut(ctx context.Context, agentID string) error {

View File

@@ -93,7 +93,9 @@ func (u *UserSession) Reduce(event *models.Event) (err error) {
return u.view.ProcessedUserSessionSequence(event.Sequence, event.CreationDate)
}
for _, session := range sessions {
session.AppendEvent(event)
if err := session.AppendEvent(event); err != nil {
return err
}
if err := u.fillUserInfo(session, event.AggregateID); err != nil {
return err
}
@@ -116,7 +118,9 @@ func (u *UserSession) OnSuccess() error {
}
func (u *UserSession) updateSession(session *view_model.UserSessionView, event *models.Event) error {
session.AppendEvent(event)
if err := session.AppendEvent(event); err != nil {
return err
}
if err := u.fillUserInfo(session, event.AggregateID); err != nil {
return err
}

View File

@@ -16,8 +16,8 @@ type UserRepository interface {
SkipMFAInit(ctx context.Context, userID string) error
RequestPasswordReset(ctx context.Context, username string) error
SetPassword(ctx context.Context, userID, code, password string) error
ChangePassword(ctx context.Context, userID, old, new string) error
SetPassword(ctx context.Context, userID, code, password, userAgentID string) error
ChangePassword(ctx context.Context, userID, old, new, userAgentID string) error
VerifyEmail(ctx context.Context, userID, code string) error
ResendEmailVerificationMail(ctx context.Context, userID string) error
@@ -26,14 +26,14 @@ type UserRepository interface {
ResendInitVerificationMail(ctx context.Context, userID string) error
AddMFAOTP(ctx context.Context, userID string) (*model.OTP, error)
VerifyMFAOTPSetup(ctx context.Context, userID, code string) error
VerifyMFAOTPSetup(ctx context.Context, userID, code, userAgentID string) error
AddMFAU2F(ctx context.Context, id string) (*model.WebAuthNToken, error)
VerifyMFAU2FSetup(ctx context.Context, userID, tokenName string, credentialData []byte) error
VerifyMFAU2FSetup(ctx context.Context, userID, tokenName, userAgentID string, credentialData []byte) error
RemoveMFAU2F(ctx context.Context, userID, webAuthNTokenID string) error
AddPasswordless(ctx context.Context, id string) (*model.WebAuthNToken, error)
VerifyPasswordlessSetup(ctx context.Context, userID, tokenName string, credentialData []byte) error
VerifyPasswordlessSetup(ctx context.Context, userID, tokenName, userAgentID string, credentialData []byte) error
RemovePasswordless(ctx context.Context, userID, webAuthNTokenID string) error
ChangeUsername(ctx context.Context, userID, username string) error