fix: passwordless (#1116)

* fix passwordless session handling

* only check passwordless when enabled in policy

* set preferred user name in webauthn

* fix tests

* add passwordless in setup

* fix(console): exclude credentials for passwordless (#1115)

* fix: exclude creds

* fix i18n type loginpolicy

* fix enter on dialog input

* remove arg

Co-authored-by: Max Peintner <max@caos.ch>
This commit is contained in:
Livio Amstutz
2020-12-17 16:22:27 +01:00
committed by GitHub
parent c5287364a4
commit b183d49761
19 changed files with 194 additions and 40 deletions

View File

@@ -643,7 +643,7 @@ func (repo *AuthRequestRepo) firstFactorChecked(request *model.AuthRequest, user
return &model.InitUserStep{PasswordSet: user.PasswordSet}
}
if user.IsPasswordlessReady() {
if request.LoginPolicy.PasswordlessType != iam_model.PasswordlessTypeNotAllowed && user.IsPasswordlessReady() {
if !checkVerificationTime(userSession.PasswordlessVerification, repo.MultiFactorCheckLifeTime) {
return &model.PasswordlessStep{}
}
@@ -815,9 +815,8 @@ func userSessionByIDs(ctx context.Context, provider userSessionViewProvider, eve
case es_model.UserRemoved:
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dG2fe", "Errors.User.NotActive")
}
if err := sessionCopy.AppendEvent(event); err != nil {
return user_view_model.UserSessionToModel(&sessionCopy), nil
}
err := sessionCopy.AppendEvent(event)
logging.Log("EVENT-qbhj3").OnError(err).WithField("traceID", tracing.TraceIDFromCtx(ctx)).Warn("error appending event")
}
return user_view_model.UserSessionToModel(&sessionCopy), nil
}

View File

@@ -430,7 +430,7 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
userEventProvider: &mockEventUser{},
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
},
args{&model.AuthRequest{UserID: "UserID"}, false},
args{&model.AuthRequest{UserID: "UserID", LoginPolicy: &iam_model.LoginPolicyView{}}, false},
[]model.NextStep{&model.PasswordStep{}},
nil,
},
@@ -475,7 +475,7 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
MultiFactorCheckLifeTime: 10 * time.Hour,
},
args{&model.AuthRequest{UserID: "UserID"}, false},
args{&model.AuthRequest{UserID: "UserID", LoginPolicy: &iam_model.LoginPolicyView{PasswordlessType: iam_model.PasswordlessTypeAllowed}}, false},
[]model.NextStep{&model.PasswordlessStep{}},
nil,
},
@@ -500,7 +500,8 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
args{&model.AuthRequest{
UserID: "UserID",
LoginPolicy: &iam_model.LoginPolicyView{
MultiFactors: []iam_model.MultiFactorType{iam_model.MultiFactorTypeU2FWithPIN},
PasswordlessType: iam_model.PasswordlessTypeAllowed,
MultiFactors: []iam_model.MultiFactorType{iam_model.MultiFactorTypeU2FWithPIN},
},
}, false},
[]model.NextStep{&model.VerifyEMailStep{}},
@@ -514,7 +515,7 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
userEventProvider: &mockEventUser{},
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
},
args{&model.AuthRequest{UserID: "UserID"}, false},
args{&model.AuthRequest{UserID: "UserID", LoginPolicy: &iam_model.LoginPolicyView{}}, false},
[]model.NextStep{&model.InitPasswordStep{}},
nil,
},
@@ -578,7 +579,7 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
PasswordCheckLifeTime: 10 * 24 * time.Hour,
},
args{&model.AuthRequest{UserID: "UserID"}, false},
args{&model.AuthRequest{UserID: "UserID", LoginPolicy: &iam_model.LoginPolicyView{}}, false},
[]model.NextStep{&model.PasswordStep{}},
nil,
},
@@ -887,6 +888,7 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
args{
&model.AuthRequest{
UserID: "UserID",
LoginPolicy: &iam_model.LoginPolicyView{},
SelectedIDPConfigID: "IDPConfigID",
LinkingUsers: []*model.ExternalUser{{IDPConfigID: "IDPConfigID", ExternalUserID: "UserID", DisplayName: "DisplayName"}},
}, false},

View File

@@ -303,11 +303,26 @@ func (repo *UserRepo) RemoveMyMFAOTP(ctx context.Context) error {
}
func (repo *UserRepo) AddMFAU2F(ctx context.Context, userID string) (*model.WebAuthNToken, error) {
return repo.UserEvents.AddU2F(ctx, userID, true)
accountName := ""
user, err := repo.UserByID(ctx, userID)
if err != nil {
logging.Log("EVENT-DAqe1").WithError(err).WithField("traceID", tracing.TraceIDFromCtx(ctx)).Debug("unable to get user for loginname")
} else {
accountName = user.PreferredLoginName
}
return repo.UserEvents.AddU2F(ctx, userID, accountName, true)
}
func (repo *UserRepo) AddMyMFAU2F(ctx context.Context) (*model.WebAuthNToken, error) {
return repo.UserEvents.AddU2F(ctx, authz.GetCtxData(ctx).UserID, false)
userID := authz.GetCtxData(ctx).UserID
accountName := ""
user, err := repo.UserByID(ctx, userID)
if err != nil {
logging.Log("EVENT-Ghwl1").WithError(err).WithField("traceID", tracing.TraceIDFromCtx(ctx)).Debug("unable to get user for loginname")
} else {
accountName = user.PreferredLoginName
}
return repo.UserEvents.AddU2F(ctx, userID, accountName, false)
}
func (repo *UserRepo) VerifyMFAU2FSetup(ctx context.Context, userID, tokenName, userAgentID string, credentialData []byte) error {
@@ -331,7 +346,14 @@ func (repo *UserRepo) GetPasswordless(ctx context.Context, userID string) ([]*mo
}
func (repo *UserRepo) AddPasswordless(ctx context.Context, userID string) (*model.WebAuthNToken, error) {
return repo.UserEvents.AddPasswordless(ctx, userID, true)
accountName := ""
user, err := repo.UserByID(ctx, userID)
if err != nil {
logging.Log("EVENT-Vj2k1").WithError(err).WithField("traceID", tracing.TraceIDFromCtx(ctx)).Debug("unable to get user for loginname")
} else {
accountName = user.PreferredLoginName
}
return repo.UserEvents.AddPasswordless(ctx, userID, accountName, true)
}
func (repo *UserRepo) GetMyPasswordless(ctx context.Context) ([]*model.WebAuthNToken, error) {
@@ -339,7 +361,15 @@ func (repo *UserRepo) GetMyPasswordless(ctx context.Context) ([]*model.WebAuthNT
}
func (repo *UserRepo) AddMyPasswordless(ctx context.Context) (*model.WebAuthNToken, error) {
return repo.UserEvents.AddPasswordless(ctx, authz.GetCtxData(ctx).UserID, false)
userID := authz.GetCtxData(ctx).UserID
accountName := ""
user, err := repo.UserByID(ctx, userID)
if err != nil {
logging.Log("EVENT-AEq21").WithError(err).WithField("traceID", tracing.TraceIDFromCtx(ctx)).Debug("unable to get user for loginname")
} else {
accountName = user.PreferredLoginName
}
return repo.UserEvents.AddPasswordless(ctx, authz.GetCtxData(ctx).UserID, accountName, false)
}
func (repo *UserRepo) VerifyPasswordlessSetup(ctx context.Context, userID, tokenName, userAgentID string, credentialData []byte) error {