fix: improvements for WebAuthN (#1105)

* add missing translations

* add missing passwordless funcs in api

* remove u2f with verification from setup in login
This commit is contained in:
Livio Amstutz
2020-12-15 16:44:16 +01:00
committed by GitHub
parent 7463bf4fe0
commit 71df1bcd0e
14 changed files with 150 additions and 11 deletions

View File

@@ -2,6 +2,7 @@ package auth
import (
"context"
"github.com/golang/protobuf/ptypes/empty"
"github.com/caos/zitadel/pkg/grpc/auth"
@@ -175,6 +176,14 @@ func (s *Server) RemoveMyMfaU2F(ctx context.Context, id *auth.WebAuthNTokenID) (
return &empty.Empty{}, err
}
func (s *Server) GetMyPasswordless(ctx context.Context, _ *empty.Empty) (_ *auth.WebAuthNTokens, err error) {
tokens, err := s.repo.GetMyPasswordless(ctx)
if err != nil {
return nil, err
}
return webAuthNTokensFromModel(tokens), err
}
func (s *Server) AddMyPasswordless(ctx context.Context, _ *empty.Empty) (_ *auth.WebAuthNResponse, err error) {
u2f, err := s.repo.AddMyPasswordless(ctx)
return verifyWebAuthNFromModel(u2f), err

View File

@@ -436,3 +436,19 @@ func verifyWebAuthNFromModel(u2f *usr_model.WebAuthNToken) *auth.WebAuthNRespons
State: mfaStateFromModel(u2f.State),
}
}
func webAuthNTokensFromModel(tokens []*usr_model.WebAuthNToken) *auth.WebAuthNTokens {
result := make([]*auth.WebAuthNToken, len(tokens))
for i, token := range tokens {
result[i] = webAuthNTokenFromModel(token)
}
return &auth.WebAuthNTokens{Tokens: result}
}
func webAuthNTokenFromModel(token *usr_model.WebAuthNToken) *auth.WebAuthNToken {
return &auth.WebAuthNToken{
Id: token.WebAuthNTokenID,
Name: token.WebAuthNTokenName,
State: mfaStateFromModel(token.State),
}
}

View File

@@ -2,9 +2,11 @@ package management
import (
"context"
"github.com/golang/protobuf/ptypes/empty"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/pkg/grpc/management"
"github.com/golang/protobuf/ptypes/empty"
)
func (s *Server) GetUserByID(ctx context.Context, id *management.UserID) (*management.UserView, error) {
@@ -231,6 +233,19 @@ func (s *Server) RemoveMfaU2F(ctx context.Context, webAuthNTokenID *management.W
return &empty.Empty{}, err
}
func (s *Server) GetPasswordless(ctx context.Context, userID *management.UserID) (_ *management.WebAuthNTokens, err error) {
tokens, err := s.user.GetPasswordless(ctx, userID.Id)
if err != nil {
return nil, err
}
return webAuthNTokensFromModel(tokens), err
}
func (s *Server) RemovePasswordless(ctx context.Context, id *management.WebAuthNTokenID) (*empty.Empty, error) {
err := s.user.RemovePasswordless(ctx, id.UserId, id.Id)
return &empty.Empty{}, err
}
func (s *Server) SearchUserMemberships(ctx context.Context, in *management.UserMembershipSearchRequest) (*management.UserMembershipSearchResponse, error) {
request := userMembershipSearchRequestsToModel(in)
request.AppendUserIDQuery(in.UserId)

View File

@@ -629,3 +629,19 @@ func userChangesToMgtAPI(changes *usr_model.UserChanges) (_ []*management.Change
return result
}
func webAuthNTokensFromModel(tokens []*usr_model.WebAuthNToken) *management.WebAuthNTokens {
result := make([]*management.WebAuthNToken, len(tokens))
for i, token := range tokens {
result[i] = webAuthNTokenFromModel(token)
}
return &management.WebAuthNTokens{Tokens: result}
}
func webAuthNTokenFromModel(token *usr_model.WebAuthNToken) *management.WebAuthNToken {
return &management.WebAuthNToken{
Id: token.WebAuthNTokenID,
Name: token.WebAuthNTokenName,
State: mfaStateFromModel(token.State),
}
}

View File

@@ -326,10 +326,18 @@ func (repo *UserRepo) RemoveMyMFAU2F(ctx context.Context, webAuthNTokenID string
return repo.UserEvents.RemoveU2FToken(ctx, authz.GetCtxData(ctx).UserID, webAuthNTokenID)
}
func (repo *UserRepo) GetPasswordless(ctx context.Context, userID string) ([]*model.WebAuthNToken, error) {
return repo.UserEvents.GetPasswordless(ctx, userID)
}
func (repo *UserRepo) AddPasswordless(ctx context.Context, userID string) (*model.WebAuthNToken, error) {
return repo.UserEvents.AddPasswordless(ctx, userID, true)
}
func (repo *UserRepo) GetMyPasswordless(ctx context.Context) ([]*model.WebAuthNToken, error) {
return repo.UserEvents.GetPasswordless(ctx, authz.GetCtxData(ctx).UserID)
}
func (repo *UserRepo) AddMyPasswordless(ctx context.Context) (*model.WebAuthNToken, error) {
return repo.UserEvents.AddPasswordless(ctx, authz.GetCtxData(ctx).UserID, false)
}

View File

@@ -32,6 +32,7 @@ type UserRepository interface {
VerifyMFAU2FSetup(ctx context.Context, userID, tokenName, userAgentID string, credentialData []byte) error
RemoveMFAU2F(ctx context.Context, userID, webAuthNTokenID string) error
GetPasswordless(ctx context.Context, id string) ([]*model.WebAuthNToken, error)
AddPasswordless(ctx context.Context, id string) (*model.WebAuthNToken, error)
VerifyPasswordlessSetup(ctx context.Context, userID, tokenName, userAgentID string, credentialData []byte) error
RemovePasswordless(ctx context.Context, userID, webAuthNTokenID string) error
@@ -80,6 +81,7 @@ type myUserRepo interface {
VerifyMyMFAU2FSetup(ctx context.Context, tokenName string, data []byte) error
RemoveMyMFAU2F(ctx context.Context, webAuthNTokenID string) error
GetMyPasswordless(ctx context.Context) ([]*model.WebAuthNToken, error)
AddMyPasswordless(ctx context.Context) (*model.WebAuthNToken, error)
VerifyMyPasswordlessSetup(ctx context.Context, tokenName string, data []byte) error
RemoveMyPasswordless(ctx context.Context, webAuthNTokenID string) error

View File

@@ -235,6 +235,14 @@ func (repo *UserRepo) RemoveU2F(ctx context.Context, userID, webAuthNTokenID str
return repo.UserEvents.RemoveU2FToken(ctx, userID, webAuthNTokenID)
}
func (repo *UserRepo) GetPasswordless(ctx context.Context, userID string) ([]*usr_model.WebAuthNToken, error) {
return repo.UserEvents.GetPasswordless(ctx, userID)
}
func (repo *UserRepo) RemovePasswordless(ctx context.Context, userID, webAuthNTokenID string) error {
return repo.UserEvents.RemovePasswordlessToken(ctx, userID, webAuthNTokenID)
}
func (repo *UserRepo) SetOneTimePassword(ctx context.Context, password *usr_model.Password) (*usr_model.Password, error) {
policy, err := repo.View.PasswordComplexityPolicyByAggregateID(authz.GetCtxData(ctx).OrgID)
if err != nil && caos_errs.IsNotFound(err) {

View File

@@ -34,6 +34,9 @@ type UserRepository interface {
RemoveOTP(ctx context.Context, userID string) error
RemoveU2F(ctx context.Context, userID, webAuthNTokenID string) error
GetPasswordless(ctx context.Context, userID string) ([]*model.WebAuthNToken, error)
RemovePasswordless(ctx context.Context, userID, webAuthNTokenID string) error
SearchExternalIDPs(ctx context.Context, request *model.ExternalIDPSearchRequest) (*model.ExternalIDPSearchResponse, error)
RemoveExternalIDP(ctx context.Context, externalIDP *model.ExternalIDP) error

View File

@@ -446,9 +446,16 @@ EventTypes:
login:
added: Login Richtlinie hinzugefügt
changed: Login Richtlinie geändert
removed: Login Richtline gelöscht
idpprovider:
added: Idp Provider zu Login Richtlinie hinzugefügt
removed: Idp Provider aus Login Richtlinie gelöscht
secondfactor:
added: Zweitfaktor zu Login Richtlinie hinzugefügt
removed: Zweitfaktor aus Login Richtlinie gelöscht
multifactor:
added: Multifaktor zu Login Richtlinie hinzugefügt
removed: Multifaktor aus Login Richtlinie gelöscht
password:
complexity:
added: Passwort Komplexitäts Richtlinie hinzugefügt

View File

@@ -446,9 +446,16 @@ EventTypes:
login:
added: Login Policy added
changed: Login Policy changed
removed: Login Policy removed
idpprovider:
added: Idp Provider added to Login Policy
removed: Idp Provider removed from Login Policy
secondfactor:
added: Second factor added to Login Policy
removed: Second factor removed from Login Policy
multifactor:
added: Multi factor added to Login Policy
removed: Multi factor removed from Login Policy
password:
complexity:
added: Password complexity policy added

View File

@@ -136,16 +136,6 @@ func (u *UserView) MFATypesSetupPossible(level req_model.MFALevel, policy *iam_m
}
}
//PLANNED: add sms
fallthrough
case req_model.MFALevelMultiFactor:
if policy.HasMultiFactors() {
for _, mfaType := range policy.MultiFactors {
switch mfaType {
case iam_model.MultiFactorTypeU2FWithPIN:
types = append(types, req_model.MFATypeU2FUserVerification)
}
}
}
}
return types
}

View File

@@ -1410,6 +1410,14 @@ func (es *UserEventstore) VerifyMFAU2F(ctx context.Context, userID string, crede
return finishErr
}
func (es *UserEventstore) GetPasswordless(ctx context.Context, userID string) ([]*usr_model.WebAuthNToken, error) {
user, err := es.HumanByID(ctx, userID)
if err != nil {
return nil, err
}
return user.PasswordlessTokens, nil
}
func (es *UserEventstore) AddPasswordless(ctx context.Context, userID string, isLoginUI bool) (*usr_model.WebAuthNToken, error) {
user, err := es.HumanByID(ctx, userID)
if err != nil {