from flask import abort, current_app from flask_login import current_user from functools import wraps from threading import Thread from .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) def background(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 thread return wrapped