"""
Autorizacion por alcances.

`IsAuthenticated` responde a "¿tienes una credencial valida?", que es
autenticacion, no autorizacion. Con solo eso, cualquier cliente con una clave
podia hacer cualquier cosa: enviar por los tres canales y consultar los envios
de los demas.

Estas clases responden a la otra pregunta: "¿esta credencial puede hacer *esto*?".
"""

from __future__ import annotations

from rest_framework.permissions import BasePermission


class HasScope(BasePermission):
    """
    Exige que la clave que autentico la peticion tenga el alcance declarado.

    La vista lo declara en `required_scope`. Una vista sin `required_scope` no
    pasa el permiso: es preferible que un endpoint nuevo devuelva 403 por
    despiste a que quede abierto, que es justo el fallo que ya se cometio una
    vez con `permission_classes`.
    """

    message = "Esta credencial no tiene permiso para esta operacion."

    def has_permission(self, request, view) -> bool:
        scope = getattr(view, "required_scope", None)
        if not scope:
            return False

        clave = getattr(request, "api_key_record", None)
        if clave is None:
            # Sin credencial identificada no hay nada que autorizar. Quien
            # rechaza con 401 es IsAuthenticated, que va delante.
            return False

        return clave.has_scope(scope)
