diff --git a/cmd/climc/shell/identity/identityproviders.go b/cmd/climc/shell/identity/identityproviders.go index f1800db667..9d05ecd2a4 100644 --- a/cmd/climc/shell/identity/identityproviders.go +++ b/cmd/climc/shell/identity/identityproviders.go @@ -299,7 +299,9 @@ func init() { IDP string `help:"identity provider name or ID"` } R(&IdentityProviderConfigEditOptions{}, "idp-config-edit", "Edit config yaml of an identity provider", func(s *mcclient.ClientSession, args *IdentityProviderConfigEditOptions) error { - conf, err := modules.IdentityProviders.GetSpecific(s, args.IDP, "config", nil) + params := jsonutils.NewDict() + params.Add(jsonutils.JSONTrue, "sensitive") + conf, err := modules.IdentityProviders.GetSpecific(s, args.IDP, "config", params) if err != nil { return err } diff --git a/pkg/apigateway/options/options.go b/pkg/apigateway/options/options.go index 677ddff2b4..60e24b6197 100644 --- a/pkg/apigateway/options/options.go +++ b/pkg/apigateway/options/options.go @@ -26,7 +26,7 @@ type GatewayOptions struct { DisableModuleApiVersion bool `help:"Disable each modules default api version" default:"false"` - EnableTotp bool `help:"Enable two-factor authentication" default:"false"` + EnableTotp bool `help:"Enable two-factor authentication" default:"true"` SqlitePath string `help:"sqlite db path" default:"/etc/yunion/data/yunionapi.db"` diff --git a/pkg/apis/identity/config.go b/pkg/apis/identity/config.go index eba5b23c19..6f710fb47f 100644 --- a/pkg/apis/identity/config.go +++ b/pkg/apis/identity/config.go @@ -28,6 +28,8 @@ type SLDAPIdpConfigBaseOptions struct { Suffix string `json:"suffix,omitempty" required:"true"` User string `json:"user,omitempty" required:"true"` Password string `json:"password,omitempty" required:"true"` + + DisableUserOnImport bool `json:"disable_user_on_import"` } type SLDAPIdpConfigSingleDomainOptions struct { @@ -51,6 +53,8 @@ type SLDAPIdpConfigOptions struct { User string `json:"user,omitempty"` Password string `json:"password,omitempty"` + DisableUserOnImport bool `json:"disable_user_on_import"` + DomainTreeDN string `json:"domain_tree_dn,omitempty" help:"Domain tree root node dn(distinguished name)"` DomainFilter string `json:"domain_filter,omitempty"` DomainObjectclass string `json:"domain_objectclass,omitempty"` diff --git a/pkg/keystone/driver/cas/cas.go b/pkg/keystone/driver/cas/cas.go index f6d0a702de..c6947b37cb 100644 --- a/pkg/keystone/driver/cas/cas.go +++ b/pkg/keystone/driver/cas/cas.go @@ -140,7 +140,7 @@ func (self *SCASDriver) Authenticate(ctx context.Context, ident mcclient.SAuthen if err != nil { return nil, errors.Wrap(err, "idp.GetSingleDomain") } - usr, err := idp.SyncOrCreateUser(ctx, usrId, usrId, domain.Id, nil) + usr, err := idp.SyncOrCreateUser(ctx, usrId, usrId, domain.Id, true, nil) if err != nil { return nil, errors.Wrap(err, "idp.SyncOrCreateUser") } diff --git a/pkg/keystone/driver/ldap/info.go b/pkg/keystone/driver/ldap/info.go index 78ad6654e6..cf22ffd6dc 100644 --- a/pkg/keystone/driver/ldap/info.go +++ b/pkg/keystone/driver/ldap/info.go @@ -34,3 +34,14 @@ type SGroupInfo struct { func (info SDomainInfo) isValid() bool { return len(info.DN) > 0 && len(info.Id) > 0 && len(info.Name) > 0 } + +func (info SUserInfo) isValid() bool { + if !info.SDomainInfo.isValid() { + return false + } + // regarding disabled LDAP user as invalid + if !info.Enabled { + return false + } + return true +} diff --git a/pkg/keystone/driver/ldap/sync.go b/pkg/keystone/driver/ldap/sync.go index df1b059440..e28c2931b1 100644 --- a/pkg/keystone/driver/ldap/sync.go +++ b/pkg/keystone/driver/ldap/sync.go @@ -22,7 +22,6 @@ import ( "yunion.io/x/log" "yunion.io/x/pkg/errors" - "yunion.io/x/pkg/tristate" api "yunion.io/x/onecloud/pkg/apis/identity" "yunion.io/x/onecloud/pkg/keystone/models" @@ -230,12 +229,13 @@ func (self *SLDAPDriver) syncUserDB(ctx context.Context, ui SUserInfo, domainId if err != nil { return "", errors.Wrap(err, "models.IdentityProviderManager.FetchIdentityProviderById") } - usr, err := idp.SyncOrCreateUser(ctx, ui.Id, ui.Name, domainId, func(user *models.SUser) { - if ui.Enabled { - user.Enabled = tristate.True - } else { - user.Enabled = tristate.False - } + usr, err := idp.SyncOrCreateUser(ctx, ui.Id, ui.Name, domainId, !self.ldapConfig.DisableUserOnImport, func(user *models.SUser) { + // LDAP user is always enabled + // if ui.Enabled { + // user.Enabled = tristate.True + // } else { + // user.Enabled = tristate.False + // } if val, ok := ui.Extra["email"]; ok && len(val) > 0 { user.Email = val } diff --git a/pkg/keystone/models/identity_provider.go b/pkg/keystone/models/identity_provider.go index 993cdf30a0..1d8cd0465c 100644 --- a/pkg/keystone/models/identity_provider.go +++ b/pkg/keystone/models/identity_provider.go @@ -212,7 +212,13 @@ func (self *SIdentityProvider) AllowGetDetailsConfig(ctx context.Context, userCr } func (self *SIdentityProvider) GetDetailsConfig(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (jsonutils.JSONObject, error) { - conf, err := GetConfigs(self, false, nil, nil) + sensitive := jsonutils.QueryBoolean(query, "sensitive", false) + if sensitive { + if !db.IsAdminAllowGetSpec(userCred, self, "config") { + return nil, httperrors.NewNotSufficientPrivilegeError("get sensitive config requires admin priviliges") + } + } + conf, err := GetConfigs(self, sensitive, nil, nil) if err != nil { return nil, err } @@ -859,7 +865,7 @@ func (self *SIdentityProvider) SyncOrCreateDomain(ctx context.Context, extId str return domain, nil } -func (self *SIdentityProvider) SyncOrCreateUser(ctx context.Context, extId string, extName string, domainId string, syncUserInfo func(*SUser)) (*SUser, error) { +func (self *SIdentityProvider) SyncOrCreateUser(ctx context.Context, extId string, extName string, domainId string, enableDefault bool, syncUserInfo func(*SUser)) (*SUser, error) { userId, err := IdmappingManager.RegisterIdMap(ctx, self.Id, extId, api.IdMappingEntityUser) if err != nil { return nil, errors.Wrap(err, "IdmappingManager.RegisterIdMap") @@ -880,13 +886,21 @@ func (self *SIdentityProvider) SyncOrCreateUser(ctx context.Context, extId strin } if err == nil { // update + log.Debugf("find user %s", extName) _, err := db.Update(user, func() error { if syncUserInfo != nil { syncUserInfo(user) } user.Name = extName user.DomainId = domainId - user.MarkUnDelete() + if user.Deleted { + user.MarkUnDelete() + if enableDefault { + user.Enabled = tristate.True + } else { + user.Enabled = tristate.False + } + } return nil }) if err != nil { @@ -896,6 +910,11 @@ func (self *SIdentityProvider) SyncOrCreateUser(ctx context.Context, extId strin if syncUserInfo != nil { syncUserInfo(user) } + if enableDefault { + user.Enabled = tristate.True + } else { + user.Enabled = tristate.False + } user.Id = userId user.Name = extName user.DomainId = domainId diff --git a/pkg/keystone/models/users.go b/pkg/keystone/models/users.go index 3444ce8929..4fc21a353c 100644 --- a/pkg/keystone/models/users.go +++ b/pkg/keystone/models/users.go @@ -91,7 +91,7 @@ type SUser struct { DefaultProjectId string `width:"64" charset:"ascii" nullable:"true"` AllowWebConsole tristate.TriState `nullable:"false" default:"true" list:"domain" update:"domain" create:"domain_optional"` - EnableMfa tristate.TriState `nullable:"false" default:"true" list:"domain" update:"domain" create:"domain_optional"` + EnableMfa tristate.TriState `nullable:"false" default:"false" list:"domain" update:"domain" create:"domain_optional"` } func (manager *SUserManager) GetContextManagers() [][]db.IModelManager { @@ -481,7 +481,6 @@ func (user *SUser) ValidateUpdateData(ctx context.Context, userCred mcclient.Tok data := jsonutils.Marshal(input) for _, k := range []string{ "name", - "enabled", "displayname", "email", "mobile",