Newer
Older
from flask import abort, current_app, request
from flask_login import current_user
from threading import Thread
from typing import List, Union
from werkzeug.exceptions import NotAcceptable
from app.models import Permission
def permission_required(permission):
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if not current_user.can(permission):
abort(403)
return f(*args, **kwargs)
return decorated_function
return decorator
def admin_required(f):
return permission_required(Permission.ADMINISTRATE)(f)
def socketio_login_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if current_user.is_authenticated:
return f(*args, **kwargs)
else:
return {'code': 401, 'msg': 'Unauthorized'}
return decorated_function
def socketio_permission_required(permission):
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if not current_user.can(permission):
return {'code': 403, 'msg': 'Forbidden'}
return f(*args, **kwargs)
return decorated_function
return decorator
def socketio_admin_required(f):
return socketio_permission_required(Permission.ADMINISTRATE)(f)
'''
' This decorator executes a function in a Thread.
' Decorated functions need to be executed within a code block where an
' app context exists.
'
' NOTE: An app object is passed as a keyword argument to the decorated
' function.
'''
@wraps(f)
def wrapped(*args, **kwargs):
kwargs['app'] = current_app._get_current_object()
thread = Thread(target=f, args=args, kwargs=kwargs)
thread.start()
return wrapped
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
def consumes(mime_type: str, *_mime_types: str):
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
provided = request.mimetype
consumeables = {mime_type, *_mime_types}
if provided not in consumeables:
raise NotAcceptable()
return f(*args, **kwargs)
return decorated_function
return decorator
def produces(mime_type: str, *_mime_types: str):
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
accepted = {*request.accept_mimetypes.values()}
produceables = {mime_type, *_mime_types}
if len(produceables & accepted) == 0:
raise NotAcceptable()
return f(*args, **kwargs)
return decorated_function
return decorator
def content_negotiation(
produces: Union[str, List[str]],
consumes: Union[str, List[str]]
):
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
provided = request.mimetype
if isinstance(consumes, str):
consumeables = {consumes}
else:
consumeables = {*consumes}
accepted = {*request.accept_mimetypes.values()}
if isinstance(produces, str):
produceables = {produces}
else:
produceables = {*produces}
if len(produceables & accepted) == 0:
raise NotAcceptable()
if provided not in consumeables:
raise NotAcceptable()
return f(*args, **kwargs)
return decorated_function
return decorator