diff --git a/api/v1/views/__init__.py b/api/v1/views/__init__.py index 354446ee2..d7e480461 100644 --- a/api/v1/views/__init__.py +++ b/api/v1/views/__init__.py @@ -20,6 +20,7 @@ scim_sync, webhook, send_sms, + permission, tenant, account_life, app_protocol, diff --git a/api/v1/views/app.py b/api/v1/views/app.py index e5c5b11f4..4cc05520c 100644 --- a/api/v1/views/app.py +++ b/api/v1/views/app.py @@ -13,7 +13,10 @@ from arkid.extension.models import TenantExtensionConfig from arkid.core.event import Event, register_event, dispatch_event from arkid.core.extension.app_protocol import AppProtocolExtension -from arkid.core.event import CREATE_APP, UPDATE_APP, DELETE_APP +from arkid.core.event import( + CREATE_APP, UPDATE_APP, DELETE_APP, + CREATE_APP_DONE, +) import uuid @@ -63,7 +66,7 @@ def create_app(request, tenant_id: str, data: AppConfigSchemaIn): for func, (result, extension) in results: if result: # 创建config - config = extension.create_tenant_config(tenant, data.config.dict()) + config = extension.create_tenant_config(tenant, data.config.dict(), data.name) # 创建app app = App() app.id = data.id @@ -76,6 +79,8 @@ def create_app(request, tenant_id: str, data: AppConfigSchemaIn): app.config = config app.tenant_id = tenant_id app.save() + # 创建app完成进行事件分发 + dispatch_event(Event(tag=CREATE_APP_DONE, tenant=tenant, request=request, data=app)) break return {"app_id": app.id.hex} diff --git a/api/v1/views/group.py b/api/v1/views/group.py index af2286c19..dd820f050 100644 --- a/api/v1/views/group.py +++ b/api/v1/views/group.py @@ -10,6 +10,7 @@ from django.shortcuts import get_object_or_404 from arkid.core.event import Event, dispatch_event from arkid.core.event import CREATE_GROUP, UPDATE_GROUP, DELETE_GROUP +from uuid import UUID class UserGroupListSchemaOut(ModelSchema): @@ -34,6 +35,8 @@ class Config: class UserGroupDetailSchemaOut(ModelSchema): + parent_id: UUID = None + class Config: model = UserGroup model_fields = ['id', 'name'] diff --git a/api/v1/views/permission.py b/api/v1/views/permission.py index 38a2f07f2..edd1d3632 100644 --- a/api/v1/views/permission.py +++ b/api/v1/views/permission.py @@ -1,35 +1,125 @@ + +from ninja import Schema +from ninja import Field +from ninja import ModelSchema from arkid.core.api import api -from arkid.core.translation import gettext_default as _ +from typing import List, Optional +from django.db import transaction +from ninja.pagination import paginate +from arkid.core.error import ErrorCode +from arkid.core.models import Permission +from django.shortcuts import get_object_or_404 +from arkid.core.event import Event, dispatch_event +from arkid.core.event import CREATE_PERMISSION, UPDATE_PERMISSION, DELETE_PERMISSION +from uuid import UUID + +import uuid + + +class PermissionListSchemaOut(ModelSchema): + + class Config: + model = Permission + model_fields = ['id', 'name', 'category', 'is_system'] + + +class PermissionSchemaOut(Schema): + permission_id: str + + +class PermissionSchemaIn(ModelSchema): + + app_id: str = None + parent_id: str = None + + class Config: + model = Permission + model_fields = ['name', 'category'] + + +class PermissionDetailSchemaOut(ModelSchema): + + app_id: UUID = Field(default=None) + parent_id: UUID = Field(default=None) + + class Config: + model = Permission + model_fields = ['id', 'name', 'category'] + + +@transaction.atomic +@api.post("/{tenant_id}/permissions", response=PermissionSchemaOut, tags=['权限'], auth=None) +def create_permission(request, tenant_id: str, data: PermissionSchemaIn): + ''' + 权限创建 + ''' + permission = Permission() + permission.tenant_id = tenant_id + permission.name = data.name + permission.category = data.category + permission.code = 'other_{}'.format(uuid.uuid4()) + if data.parent_id: + permission.parent_id = data.parent_id + if data.app_id: + permission.app_id = data.app_id + permission.is_system = False + permission.save() + # 分发事件开始 + result = dispatch_event(Event(tag=CREATE_PERMISSION, tenant=request.tenant, request=request, data=permission)) + # 分发事件结束 + return {"permission_id": permission.id.hex} -@api.get("/tenant/{tenant_id}/permissions/", tags=["权限"],auth=None) -def get_permissions(request, tenant_id: str): - """ 权限列表,TODO - """ - return [] +@api.get("/{tenant_id}/permissions", response=List[PermissionListSchemaOut], tags=['权限'], auth=None) +@paginate +def list_permissions(request, tenant_id: str, parent_id: str = None): + ''' + 权限列表 + ''' + permissions = Permission.valid_objects.filter( + tenant_id=tenant_id + ) + if parent_id: + permissions = permissions.filter(parent_id=parent_id) + return permissions -@api.get(operation_id="",path="/tenant/{tenant_id}/permissions/{id}/", tags=["权限"],auth=None) -def get_permission(request, tenant_id: str, id: str): - """ 获取权限,TODO - """ - return {} -@api.post("/tenant/{tenant_id}/permissions/", tags=["权限"],auth=None) -def create_permission(request, tenant_id: str): - """ 创建权限,TODO - """ - return {} +@api.get("/{tenant_id}/permission/{permission_id}", response=PermissionDetailSchemaOut, tags=['权限'], auth=None) +def get_permission(request, tenant_id: str, permission_id: str): + ''' + 获取权限 + ''' + permission = get_object_or_404(Permission, id=permission_id, is_del=False) + return permission -@api.put("/tenant/{tenant_id}/permissions/{id}/", tags=["权限"],auth=None) -def update_permission(request, tenant_id: str, id: str): - """ 编辑权限,TODO - """ - return {} -@api.delete("/tenant/{tenant_id}/permissions/{id}/", tags=["权限"],auth=None) -def delete_permission(request, tenant_id: str, id: str): - """ 删除权限,TODO - """ - return {} +@api.put("/{tenant_id}/permission/{permission_id}", tags=['权限'], auth=None) +def update_permission(request, tenant_id: str, permission_id: str, data: PermissionSchemaIn): + ''' + 修改权限 + ''' + permission = get_object_or_404(Permission, id=permission_id, is_del=False) + permission.name = data.name + permission.category = data.category + if data.parent_id: + permission.parent_id = data.parent_id + if data.app_id: + permission.app_id = data.app_id + permission.save() + # 分发事件开始 + dispatch_event(Event(tag=UPDATE_PERMISSION, tenant=request.tenant, request=request, data=permission)) + # 分发事件结束 + return {'error': ErrorCode.OK.value} +@api.delete("/{tenant_id}/permission/{permission_id}", tags=['权限'], auth=None) +def delete_permission(request, tenant_id: str, permission_id: str): + ''' + 删除权限 + ''' + permission = get_object_or_404(Permission, id=permission_id, is_del=False) + # 分发事件开始 + dispatch_event(Event(tag=DELETE_PERMISSION, tenant=request.tenant, request=request, data=permission)) + # 分发事件结束 + permission.delete() + return {'error': ErrorCode.OK.value} diff --git a/arkid/core/event.py b/arkid/core/event.py index 871a48ff9..dd8af8509 100644 --- a/arkid/core/event.py +++ b/arkid/core/event.py @@ -198,21 +198,29 @@ def unlisten_event(tag, func, **kwargs): CREATE_LOGIN_PAGE_AUTH_FACTOR = 'CREATE_LOGIN_PAGE_AUTH_FACTOR' CREATE_LOGIN_PAGE_RULES = 'CREATE_LOGIN_PAGE_RULES' CREATE_APP = 'CREATE_APP' +CREATE_APP_DONE = 'CREATE_APP_DONE' UPDATE_APP = 'UPDATE_APP' DELETE_APP = 'DELETE_APP' SEND_SMS = 'SEND_SMS' CREATE_GROUP = 'CREATE_GROUP' UPDATE_GROUP = 'UPDATE_GROUP' DELETE_GROUP = 'DELETE_GROUP' +CREATE_PERMISSION = 'CREATE_PERMISSION' +UPDATE_PERMISSION = 'UPDATE_PERMISSION' +DELETE_PERMISSION = 'DELETE_PERMISSION' # register events register_event(CREATE_LOGIN_PAGE_AUTH_FACTOR, _('create login page by auth factor','认证因素生成登录页面')) register_event(CREATE_LOGIN_PAGE_RULES, _('create login page rules','登录页面生成规则')) register_event(CREATE_APP, _('create app','创建应用')) +register_event(CREATE_APP_DONE, _('create app done','创建应用完成')) register_event(UPDATE_APP, _('update app','修改应用')) register_event(DELETE_APP, _('delete app','删除应用')) register_event(CREATE_GROUP, _('create group','创建分组')) register_event(UPDATE_GROUP, _('update group','修改分组')) register_event(DELETE_GROUP, _('delete group','删除分组')) register_event(SEND_SMS, _('send sms','发送短信')) +register_event(CREATE_PERMISSION, _('create permission','创建权限')) +register_event(UPDATE_PERMISSION, _('update permission','修改权限')) +register_event(DELETE_PERMISSION, _('delete permission','删除权限')) diff --git a/arkid/core/migrations/0005_merge_0003_auto_20220429_0847_0004_grouppermission.py b/arkid/core/migrations/0005_merge_0003_auto_20220429_0847_0004_grouppermission.py new file mode 100644 index 000000000..cd6c427b0 --- /dev/null +++ b/arkid/core/migrations/0005_merge_0003_auto_20220429_0847_0004_grouppermission.py @@ -0,0 +1,14 @@ +# Generated by Django 3.2.13 on 2022-05-05 02:34 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0003_auto_20220429_0847'), + ('core', '0004_grouppermission'), + ] + + operations = [ + ] diff --git a/arkid/perm/event_callback.py b/arkid/perm/event_callback.py index 9857fd47c..c15cb8eb6 100644 --- a/arkid/perm/event_callback.py +++ b/arkid/perm/event_callback.py @@ -1,6 +1,11 @@ from arkid.core import event as core_event -from arkid.core.event import CREATE_GROUP, DELETE_GROUP -from arkid.core.models import Permission, GroupPermission +from arkid.core.models import( + Permission, GroupPermission, +) +from arkid.core.event import ( + CREATE_GROUP, DELETE_GROUP, CREATE_APP_DONE, + DELETE_APP, +) import uuid @@ -12,6 +17,8 @@ def __init__(self): core_event.listen_event('api_v1_views_auth_auth', self.login) core_event.listen_event(CREATE_GROUP, self.create_group) core_event.listen_event(DELETE_GROUP, self.delete_group) + core_event.listen_event(CREATE_APP_DONE, self.create_app) + core_event.listen_event(DELETE_APP, self.delete_app) def login(self, event, **kwargs): from arkid.tasks.tasks import update_permission @@ -36,7 +43,26 @@ def create_group(self, event, **kwargs): def delete_group(self, event, **kwargs): group = event.data tenant = event.tenant - GroupPermission.active_objects.filter(category='group', group=group).delete() + GroupPermission.active_objects.filter(category='group', group=group, is_system=True).delete() + return True + + def create_app(self, event, **kwargs): + app = event.data + tenant = event.tenant + permission = Permission() + permission.name = app.name + permission.code = 'entry_{}'.format(uuid.uuid4()) + permission.tenant = tenant + permission.app = app + permission.category = 'entry' + permission.is_system = True + permission.save() + return True + + def delete_app(self, event, **kwargs): + app = event.data + tenant = event.tenant + Permission.active_objects.filter(category='entry', app=app, is_system=True).delete() return True EventCall() \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 88c298305..9823b58cd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,9 @@ - Warning: The lock flag -r/--requirements will be deprecated in a future version - of pipenv in favor of the new requirements command. For more info see - https://pipenv.pypa.io/en/latest/advanced/#generating-a-requirements-txt - NOTE: the requirements command parses Pipfile.lock directly without performing any - locking operations. Updating packages should be done by running pipenv lock +# Warning: The lock flag -r/--requirements will be deprecated in a future version +# of pipenv in favor of the new requirements command. For more info see +# https://pipenv.pypa.io/en/latest/advanced/#generating-a-requirements-txt +# NOTE: the requirements command parses Pipfile.lock directly without performing any +# locking operations. Updating packages should be done by running pipenv lock # # These requirements were autogenerated by pipenv