From fde60ed9b0707a84a1f95325645e0b4f1d4b300c Mon Sep 17 00:00:00 2001 From: IMBlues Date: Wed, 8 Dec 2021 15:01:53 +0800 Subject: [PATCH 1/3] refactor: exposing enabled of setting to frontend --- src/api/bkuser_core/categories/models.py | 12 +++++------ src/api/bkuser_core/profiles/views.py | 19 +++++++++++------ .../bkuser_core/user_settings/exceptions.py | 21 +++++++++++++++++++ src/api/bkuser_core/user_settings/loader.py | 7 ++++++- .../bkuser_core/user_settings/serializers.py | 1 + src/api/bkuser_core/user_settings/views.py | 2 +- .../bkuser_shell/config_center/serializers.py | 1 + src/saas/bkuser_shell/config_center/views.py | 4 ++-- 8 files changed, 51 insertions(+), 16 deletions(-) create mode 100644 src/api/bkuser_core/user_settings/exceptions.py diff --git a/src/api/bkuser_core/categories/models.py b/src/api/bkuser_core/categories/models.py index 8c77be765..65666940c 100644 --- a/src/api/bkuser_core/categories/models.py +++ b/src/api/bkuser_core/categories/models.py @@ -118,7 +118,7 @@ def get_required_metas(self): def get_unfilled_settings(self): """获取未就绪的配置""" required_metas = self.get_required_metas() - configured_meta_ids = self.settings.filter(enabled=True).values_list("meta", flat=True) + configured_meta_ids = self.settings.all().values_list("meta", flat=True) return required_metas.exclude(id__in=configured_meta_ids) def mark_synced(self): @@ -144,7 +144,7 @@ def to_audit_info(self): class SyncTaskManager(models.Manager): def register_task( self, category: ProfileCategory, operator: str, type_: SyncTaskType = SyncTaskType.MANUAL - ) -> 'SyncTask': + ) -> "SyncTask": qs = self.filter(category=category, status=SyncTaskStatus.RUNNING.value).order_by("-create_time") running = qs.first() if not running: @@ -164,7 +164,7 @@ def register_task( class SyncTask(TimestampedModel): - id = models.UUIDField('UUID', default=uuid4, primary_key=True, editable=False, auto_created=True, unique=True) + id = models.UUIDField("UUID", default=uuid4, primary_key=True, editable=False, auto_created=True, unique=True) category = models.ForeignKey(ProfileCategory, verbose_name="用户目录", on_delete=models.CASCADE, db_index=True) status = models.CharField( verbose_name="状态", max_length=16, choices=SyncTaskStatus.get_choices(), default=SyncTaskStatus.RUNNING.value @@ -196,8 +196,8 @@ def progresses(self): class SyncProgressManager(models.Manager): - def init_progresses(self, category: ProfileCategory, task_id: UUID) -> Dict[SyncStep, 'SyncProgress']: - progresses: Dict[SyncStep, 'SyncProgress'] = {} + def init_progresses(self, category: ProfileCategory, task_id: UUID) -> Dict[SyncStep, "SyncProgress"]: + progresses: Dict[SyncStep, "SyncProgress"] = {} for step in [ SyncStep.DEPARTMENTS, SyncStep.USERS, @@ -211,7 +211,7 @@ def init_progresses(self, category: ProfileCategory, task_id: UUID) -> Dict[Sync class SyncProgress(TimestampedModel): - task_id = models.UUIDField(db_index=True, verbose_name='任务id') + task_id = models.UUIDField(db_index=True, verbose_name="任务id") category = models.ForeignKey(ProfileCategory, verbose_name="用户目录", on_delete=models.CASCADE) step = models.CharField(verbose_name="同步步骤", max_length=32, choices=SyncStep.get_choices()) status = models.CharField( diff --git a/src/api/bkuser_core/profiles/views.py b/src/api/bkuser_core/profiles/views.py index b4b9faa50..b68eb7064 100644 --- a/src/api/bkuser_core/profiles/views.py +++ b/src/api/bkuser_core/profiles/views.py @@ -63,6 +63,7 @@ from bkuser_global.utils import force_str_2_bool +from ..user_settings.exceptions import SettingHasBeenDisabledError from . import serializers as local_serializers logger = logging.getLogger(__name__) @@ -320,9 +321,12 @@ def _update(self, request, partial): if validated_data.get("password"): pending_password = validated_data.get("password") config_loader = ConfigProvider(category_id=instance.category_id) - max_password_history = config_loader.get("max_password_history", settings.DEFAULT_MAX_PASSWORD_HISTORY) - if check_former_passwords(instance, pending_password, max_password_history): - raise error_codes.PASSWORD_DUPLICATED.f(max_password_history=max_password_history) + try: + max_password_history = config_loader.get("max_password_history", settings.DEFAULT_MAX_PASSWORD_HISTORY) + if check_former_passwords(instance, pending_password, int(max_password_history)): + raise error_codes.PASSWORD_DUPLICATED.f(max_password_history=max_password_history) + except SettingHasBeenDisabledError: + logger.info("category<%s> has disabled checking password", instance.category_id) PasswordValidator( min_length=int(config_loader["password_min_length"]), @@ -400,9 +404,12 @@ def modify_password(self, request, *args, **kwargs): new_password = serializer.validated_data["new_password"] config_loader = ConfigProvider(category_id=instance.category_id) - max_password_history = config_loader.get("max_password_history", settings.DEFAULT_MAX_PASSWORD_HISTORY) - if check_former_passwords(instance, new_password, max_password_history): - raise error_codes.PASSWORD_DUPLICATED.f(max_password_history=max_password_history) + try: + max_password_history = config_loader.get("max_password_history", settings.DEFAULT_MAX_PASSWORD_HISTORY) + if check_former_passwords(instance, new_password, int(max_password_history)): + raise error_codes.PASSWORD_DUPLICATED.f(max_password_history=max_password_history) + except SettingHasBeenDisabledError: + logger.info("category<%s> has disabled checking password", instance.category_id) if not instance.check_password(old_password): raise error_codes.PASSWORD_ERROR diff --git a/src/api/bkuser_core/user_settings/exceptions.py b/src/api/bkuser_core/user_settings/exceptions.py new file mode 100644 index 000000000..c87172c09 --- /dev/null +++ b/src/api/bkuser_core/user_settings/exceptions.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +""" +TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-用户管理(Bk-User) available. +Copyright (C) 2017-2021 THL A29 Limited, a Tencent company. All rights reserved. +Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. +You may obtain a copy of the License at http://opensource.org/licenses/MIT +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on +an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. +""" + + +class SettingHasBeenDisabledError(Exception): + """配置已经被禁用""" + + def __init__(self, key: str, *args): + self.key = key + super().__init__(*args) + + def __str__(self): + return f"setting {self.key} has been disabled." diff --git a/src/api/bkuser_core/user_settings/loader.py b/src/api/bkuser_core/user_settings/loader.py index 3d60b486c..f5452fc7a 100644 --- a/src/api/bkuser_core/user_settings/loader.py +++ b/src/api/bkuser_core/user_settings/loader.py @@ -10,6 +10,8 @@ """ from dataclasses import dataclass, field +from bkuser_core.user_settings.exceptions import SettingHasBeenDisabledError + from .models import Setting @@ -24,11 +26,14 @@ def __post_init__(self): self._refresh_config() def _refresh_config(self): - settings = Setting.objects.prefetch_related("meta").filter(category_id=self.category_id, enabled=True) + settings = Setting.objects.prefetch_related("meta").filter(category_id=self.category_id) self._raws = {x.meta.key: x for x in settings} self._config = {x.meta.key: x.value for x in settings} def get(self, k, d=None): + if not self._raws.get(k).enabled: + raise SettingHasBeenDisabledError(k) + return self._config.get(k, d) def __getitem__(self, key): diff --git a/src/api/bkuser_core/user_settings/serializers.py b/src/api/bkuser_core/user_settings/serializers.py index a7ff4fa68..eaaa5ddcf 100644 --- a/src/api/bkuser_core/user_settings/serializers.py +++ b/src/api/bkuser_core/user_settings/serializers.py @@ -45,6 +45,7 @@ class SettingCreateSerializer(serializers.Serializer): class SettingUpdateSerializer(serializers.Serializer): value = serializers.JSONField() + enabled = serializers.BooleanField(default=True) class SettingListSerializer(serializers.Serializer): diff --git a/src/api/bkuser_core/user_settings/views.py b/src/api/bkuser_core/user_settings/views.py index f3cd4b111..49351cf41 100644 --- a/src/api/bkuser_core/user_settings/views.py +++ b/src/api/bkuser_core/user_settings/views.py @@ -29,7 +29,7 @@ class SettingViewSet(AdvancedModelViewSet): """配置项""" - queryset = Setting.objects.filter(enabled=True) + queryset = Setting.objects.all() serializer_class = serializers.SettingSerializer lookup_field: str = "id" diff --git a/src/saas/bkuser_shell/config_center/serializers.py b/src/saas/bkuser_shell/config_center/serializers.py index c2f030e21..05ad8930d 100644 --- a/src/saas/bkuser_shell/config_center/serializers.py +++ b/src/saas/bkuser_shell/config_center/serializers.py @@ -147,6 +147,7 @@ class ListNamespaceSettingsSerializer(serializers.Serializer): class UpdateNamespaceSettingSerializer(serializers.Serializer): key = serializers.CharField() value = serializers.JSONField() + enabled = serializers.BooleanField(required=False, default=True) class SettingMetaSerializer(serializers.Serializer): diff --git a/src/saas/bkuser_shell/config_center/views.py b/src/saas/bkuser_shell/config_center/views.py index 9453e7783..f501a5f63 100644 --- a/src/saas/bkuser_shell/config_center/views.py +++ b/src/saas/bkuser_shell/config_center/views.py @@ -214,7 +214,7 @@ def update(self, request, category_id, namespace_name, validated_data): # TODO: 后续改为批量接口 result = [] for setting_info in validated_data: - body = {"value": setting_info["value"]} + body = {"value": setting_info["value"], "enabled": setting_info["enabled"]} try: setting_id = setting_instances[setting_info["key"]].id except KeyError: @@ -224,7 +224,7 @@ def update(self, request, category_id, namespace_name, validated_data): try: api_response = api_instance.v2_settings_partial_update(body=body, lookup_value=setting_id) except ApiException: - logger.exception("更新 Setting<%s> 失败", setting_info["id"]) + logger.exception("在目录<%s>中更新 Setting<%s>-<%s> 失败", category_id, setting_info["key"], setting_id) continue result.append(api_response) From 5b177dc55fedbaf2d4a21d9ae5ad67ea5ece8c0f Mon Sep 17 00:00:00 2001 From: Blues Yu Date: Thu, 9 Dec 2021 18:57:51 +0800 Subject: [PATCH 2/3] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E4=B8=8D=E5=AD=98=E5=9C=A8=E7=9A=84=20setting=20=E4=BC=9A?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E8=AF=BB=E5=8F=96=E5=88=B0=20enabled=20?= =?UTF-8?q?=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/bkuser_core/user_settings/loader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/bkuser_core/user_settings/loader.py b/src/api/bkuser_core/user_settings/loader.py index f5452fc7a..bc08d4205 100644 --- a/src/api/bkuser_core/user_settings/loader.py +++ b/src/api/bkuser_core/user_settings/loader.py @@ -31,7 +31,7 @@ def _refresh_config(self): self._config = {x.meta.key: x.value for x in settings} def get(self, k, d=None): - if not self._raws.get(k).enabled: + if k in self._raws and not self._raws.get(k).enabled: raise SettingHasBeenDisabledError(k) return self._config.get(k, d) From 84252ee03f705e26e4503b7a70df76648477f170 Mon Sep 17 00:00:00 2001 From: Blues Yu Date: Thu, 9 Dec 2021 19:07:53 +0800 Subject: [PATCH 3/3] fix: revert eslint actions --- .github/workflows/eslint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/eslint.yaml b/.github/workflows/eslint.yaml index ab2c09573..8a20e5222 100644 --- a/.github/workflows/eslint.yaml +++ b/.github/workflows/eslint.yaml @@ -14,7 +14,7 @@ jobs: - name: Install modules run: | cd src/pages - npm i --force + npm i - name: Run ESLint run: | cd src/pages