diff --git a/passbook/core/templates/partials/form.html b/passbook/core/templates/partials/form.html index 83a6e8ae3..efd249d08 100644 --- a/passbook/core/templates/partials/form.html +++ b/passbook/core/templates/partials/form.html @@ -2,6 +2,13 @@ {% load i18n %} {% csrf_token %} +{% if form.non_field_errors %} +
+

+ {{ form.non_field_errors }} +

+
+{% endif %} {% for field in form %}
{% if field.field.widget|fieldtype == 'RadioSelect' %} diff --git a/passbook/policies/expression/evaluator.py b/passbook/policies/expression/evaluator.py index 047c5f1ac..2a0fa8904 100644 --- a/passbook/policies/expression/evaluator.py +++ b/passbook/policies/expression/evaluator.py @@ -1,6 +1,6 @@ """passbook expression policy evaluator""" import re -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from django.core.exceptions import ValidationError from django.http import HttpRequest @@ -10,14 +10,12 @@ from jinja2.nativetypes import NativeEnvironment from requests import Session from structlog import get_logger +from passbook.core.models import User from passbook.flows.planner import PLAN_CONTEXT_SSO from passbook.flows.views import SESSION_KEY_PLAN from passbook.lib.utils.http import get_client_ip from passbook.policies.types import PolicyRequest, PolicyResult -if TYPE_CHECKING: - from passbook.core.models import User - LOGGER = get_logger() @@ -43,6 +41,7 @@ class Evaluator: self._env.globals["pb_message"] = self.jinja2_func_message self._context = { "pb_is_group_member": Evaluator.jinja2_func_is_group_member, + "pb_user_by": Evaluator.jinja2_func_user_by, "pb_logger": get_logger(), "requests": Session(), } @@ -64,7 +63,15 @@ class Evaluator: return re.sub(regex, repl, value) @staticmethod - def jinja2_func_is_group_member(user: "User", group_name: str) -> bool: + def jinja2_func_user_by(**filters) -> Optional[User]: + """Get user by filters""" + users = User.objects.filter(**filters) + if users: + return users.first() + return None + + @staticmethod + def jinja2_func_is_group_member(user: User, group_name: str) -> bool: """Check if `user` is member of group with name `group_name`""" return user.groups.filter(name=group_name).exists() @@ -126,4 +133,4 @@ class Evaluator: self._env.from_string(expression) return True except TemplateSyntaxError as exc: - raise ValidationError("Expression Syntax Error") from exc + raise ValidationError(f"Expression Syntax Error: {str(exc)}") from exc diff --git a/passbook/policies/types.py b/passbook/policies/types.py index 1fd65e63b..29bf02932 100644 --- a/passbook/policies/types.py +++ b/passbook/policies/types.py @@ -39,4 +39,6 @@ class PolicyResult: self.messages = messages def __str__(self): - return f"" + if self.messages: + return f"PolicyResult passing={self.passing} messages={self.messages}" + return f"PolicyResult passing={self.passing}" diff --git a/passbook/stages/prompt/forms.py b/passbook/stages/prompt/forms.py index 7347e9053..e9157d198 100644 --- a/passbook/stages/prompt/forms.py +++ b/passbook/stages/prompt/forms.py @@ -64,4 +64,4 @@ class PromptForm(forms.Form): engine.build() result = engine.result if not result.passing: - raise forms.ValidationError(result.messages) + raise forms.ValidationError(list(result.messages))