Skip to content
Snippets Groups Projects
Select Git revision
  • 2642a25cf743ec1d176cf64d63c3f412cf492dc3
  • master default protected
2 results

__init__.py

Blame
  • Forked from Jean-Marie Place / SCODOC_R6A06
    Source project has a limited visibility.
    __init__.py 3.71 KiB
    """api.__init__
    """
    
    from functools import wraps
    
    from flask_json import as_json
    from flask import Blueprint
    from flask import current_app, g, request
    from flask_login import current_user
    from app import db, log
    from app.decorators import permission_required
    from app.scodoc import sco_utils as scu
    from app.scodoc.sco_exceptions import AccessDenied, ScoException
    from app.scodoc.sco_permissions import Permission
    
    api_bp = Blueprint("api", __name__)
    api_web_bp = Blueprint("apiweb", __name__)
    
    # HTTP ERROR STATUS
    API_CLIENT_ERROR = 400  # erreur dans les paramètres fournis par le client
    
    
    def api_permission_required(permission):
        """Ce décorateur fait la même chose que @permission_required
        mais enregistre dans l'attribut .scodoc_permission
        de la fonction la valeur de la permission.
        Cette valeur n'est utilisée que pour la génération automatique de la documentation.
        """
    
        def decorator(f):
            f.scodoc_permission = permission
    
            @wraps(f)
            def decorated_function(*args, **kwargs):
                scodoc_dept = getattr(g, "scodoc_dept", None)
                if not current_user.has_permission(permission, scodoc_dept):
                    return current_app.login_manager.unauthorized()
                return f(*args, **kwargs)
    
            return decorated_function
    
        return decorator
    
    
    @api_bp.errorhandler(ScoException)
    @api_web_bp.errorhandler(ScoException)
    @api_bp.errorhandler(404)
    def api_error_handler(e):
        "erreurs API => json"
        log(f"api_error_handler: {e}")
        return scu.json_error(404, message=str(e))
    
    
    @api_bp.errorhandler(AccessDenied)
    @api_web_bp.errorhandler(AccessDenied)
    def permission_denied_error_handler(exc):
        """
        Renvoie message d'erreur pour l'erreur 403
        """
        return scu.json_error(
            403, f"operation non autorisee ({exc.args[0] if exc.args else ''})"
        )
    
    
    def requested_format(default_format="json", allowed_formats=None):
        """Extract required format from query string.
        * default value is json. A list of allowed formats may be provided
        (['json'] considered if not provided).
        * if the required format is not in allowed list, returns None.
    
        NB: if json in not in allowed_formats, format specification is mandatory.
        """
        format_type = request.args.get("format", default_format)
        if format_type in (allowed_formats or ["json"]):
            return format_type
        return None
    
    
    @as_json
    def get_model_api_object(
        model_cls: db.Model,
        model_id: int,
        join_cls: db.Model = None,
        restrict: bool | None = None,
    ):
        """
        Retourne une réponse contenant la représentation api de l'objet "Model[model_id]"
    
        Filtrage du département en fonction d'une classe de jointure (eg: Identite, Formsemestre) -> join_cls
    
        exemple d'utilisation : fonction "justificatif()" -> app/api/justificatifs.py
    
        L'agument restrict est passé to_dict, est signale que l'on veut une version restreinte
        (sans données personnelles, ou sans informations sur le justificatif d'absence)
        """
        query = model_cls.query.filter_by(id=model_id)
        if g.scodoc_dept and join_cls is not None:
            query = query.join(join_cls).filter_by(dept_id=g.scodoc_dept_id)
        unique: model_cls = query.first()
    
        if unique is None:
            return scu.json_error(
                404,
                message=f"{model_cls.__name__} inexistant(e)",
            )
        if restrict is None:
            return unique.to_dict(format_api=True)
        return unique.to_dict(format_api=True, restrict=restrict)
    
    
    from app.api import tokens
    from app.api import (
        assiduites,
        billets_absences,
        departements,
        etud_suivi,
        etudiants,
        evaluations,
        formations,
        formsemestres,
        jury,
        justificatifs,
        logos,
        moduleimpl,
        operations,
        partitions,
        semset,
        users,
    )