Source code for zemfrog.decorators

from functools import wraps
from typing import Callable

from flask import current_app, jsonify
from flask_apispec import doc
from flask_jwt_extended import verify_jwt_in_request
from flask_jwt_extended.utils import get_jwt_claims

[docs]def http_code(func: Callable) -> Callable: """ Decorator to generate HTTP status response code automatically according to the key ``code`` in json. :param func: Your view function. """ @wraps(func) def wrapper(*args, **kwds): result = func(*args, **kwds) code = 200 if isinstance(result, dict): code = result.get("code", 200) if not isinstance(result, (tuple, list)): result = result, code return result return wrapper
[docs]def api_doc(**kwds) -> Callable: """ Decorator for adding API documentation through the documentation in the view function. """ def wrapper(func: Callable): d = kwds.pop("description", func.__doc__ or "") kwds["description"] = d func = doc(**kwds)(func) return func return wrapper
[docs]def jwt_required(roles={}) -> Callable: """ Decorator to protect views with JWT & user roles. """ def decorated(func: Callable) -> Callable: @wraps(func) def wrapper(*args, **kwds): verify_jwt_in_request() claims = get_jwt_claims() jwt_roles = claims.get("roles", {}) for role, permissions in roles.items(): if not isinstance(permissions, (list, tuple)): permissions = [] if role in jwt_roles: valid_perms = jwt_roles.get(role, []) for perm in permissions: if perm not in valid_perms: return ( jsonify(message="You don't have permission!", code=403), 403, ) else: return (jsonify(message="Role not allowed!", code=403), 403) return func(*args, **kwds) return wrapper return decorated
[docs]def authenticate(roles={}) -> Callable: """ Decorator to add jwt view authentication to API Docs. Reference: """ def decorated(func: Callable) -> Callable: func = api_doc(security=current_app.config.get("APISPEC_SECURITY_PARAMS", []))( jwt_required(roles)(func) ) return func return decorated