From 43647c06cb584faf10febcfcb8763ceff94300e7 Mon Sep 17 00:00:00 2001 From: alex-smile <443677891@qq.com> Date: Fri, 8 Dec 2023 18:28:40 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8D=95=E5=85=83=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apis/open/esb/permission/helpers.py | 151 ---------------- .../apigateway/apis/open/permission/views.py | 8 +- .../apigateway/apps/permission/tasks.py | 3 +- .../apigateway/biz/esb/permissions.py | 8 +- .../apigateway/apigateway/biz/permission.py | 2 +- .../ee/tests/apps/esb/bkcore/test_managers.py | 39 ++++ .../apis/open/esb/permission/test_views.py | 78 ++++---- .../apigateway/tests/biz/esb/__init__.py | 17 ++ .../apigateway/tests/biz/esb/conftest.py | 31 ++++ .../esb/test_permissions.py} | 166 +++++++++++------- .../apigateway/tests/biz/test_permission.py | 33 ++++ 11 files changed, 276 insertions(+), 260 deletions(-) delete mode 100644 src/dashboard/apigateway/apigateway/apis/open/esb/permission/helpers.py create mode 100644 src/dashboard/apigateway/apigateway/editions/ee/tests/apps/esb/bkcore/test_managers.py create mode 100644 src/dashboard/apigateway/apigateway/tests/biz/esb/__init__.py create mode 100644 src/dashboard/apigateway/apigateway/tests/biz/esb/conftest.py rename src/dashboard/apigateway/apigateway/tests/{apis/open/esb/permission/test_helpers.py => biz/esb/test_permissions.py} (62%) diff --git a/src/dashboard/apigateway/apigateway/apis/open/esb/permission/helpers.py b/src/dashboard/apigateway/apigateway/apis/open/esb/permission/helpers.py deleted file mode 100644 index 676f1e452..000000000 --- a/src/dashboard/apigateway/apigateway/apis/open/esb/permission/helpers.py +++ /dev/null @@ -1,151 +0,0 @@ -# -*- coding: utf-8 -*- -# -# TencentBlueKing is pleased to support the open source community by making -# 蓝鲸智云 - API 网关(BlueKing - APIGateway) available. -# Copyright (C) 2017 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. -# -# We undertake not to change the open source license (MIT license) applicable -# to the current version of the project delivered to anyone in the future. -# -import copy -import math -from dataclasses import dataclass -from typing import List, Optional, Union - -from django.utils.functional import cached_property -from pydantic import BaseModel, parse_obj_as - -from apigateway.apps.esb.bkcore.models import AppComponentPermission, AppPermissionApplyRecord -from apigateway.apps.esb.helpers import get_component_doc_link -from apigateway.apps.permission.constants import ApplyStatusEnum, PermissionLevelEnum, PermissionStatusEnum - - -class ComponentPermission(BaseModel): - class Config: - arbitrary_types_allowed = True - keep_untouched = (cached_property,) - - id: int - board: str - name: str - description: str - description_en: Optional[str] = None - system_name: str - permission_level: str - component_permission: Optional[AppComponentPermission] - component_permission_apply_status: Optional[str] - - def as_dict(self): - return { - "board": self.board, - "id": self.id, - "name": self.name, - "system_name": self.system_name, - "description": self.description, - "description_en": self.description_en, - "permission_level": self.permission_level, - "permission_status": self.permission_status, - "expires_in": self.expires_in, - "doc_link": self.doc_link, - } - - @property - def component_perm_required(self) -> bool: - return self.permission_level != PermissionLevelEnum.UNLIMITED.value - - @property - def doc_link(self): - return get_component_doc_link( - board=self.board, - system_name=self.system_name, - component_name=self.name, - ) - - @property - def permission_status(self) -> str: - # 如果组件不需要权限校验,则权限类型为:无限制,即默认拥有权限 - if not self.component_perm_required: - return PermissionStatusEnum.UNLIMITED.value - - # 如果权限记录中,有效期为永久有效;权限不需要再申请,优先展示 - if self.expires_in == math.inf: - return PermissionStatusEnum.OWNED.value - - # 如果权限已有申请状态,如已拒绝、申请中;优先展示 - if self.component_permission_apply_status: - return self.component_permission_apply_status - - # 有权限且未过期 - if self.expires_in > 0: - return PermissionStatusEnum.OWNED.value - - # 有权限,但是已过期 - if self.expires_in > -math.inf: - return PermissionStatusEnum.EXPIRED.value - - # 无权限,待申请 - return PermissionStatusEnum.NEED_APPLY.value - - @cached_property - def expires_in(self) -> Union[int, float]: - if not self.component_perm_required: - return math.inf - - return self._get_component_permission_expires_in() - - def _get_component_permission_expires_in(self) -> Union[int, float]: - if not self.component_permission: - return -math.inf - - return self._normalize_expires_in(self.component_permission.expires_in) - - def _normalize_expires_in(self, expires_in) -> Union[int, float]: - # 指定的过期时间为None,表示不过期,过期时间设置为 math.inf - if expires_in is None: - return math.inf - - return expires_in - - -@dataclass -class ComponentPermissionBuilder: - system_id: Optional[int] - target_app_code: str - - def build(self, components: list) -> list: - component_ids = [component["id"] for component in components] - component_permission_map = self._get_component_permission_map(component_ids) - component_permission_apply_status_map = AppPermissionApplyRecord.objects.get_component_permisson_status( - self.target_app_code, - self.system_id, - [ApplyStatusEnum.PENDING.value], - ) - - components = copy.copy(components) - for component in components: - component["component_permission"] = component_permission_map.get(component["id"]) - component["component_permission_apply_status"] = component_permission_apply_status_map.get( - component["id"], None - ) - - component_permissions = parse_obj_as(List[ComponentPermission], components) - - return [perm.as_dict() for perm in component_permissions] - - def _get_component_permission_map(self, component_ids: List[int]): - return { - perm.component_id: perm - for perm in AppComponentPermission.objects.filter( - bk_app_code=self.target_app_code, - component_id__in=component_ids, - ) - } diff --git a/src/dashboard/apigateway/apigateway/apis/open/permission/views.py b/src/dashboard/apigateway/apigateway/apis/open/permission/views.py index c160b9cf1..f3889322f 100644 --- a/src/dashboard/apigateway/apigateway/apis/open/permission/views.py +++ b/src/dashboard/apigateway/apigateway/apis/open/permission/views.py @@ -123,7 +123,7 @@ def post(self, request, *args, **kwargs): data = slz.validated_data manager = PermissionDimensionManager.get_manager(data["grant_dimension"]) - instance = manager.create_apply_record( + record = manager.create_apply_record( data["target_app_code"], request.gateway, data.get("resource_ids", []), @@ -134,14 +134,14 @@ def post(self, request, *args, **kwargs): ) try: - apply_async_on_commit(send_mail_for_perm_apply, args=[instance.id]) + apply_async_on_commit(send_mail_for_perm_apply, args=[record.id]) except Exception: - logger.exception("send mail to api manager fail. apply_record_id=%s", instance.apply_record_id) + logger.exception("send mail to api manager fail. apply_record_id=%s", record.id) return OKJsonResponse( "OK", data={ - "record_id": instance.apply_record_id, + "record_id": record.id, }, ) diff --git a/src/dashboard/apigateway/apigateway/apps/permission/tasks.py b/src/dashboard/apigateway/apigateway/apps/permission/tasks.py index dce8c7c68..adbc45002 100644 --- a/src/dashboard/apigateway/apigateway/apps/permission/tasks.py +++ b/src/dashboard/apigateway/apigateway/apps/permission/tasks.py @@ -37,7 +37,6 @@ ) from apigateway.apps.permission.models import ( AppAPIPermission, - AppPermissionApply, AppPermissionRecord, AppResourcePermission, ) @@ -61,7 +60,7 @@ def send_mail_for_perm_apply(record_id): """ 申请权限,发送邮件通知管理员审批 """ - record = AppPermissionApply.objects.get(id=record_id) + record = AppPermissionRecord.objects.get(id=record_id) apigw_domain = getattr(settings, "DASHBOARD_FE_URL", "").rstrip("/") manager = PermissionDimensionManager.get_manager(record.grant_dimension) diff --git a/src/dashboard/apigateway/apigateway/biz/esb/permissions.py b/src/dashboard/apigateway/apigateway/biz/esb/permissions.py index 79c4e6c53..679a7db41 100644 --- a/src/dashboard/apigateway/apigateway/biz/esb/permissions.py +++ b/src/dashboard/apigateway/apigateway/biz/esb/permissions.py @@ -72,7 +72,7 @@ def create_apply_record( username: str, ) -> AppPermissionApplyRecord: """创建权限申请单""" - instance = AppPermissionApplyRecord.objects.create_record( + record = AppPermissionApplyRecord.objects.create_record( board=system.board, bk_app_code=bk_app_code, applied_by=username, @@ -91,14 +91,14 @@ def create_apply_record( component_id__in=component_ids, ).delete() AppPermissionApplyStatus.objects.batch_create( - record=instance, + record=record, bk_app_code=bk_app_code, system=system, component_ids=component_ids, status=ApplyStatusEnum.PENDING.value, ) - return instance + return record def renew_permission(self, bk_app_code: str, component_ids: List[int], expire_days: int): """权限续期""" @@ -299,7 +299,7 @@ def patch_permission_apply_records(self, records: List[AppPermissionApplyRecord] class AppComponentPermissionData(BaseModel): - expires_in: int + expires_in: Optional[int] class ComponentPermission(BaseModel): diff --git a/src/dashboard/apigateway/apigateway/biz/permission.py b/src/dashboard/apigateway/apigateway/biz/permission.py index 20eac75d1..4d11bda08 100644 --- a/src/dashboard/apigateway/apigateway/biz/permission.py +++ b/src/dashboard/apigateway/apigateway/biz/permission.py @@ -151,7 +151,7 @@ def create_apply_record( resources=Resource.objects.filter_by_ids(gateway, ids=resource_ids), ) - return instance + return record class APIPermissionDimensionManager(PermissionDimensionManager): diff --git a/src/dashboard/apigateway/apigateway/editions/ee/tests/apps/esb/bkcore/test_managers.py b/src/dashboard/apigateway/apigateway/editions/ee/tests/apps/esb/bkcore/test_managers.py new file mode 100644 index 000000000..db989dd56 --- /dev/null +++ b/src/dashboard/apigateway/apigateway/editions/ee/tests/apps/esb/bkcore/test_managers.py @@ -0,0 +1,39 @@ +# +# TencentBlueKing is pleased to support the open source community by making +# 蓝鲸智云 - API 网关(BlueKing - APIGateway) available. +# Copyright (C) 2017 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. +# +# We undertake not to change the open source license (MIT license) applicable +# to the current version of the project delivered to anyone in the future. +# +from ddf import G + +from apigateway.apps.esb.bkcore.models import AppComponentPermission +from apigateway.utils.time import to_datetime_from_now + + +class TestAppComponentPermissionManager: + def test_renew_permissions(self, unique_id): + perm = G( + AppComponentPermission, + bk_app_code=unique_id, + component_id=1, + expires=to_datetime_from_now(days=100), + ) + + AppComponentPermission.objects.renew_permissions(unique_id, [1], 70) + perm.refresh_from_db() + to_datetime_from_now(days=99) < perm.expires < to_datetime_from_now(days=101) + + AppComponentPermission.objects.renew_permissions(unique_id, [1], 170) + perm.refresh_from_db() + to_datetime_from_now(days=160) < perm.expires < to_datetime_from_now(days=180) diff --git a/src/dashboard/apigateway/apigateway/tests/apis/open/esb/permission/test_views.py b/src/dashboard/apigateway/apigateway/tests/apis/open/esb/permission/test_views.py index 0441b6505..d409fd7fe 100644 --- a/src/dashboard/apigateway/apigateway/tests/apis/open/esb/permission/test_views.py +++ b/src/dashboard/apigateway/apigateway/tests/apis/open/esb/permission/test_views.py @@ -35,22 +35,26 @@ def test_list(self, mocker, request_factory): return_value="my-test", ) mocker.patch( - "apigateway.apis.open.esb.permission.views.ComponentPermissionBuilder.build", - return_value=[ - { - "id": 1, - "board": "test", - "name": "test", - "system_name": "test", - "description": "test", - "description_en": "test_en", - "expires_in": math.inf, - "permission_level": "normal", - "permission_status": "owned", - "doc_link": "", - "tag": "", + "apigateway.apis.open.esb.permission.views.ComponentPermissionManager.get_manager", + return_value=mocker.MagicMock( + **{ + "list_permissions.return_value": [ + { + "id": 1, + "board": "test", + "name": "test", + "system_name": "test", + "description": "test", + "description_en": "test_en", + "expires_in": math.inf, + "permission_level": "normal", + "permission_status": "owned", + "doc_link": "", + "tag": "", + } + ] } - ], + ), ) params = { @@ -82,15 +86,13 @@ def test_list(self, mocker, request_factory): class TestAppPermissionApplyV1APIView: - def test_apply(self, mocker, request_factory, unique_id): + def test_apply(self, settings, mocker, request_factory, unique_id): + settings.USE_GATEWAY_BK_ESB_MANAGE_COMPONENT_PERMISSIONS = False + mocker.patch( "apigateway.apis.open.esb.permission.serializers.BKAppCodeValidator.__call__", return_value=None, ) - mocker.patch( - "apigateway.apis.open.esb.permission.views.send_mail_for_perm_apply.apply_async", - return_value=None, - ) system = G(ComponentSystem) channel = G(ESBChannel, system=system) @@ -123,22 +125,26 @@ def test_list(self, mocker, request_factory): return_value=[1], ) mocker.patch( - "apigateway.apis.open.esb.permission.views.ComponentPermissionBuilder.build", - return_value=[ - { - "board": "test", - "id": 1, - "name": "test", - "system_name": "test", - "description": "desc", - "description_en": "desc_en", - "expires_in": 10, - "permission_level": "nomal", - "permission_status": "owned", - "permission_action": "", - "doc_link": "", - }, - ], + "apigateway.apis.open.esb.permission.views.ComponentPermissionManager.get_manager", + return_value=mocker.MagicMock( + **{ + "list_permissions.return_value": [ + { + "board": "test", + "id": 1, + "name": "test", + "system_name": "test", + "description": "desc", + "description_en": "desc_en", + "expires_in": 10, + "permission_level": "nomal", + "permission_status": "owned", + "permission_action": "", + "doc_link": "", + }, + ] + } + ), ) mocker.patch( "apigateway.apis.open.esb.permission.serializers.BoardConfigManager.get_optional_display_label", diff --git a/src/dashboard/apigateway/apigateway/tests/biz/esb/__init__.py b/src/dashboard/apigateway/apigateway/tests/biz/esb/__init__.py new file mode 100644 index 000000000..2941673fe --- /dev/null +++ b/src/dashboard/apigateway/apigateway/tests/biz/esb/__init__.py @@ -0,0 +1,17 @@ +# +# TencentBlueKing is pleased to support the open source community by making +# 蓝鲸智云 - API 网关(BlueKing - APIGateway) available. +# Copyright (C) 2017 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. +# +# We undertake not to change the open source license (MIT license) applicable +# to the current version of the project delivered to anyone in the future. +# diff --git a/src/dashboard/apigateway/apigateway/tests/biz/esb/conftest.py b/src/dashboard/apigateway/apigateway/tests/biz/esb/conftest.py new file mode 100644 index 000000000..a19cd61f0 --- /dev/null +++ b/src/dashboard/apigateway/apigateway/tests/biz/esb/conftest.py @@ -0,0 +1,31 @@ +# +# TencentBlueKing is pleased to support the open source community by making +# 蓝鲸智云 - API 网关(BlueKing - APIGateway) available. +# Copyright (C) 2017 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. +# +# We undertake not to change the open source license (MIT license) applicable +# to the current version of the project delivered to anyone in the future. +# +import pytest +from ddf import G + +from apigateway.apps.esb.bkcore.models import ComponentSystem, ESBChannel + + +@pytest.fixture +def fake_system(): + return G(ComponentSystem) + + +@pytest.fixture +def fake_channel(fake_system): + return G(ESBChannel, system=fake_system) diff --git a/src/dashboard/apigateway/apigateway/tests/apis/open/esb/permission/test_helpers.py b/src/dashboard/apigateway/apigateway/tests/biz/esb/test_permissions.py similarity index 62% rename from src/dashboard/apigateway/apigateway/tests/apis/open/esb/permission/test_helpers.py rename to src/dashboard/apigateway/apigateway/tests/biz/esb/test_permissions.py index a38b5dcc4..4e3064f50 100644 --- a/src/dashboard/apigateway/apigateway/tests/apis/open/esb/permission/test_helpers.py +++ b/src/dashboard/apigateway/apigateway/tests/biz/esb/test_permissions.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # # TencentBlueKing is pleased to support the open source community by making # 蓝鲸智云 - API 网关(BlueKing - APIGateway) available. @@ -17,15 +16,106 @@ # to the current version of the project delivered to anyone in the future. # import math -from unittest import mock import pytest from ddf import G -from apigateway.apis.open.esb.permission.helpers import ComponentPermission, ComponentPermissionBuilder -from apigateway.apps.esb.bkcore.models import AppComponentPermission, ComponentSystem, ESBChannel +from apigateway.apps.esb.bkcore.models import ( + AppComponentPermission, + AppPermissionApplyRecord, + ComponentResourceBinding, +) +from apigateway.biz.esb.permissions import ( + AppComponentPermissionData, + ComponentPermission, + ComponentPermissionByEsbManager, +) +from apigateway.utils.time import to_datetime_from_now -pytestmark = pytest.mark.django_db + +class TestComponentPermissionByEsbManager: + def test_create_apply_record(self, unique_id, fake_system, fake_channel): + manager = ComponentPermissionByEsbManager() + record = manager.create_apply_record( + bk_app_code=unique_id, + system=fake_system, + component_ids=[fake_channel.id], + reason="", + expire_days=180, + username="admin", + ) + + assert AppPermissionApplyRecord.objects.filter(id=record.id).exists() + + def test_renew_permission(self, unique_id, fake_channel): + perm = G( + AppComponentPermission, + bk_app_code=unique_id, + component_id=fake_channel.id, + expires=to_datetime_from_now(days=10), + ) + + manager = ComponentPermissionByEsbManager() + manager.renew_permission(unique_id, [fake_channel.id], 180) + + perm.refresh_from_db() + + assert to_datetime_from_now(days=170) < perm.expires < to_datetime_from_now(days=190) + + def test_list_permissions(self, mocker, fake_system, fake_channel): + mocker.patch( + "apigateway.biz.esb.permissions.get_component_doc_link", + return_value="", + ) + mocker.patch( + "apigateway.biz.esb.permissions.ComponentPermission.expires_in", + new_callable=mocker.PropertyMock(return_value=-math.inf), + ) + mocker.patch( + "apigateway.biz.esb.permissions.ComponentPermission.permission_status", + new_callable=mocker.PropertyMock(return_value="need_apply"), + ) + + components = [ + { + "id": fake_channel.id, + "board": fake_channel.board or "", + "name": fake_channel.name, + "description": fake_channel.description, + "description_en": fake_channel.description_en, + "system_name": fake_system.name, + "permission_level": fake_channel.permission_level, + } + ] + + manager = ComponentPermissionByEsbManager() + result = manager.list_permissions("test", components) + assert result == [ + { + "id": fake_channel.id, + "board": fake_channel.board or "", + "name": fake_channel.name, + "description": fake_channel.description, + "description_en": fake_channel.description_en, + "system_name": fake_system.name, + "permission_level": fake_channel.permission_level, + "permission_status": "need_apply", + "expires_in": -math.inf, + "doc_link": "", + } + ] + + def test_get_component_id_to_resource_id(self, fake_channel, faker): + if not ComponentResourceBinding: + return + + resource_id = faker.pyint() + + G(ComponentResourceBinding, component_id=fake_channel.id, resource_id=resource_id) + + manager = ComponentPermissionByEsbManager() + result = manager._get_component_id_to_resource_id([fake_channel.id]) + assert result == {fake_channel.id: resource_id} class TestComponentPermission: @@ -73,7 +163,7 @@ def mocked_component(self): ) def test_as_dict(self, mocker, component, expected): mocker.patch( - "apigateway.apis.open.esb.permission.helpers.get_component_doc_link", + "apigateway.biz.esb.permissions.get_component_doc_link", return_value="", ) perm = ComponentPermission.parse_obj(component) @@ -146,13 +236,13 @@ def test_component_perm_required(self, mocked_component, permission_level, expec ) def test_permission_status(self, mocker, mocked_component, params, expected): mocker.patch( - "apigateway.apis.open.esb.permission.helpers.ComponentPermission.component_perm_required", - new_callable=mock.PropertyMock(return_value=params["component_perm_required"]), + "apigateway.biz.esb.permissions.ComponentPermission.component_perm_required", + new_callable=mocker.PropertyMock(return_value=params["component_perm_required"]), ) if "expires_in" in params: mocker.patch( - "apigateway.apis.open.esb.permission.helpers.ComponentPermission.expires_in", - new_callable=mock.PropertyMock(return_value=params["expires_in"]), + "apigateway.biz.esb.permissions.ComponentPermission.expires_in", + new_callable=mocker.PropertyMock(return_value=params["expires_in"]), ) mocked_component.update(params) @@ -200,64 +290,16 @@ def test_permission_status(self, mocker, mocked_component, params, expected): ) def test_expires_in(self, mocker, mocked_component, params, expected): mocker.patch( - "apigateway.apis.open.esb.permission.helpers.ComponentPermission.component_perm_required", - new_callable=mock.PropertyMock(return_value=params["component_perm_required"]), + "apigateway.biz.esb.permissions.ComponentPermission.component_perm_required", + new_callable=mocker.PropertyMock(return_value=params["component_perm_required"]), ) if "component_permission_expires_in" in params: - params["component_permission"] = G(AppComponentPermission) - mocker.patch( - "apigateway.apps.esb.bkcore.models.AppComponentPermission.expires_in", - new_callable=mock.PropertyMock(return_value=params["component_permission_expires_in"]), + params["component_permission"] = AppComponentPermissionData( + expires_in=params["component_permission_expires_in"] ) mocked_component.update(params) perm = ComponentPermission.parse_obj(mocked_component) assert perm.expires_in == expected - - -class TestComponentPermissionBuilder: - def test_build(self, mocker): - mocker.patch( - "apigateway.apis.open.esb.permission.helpers.get_component_doc_link", - return_value="", - ) - mocker.patch( - "apigateway.apis.open.esb.permission.helpers.ComponentPermission.expires_in", - new_callable=mock.PropertyMock(return_value=-math.inf), - ) - mocker.patch( - "apigateway.apis.open.esb.permission.helpers.ComponentPermission.permission_status", - new_callable=mock.PropertyMock(return_value="need_apply"), - ) - system = G(ComponentSystem) - component = G(ESBChannel, system=system) - - components = [ - { - "id": component.id, - "board": component.board or "", - "name": component.name, - "description": component.description, - "description_en": component.description_en, - "system_name": system.name, - "permission_level": component.permission_level, - } - ] - - result = ComponentPermissionBuilder(system.id, target_app_code="test").build(components) - assert result == [ - { - "id": component.id, - "board": component.board or "", - "name": component.name, - "description": component.description, - "description_en": component.description_en, - "system_name": system.name, - "permission_level": component.permission_level, - "permission_status": "need_apply", - "expires_in": -math.inf, - "doc_link": "", - } - ] diff --git a/src/dashboard/apigateway/apigateway/tests/biz/test_permission.py b/src/dashboard/apigateway/apigateway/tests/biz/test_permission.py index 28a637959..eb489c703 100644 --- a/src/dashboard/apigateway/apigateway/tests/biz/test_permission.py +++ b/src/dashboard/apigateway/apigateway/tests/biz/test_permission.py @@ -26,6 +26,7 @@ AppAPIPermission, AppPermissionApply, AppPermissionApplyStatus, + AppPermissionRecord, AppResourcePermission, ) from apigateway.biz.permission import ( @@ -203,6 +204,22 @@ def test_allow_apply_permission(self, mocker, fake_gateway): result, _ = manager.allow_apply_permission(fake_gateway, target_app_code) assert result is True + def test_create_apply_record(self, fake_gateway, fake_resource): + manager = APIPermissionDimensionManager() + record = manager.create_apply_record( + "test", + fake_gateway, + [fake_resource.id], + GrantDimensionEnum.API.value, + "", + 180, + "admin", + ) + + assert AppPermissionRecord.objects.filter(id=record.id).exists() + assert AppPermissionApply.objects.filter(apply_record_id=record.id).exists() + assert AppPermissionApplyStatus.objects.filter(api=fake_gateway).exists() + class TestResourcePermissionDimensionManager: def _make_fake_apply(self, fake_gateway): @@ -334,3 +351,19 @@ def test_allow_apply_permission(self, fake_gateway): manager = ResourcePermissionDimensionManager() result, _ = manager.allow_apply_permission(fake_gateway.id, "test") assert not result + + def test_create_apply_record(self, fake_gateway, fake_resource): + manager = ResourcePermissionDimensionManager() + record = manager.create_apply_record( + "test", + fake_gateway, + [fake_resource.id], + GrantDimensionEnum.API.value, + "", + 180, + "admin", + ) + + assert AppPermissionRecord.objects.filter(id=record.id).exists() + assert AppPermissionApply.objects.filter(apply_record_id=record.id).exists() + assert AppPermissionApplyStatus.objects.filter(api=fake_gateway).exists()