feat: mfa policy (#913)

* feat: add mfa to login policy

* feat: add mfa to login policy

* feat: add mfa to login policy

* feat: add mfa to login policy

* feat: add mfa to login policy on org

* feat: add mfa to login policy on org

* feat: append events on policy views

* feat: iam login policy mfa definition

* feat: login policies on orgs

* feat: configured mfas in login process

* feat: configured mfas in login process

* Update internal/ui/login/static/i18n/en.yaml

Co-authored-by: Livio Amstutz <livio.a@gmail.com>

* fix: rename software and hardware mfas

* fix: pr requests

* fix user mfa

* fix: test

* fix: oidc version

* fix: oidc version

* fix: proto gen

Co-authored-by: Livio Amstutz <livio.a@gmail.com>
Co-authored-by: Max Peintner <max@caos.ch>
This commit is contained in:
Fabi
2020-11-04 11:26:10 +01:00
committed by GitHub
parent 51417be35d
commit 202aae4954
76 changed files with 12913 additions and 5614 deletions

View File

@@ -42,3 +42,45 @@ func (s *Server) RemoveIdpProviderFromDefaultLoginPolicy(ctx context.Context, pr
err := s.iam.RemoveIDPProviderFromLoginPolicy(ctx, idpProviderToModel(provider))
return &empty.Empty{}, err
}
func (s *Server) GetDefaultLoginPolicySecondFactors(ctx context.Context, _ *empty.Empty) (*admin.SecondFactorsResult, error) {
result, err := s.iam.SearchDefaultSecondFactors(ctx)
if err != nil {
return nil, err
}
return secondFactorsResultFromModel(result), nil
}
func (s *Server) AddSecondFactorToDefaultLoginPolicy(ctx context.Context, mfa *admin.SecondFactor) (*admin.SecondFactor, error) {
result, err := s.iam.AddSecondFactorToLoginPolicy(ctx, secondFactorTypeToModel(mfa))
if err != nil {
return nil, err
}
return secondFactorFromModel(result), nil
}
func (s *Server) RemoveSecondFactorFromDefaultLoginPolicy(ctx context.Context, mfa *admin.SecondFactor) (*empty.Empty, error) {
err := s.iam.RemoveSecondFactorFromLoginPolicy(ctx, secondFactorTypeToModel(mfa))
return &empty.Empty{}, err
}
func (s *Server) GetDefaultLoginPolicyMultiFactors(ctx context.Context, _ *empty.Empty) (*admin.MultiFactorsResult, error) {
result, err := s.iam.SearchDefaultMultiFactors(ctx)
if err != nil {
return nil, err
}
return multiFactorResultFromModel(result), nil
}
func (s *Server) AddMultiFactorToDefaultLoginPolicy(ctx context.Context, mfa *admin.MultiFactor) (*admin.MultiFactor, error) {
result, err := s.iam.AddMultiFactorToLoginPolicy(ctx, multiFactorTypeToModel(mfa))
if err != nil {
return nil, err
}
return multiFactorFromModel(result), nil
}
func (s *Server) RemoveMultiFactorFromDefaultLoginPolicy(ctx context.Context, mfa *admin.MultiFactor) (*empty.Empty, error) {
err := s.iam.RemoveMultiFactorFromLoginPolicy(ctx, multiFactorTypeToModel(mfa))
return &empty.Empty{}, err
}

View File

@@ -12,6 +12,7 @@ func loginPolicyToModel(policy *admin.DefaultLoginPolicyRequest) *iam_model.Logi
AllowUsernamePassword: policy.AllowUsernamePassword,
AllowExternalIdp: policy.AllowExternalIdp,
AllowRegister: policy.AllowRegister,
ForceMFA: policy.ForceMfa,
}
}
@@ -26,6 +27,7 @@ func loginPolicyFromModel(policy *iam_model.LoginPolicy) *admin.DefaultLoginPoli
AllowUsernamePassword: policy.AllowUsernamePassword,
AllowExternalIdp: policy.AllowExternalIdp,
AllowRegister: policy.AllowRegister,
ForceMfa: policy.ForceMFA,
CreationDate: creationDate,
ChangeDate: changeDate,
}
@@ -42,6 +44,7 @@ func loginPolicyViewFromModel(policy *iam_model.LoginPolicyView) *admin.DefaultL
AllowUsernamePassword: policy.AllowUsernamePassword,
AllowExternalIdp: policy.AllowExternalIDP,
AllowRegister: policy.AllowRegister,
ForceMfa: policy.ForceMFA,
CreationDate: creationDate,
ChangeDate: changeDate,
}
@@ -103,3 +106,75 @@ func idpConfigTypeToModel(providerType iam_model.IdpConfigType) admin.IdpType {
return admin.IdpType_IDPTYPE_UNSPECIFIED
}
}
func secondFactorsResultFromModel(result *iam_model.SecondFactorsSearchResponse) *admin.SecondFactorsResult {
converted := make([]admin.SecondFactorType, len(result.Result))
for i, mfaType := range result.Result {
converted[i] = secondFactorTypeFromModel(mfaType)
}
return &admin.SecondFactorsResult{
SecondFactors: converted,
}
}
func secondFactorFromModel(mfaType iam_model.SecondFactorType) *admin.SecondFactor {
return &admin.SecondFactor{
SecondFactor: secondFactorTypeFromModel(mfaType),
}
}
func secondFactorTypeFromModel(mfaType iam_model.SecondFactorType) admin.SecondFactorType {
switch mfaType {
case iam_model.SecondFactorTypeOTP:
return admin.SecondFactorType_SECONDFACTORTYPE_OTP
case iam_model.SecondFactorTypeU2F:
return admin.SecondFactorType_SECONDFACTORTYPE_U2F
default:
return admin.SecondFactorType_SECONDFACTORTYPE_UNSPECIFIED
}
}
func secondFactorTypeToModel(mfaType *admin.SecondFactor) iam_model.SecondFactorType {
switch mfaType.SecondFactor {
case admin.SecondFactorType_SECONDFACTORTYPE_OTP:
return iam_model.SecondFactorTypeOTP
case admin.SecondFactorType_SECONDFACTORTYPE_U2F:
return iam_model.SecondFactorTypeU2F
default:
return iam_model.SecondFactorTypeUnspecified
}
}
func multiFactorResultFromModel(result *iam_model.MultiFactorsSearchResponse) *admin.MultiFactorsResult {
converted := make([]admin.MultiFactorType, len(result.Result))
for i, mfaType := range result.Result {
converted[i] = multiFactorTypeFromModel(mfaType)
}
return &admin.MultiFactorsResult{
MultiFactors: converted,
}
}
func multiFactorFromModel(mfaType iam_model.MultiFactorType) *admin.MultiFactor {
return &admin.MultiFactor{
MultiFactor: multiFactorTypeFromModel(mfaType),
}
}
func multiFactorTypeFromModel(mfaType iam_model.MultiFactorType) admin.MultiFactorType {
switch mfaType {
case iam_model.MultiFactorTypeU2FWithPIN:
return admin.MultiFactorType_MULTIFACTORTYPE_U2F_WITH_PIN
default:
return admin.MultiFactorType_MULTIFACTORTYPE_UNSPECIFIED
}
}
func multiFactorTypeToModel(mfaType *admin.MultiFactor) iam_model.MultiFactorType {
switch mfaType.MultiFactor {
case admin.MultiFactorType_MULTIFACTORTYPE_U2F_WITH_PIN:
return iam_model.MultiFactorTypeU2FWithPIN
default:
return iam_model.MultiFactorTypeUnspecified
}
}

View File

@@ -63,3 +63,45 @@ func (s *Server) RemoveIdpProviderFromLoginPolicy(ctx context.Context, provider
err := s.org.RemoveIDPProviderFromLoginPolicy(ctx, idpProviderToModel(provider))
return &empty.Empty{}, err
}
func (s *Server) GetLoginPolicySecondFactors(ctx context.Context, _ *empty.Empty) (*management.SecondFactorsResult, error) {
result, err := s.org.SearchSecondFactors(ctx)
if err != nil {
return nil, err
}
return secondFactorResultFromModel(result), nil
}
func (s *Server) AddSecondFactorToLoginPolicy(ctx context.Context, mfa *management.SecondFactor) (*management.SecondFactor, error) {
result, err := s.org.AddSecondFactorToLoginPolicy(ctx, secondFactorTypeToModel(mfa))
if err != nil {
return nil, err
}
return secondFactorFromModel(result), nil
}
func (s *Server) RemoveSecondFactorFromLoginPolicy(ctx context.Context, mfa *management.SecondFactor) (*empty.Empty, error) {
err := s.org.RemoveSecondFactorFromLoginPolicy(ctx, secondFactorTypeToModel(mfa))
return &empty.Empty{}, err
}
func (s *Server) GetLoginPolicyMultiFactors(ctx context.Context, _ *empty.Empty) (*management.MultiFactorsResult, error) {
result, err := s.org.SearchMultiFactors(ctx)
if err != nil {
return nil, err
}
return multiFactorResultFromModel(result), nil
}
func (s *Server) AddMultiFactorToLoginPolicy(ctx context.Context, mfa *management.MultiFactor) (*management.MultiFactor, error) {
result, err := s.org.AddMultiFactorToLoginPolicy(ctx, multiFactorTypeToModel(mfa))
if err != nil {
return nil, err
}
return multiFactorFromModel(result), nil
}
func (s *Server) RemoveMultiFactorFromLoginPolicy(ctx context.Context, mfa *management.MultiFactor) (*empty.Empty, error) {
err := s.org.RemoveMultiFactorFromLoginPolicy(ctx, multiFactorTypeToModel(mfa))
return &empty.Empty{}, err
}

View File

@@ -12,6 +12,7 @@ func loginPolicyRequestToModel(policy *management.LoginPolicyRequest) *iam_model
AllowUsernamePassword: policy.AllowUsernamePassword,
AllowExternalIdp: policy.AllowExternalIdp,
AllowRegister: policy.AllowRegister,
ForceMFA: policy.ForceMfa,
}
}
@@ -28,6 +29,7 @@ func loginPolicyFromModel(policy *iam_model.LoginPolicy) *management.LoginPolicy
AllowRegister: policy.AllowRegister,
CreationDate: creationDate,
ChangeDate: changeDate,
ForceMfa: policy.ForceMFA,
}
}
@@ -45,6 +47,7 @@ func loginPolicyViewFromModel(policy *iam_model.LoginPolicyView) *management.Log
AllowRegister: policy.AllowRegister,
CreationDate: creationDate,
ChangeDate: changeDate,
ForceMfa: policy.ForceMFA,
}
}
@@ -140,3 +143,75 @@ func idpProviderTypeFromModel(providerType iam_model.IDPProviderType) management
return management.IdpProviderType_IDPPROVIDERTYPE_UNSPECIFIED
}
}
func secondFactorResultFromModel(result *iam_model.SecondFactorsSearchResponse) *management.SecondFactorsResult {
converted := make([]management.SecondFactorType, len(result.Result))
for i, mfaType := range result.Result {
converted[i] = secondFactorTypeFromModel(mfaType)
}
return &management.SecondFactorsResult{
SecondFactors: converted,
}
}
func secondFactorFromModel(mfaType iam_model.SecondFactorType) *management.SecondFactor {
return &management.SecondFactor{
SecondFactor: secondFactorTypeFromModel(mfaType),
}
}
func secondFactorTypeFromModel(mfaType iam_model.SecondFactorType) management.SecondFactorType {
switch mfaType {
case iam_model.SecondFactorTypeOTP:
return management.SecondFactorType_SECONDFACTORTYPE_OTP
case iam_model.SecondFactorTypeU2F:
return management.SecondFactorType_SECONDFACTORTYPE_U2F
default:
return management.SecondFactorType_SECONDFACTORTYPE_UNSPECIFIED
}
}
func secondFactorTypeToModel(mfaType *management.SecondFactor) iam_model.SecondFactorType {
switch mfaType.SecondFactor {
case management.SecondFactorType_SECONDFACTORTYPE_OTP:
return iam_model.SecondFactorTypeOTP
case management.SecondFactorType_SECONDFACTORTYPE_U2F:
return iam_model.SecondFactorTypeU2F
default:
return iam_model.SecondFactorTypeUnspecified
}
}
func multiFactorResultFromModel(result *iam_model.MultiFactorsSearchResponse) *management.MultiFactorsResult {
converted := make([]management.MultiFactorType, len(result.Result))
for i, mfaType := range result.Result {
converted[i] = multiFactorTypeFromModel(mfaType)
}
return &management.MultiFactorsResult{
MultiFactors: converted,
}
}
func multiFactorFromModel(mfaType iam_model.MultiFactorType) *management.MultiFactor {
return &management.MultiFactor{
MultiFactor: multiFactorTypeFromModel(mfaType),
}
}
func multiFactorTypeFromModel(mfaType iam_model.MultiFactorType) management.MultiFactorType {
switch mfaType {
case iam_model.MultiFactorTypeU2FWithPIN:
return management.MultiFactorType_MULTIFACTORTYPE_U2F_WITH_PIN
default:
return management.MultiFactorType_MULTIFACTORTYPE_UNSPECIFIED
}
}
func multiFactorTypeToModel(mfaType *management.MultiFactor) iam_model.MultiFactorType {
switch mfaType.MultiFactor {
case management.MultiFactorType_MULTIFACTORTYPE_U2F_WITH_PIN:
return iam_model.MultiFactorTypeU2FWithPIN
default:
return iam_model.MultiFactorTypeUnspecified
}
}

View File

@@ -208,12 +208,12 @@ func (s *Server) RemoveExternalIDP(ctx context.Context, request *management.Exte
return &empty.Empty{}, err
}
func (s *Server) GetUserMfas(ctx context.Context, userID *management.UserID) (*management.MultiFactors, error) {
func (s *Server) GetUserMfas(ctx context.Context, userID *management.UserID) (*management.UserMultiFactors, error) {
mfas, err := s.user.UserMfas(ctx, userID.Id)
if err != nil {
return nil, err
}
return &management.MultiFactors{Mfas: mfasFromModel(mfas)}, nil
return &management.UserMultiFactors{Mfas: mfasFromModel(mfas)}, nil
}
func (s *Server) SearchUserMemberships(ctx context.Context, in *management.UserMembershipSearchRequest) (*management.UserMembershipSearchResponse, error) {

View File

@@ -491,16 +491,16 @@ func userMembershipViewFromModel(membership *usr_model.UserMembershipView) *mana
}
}
func mfasFromModel(mfas []*usr_model.MultiFactor) []*management.MultiFactor {
converted := make([]*management.MultiFactor, len(mfas))
func mfasFromModel(mfas []*usr_model.MultiFactor) []*management.UserMultiFactor {
converted := make([]*management.UserMultiFactor, len(mfas))
for i, mfa := range mfas {
converted[i] = mfaFromModel(mfa)
}
return converted
}
func mfaFromModel(mfa *usr_model.MultiFactor) *management.MultiFactor {
return &management.MultiFactor{
func mfaFromModel(mfa *usr_model.MultiFactor) *management.UserMultiFactor {
return &management.UserMultiFactor{
State: mfaStateFromModel(mfa.State),
Type: mfaTypeFromModel(mfa.Type),
}

View File

@@ -243,9 +243,9 @@ func CodeChallengeToOIDC(challenge *model.OIDCCodeChallenge) *oidc.CodeChallenge
}
}
func AMRFromMFAType(mfaType model.MfaType) string {
func AMRFromMFAType(mfaType model.MFAType) string {
switch mfaType {
case model.MfaTypeOTP:
case model.MFATypeOTP:
return amrOTP
default:
return ""