Skip to content

Commit

Permalink
feat:超管类API增加授权工具接口 TencentBlueKing#2409
Browse files Browse the repository at this point in the history
  • Loading branch information
Canway-shiisa committed Apr 24, 2024
1 parent ead03cf commit 9c189e1
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 5 deletions.
10 changes: 10 additions & 0 deletions saas/backend/api/admin/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,19 @@ class AdminAPIEnum(BaseAPIEnum):
# 用户组成员
GROUP_MEMBER_LIST = auto()

# 用户组权限
GROUP_POLICY_GRANT = auto()

# 模板
TEMPLATE_CREATE = auto()

# Subject
SUBJECT_JOINED_GROUP_LIST = auto()
SUBJECT_ROLE_LIST = auto()

# System
SYSTEM_LIST = auto()
SYSTEM_PROVIDER_CONFIG_LIST = auto()

# 角色
ROLE_SUPER_MANAGER_MEMBER_LIST = auto()
Expand All @@ -52,11 +59,14 @@ class AdminAPIEnum(BaseAPIEnum):
_choices_labels = skip(
(
(SYSTEM_LIST, "获取系统列表"),
(SYSTEM_PROVIDER_CONFIG_LIST, "获取系统回调信息"),
(GROUP_LIST, "获取用户组列表"),
(GROUP_BATCH_CREATE, "批量创建用户组"),
(GROUP_UPDATE, "更新用户组"),
(GROUP_DELETE, "删除用户组"),
(GROUP_MEMBER_LIST, "获取用户组成员列表"),
(GROUP_POLICY_GRANT, "授权用户组"),
(TEMPLATE_CREATE, "新建模板"),
(SUBJECT_JOINED_GROUP_LIST, "获取Subject加入的用户组列表"),
(SUBJECT_ROLE_LIST, "获取Subject角色列表"),
(ROLE_SUPER_MANAGER_MEMBER_LIST, "获取超级管理员成员列表"),
Expand Down
19 changes: 19 additions & 0 deletions saas/backend/api/admin/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@

from backend.api.management.v2.serializers import ManagementGradeManagerGroupCreateSLZ
from backend.apps.group.models import Group
from backend.apps.group.serializers import GroupAuthorizationSLZ
from backend.apps.role.models import Role
from backend.apps.role.serializers import BaseGradeMangerSLZ
from backend.apps.template.serializers import TemplateCreateSLZ, TemplateIdSLZ
from backend.service.constants import GroupMemberType, RoleType


Expand All @@ -40,6 +42,15 @@ class AdminSubjectGroupSLZ(serializers.Serializer):
expired_at = serializers.IntegerField(label="过期时间戳(单位秒)")


class AdminGroupAuthorizationSLZ(GroupAuthorizationSLZ):
pass


class AdminSystemProviderConfigSLZ(serializers.Serializer):
token = serializers.CharField(label="回调token")
host = serializers.CharField(label="回调地址")


class SystemManageSLZ(serializers.Serializer):
managers = serializers.ListField(child=serializers.CharField(label="成员"), max_length=100)

Expand Down Expand Up @@ -78,3 +89,11 @@ class SubjectSLZ(serializers.Serializer):
class FreezeSubjectResponseSLZ(serializers.Serializer):
type = serializers.CharField(label="SubjectType")
id = serializers.CharField(label="SubjectID")


class AdminTemplateCreateSLZ(TemplateCreateSLZ):
pass


class AdminTemplateIdSLZ(TemplateIdSLZ):
pass
14 changes: 14 additions & 0 deletions saas/backend/api/admin/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@
views.AdminGroupMemberViewSet.as_view({"get": "list"}),
name="open.admin.group_member",
),
# 用户组授权
path(
"groups/<str:id>/policies/",
views.AdminGroupPolicyViewSet.as_view({"post": "create"}),
name="open.admin.group_policy",
),
# 模板
path("templates/", views.AdminTemplateViewSet.as_view({"post": "create"}), name="open.admin.template"),
# Subject
path(
"subjects/<str:subject_type>/<str:subject_id>/groups/",
Expand All @@ -39,6 +47,12 @@
views.AdminSystemViewSet.as_view({"get": "list"}),
name="open.admin.system",
),
# 系统回调信息
path(
"systems/<str:system_id>/provider_config/",
views.AdminSystemProviderConfigViewSet.as_view({"get": "list"}),
name="open.admin.system_provider_config",
),
# 超级管理员成员列表 get
path(
"roles/super_managers/members/",
Expand Down
8 changes: 6 additions & 2 deletions saas/backend/api/admin/views/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
specific language governing permissions and limitations under the License.
"""
from .audit import AdminAuditEventViewSet
from .group import AdminGroupInfoViewSet, AdminGroupMemberViewSet, AdminGroupViewSet
from .group import AdminGroupInfoViewSet, AdminGroupMemberViewSet, AdminGroupPolicyViewSet, AdminGroupViewSet
from .role import AdminSuperManagerMemberViewSet, AdminSystemManagerMemberViewSet
from .subject import (
AdminSubjectFreezeViewSet,
Expand All @@ -18,7 +18,8 @@
AdminSubjectPermissionExistsViewSet,
AdminSubjectRoleViewSet,
)
from .system import AdminSystemViewSet
from .system import AdminSystemProviderConfigViewSet, AdminSystemViewSet
from .template import AdminTemplateViewSet

__all__ = [
"AdminGroupViewSet",
Expand All @@ -33,4 +34,7 @@
"AdminSubjectFreezeViewSet",
"AdminSubjectPermissionCleanupViewSet",
"AdminSubjectPermissionExistsViewSet",
"AdminTemplateViewSet",
"AdminGroupPolicyViewSet",
"AdminSystemProviderConfigViewSet",
]
60 changes: 57 additions & 3 deletions saas/backend/api/admin/views/group.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,27 @@
from backend.api.admin.constants import AdminAPIEnum, VerifyApiParamLocationEnum
from backend.api.admin.filters import GroupFilter
from backend.api.admin.permissions import AdminAPIPermission
from backend.api.admin.serializers import AdminGroupBasicSLZ, AdminGroupCreateSLZ, AdminGroupMemberSLZ
from backend.api.admin.serializers import (
AdminGroupAuthorizationSLZ,
AdminGroupBasicSLZ,
AdminGroupCreateSLZ,
AdminGroupMemberSLZ,
)
from backend.api.authentication import ESBAuthentication
from backend.api.management.v2.views import ManagementGroupViewSet
from backend.apps.group.audit import GroupCreateAuditProvider
from backend.apps.group.audit import GroupCreateAuditProvider, GroupTemplateCreateAuditProvider
from backend.apps.group.constants import OperateEnum
from backend.apps.group.models import Group
from backend.apps.group.views import check_readonly_group
from backend.apps.role.models import Role
from backend.audit.audit import add_audit
from backend.audit.audit import add_audit, audit_context_setter, view_audit_decorator
from backend.audit.constants import AuditSourceType
from backend.biz.group import GroupBiz, GroupCheckBiz, GroupCreationBean
from backend.biz.role import RoleBiz
from backend.common.lock import gen_group_upsert_lock
from backend.common.pagination import CompatiblePagination
from backend.service.constants import GroupSaaSAttributeEnum, RoleType
from backend.trans.group import GroupTrans


class AdminGroupViewSet(mixins.ListModelMixin, GenericViewSet):
Expand Down Expand Up @@ -143,3 +152,48 @@ def list(self, request, *args, **kwargs):
count, group_members = self.biz.list_paging_thin_group_member(group.id, limit, offset)
results = [one.dict(include={"type", "id", "name", "expired_at"}) for one in group_members]
return Response({"count": count, "results": results})


class AdminGroupPolicyViewSet(GenericViewSet):
"""用户组授权"""

authentication_classes = [ESBAuthentication]
permission_classes = [AdminAPIPermission]

admin_api_permission = {"create": AdminAPIEnum.GROUP_POLICY_GRANT.value}

pagination_class = None # 去掉swagger中的limit offset参数
queryset = Group.objects.all()
lookup_field = "id"

group_biz = GroupBiz()
role_biz = RoleBiz()

group_trans = GroupTrans()

@swagger_auto_schema(
operation_description="用户组添加权限",
request_body=AdminGroupAuthorizationSLZ(label="授权信息"),
responses={status.HTTP_201_CREATED: serializers.Serializer()},
tags=["admin.group.policy"],
)
@view_audit_decorator(GroupTemplateCreateAuditProvider)
@check_readonly_group(operation=OperateEnum.GROUP_POLICY_CREATE.label)
def create(self, request, *args, **kwargs):
serializer = AdminGroupAuthorizationSLZ(data=request.data)
serializer.is_valid(raise_exception=True)

group = self.get_object()
data = serializer.validated_data

role = self.role_biz.get_role_by_group_id(group.id)
templates = self.group_trans.from_group_grant_data(data["templates"])
self.group_biz.grant(role, group, templates)

# 写入审计上下文
audit_context_setter(
group=group,
templates=[{"system_id": t["system_id"], "template_id": t["template_id"]} for t in data["templates"]],
)

return Response({}, status=status.HTTP_201_CREATED)
23 changes: 23 additions & 0 deletions saas/backend/api/admin/views/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,17 @@
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.
"""
from drf_yasg.utils import swagger_auto_schema
from rest_framework import status
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet

from backend.api.admin.constants import AdminAPIEnum
from backend.api.admin.permissions import AdminAPIPermission
from backend.api.admin.serializers import AdminSystemProviderConfigSLZ
from backend.api.authentication import ESBAuthentication
from backend.apps.system.views import SystemViewSet
from backend.service.resource import SystemProviderConfigService


class AdminSystemViewSet(SystemViewSet):
Expand All @@ -30,3 +36,20 @@ def list(self, request, *args, **kwargs):
request.query_params["hidden"] = False

return super().list(request, *args, **kwargs)


class AdminSystemProviderConfigViewSet(GenericViewSet):
authentication_classes = [ESBAuthentication]
permission_classes = [AdminAPIPermission]
admin_api_permission = {"list": AdminAPIEnum.SYSTEM_PROVIDER_CONFIG_LIST.value}

@swagger_auto_schema(
operation_description="系统回调信息",
responses={status.HTTP_200_OK: AdminSystemProviderConfigSLZ(label="系统回调信息")},
tags=["admin.system.provider_config"],
)
def list(self, request, *args, **kwargs):
system_id = kwargs["system_id"]
system_provider_config = SystemProviderConfigService().get_provider_config(system_id=system_id)

return Response(AdminSystemProviderConfigSLZ(system_provider_config).data)
60 changes: 60 additions & 0 deletions saas/backend/api/admin/views/template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from drf_yasg.utils import swagger_auto_schema
from rest_framework import status
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet

from backend.api.admin.constants import AdminAPIEnum
from backend.api.admin.permissions import AdminAPIPermission
from backend.api.admin.serializers import AdminTemplateCreateSLZ, AdminTemplateIdSLZ
from backend.api.authentication import ESBAuthentication
from backend.apps.role.models import Role
from backend.apps.template.audit import TemplateCreateAuditProvider
from backend.audit.audit import audit_context_setter, view_audit_decorator
from backend.biz.role import RoleAuthorizationScopeChecker
from backend.biz.template import TemplateBiz, TemplateCheckBiz, TemplateCreateBean
from backend.common.lock import gen_template_upsert_lock
from backend.service.constants import RoleType


class AdminTemplateViewSet(GenericViewSet):
"""模板"""

authentication_classes = [ESBAuthentication]
permission_classes = [AdminAPIPermission]

admin_api_permission = {"create": AdminAPIEnum.TEMPLATE_CREATE.value}

template_biz = TemplateBiz()
template_check_biz = TemplateCheckBiz()

@swagger_auto_schema(
operation_description="创建模板",
request_body=AdminTemplateCreateSLZ(label="模板"),
responses={status.HTTP_201_CREATED: AdminTemplateIdSLZ(label="模板ID")},
tags=["admin.template"],
)
@view_audit_decorator(TemplateCreateAuditProvider)
def create(self, request, *args, **kwargs):
"""
创建模板
"""
serializer = AdminTemplateCreateSLZ(data=request.data)
serializer.is_valid(raise_exception=True)

user_id = request.user.username
data = serializer.validated_data
role = Role.objects.get(type=RoleType.SUPER_MANAGER.value)

# 检查模板的授权是否满足管理员的授权范围
scope_checker = RoleAuthorizationScopeChecker(role)
scope_checker.check_actions(data["system_id"], data["action_ids"])

with gen_template_upsert_lock(role.id, data["name"]):
# 检查权限模板是否在角色内唯一
self.template_check_biz.check_role_template_name_exists(role.id, data["name"])

template = self.template_biz.create(role.id, TemplateCreateBean.parse_obj(data), user_id)

audit_context_setter(template=template)

return Response({"id": template.id}, status=status.HTTP_201_CREATED)

0 comments on commit 9c189e1

Please sign in to comment.