diff --git a/authentik/policies/api/policies.py b/authentik/policies/api/policies.py index 7c289e8a4..b57ab8213 100644 --- a/authentik/policies/api/policies.py +++ b/authentik/policies/api/policies.py @@ -39,8 +39,11 @@ class PolicySerializer(ModelSerializer, MetaNameSerializer): super().__init__(*args, **kwargs) self._resolve_inheritance = resolve_inheritance - def get_component(self, obj: Policy) -> str: + def get_component(self, obj: Policy) -> str: # pragma: no cover """Get object component so that we know how to edit the object""" + # pyright: reportGeneralTypeIssues=false + if obj.__class__ == Policy: + return "" return obj.component def get_bound_to(self, obj: Policy) -> int: diff --git a/authentik/policies/engine.py b/authentik/policies/engine.py index 7019af158..492594fad 100644 --- a/authentik/policies/engine.py +++ b/authentik/policies/engine.py @@ -149,6 +149,7 @@ class PolicyEngine: if self.mode == PolicyEngineMode.MODE_ANY: passing = any(x.passing for x in all_results) result = PolicyResult(passing) + result.source_results = all_results result.messages = tuple(y for x in all_results for y in x.messages) return result diff --git a/authentik/policies/models.py b/authentik/policies/models.py index e7f0a71b6..084a0ca9f 100644 --- a/authentik/policies/models.py +++ b/authentik/policies/models.py @@ -112,10 +112,17 @@ class PolicyBinding(SerializerModel): return PolicyBindingSerializer def __str__(self) -> str: + suffix = "" + if self.policy: + suffix = f"Policy {self.policy.name}" + if self.group: + suffix = f"Group {self.group.name}" + if self.user: + suffix = f"User {self.user.name}" try: - return f"Policy Binding {self.target} #{self.order} {self.policy}" + return f"Binding from {self.target} #{self.order} to {suffix}" except PolicyBinding.target.RelatedObjectDoesNotExist: # pylint: disable=no-member - return f"Policy Binding - #{self.order} {self.policy}" + return f"Binding - #{self.order} to {suffix}" class Meta: diff --git a/authentik/policies/process.py b/authentik/policies/process.py index 589173cf2..263881ca5 100644 --- a/authentik/policies/process.py +++ b/authentik/policies/process.py @@ -100,7 +100,7 @@ class PolicyProcess(PROCESS_CLASS): self.create_event(EventAction.POLICY_EXCEPTION, message=error_string) LOGGER.debug("P_ENG(proc): error", exc=src_exc) policy_result = PolicyResult(False, str(src_exc)) - policy_result.source_policy = self.binding.policy + policy_result.source_binding = self.binding # Invert result if policy.negate is set if self.binding.negate: policy_result.passing = not policy_result.passing diff --git a/authentik/policies/templates/policies/denied.html b/authentik/policies/templates/policies/denied.html index aa6b08095..b4996feae 100644 --- a/authentik/policies/templates/policies/denied.html +++ b/authentik/policies/templates/policies/denied.html @@ -3,58 +3,58 @@ {% load static %} {% load i18n %} +{% block title %} +{% trans 'Permission denied - authentik' %} +{% endblock %} + {% block card_title %} {% trans 'Permission denied' %} {% endblock %} -{% block title %} -{% trans 'Permission denied' %} -{% endblock %} - {% block card %} -
- {% csrf_token %} -
-

- - {% trans 'Request has been denied.' %} -

- {% if error %} -
-

- {{ error }} -

- {% endif %} - {% if policy_result %} -
- {% trans 'Messages:' %} + + {% csrf_token %} +
+

+ + {% trans 'Request has been denied.' %} +

+ {% if error %} +
+

+ {{ error }} +

+ {% endif %} + {% if policy_result %} +
+ {% trans 'Messages:' %} +
    + {% for message in policy_result.messages %} +
  • + {{ message }} +
  • + {% endfor %} +
+ {% if policy_result.source_results %} + {% trans 'Explanation:' %}
    - {% for message in policy_result.messages %} + {% for source_result in policy_result.source_results %}
  • - {{ message }} + {% blocktrans with name=source_result.source_binding result=source_result.passing %} + Policy binding '{{ name }}' returned result '{{ result }}' + {% endblocktrans %} + {% if source_result.messages %} +
      + {% for message in source_result.messages %} +
    • {{ message }}
    • + {% endfor %} +
    + {% endif %}
  • {% endfor %}
- {% if policy_result.source_results %} - {% trans 'Explanation:' %} -
    - {% for source_result in policy_result.source_results %} -
  • - {% blocktrans with name=source_result.source_policy.name result=source_result.passing %} - Policy '{{ name }}' returned result '{{ result }}' - {% endblocktrans %} - {% if source_result.messages %} -
      - {% for message in source_result.messages %} -
    • {{ message }}
    • - {% endfor %} -
    - {% endif %} -
  • - {% endfor %} -
- {% endif %} {% endif %} -
- + {% endif %} +
+ {% endblock %} diff --git a/authentik/policies/types.py b/authentik/policies/types.py index 076e2a9f6..d69748944 100644 --- a/authentik/policies/types.py +++ b/authentik/policies/types.py @@ -14,7 +14,7 @@ from authentik.lib.utils.http import get_client_ip if TYPE_CHECKING: from authentik.core.models import User - from authentik.policies.models import Policy + from authentik.policies.models import PolicyBinding LOGGER = get_logger() @@ -61,14 +61,14 @@ class PolicyResult: passing: bool messages: tuple[str, ...] - source_policy: Optional[Policy] + source_binding: Optional["PolicyBinding"] source_results: Optional[list["PolicyResult"]] def __init__(self, passing: bool, *messages: str): super().__init__() self.passing = passing self.messages = messages - self.source_policy = None + self.source_binding = None self.source_results = [] def __repr__(self):