Files
Arcaea-server/latest version/api/api_auth.py
Lost-MSth 93f4ad4999 Fix some bugs
- Fix a bug that `GET` requests without data will report an error in API
- Fix a bug that `aggregate` requests will get an error when the inner function raises an error
- Fix a bug that the charts of a course cannot be the same because of the incorrect primary keys
- Fix a bug that global ranking scores cannot be calculated if there are no chart in the database #61
- The first try to fix #60 (I don't think it can be done so easily.)
2022-07-20 21:59:26 +08:00

97 lines
3.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from functools import wraps
from traceback import format_exc
from core.api_user import APIUser
from core.error import ArcError, NoAccess, PostError
from core.sql import Connect
from flask import current_app
from setting import Config
from .api_code import error_return
def role_required(request, powers=[]):
'''api token验证写成了修饰器'''
def decorator(view):
@wraps(view)
def wrapped_view(*args, **kwargs):
try:
if request.data:
request.json # 检查请求json格式
except:
return error_return(PostError('Payload must be a valid json', api_error_code=-1), 400)
if not 'Token' in request.headers:
return error_return(PostError('No token', api_error_code=-1), 401)
user = APIUser()
if Config.API_TOKEN == request.headers['Token'] and Config.API_TOKEN != '':
user.user_id = 0
elif powers == []:
# 无powers则非本地权限API_TOKEN规定的无法访问
return error_return(NoAccess('No permission', api_error_code=-1), 403)
else:
with Connect() as c:
try:
user.c = c
user.select_user_id_from_api_token(
request.headers['Token'])
user.select_role_and_powers()
if not any([y in [x.power_name for x in user.role.powers] for y in powers]):
return error_return(NoAccess('No permission', api_error_code=-1), 403)
except ArcError as e:
return error_return(e, 401)
return view(user, *args, **kwargs)
return wrapped_view
return decorator
def request_json_handle(request, required_keys=[], optional_keys=[]):
'''
提取post参数返回dict写成了修饰器\
parameters: \
`request`: `Request` - 当前请求\
`required_keys`: `list` - 必须的参数\
`optional_keys`: `list` - 可选的参数
'''
def decorator(view):
@wraps(view)
def wrapped_view(*args, **kwargs):
data = {}
for key in required_keys:
if key not in request.json:
return error_return(PostError('Missing parameter: ' + key, api_error_code=-100))
data[key] = request.json[key]
for key in optional_keys:
if key in request.json:
data[key] = request.json[key]
return view(data, *args, **kwargs)
return wrapped_view
return decorator
def api_try(view):
'''替代try/except记录`ArcError`为warning'''
@wraps(view)
def wrapped_view(*args, **kwargs):
try:
data = view(*args, **kwargs)
if data is None:
return error_return()
else:
return data
except ArcError as e:
if Config.ALLOW_WARNING_LOG:
current_app.logger.warning(format_exc())
return error_return(e, e.status)
return wrapped_view