policies: add references for source_policy and source_results

This commit is contained in:
Jens Langhammer 2020-09-14 21:51:59 +02:00
parent e21ed92848
commit 812cc0d2f1
5 changed files with 30 additions and 10 deletions

View File

@ -109,19 +109,23 @@ class PolicyEngine:
@property @property
def result(self) -> PolicyResult: def result(self) -> PolicyResult:
"""Get policy-checking result""" """Get policy-checking result"""
messages: List[str] = []
process_results: List[PolicyResult] = [ process_results: List[PolicyResult] = [
x.result for x in self.__processes if x.result x.result for x in self.__processes if x.result
] ]
final_result = PolicyResult(False)
final_result.messages = []
final_result.source_results = list(process_results + self.__cached_policies)
for result in process_results + self.__cached_policies: for result in process_results + self.__cached_policies:
LOGGER.debug( LOGGER.debug(
"P_ENG: result", passing=result.passing, messages=result.messages "P_ENG: result", passing=result.passing, messages=result.messages
) )
if result.messages: if result.messages:
messages += result.messages final_result.messages.extend(result.messages)
if not result.passing: if not result.passing:
return PolicyResult(False, *messages) final_result.passing = False
return PolicyResult(True, *messages) return final_result
final_result.passing = True
return final_result
@property @property
def passing(self) -> bool: def passing(self) -> bool:

View File

@ -7,7 +7,7 @@
<label for="" class="pf-c-form__label"></label> <label for="" class="pf-c-form__label"></label>
<div class="c-form__horizontal-group"> <div class="c-form__horizontal-group">
<p> <p>
Expression using Python. See <a href="https://passbook.beryju.org/policies/expression/">here</a> for a list of all variables. Expression using Python. See <a target="_blank" href="https://passbook.beryju.org/policies/expression/">here</a> for a list of all variables.
</p> </p>
</div> </div>
</div> </div>

View File

@ -10,7 +10,11 @@ from django.utils.translation import gettext as _
from structlog import get_logger from structlog import get_logger
from passbook.core.models import Application, Provider, User from passbook.core.models import Application, Provider, User
from passbook.flows.views import SESSION_KEY_APPLICATION_PRE from passbook.flows.views import (
SESSION_KEY_APPLICATION_PRE,
SESSION_KEY_DENIED_ERROR,
SESSION_KEY_DENIED_POLICY_RESULT,
)
from passbook.policies.engine import PolicyEngine from passbook.policies.engine import PolicyEngine
from passbook.policies.types import PolicyResult from passbook.policies.types import PolicyResult
@ -36,8 +40,12 @@ class PolicyAccessMixin(BaseMixin, AccessMixin):
self.get_redirect_field_name(), self.get_redirect_field_name(),
) )
def handle_no_permission_authorized(self) -> HttpResponse: def handle_no_permission_authenticated(
"""Function called when user has no permissions but is authorized""" self, result: Optional[PolicyResult] = None
) -> HttpResponse:
"""Function called when user has no permissions but is authenticated"""
if result:
self.request.session[SESSION_KEY_DENIED_POLICY_RESULT] = result
# TODO: Remove this URL and render the view instead # TODO: Remove this URL and render the view instead
return redirect("passbook_flows:denied") return redirect("passbook_flows:denied")

View File

@ -9,7 +9,7 @@ from sentry_sdk.tracing import Span
from structlog import get_logger from structlog import get_logger
from passbook.policies.exceptions import PolicyException from passbook.policies.exceptions import PolicyException
from passbook.policies.models import PolicyBinding from passbook.policies.models import Policy, PolicyBinding
from passbook.policies.types import PolicyRequest, PolicyResult from passbook.policies.types import PolicyRequest, PolicyResult
LOGGER = get_logger() LOGGER = get_logger()
@ -63,6 +63,7 @@ class PolicyProcess(Process):
except PolicyException as exc: except PolicyException as exc:
LOGGER.debug("P_ENG(proc): error", exc=exc) LOGGER.debug("P_ENG(proc): error", exc=exc)
policy_result = PolicyResult(False, str(exc)) policy_result = PolicyResult(False, str(exc))
policy_result.source_policy = self.binding.policy
# Invert result if policy.negate is set # Invert result if policy.negate is set
if self.binding.negate: if self.binding.negate:
policy_result.passing = not policy_result.passing policy_result.passing = not policy_result.passing

View File

@ -1,13 +1,15 @@
"""policy structures""" """policy structures"""
from __future__ import annotations from __future__ import annotations
from typing import TYPE_CHECKING, Dict, Optional, Tuple from dataclasses import field
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple
from django.db.models import Model from django.db.models import Model
from django.http import HttpRequest from django.http import HttpRequest
if TYPE_CHECKING: if TYPE_CHECKING:
from passbook.core.models import User from passbook.core.models import User
from passbook.policies.models import Policy
class PolicyRequest: class PolicyRequest:
@ -34,9 +36,14 @@ class PolicyResult:
passing: bool passing: bool
messages: Tuple[str, ...] messages: Tuple[str, ...]
source_policy: Optional[Policy]
source_results: Optional[List["PolicyResult"]]
def __init__(self, passing: bool, *messages: str): def __init__(self, passing: bool, *messages: str):
self.passing = passing self.passing = passing
self.messages = messages self.messages = messages
self.source_policy = None
self.source_results = []
def __repr__(self): def __repr__(self):
return self.__str__() return self.__str__()