policies/*: remove Policy.negate, order, timeout (#39)

policies: rewrite engine to use PolicyBinding for order/negate/timeout
policies: rewrite engine to use PolicyResult instead of tuple
This commit is contained in:
Jens L
2020-05-28 21:45:54 +02:00
committed by GitHub
parent fdfc6472d2
commit df8995deed
21 changed files with 290 additions and 224 deletions

View File

@ -1,7 +1,7 @@
"""Flows Planner"""
from dataclasses import dataclass, field
from time import time
from typing import Any, Dict, List, Optional, Tuple
from typing import Any, Dict, List, Optional
from django.core.cache import cache
from django.http import HttpRequest
@ -11,6 +11,7 @@ from passbook.core.models import User
from passbook.flows.exceptions import EmptyFlowException, FlowNonApplicableException
from passbook.flows.models import Flow, Stage
from passbook.policies.engine import PolicyEngine
from passbook.policies.types import PolicyResult
LOGGER = get_logger()
@ -51,8 +52,8 @@ class FlowPlanner:
self.use_cache = True
self.flow = flow
def _check_flow_root_policies(self, request: HttpRequest) -> Tuple[bool, List[str]]:
engine = PolicyEngine(self.flow.policies.all(), request.user, request)
def _check_flow_root_policies(self, request: HttpRequest) -> PolicyResult:
engine = PolicyEngine(self.flow, request.user, request)
engine.build()
return engine.result
@ -64,9 +65,9 @@ class FlowPlanner:
LOGGER.debug("f(plan): Starting planning process", flow=self.flow)
# First off, check the flow's direct policy bindings
# to make sure the user even has access to the flow
root_passing, root_passing_messages = self._check_flow_root_policies(request)
if not root_passing:
raise FlowNonApplicableException(root_passing_messages)
root_result = self._check_flow_root_policies(request)
if not root_result.passing:
raise FlowNonApplicableException(*root_result.messages)
# Bit of a workaround here, if there is a pending user set in the default context
# we use that user for our cache key
# to make sure they don't get the generic response
@ -106,11 +107,10 @@ class FlowPlanner:
.select_related()
):
binding = stage.flowstagebinding_set.get(flow__pk=self.flow.pk)
engine = PolicyEngine(binding.policies.all(), user, request)
engine = PolicyEngine(binding, user, request)
engine.request.context = plan.context
engine.build()
passing, _ = engine.result
if passing:
if engine.passing:
LOGGER.debug("f(plan): Stage passing", stage=stage, flow=self.flow)
plan.stages.append(stage)
end_time = time()