-
Notifications
You must be signed in to change notification settings - Fork 288
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #823 from longguikeji/feature-187
Feature 187
- Loading branch information
Showing
12 changed files
with
729 additions
and
113 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#!/usr/bin/env python3 | ||
|
||
from arkid.core import routers, pages, actions | ||
from arkid.core.translation import gettext_default as _ | ||
|
||
tag = 'all_approve_requests' | ||
name = '审批请求-ALL' | ||
|
||
|
||
page = pages.TablePage(tag=tag, name=name) | ||
|
||
|
||
router = routers.FrontRouter( | ||
path=tag, | ||
name=name, | ||
page=page, | ||
) | ||
|
||
page.create_actions( | ||
init_action=actions.DirectAction( | ||
path='/api/v1/tenant/{tenant_id}/approve_requests/', | ||
method=actions.FrontActionMethod.GET, | ||
), | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,151 @@ | ||
from arkid.core.api import api | ||
from arkid.core.translation import gettext_default as _ | ||
from ninja import ModelSchema, Schema | ||
from arkid.core.models import ApproveAction, ApproveRequest | ||
from pydantic import Field | ||
from enum import Enum | ||
from arkid.extension.models import TenantExtensionConfig, Extension | ||
from arkid.core.error import ErrorCode | ||
from typing import List | ||
|
||
|
||
@api.get("/tenant/{tenant_id}/approve_actions/", tags=["审批动作"],auth=None) | ||
class METHOD_TYPE(str, Enum): | ||
GET = _('GET', 'GET') | ||
POST = _('POST', 'POST') | ||
DELETE = _('DELETE', 'DELETE') | ||
PUT = _('PUT', 'PUT') | ||
|
||
|
||
class ApproveActionSchemaIn(Schema): | ||
name: str = Field(title=_('Name', '名称'), default='') | ||
description: str = Field(title=_('Description', '备注'), default='') | ||
path: str = Field(title=_('Path', '请求路径')) | ||
method: METHOD_TYPE = Field(title=_('Method', '请求方法')) | ||
extension_id: str = Field(title=_('Method', '请求方法')) | ||
|
||
|
||
class ApproveActionSchemaOut(ModelSchema): | ||
class Config: | ||
model = ApproveAction | ||
model_fields = ['id', 'name', 'path', 'method', 'description'] | ||
|
||
package: str | ||
|
||
@staticmethod | ||
def resolve_package(obj): | ||
if obj.extension: | ||
return obj.extension.package | ||
else: | ||
return '' | ||
|
||
|
||
@api.get( | ||
"/tenant/{tenant_id}/approve_actions/", | ||
tags=["审批动作"], | ||
auth=None, | ||
response=List[ApproveActionSchemaOut], | ||
) | ||
def get_approve_actions(request, tenant_id: str): | ||
""" 审批动作列表,TODO | ||
""" | ||
return [] | ||
"""审批动作列表,TODO""" | ||
tenant = request.tenant | ||
actions = ApproveAction.valid_objects.filter(tenant=tenant) | ||
return actions | ||
|
||
@api.get(operation_id="",path="/tenant/{tenant_id}/approve_actions/{id}/", tags=["审批动作"],auth=None) | ||
|
||
@api.get( | ||
operation_id="", | ||
path="/tenant/{tenant_id}/approve_actions/{id}/", | ||
tags=["审批动作"], | ||
auth=None, | ||
response=ApproveActionSchemaOut, | ||
) | ||
def get_approve_action(request, tenant_id: str, id: str): | ||
""" 获取审批动作,TODO | ||
""" | ||
return {} | ||
"""获取审批动作,TODO""" | ||
tenant = request.tenant | ||
action = ApproveAction.valid_objects.filter(tenant=tenant, id=id).first() | ||
if not action: | ||
return {'error': ErrorCode.APPROVE_ACTION_NOT_EXISTS.value} | ||
else: | ||
return action | ||
|
||
@api.post("/tenant/{tenant_id}/approve_actions/", tags=["审批动作"],auth=None) | ||
def create_approve_action(request, tenant_id: str): | ||
""" 创建审批动作,TODO | ||
""" | ||
return {} | ||
|
||
@api.put("/tenant/{tenant_id}/approve_actions/{id}/", tags=["审批动作"],auth=None) | ||
def update_approve_action(request, tenant_id: str, id: str): | ||
""" 编辑审批动作,TODO | ||
""" | ||
return {} | ||
@api.post("/tenant/{tenant_id}/approve_actions/", tags=["审批动作"], auth=None) | ||
def create_approve_action(request, tenant_id: str, data: ApproveActionSchemaIn): | ||
"""创建审批动作,TODO""" | ||
tenant = request.tenant | ||
name = data.name | ||
description = data.description | ||
path = data.path | ||
method = data.method | ||
extension_id = data.extension_id | ||
extension = Extension.valid_objects.get(id=extension_id) | ||
action = ApproveAction.valid_objects.filter( | ||
path=path, method=method, extension=extension, tenant=tenant | ||
).first() | ||
if action: | ||
return {'error': ErrorCode.APPROVE_ACTION_DUPLICATED.value} | ||
else: | ||
action = ApproveAction.valid_objects.create( | ||
name=name, | ||
description=description, | ||
path=path, | ||
method=method, | ||
extension=extension, | ||
tenant=tenant, | ||
) | ||
return {'error': ErrorCode.OK.value} | ||
|
||
|
||
@api.put("/tenant/{tenant_id}/approve_actions/{id}/", tags=["审批动作"], auth=None) | ||
def update_approve_action( | ||
request, tenant_id: str, id: str, data: ApproveActionSchemaIn | ||
): | ||
"""编辑审批动作,TODO""" | ||
tenant = request.tenant | ||
name = data.name | ||
description = data.description | ||
path = data.path | ||
method = data.method | ||
extension_id = data.extension_id | ||
extension = Extension.valid_objects.get(id=extension_id) | ||
action = ApproveAction.valid_objects.filter(tenant=tenant, id=id).first() | ||
if not action: | ||
return {'error': ErrorCode.APPROVE_ACTION_NOT_EXISTS.value} | ||
else: | ||
action.name = name | ||
action.description = description | ||
action.path = path | ||
action.method = method | ||
action.extension = extension | ||
action.save() | ||
return {'error': ErrorCode.OK.value} | ||
|
||
|
||
@api.delete("/tenant/{tenant_id}/approve_actions/{id}/", tags=["审批动作"],auth=None) | ||
@api.delete("/tenant/{tenant_id}/approve_actions/{id}/", tags=["审批动作"], auth=None) | ||
def delete_approve_action(request, tenant_id: str, id: str): | ||
""" 删除审批动作,TODO | ||
""" | ||
return {} | ||
"""删除审批动作,TODO""" | ||
tenant = request.tenant | ||
action = ApproveAction.valid_objects.filter(tenant=tenant, id=id).first() | ||
if not action: | ||
return {'error': ErrorCode.APPROVE_ACTION_NOT_EXISTS.value} | ||
else: | ||
action.delete() | ||
return {'error': ErrorCode.OK.value} | ||
|
||
|
||
from arkid.core.extension.approve_system import ApproveRequestOut | ||
|
||
|
||
@api.get( | ||
"/tenant/{tenant_id}/approve_requests/", | ||
tags=["审批动作"], | ||
auth=None, | ||
response=List[ApproveRequestOut], | ||
) | ||
def get_tenant_approve_requests(request, tenant_id: str): | ||
""" | ||
返回当前租户所有审批请求 | ||
""" | ||
tenant = request.tenant | ||
requests = ApproveRequest.valid_objects.filter(action__tenant=tenant) | ||
return requests |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
#!/usr/bin/env python3 | ||
from os import environ | ||
import re | ||
import io | ||
import json | ||
from django.urls import resolve | ||
from arkid.core.models import Tenant | ||
from django.http import HttpResponse | ||
from arkid.core.models import ApproveAction, ApproveRequest | ||
from arkid.core.models import ExpiringToken | ||
from django.core.handlers.wsgi import WSGIRequest | ||
|
||
|
||
class ApproveRequestMiddleware: | ||
def __init__(self, get_response): | ||
self.get_response = get_response | ||
# One-time configuration and initialization. | ||
|
||
def __call__(self, request): | ||
# Code to be executed for each request before | ||
# the view (and later middleware) are called. | ||
response = self.get_response(request) | ||
|
||
# Code to be executed for each request/response after | ||
# the view is called. | ||
return response | ||
|
||
def process_view(self, request, view_func, view_args, view_kwargs): | ||
tenant = request.tenant | ||
path = ('/' + request.resolver_match.route).replace("<", "{").replace(">", "}") | ||
method = request.method | ||
|
||
user = self.get_user(request) | ||
approve_action = ApproveAction.valid_objects.filter( | ||
tenant=tenant, path=path, method=method | ||
).first() | ||
if not user or not approve_action: | ||
return None | ||
if not approve_action.extension: | ||
return None | ||
|
||
approve_request = ApproveRequest.valid_objects.filter( | ||
action=approve_action, user=user | ||
).first() | ||
if not approve_request: | ||
environ = request.environ | ||
environ.pop("wsgi.input") | ||
environ.pop("wsgi.errors") | ||
environ.pop("wsgi.file_wrapper") | ||
approve_request = ApproveRequest.valid_objects.create( | ||
action=approve_action, | ||
user=user, | ||
environ=environ, | ||
body=request.body, | ||
) | ||
response = HttpResponse(status=401) | ||
return response | ||
else: | ||
if approve_request.status != "pass": | ||
response = HttpResponse(status=401) | ||
return response | ||
else: | ||
return None | ||
|
||
def get_user(self, request): | ||
auth_header = request.headers.get("Authorization") | ||
if not auth_header: | ||
return None | ||
token = auth_header.split(" ")[1] | ||
try: | ||
token = ExpiringToken.objects.get(token=token) | ||
|
||
if not token.user.is_active: | ||
return None | ||
|
||
if token.expired(request.tenant): | ||
return None | ||
|
||
except ExpiringToken.DoesNotExist: | ||
return None | ||
except Exception as err: | ||
return None | ||
|
||
return token.user | ||
|
||
def restore_request(self, approve_request): | ||
environ = approve_request.environ | ||
body = approve_request.body | ||
environ["wsgi.input"] = io.BytesIO(body) | ||
request = WSGIRequest(environ) | ||
request.tenant = approve_request.action.tenant | ||
request.user = approve_request.user | ||
view_func, args, kwargs = resolve(request.path) | ||
klass = view_func.__self__ | ||
operation, _ = klass._find_operation(request) | ||
response = operation.run(request, **kwargs) | ||
print(response) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.