Skip to content

Commit

Permalink
Merge pull request #823 from longguikeji/feature-187
Browse files Browse the repository at this point in the history
Feature 187
  • Loading branch information
fanhe-lg authored May 12, 2022
2 parents 07043f8 + 2dbb59a commit 1c44491
Show file tree
Hide file tree
Showing 12 changed files with 729 additions and 113 deletions.
7 changes: 4 additions & 3 deletions api/v1/pages/approve_manage/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from . import approve_action,approve_system
from . import approve_action, approve_system, all_approve_requests
from arkid.core import routers


Expand All @@ -7,6 +7,7 @@
name='审批管理',
children=[
approve_action.router,
approve_system.router
approve_system.router,
all_approve_requests.router,
],
)
)
24 changes: 24 additions & 0 deletions api/v1/pages/approve_manage/all_approve_requests.py
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,
),
)
160 changes: 138 additions & 22 deletions api/v1/views/approve_action.py
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
97 changes: 97 additions & 0 deletions arkid/core/approve_request_middleware.py
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)
3 changes: 3 additions & 0 deletions arkid/core/error.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,6 @@ class ErrorCode(Enum):
EMAIL_ERROR = '12004'

ADD_AUTH_TMPL_ERROR = '13001'

APPROVE_ACTION_DUPLICATED = '14001'
APPROVE_ACTION_NOT_EXISTS = '14002'
Loading

0 comments on commit 1c44491

Please sign in to comment.