From 11a30253a276503356cb69c69fb771c8eaa77d88 Mon Sep 17 00:00:00 2001 From: Jian Qiu Date: Tue, 17 Dec 2024 19:39:40 +0800 Subject: [PATCH] fix: enfore mfa (#21801) Co-authored-by: Qiu Jian --- pkg/keystone/models/users.go | 50 ++++++++++++++++++++++++++++++--- pkg/keystone/options/options.go | 6 ++++ pkg/keystone/service/service.go | 8 ++++++ 3 files changed, 60 insertions(+), 4 deletions(-) diff --git a/pkg/keystone/models/users.go b/pkg/keystone/models/users.go index 98a630ffa3..7ef9ae22a5 100644 --- a/pkg/keystone/models/users.go +++ b/pkg/keystone/models/users.go @@ -165,11 +165,20 @@ func (manager *SUserManager) InitializeData() error { return errors.Wrap(err, "update") } } - err = manager.initSystemAccount() - if err != nil { - return errors.Wrap(err, "initSystemAccount") + { + err := manager.initSystemAccount() + if err != nil { + return errors.Wrap(err, "initSystemAccount") + } } - return manager.initSysUser(context.TODO()) + { + err := manager.initSysUser(context.TODO()) + if err != nil { + return errors.Wrap(err, "initSystemAccount") + } + } + + return nil } func (manager *SUserManager) initSystemAccount() error { @@ -241,6 +250,30 @@ func (manager *SUserManager) initSysUser(ctx context.Context) error { return nil } +func (manager *SUserManager) EnforceUserMfa(ctx context.Context) error { + if options.Options.ForceEnableMfa != "all" { + return nil + } + q := manager.Query().IsFalse("enable_mfa") + + users := make([]SUser, 0) + err := db.FetchModelObjects(manager, q, &users) + if err != nil { + return errors.Wrap(err, "FetchModelObjects") + } + for i := range users { + _, err := db.Update(&users[i], func() error { + users[i].EnableMfa = tristate.True + return nil + }) + if err != nil { + return errors.Wrap(err, "update enable mfa") + } + logclient.AddSimpleActionLog(&users[i], logclient.ACT_UPDATE, "force enable mfa", GetDefaultAdminCred(), true) + } + return nil +} + /* Fetch extended userinfo by Id or name + domainId or name + domainName */ @@ -549,6 +582,11 @@ func (manager *SUserManager) ValidateCreateData( return input, errors.Wrapf(err, "CheckSetPendingQuota") } + if options.Options.ForceEnableMfa != "disable" { + boolTrue := true + input.EnableMfa = &boolTrue + } + return input, nil } @@ -590,6 +628,10 @@ func (user *SUser) ValidateUpdateData(ctx context.Context, userCred mcclient.Tok return input, httperrors.NewInputParameterError("invalid password: %s", err) } } + if options.Options.ForceEnableMfa != "disable" { + boolTrue := true + input.EnableMfa = &boolTrue + } var err error input.EnabledIdentityBaseUpdateInput, err = user.SEnabledIdentityBaseResource.ValidateUpdateData(ctx, userCred, query, input.EnabledIdentityBaseUpdateInput) if err != nil { diff --git a/pkg/keystone/options/options.go b/pkg/keystone/options/options.go index 897a36f98b..a678320016 100644 --- a/pkg/keystone/options/options.go +++ b/pkg/keystone/options/options.go @@ -79,6 +79,8 @@ type SKeystoneOptions struct { MaxUserRolesInProject int `help:"maximal allowed roles of a user in a project" default:"20"` MaxGroupRolesInProject int `help:"maximal allowed roles of a group in a project" default:"20"` + + ForceEnableMfa string `help:"force enable mfa" default:"disable" choices:"all|after|disable"` } var ( @@ -102,5 +104,9 @@ func OnOptionsChange(oldOptions, newOptions interface{}) bool { changed = true } + if oldOpts.ForceEnableMfa != newOpts.ForceEnableMfa { + changed = true + } + return changed } diff --git a/pkg/keystone/service/service.go b/pkg/keystone/service/service.go index cea7eb2ce3..fd3628b5d0 100644 --- a/pkg/keystone/service/service.go +++ b/pkg/keystone/service/service.go @@ -20,6 +20,7 @@ import ( "time" "yunion.io/x/jsonutils" + "yunion.io/x/log" _ "yunion.io/x/sqlchemy/backends" api "yunion.io/x/onecloud/pkg/apis/identity" @@ -92,6 +93,13 @@ func StartService() { common_options.StartOptionManagerWithSessionDriver(opts, opts.ConfigSyncPeriodSeconds, api.SERVICE_TYPE, "", options.OnOptionsChange, models.NewServiceConfigSession()) + { + err := models.UserManager.EnforceUserMfa(context.Background()) + if err != nil { + log.Errorf("EnforceUserMfa fail %s", err) + } + } + cache.Init(opts.TokenExpirationSeconds) if !opts.IsSlaveNode {