From 191ef067ecacb2b5a18683ee0738b0c4d9875f0e Mon Sep 17 00:00:00 2001 From: nannan00 <17491932+nannan00@users.noreply.github.com> Date: Wed, 17 Apr 2024 09:08:40 +0800 Subject: [PATCH] feat(bkuser): adjust local data source config model (#1652) --- .../apis/web/data_source/serializers.py | 2 +- .../web/data_source_organization/views.py | 6 ++-- src/bk-user/bkuser/apis/web/password/views.py | 2 +- .../bkuser/apis/web/personal_center/views.py | 8 ++--- .../apis/web/platform_management/views.py | 4 +-- .../apis/web/tenant_info/serializers.py | 4 +-- .../bkuser/apis/web/tenant_info/views.py | 20 +++++++---- .../bkuser/apis/web/virtual_user/mixins.py | 2 +- .../bkuser/apps/data_source/initializers.py | 8 ++--- src/bk-user/bkuser/apps/idp/handlers.py | 6 ++-- src/bk-user/bkuser/apps/notification/tasks.py | 4 +-- src/bk-user/bkuser/apps/sync/handlers.py | 2 +- src/bk-user/bkuser/plugins/local/defaults.py | 13 ++++--- src/bk-user/bkuser/plugins/local/models.py | 36 +++++++++++-------- .../apis/web/data_source/test_data_source.py | 14 ++++---- .../personal_center/test_personal_center.py | 2 +- .../apps/data_source/test_initializers.py | 2 +- .../tests/apps/data_source/test_models.py | 6 ++-- src/bk-user/tests/fixtures/data_source.py | 12 ++++--- src/idp-plugins/idp_plugins/local/plugin.py | 2 +- src/pages/src/hooks/useDataSource.ts | 2 +- src/pages/src/http/types/settingFiles.ts | 2 +- .../data-source/local-details/PswInfo.vue | 2 +- .../views/data-source/local-details/index.vue | 2 +- .../src/views/data-source/new-data/Local.vue | 16 ++++----- src/pages/src/views/setting/AdminSetting.vue | 20 +++++------ 26 files changed, 109 insertions(+), 90 deletions(-) diff --git a/src/bk-user/bkuser/apis/web/data_source/serializers.py b/src/bk-user/bkuser/apis/web/data_source/serializers.py index 3693d5867..f19458e6a 100644 --- a/src/bk-user/bkuser/apis/web/data_source/serializers.py +++ b/src/bk-user/bkuser/apis/web/data_source/serializers.py @@ -282,7 +282,7 @@ def validate(self, attrs): raise ValidationError(_("指定数据源不存在")) plugin_config = data_source.get_plugin_cfg() - if not plugin_config.enable_account_password_login: + if not plugin_config.enable_password: raise ValidationError(_("无法使用该数据源生成随机密码")) attrs["password_rule"] = plugin_config.password_rule.to_rule() diff --git a/src/bk-user/bkuser/apis/web/data_source_organization/views.py b/src/bk-user/bkuser/apis/web/data_source_organization/views.py index c2b4db971..d09840da6 100644 --- a/src/bk-user/bkuser/apis/web/data_source_organization/views.py +++ b/src/bk-user/bkuser/apis/web/data_source_organization/views.py @@ -274,9 +274,9 @@ def put(self, request, *args, **kwargs): data_source = user.data_source plugin_config = data_source.get_plugin_cfg() - if not (data_source.is_local and plugin_config.enable_account_password_login): + if not (data_source.is_local and plugin_config.enable_password): raise error_codes.DATA_SOURCE_OPERATION_UNSUPPORTED.f( - _("仅可以重置 已经启用账密登录功能 的 本地数据源 的用户密码") + _("仅可以重置 已经启用密码功能 的 本地数据源 的用户密码") ) slz = DataSourceUserPasswordResetInputSLZ( @@ -292,7 +292,7 @@ def put(self, request, *args, **kwargs): DataSourceUserHandler.update_password( data_source_user=user, password=raw_password, - valid_days=plugin_config.password_rule.valid_time, + valid_days=plugin_config.password_expire.valid_time, operator=request.user.username, ) diff --git a/src/bk-user/bkuser/apis/web/password/views.py b/src/bk-user/bkuser/apis/web/password/views.py index 2d3682a44..4deada46f 100644 --- a/src/bk-user/bkuser/apis/web/password/views.py +++ b/src/bk-user/bkuser/apis/web/password/views.py @@ -280,7 +280,7 @@ def post(self, request, *args, **kwargs): DataSourceUserHandler.update_password( data_source_user=data_source_user, password=password, - valid_days=plugin_cfg.password_rule.valid_time, + valid_days=plugin_cfg.password_expire.valid_time, operator="AnonymousByResetToken", ) # 成功修改完用户密码后,需要及时禁用 Token diff --git a/src/bk-user/bkuser/apis/web/personal_center/views.py b/src/bk-user/bkuser/apis/web/personal_center/views.py index a48022abf..8b0053403 100644 --- a/src/bk-user/bkuser/apis/web/personal_center/views.py +++ b/src/bk-user/bkuser/apis/web/personal_center/views.py @@ -256,7 +256,7 @@ def get(self, request, *args, **kwargs): feature_flags = { PersonalCenterFeatureFlag.CAN_CHANGE_PASSWORD: bool( - data_source.is_local and data_source.plugin_config.get("enable_account_password_login", False) + data_source.is_local and data_source.plugin_config.get("enable_password", False) ) } return Response(TenantUserFeatureFlagOutputSLZ(feature_flags).data) @@ -279,9 +279,9 @@ def put(self, request, *args, **kwargs): data_source = data_source_user.data_source plugin_config = data_source.get_plugin_cfg() - if not (data_source.is_local and plugin_config.enable_account_password_login): + if not (data_source.is_local and plugin_config.enable_password): raise error_codes.DATA_SOURCE_OPERATION_UNSUPPORTED.f( - _("仅可以重置 已经启用账密登录功能 的 本地数据源 的用户密码") + _("仅可以重置 已经启用密码功能 的 本地数据源 的用户密码") ) slz = TenantUserPasswordUpdateInputSLZ( @@ -298,7 +298,7 @@ def put(self, request, *args, **kwargs): DataSourceUserHandler.update_password( data_source_user=data_source_user, password=new_password, - valid_days=plugin_config.password_rule.valid_time, + valid_days=plugin_config.password_expire.valid_time, operator=request.user.username, ) diff --git a/src/bk-user/bkuser/apis/web/platform_management/views.py b/src/bk-user/bkuser/apis/web/platform_management/views.py index 899d9c4f5..6749a882f 100644 --- a/src/bk-user/bkuser/apis/web/platform_management/views.py +++ b/src/bk-user/bkuser/apis/web/platform_management/views.py @@ -305,7 +305,7 @@ def put(self, request, *args, **kwargs): plugin_config = data_source.get_plugin_cfg() assert isinstance(plugin_config, LocalDataSourcePluginConfig) assert plugin_config.password_initial is not None - assert plugin_config.password_rule is not None + assert plugin_config.password_expire is not None # 输入参数校验 slz = TenantBuiltinManagerUpdateInputSLZ( @@ -329,7 +329,7 @@ def put(self, request, *args, **kwargs): DataSourceUserHandler.update_password( data_source_user=user, password=fixed_password, - valid_days=plugin_config.password_rule.valid_time, + valid_days=plugin_config.password_expire.valid_time, operator=request.user.username, ) diff --git a/src/bk-user/bkuser/apis/web/tenant_info/serializers.py b/src/bk-user/bkuser/apis/web/tenant_info/serializers.py index 6731dbece..9e1ed0bf9 100644 --- a/src/bk-user/bkuser/apis/web/tenant_info/serializers.py +++ b/src/bk-user/bkuser/apis/web/tenant_info/serializers.py @@ -55,14 +55,14 @@ def validate_name(self, name: str) -> str: class TenantBuiltinManagerRetrieveOutputSLZ(serializers.Serializer): username = serializers.CharField(help_text="用户名") - enable_account_password_login = serializers.BooleanField(help_text="是否启用账密登录") + enable_login = serializers.BooleanField(help_text="是否启用账密登录") class TenantBuiltinManagerUpdateInputSLZ(serializers.Serializer): username = serializers.CharField( help_text="用户名", validators=[validate_data_source_user_username], required=False, allow_blank=True ) - enable_account_password_login = serializers.BooleanField(help_text="是否启用账密登录", required=False) + enable_login = serializers.BooleanField(help_text="是否启用账密登录", required=False) class TenantBuiltinManagerPasswordUpdateInputSLZ(serializers.Serializer): diff --git a/src/bk-user/bkuser/apis/web/tenant_info/views.py b/src/bk-user/bkuser/apis/web/tenant_info/views.py index 84c61c10c..99918b3cb 100644 --- a/src/bk-user/bkuser/apis/web/tenant_info/views.py +++ b/src/bk-user/bkuser/apis/web/tenant_info/views.py @@ -10,6 +10,7 @@ """ from django.db import transaction from django.db.models import Q +from django.utils.translation import gettext_lazy as _ from drf_yasg.utils import swagger_auto_schema from rest_framework import generics, status from rest_framework.permissions import IsAuthenticated @@ -22,6 +23,7 @@ from bkuser.apps.permission.permissions import perm_class from bkuser.apps.tenant.models import Tenant, TenantManager, TenantUser from bkuser.biz.data_source_organization import DataSourceUserHandler +from bkuser.common.error_codes import error_codes from bkuser.common.views import ExcludePatchAPIViewMixin, ExcludePutAPIViewMixin from bkuser.plugins.local.models import LocalDataSourcePluginConfig @@ -91,7 +93,7 @@ def get(self, request, *args, **kwargs): TenantBuiltinManagerRetrieveOutputSLZ( { "username": user.username, - "enable_account_password_login": data_source.plugin_config["enable_account_password_login"], + "enable_login": data_source.plugin_config["enable_password"], } ).data ) @@ -107,6 +109,12 @@ def patch(self, request, *args, **kwargs): slz.is_valid(raise_exception=True) data = slz.validated_data + # 若当前内置的租户管理员是唯一的管理员,则无法禁用 + if not TenantManager.objects.filter( + tenant_id=self.get_current_tenant_id(), tenant_user__data_source__type=DataSourceTypeEnum.REAL + ).exists(): + raise error_codes.VALIDATION_ERROR.f(_("不存在实名管理员,无法禁用内置管理员账号登录")) + # 内建数据源 & 用户 data_source, user = self.get_builtin_data_source_and_user() @@ -125,9 +133,9 @@ def patch(self, request, *args, **kwargs): LocalDataSourceIdentityInfo.objects.filter(user=user).update(username=new_username) # 更新是否启用登录 - enable = data.get("enable_account_password_login") - if enable is not None and plugin_config.enable_account_password_login != enable: - plugin_config.enable_account_password_login = enable + enable = data.get("enable_login") + if enable is not None and plugin_config.enable_password != enable: + plugin_config.enable_password = enable data_source.set_plugin_cfg(plugin_config) return Response(status=status.HTTP_204_NO_CONTENT) @@ -151,7 +159,7 @@ def put(self, request, *args, **kwargs): # 数据源配置 plugin_config = data_source.get_plugin_cfg() assert isinstance(plugin_config, LocalDataSourcePluginConfig) - assert plugin_config.password_rule is not None + assert plugin_config.password_expire is not None # 数据校验 slz = TenantBuiltinManagerPasswordUpdateInputSLZ( @@ -164,7 +172,7 @@ def put(self, request, *args, **kwargs): DataSourceUserHandler.update_password( data_source_user=user, password=raw_password, - valid_days=plugin_config.password_rule.valid_time, + valid_days=plugin_config.password_expire.valid_time, operator=request.user.username, ) diff --git a/src/bk-user/bkuser/apis/web/virtual_user/mixins.py b/src/bk-user/bkuser/apis/web/virtual_user/mixins.py index 7a3b21f23..7c42f389a 100644 --- a/src/bk-user/bkuser/apis/web/virtual_user/mixins.py +++ b/src/bk-user/bkuser/apis/web/virtual_user/mixins.py @@ -24,7 +24,7 @@ def get_current_virtual_data_source(self): type=DataSourceTypeEnum.VIRTUAL, defaults={ "plugin": DataSourcePlugin.objects.get(id=DataSourcePluginEnum.LOCAL), - "plugin_config": LocalDataSourcePluginConfig(enable_account_password_login=False), + "plugin_config": LocalDataSourcePluginConfig(enable_password=False), }, ) diff --git a/src/bk-user/bkuser/apps/data_source/initializers.py b/src/bk-user/bkuser/apps/data_source/initializers.py index e89325518..4bd50ac18 100644 --- a/src/bk-user/bkuser/apps/data_source/initializers.py +++ b/src/bk-user/bkuser/apps/data_source/initializers.py @@ -52,7 +52,7 @@ def __init__(self, data_source: DataSource): self.plugin_cfg = data_source.get_plugin_cfg() assert isinstance(self.plugin_cfg, LocalDataSourcePluginConfig) - if not self.plugin_cfg.enable_account_password_login: + if not self.plugin_cfg.enable_password: return self.password_provider = PasswordProvider( @@ -90,8 +90,8 @@ def _can_skip(self) -> bool: if not self.data_source.is_local: return True - # 是本地数据源,但是没开启账密登录的,不需要初始化 - if not self.plugin_cfg.enable_account_password_login: # type: ignore + # 是本地数据源,但是没开启密码功能的,不需要初始化 + if not self.plugin_cfg.enable_password: # type: ignore return True return False @@ -121,7 +121,7 @@ def _init_users_identity_info(self, users: List[DataSourceUser]) -> Dict[int, st def _get_password_expired_at(self) -> datetime.datetime: """获取密码过期的具体时间""" - valid_time: int = self.plugin_cfg.password_rule.valid_time # type: ignore + valid_time: int = self.plugin_cfg.password_expire.valid_time # type: ignore # 有效时间 -1 表示永远有效 if valid_time < 0: return PERMANENT_TIME diff --git a/src/bk-user/bkuser/apps/idp/handlers.py b/src/bk-user/bkuser/apps/idp/handlers.py index f38d7f013..77d2c0600 100644 --- a/src/bk-user/bkuser/apps/idp/handlers.py +++ b/src/bk-user/bkuser/apps/idp/handlers.py @@ -32,7 +32,7 @@ def _update_local_idp_of_tenant(data_source: DataSource): """ 更新租户的本地账密登录认证源 对于每个租户,如果有本地数据源,则必须有本地账密认证源 - 该函数主要是根据本地数据源(status和enable_account_password_login)的变化更新租户的本地账密认证源配置和状态 + 该函数主要是根据本地数据源(status 和 enable_password )的变化更新租户的本地账密认证源配置和状态 """ # 非本地数据源不需要默认认证源 if not data_source.is_local: @@ -45,11 +45,11 @@ def _update_local_idp_of_tenant(data_source: DataSource): owner_tenant_id=data_source.owner_tenant_id, plugin=plugin, defaults={"name": _("本地账密")} ) - # 判断数据源 status和enable_account_password_login ,确定是否使用账密登录 + # 判断数据源 status 和 enable_password ,确定是否使用账密登录 plugin_cfg = data_source.get_plugin_cfg() assert isinstance(plugin_cfg, LocalDataSourcePluginConfig) - enable_login = plugin_cfg.enable_account_password_login + enable_login = plugin_cfg.enable_password # 根据数据源是否使用账密登录,修改认证源配置 idp_plugin_cfg: LocalIdpPluginConfig = idp.get_plugin_cfg() diff --git a/src/bk-user/bkuser/apps/notification/tasks.py b/src/bk-user/bkuser/apps/notification/tasks.py index b83920285..95f88a9d9 100644 --- a/src/bk-user/bkuser/apps/notification/tasks.py +++ b/src/bk-user/bkuser/apps/notification/tasks.py @@ -84,7 +84,7 @@ def build_and_run_notify_password_expiring_users_task(): logger.info("data source's owner tenant %s not enabled, skip notify...", data_source.id) continue - if data_source.plugin_config.get("enable_account_password_login", False): + if data_source.plugin_config.get("enable_password", False): notify_password_expiring_users.delay(data_source.id) @@ -122,7 +122,7 @@ def build_and_run_notify_password_expired_users_task(): logger.info("data source's owner tenant %s not enabled, skip notify...", data_source.id) continue - if data_source.plugin_config.get("enable_account_password_login", False): + if data_source.plugin_config.get("enable_password", False): notify_password_expired_users.delay(data_source.id) diff --git a/src/bk-user/bkuser/apps/sync/handlers.py b/src/bk-user/bkuser/apps/sync/handlers.py index e21a80af1..80cb9745b 100644 --- a/src/bk-user/bkuser/apps/sync/handlers.py +++ b/src/bk-user/bkuser/apps/sync/handlers.py @@ -50,7 +50,7 @@ def sync_identity_infos_and_notify_after_sync_tenant(sender, data_source: DataSo @receiver(post_save, sender=DataSource) def sync_identity_infos_and_notify_after_modify_data_source(sender, instance: DataSource, created: bool, **kwargs): """ - 数据源更新后,需要检查是否是本地数据源,若是本地数据源且启用账密登录, + 数据源更新后,需要检查是否是本地数据源,若是本地数据源且启用密码功能, 则需要对没有账密信息的用户,进行密码的初始化 & 发送通知,批量创建数据源用户同理 """ if created: diff --git a/src/bk-user/bkuser/plugins/local/defaults.py b/src/bk-user/bkuser/plugins/local/defaults.py index da2606964..d2b97678c 100644 --- a/src/bk-user/bkuser/plugins/local/defaults.py +++ b/src/bk-user/bkuser/plugins/local/defaults.py @@ -15,6 +15,7 @@ ) from bkuser.plugins.local.models import ( LocalDataSourcePluginConfig, + LoginLimitConfig, NotificationConfig, NotificationTemplate, PasswordExpireConfig, @@ -24,7 +25,7 @@ # 本地数据源插件默认配置 DEFAULT_PLUGIN_CONFIG = LocalDataSourcePluginConfig( - enable_account_password_login=True, + enable_password=False, password_rule=PasswordRuleConfig( min_length=12, contain_lowercase=True, @@ -36,12 +37,8 @@ not_continuous_letter=False, not_continuous_digit=False, not_repeated_symbol=False, - valid_time=90, - max_retries=3, - lock_time=60 * 60, ), password_initial=PasswordInitialConfig( - force_change_at_first_login=True, cannot_use_previous_password=True, reserved_previous_password_count=3, generate_method=PasswordGenerateMethod.RANDOM, @@ -129,6 +126,7 @@ ), ), password_expire=PasswordExpireConfig( + valid_time=90, remind_before_expire=[1, 7, 15], notification=NotificationConfig( enabled_methods=[NotificationMethod.EMAIL], @@ -200,4 +198,9 @@ ], ), ), + login_limit=LoginLimitConfig( + force_change_at_first_login=True, + max_retries=3, + lock_time=60 * 60, + ), ) diff --git a/src/bk-user/bkuser/plugins/local/models.py b/src/bk-user/bkuser/plugins/local/models.py index 7d85f3a20..b46ac70b2 100644 --- a/src/bk-user/bkuser/plugins/local/models.py +++ b/src/bk-user/bkuser/plugins/local/models.py @@ -58,13 +58,6 @@ class PasswordRuleConfig(BaseModel): # 不允许重复字母,数字,特殊字符 not_repeated_symbol: bool - # 密码有效期(单位:天) - valid_time: int = Field(ge=NEVER_EXPIRE_TIME, le=MAX_PASSWORD_VALID_TIME) - # 密码试错次数 - max_retries: int = Field(ge=0, le=PASSWORD_MAX_RETRIES) - # 锁定时间(单位:秒) - lock_time: int = Field(ge=NEVER_EXPIRE_TIME, le=MAX_LOCK_TIME) - def to_rule(self) -> PasswordRule: """转换成密码工具可用的规则""" return PasswordRule( @@ -120,8 +113,6 @@ class NotificationConfig(BaseModel): class PasswordInitialConfig(BaseModel): """初始密码设置""" - # 首次登录后强制修改密码 - force_change_at_first_login: bool # 修改密码时候不能使用之前的密码 cannot_use_previous_password: bool # 之前的 N 个密码不能被本次修改使用,仅当 cannot_use_previous_password 为 True 时有效 @@ -135,14 +126,27 @@ class PasswordInitialConfig(BaseModel): class PasswordExpireConfig(BaseModel): - """密码到期相关配置""" + """密码有效期相关配置""" + # 密码有效期(单位:天) + valid_time: int = Field(ge=NEVER_EXPIRE_TIME, le=MAX_PASSWORD_VALID_TIME) # 在密码到期多久前提醒,单位:天,多个值表示多次提醒 remind_before_expire: List[int] # 通知相关配置 notification: NotificationConfig +class LoginLimitConfig(BaseModel): + """登录限制配置""" + + # 首次登录后强制修改密码 + force_change_at_first_login: bool + # 密码试错次数 + max_retries: int = Field(ge=0, le=PASSWORD_MAX_RETRIES) + # 锁定时间(单位:秒) + lock_time: int = Field(ge=NEVER_EXPIRE_TIME, le=MAX_LOCK_TIME) + + class LocalDataSourcePluginConfig(BasePluginConfig): """本地数据源插件配置""" @@ -151,23 +155,25 @@ class LocalDataSourcePluginConfig(BasePluginConfig): "password_initial.fixed_password", ] - # 是否允许使用账密登录 - enable_account_password_login: bool + # 是否启用密码,即用户是否添加密码数据 + enable_password: bool # 密码生成规则 password_rule: Optional[PasswordRuleConfig] = None # 密码初始化/修改规则 password_initial: Optional[PasswordInitialConfig] = None # 密码到期规则 password_expire: Optional[PasswordExpireConfig] = None + # 登录限制 + login_limit: Optional[LoginLimitConfig] = None @model_validator(mode="after") def validate_attrs(self) -> "LocalDataSourcePluginConfig": """插件配置合法性检查""" - # 如果没有开启账密登录,则不需要检查配置 - if not self.enable_account_password_login: + # 如果没有开启密码,则不需要检查配置 + if not self.enable_password: return self - # 若启用账密登录,则各字段都需要配置上 + # 若启用密码功能,则各字段都需要配置上 if not (self.password_rule and self.password_initial and self.password_expire): raise ValueError(_("密码生成规则、初始密码设置、密码到期设置均不能为空")) diff --git a/src/bk-user/tests/apis/web/data_source/test_data_source.py b/src/bk-user/tests/apis/web/data_source/test_data_source.py index 946dd3ebe..8c366e6b4 100644 --- a/src/bk-user/tests/apis/web/data_source/test_data_source.py +++ b/src/bk-user/tests/apis/web/data_source/test_data_source.py @@ -80,7 +80,7 @@ def test_create_with_minimal_plugin_config(self, api_client, random_tenant): reverse("data_source.list_create"), data={ "plugin_id": DataSourcePluginEnum.LOCAL, - "plugin_config": {"enable_account_password_login": False}, + "plugin_config": {"enable_password": False}, }, ) assert resp.status_code == status.HTTP_201_CREATED @@ -126,7 +126,7 @@ def test_create_with_invalid_notification_template(self, api_client, random_tena assert "邮件通知模板需要提供标题" in resp.data["message"] def test_create_with_invalid_plugin_config(self, api_client, random_tenant, local_ds_plugin_cfg): - local_ds_plugin_cfg.pop("enable_account_password_login") + local_ds_plugin_cfg.pop("enable_password") resp = api_client.post( reverse("data_source.list_create"), data={ @@ -135,7 +135,7 @@ def test_create_with_invalid_plugin_config(self, api_client, random_tenant, loca }, ) assert resp.status_code == status.HTTP_400_BAD_REQUEST - assert "插件配置不合法:enable_account_password_login: Field required" in resp.data["message"] + assert "插件配置不合法:enable_password: Field required" in resp.data["message"] def test_create_general_data_source( self, api_client, random_tenant, general_ds_plugin_cfg, tenant_user_custom_fields, field_mapping, sync_config @@ -253,21 +253,21 @@ def test_list_with_type(self, api_client, data_source): class TestDataSourceUpdateApi: def test_update_local_data_source(self, api_client, data_source, local_ds_plugin_cfg): url = reverse("data_source.retrieve_update_destroy", kwargs={"id": data_source.id}) - local_ds_plugin_cfg["enable_account_password_login"] = False + local_ds_plugin_cfg["enable_password"] = False resp = api_client.put(url, data={"plugin_config": local_ds_plugin_cfg}) assert resp.status_code == status.HTTP_204_NO_CONTENT resp = api_client.get(url) - assert resp.data["plugin_config"]["enable_account_password_login"] is False + assert resp.data["plugin_config"]["enable_password"] is False def test_update_with_invalid_plugin_config(self, api_client, data_source, local_ds_plugin_cfg): - local_ds_plugin_cfg.pop("enable_account_password_login") + local_ds_plugin_cfg.pop("enable_password") resp = api_client.put( reverse("data_source.retrieve_update_destroy", kwargs={"id": data_source.id}), data={"plugin_config": local_ds_plugin_cfg}, ) assert resp.status_code == status.HTTP_400_BAD_REQUEST - assert "插件配置不合法:enable_account_password_login: Field required" in resp.data["message"] + assert "插件配置不合法:enable_password: Field required" in resp.data["message"] def test_update_general_data_source( self, api_client, bare_general_data_source, general_ds_plugin_cfg, field_mapping, sync_config diff --git a/src/bk-user/tests/apis/web/personal_center/test_personal_center.py b/src/bk-user/tests/apis/web/personal_center/test_personal_center.py index 84eca4898..688efed9d 100644 --- a/src/bk-user/tests/apis/web/personal_center/test_personal_center.py +++ b/src/bk-user/tests/apis/web/personal_center/test_personal_center.py @@ -85,4 +85,4 @@ def test_list(self, api_client, tenant_user): resp = api_client.get(reverse("personal_center.tenant_users.feature_flag.list", kwargs={"id": tenant_user.id})) assert resp.status_code == status.HTTP_200_OK - assert resp.data["can_change_password"] is True + assert resp.data["can_change_password"] is False diff --git a/src/bk-user/tests/apps/data_source/test_initializers.py b/src/bk-user/tests/apps/data_source/test_initializers.py index 8a0ff2e27..dff127a63 100644 --- a/src/bk-user/tests/apps/data_source/test_initializers.py +++ b/src/bk-user/tests/apps/data_source/test_initializers.py @@ -33,7 +33,7 @@ def test_skip_not_local_data_source(self, full_general_data_source): def test_skip_not_account_password_login_data_source(self, full_local_data_source): """没有启用账密登录的,同步不会生效""" - full_local_data_source.plugin_config["enable_account_password_login"] = False + full_local_data_source.plugin_config["enable_password"] = False full_local_data_source.save() LocalDataSourceIdentityInfoInitializer(full_local_data_source).initialize() diff --git a/src/bk-user/tests/apps/data_source/test_models.py b/src/bk-user/tests/apps/data_source/test_models.py index 3605419f5..f5d85479b 100644 --- a/src/bk-user/tests/apps/data_source/test_models.py +++ b/src/bk-user/tests/apps/data_source/test_models.py @@ -76,7 +76,7 @@ def test_set_plugin_config_with_replace(local_ds_with_sensitive): def test_set_plugin_config_not_value(bare_local_data_source): - plugin_cfg = LocalDataSourcePluginConfig(enable_account_password_login=False) + plugin_cfg = LocalDataSourcePluginConfig(enable_password=False) bare_local_data_source.set_plugin_cfg(plugin_cfg) assert get_items(bare_local_data_source.plugin_config, "password_initial.fixed_password") is None @@ -85,8 +85,8 @@ def test_set_plugin_config_not_value(bare_local_data_source): def test_set_plugin_config_empty_value(local_ds_plugin_cfg, bare_local_data_source): plugin_cfg = LocalDataSourcePluginConfig(**local_ds_plugin_cfg) # local_ds_plugin_cfg 本身 fixed_password 本身就是 None,这里修改别的字段,是为了验证真的更新 - plugin_cfg.password_initial.force_change_at_first_login = False # type: ignore + plugin_cfg.login_limit.force_change_at_first_login = False # type: ignore bare_local_data_source.set_plugin_cfg(plugin_cfg) assert get_items(bare_local_data_source.plugin_config, "password_initial.fixed_password") is None - assert get_items(bare_local_data_source.plugin_config, "password_initial.force_change_at_first_login") is False + assert get_items(bare_local_data_source.plugin_config, "login_limit.force_change_at_first_login") is False diff --git a/src/bk-user/tests/fixtures/data_source.py b/src/bk-user/tests/fixtures/data_source.py index 10cd03a96..d1bf13906 100644 --- a/src/bk-user/tests/fixtures/data_source.py +++ b/src/bk-user/tests/fixtures/data_source.py @@ -22,7 +22,7 @@ @pytest.fixture() def local_ds_plugin_cfg() -> Dict[str, Any]: return { - "enable_account_password_login": True, + "enable_password": True, "password_rule": { "min_length": 12, "contain_lowercase": True, @@ -34,12 +34,8 @@ def local_ds_plugin_cfg() -> Dict[str, Any]: "not_continuous_letter": True, "not_continuous_digit": True, "not_repeated_symbol": True, - "valid_time": 7, - "max_retries": 3, - "lock_time": 3600, }, "password_initial": { - "force_change_at_first_login": True, "cannot_use_previous_password": True, "reserved_previous_password_count": 3, "generate_method": "random", @@ -81,6 +77,7 @@ def local_ds_plugin_cfg() -> Dict[str, Any]: }, }, "password_expire": { + "valid_time": 7, "remind_before_expire": [1, 7], "notification": { "enabled_methods": ["email", "sms"], @@ -118,6 +115,11 @@ def local_ds_plugin_cfg() -> Dict[str, Any]: ], }, }, + "login_limit": { + "force_change_at_first_login": True, + "max_retries": 3, + "lock_time": 3600, + }, } diff --git a/src/idp-plugins/idp_plugins/local/plugin.py b/src/idp-plugins/idp_plugins/local/plugin.py index c2d1a9a64..bc138c48f 100644 --- a/src/idp-plugins/idp_plugins/local/plugin.py +++ b/src/idp-plugins/idp_plugins/local/plugin.py @@ -23,7 +23,7 @@ class LocalIdpPluginConfig(BasePluginConfig): """本地账密认证源插件配置""" - # 开启账密登录的数据源 + # 开启密码功能的数据源 data_source_ids: List[int] = [] diff --git a/src/pages/src/hooks/useDataSource.ts b/src/pages/src/hooks/useDataSource.ts index f191e3d00..9337a5f12 100644 --- a/src/pages/src/hooks/useDataSource.ts +++ b/src/pages/src/hooks/useDataSource.ts @@ -71,7 +71,7 @@ export const useDataSource = () => { plugin_id: 'local', plugin_config: { ...res.data?.config, - enable_account_password_login: true, + enable_password: true, }, }).then((res) => { currentDataSourceId.value = res.data?.id; diff --git a/src/pages/src/http/types/settingFiles.ts b/src/pages/src/http/types/settingFiles.ts index cd1950c96..b2560b7dd 100644 --- a/src/pages/src/http/types/settingFiles.ts +++ b/src/pages/src/http/types/settingFiles.ts @@ -43,7 +43,7 @@ export interface PutUserValidityParams { */ export interface PatchBuiltinManagerParams { username?: string, - enable_account_password_login?: boolean, + enable_login?: boolean, } /** diff --git a/src/pages/src/views/data-source/local-details/PswInfo.vue b/src/pages/src/views/data-source/local-details/PswInfo.vue index b3d24a0df..c053f1066 100644 --- a/src/pages/src/views/data-source/local-details/PswInfo.vue +++ b/src/pages/src/views/data-source/local-details/PswInfo.vue @@ -99,7 +99,7 @@ onMounted(async () => { try { isLoading.value = true; const res = await getDataSourceDetails(currentId.value); - openPasswordLogin.value = res.data?.plugin_config?.enable_account_password_login; + openPasswordLogin.value = res.data?.plugin_config?.enable_password; passwordRule.value = res.data?.plugin_config?.password_rule; passwordInitial.value = res.data?.plugin_config?.password_initial; passwordExpire.value = res.data?.plugin_config?.password_expire; diff --git a/src/pages/src/views/data-source/local-details/index.vue b/src/pages/src/views/data-source/local-details/index.vue index 08020adf4..da52be903 100644 --- a/src/pages/src/views/data-source/local-details/index.vue +++ b/src/pages/src/views/data-source/local-details/index.vue @@ -93,7 +93,7 @@ onMounted(async () => { }); const pluginsRes = await getDataSourcePlugins(); const loginRes = await getDataSourceDetails(currentId?.value); - isPasswordLogin.value = loginRes.data?.plugin_config?.enable_account_password_login; + isPasswordLogin.value = loginRes.data?.plugin_config?.enable_password; typeList.value = pluginsRes.data; } catch (e) { console.warn(e); diff --git a/src/pages/src/views/data-source/new-data/Local.vue b/src/pages/src/views/data-source/new-data/Local.vue index c9d978a3f..67183d161 100644 --- a/src/pages/src/views/data-source/new-data/Local.vue +++ b/src/pages/src/views/data-source/new-data/Local.vue @@ -16,12 +16,12 @@ @focus="handleChange" /> - + {{ $t('开启账密登录') }} -