flows: Correctly check initial policies on flow with context
# Conflicts: # passbook/flows/planner.py # passbook/flows/tests/test_planner.py # passbook/flows/tests/test_views.py # passbook/flows/views.py
This commit is contained in:
@ -11,7 +11,6 @@ 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()
|
||||
|
||||
@ -52,22 +51,12 @@ class FlowPlanner:
|
||||
self.use_cache = True
|
||||
self.flow = flow
|
||||
|
||||
def _check_flow_root_policies(self, request: HttpRequest) -> PolicyResult:
|
||||
engine = PolicyEngine(self.flow, request.user, request)
|
||||
engine.build()
|
||||
return engine.result
|
||||
|
||||
def plan(
|
||||
self, request: HttpRequest, default_context: Optional[Dict[str, Any]] = None
|
||||
) -> FlowPlan:
|
||||
"""Check each of the flows' policies, check policies for each stage with PolicyBinding
|
||||
and return ordered list"""
|
||||
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_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
|
||||
@ -75,6 +64,16 @@ class FlowPlanner:
|
||||
user = default_context[PLAN_CONTEXT_PENDING_USER]
|
||||
else:
|
||||
user = request.user
|
||||
# First off, check the flow's direct policy bindings
|
||||
# to make sure the user even has access to the flow
|
||||
engine = PolicyEngine(self.flow, user, request)
|
||||
if default_context:
|
||||
engine.request.context = default_context
|
||||
engine.build()
|
||||
result = engine.result
|
||||
if not result.passing:
|
||||
raise FlowNonApplicableException(result.messages)
|
||||
# User is passing so far, check if we have a cached plan
|
||||
cached_plan_key = cache_key(self.flow, user)
|
||||
cached_plan = cache.get(cached_plan_key, None)
|
||||
if cached_plan and self.use_cache:
|
||||
@ -82,6 +81,7 @@ class FlowPlanner:
|
||||
"f(plan): Taking plan from cache", flow=self.flow, key=cached_plan_key
|
||||
)
|
||||
return cached_plan
|
||||
LOGGER.debug("f(plan): building plan", flow=self.flow)
|
||||
plan = self._build_plan(user, request, default_context)
|
||||
cache.set(cache_key(self.flow, user), plan)
|
||||
if not plan.stages:
|
||||
|
||||
Reference in New Issue
Block a user