authentik.flows.markers
Stage Markers
1"""Stage Markers""" 2 3from dataclasses import dataclass 4from typing import TYPE_CHECKING 5 6from django.contrib.messages import INFO, add_message 7from django.http.request import HttpRequest 8from structlog.stdlib import get_logger 9 10from authentik.flows.models import FlowStageBinding 11from authentik.policies.engine import PolicyEngine 12from authentik.policies.models import PolicyBinding 13 14if TYPE_CHECKING: 15 from authentik.flows.planner import FlowPlan 16 17LOGGER = get_logger() 18 19 20@dataclass 21class StageMarker: 22 """Base stage marker class, no extra attributes, and has no special handler.""" 23 24 def process( 25 self, 26 plan: FlowPlan, 27 binding: FlowStageBinding, 28 http_request: HttpRequest, 29 ) -> FlowStageBinding | None: 30 """Process callback for this marker. This should be overridden by sub-classes. 31 If a stage should be removed, return None.""" 32 return binding 33 34 35@dataclass(slots=True) 36class ReevaluateMarker(StageMarker): 37 """Reevaluate Marker, forces stage's policies to be evaluated again.""" 38 39 binding: PolicyBinding 40 41 def process( 42 self, 43 plan: FlowPlan, 44 binding: FlowStageBinding, 45 http_request: HttpRequest, 46 ) -> FlowStageBinding | None: 47 """Re-evaluate policies bound to stage, and if they fail, remove from plan""" 48 from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER 49 50 LOGGER.debug( 51 "f(plan_inst): running re-evaluation", 52 marker="ReevaluateMarker", 53 binding=binding, 54 policy_binding=self.binding, 55 ) 56 engine = PolicyEngine( 57 self.binding, plan.context.get(PLAN_CONTEXT_PENDING_USER, http_request.user) 58 ) 59 engine.use_cache = False 60 engine.request.set_http_request(http_request) 61 engine.request.context["flow_plan"] = plan 62 engine.request.context.update(plan.context) 63 engine.build() 64 result = engine.result 65 for message in result.messages: 66 add_message(http_request, INFO, message) 67 if result.passing: 68 return binding 69 LOGGER.warning( 70 "f(plan_inst): binding failed re-evaluation", 71 marker="ReevaluateMarker", 72 binding=binding, 73 messages=result.messages, 74 ) 75 return None
LOGGER =
<BoundLoggerLazyProxy(logger=None, wrapper_class=None, processors=None, context_class=None, initial_values={}, logger_factory_args=())>
@dataclass
class
StageMarker:
21@dataclass 22class StageMarker: 23 """Base stage marker class, no extra attributes, and has no special handler.""" 24 25 def process( 26 self, 27 plan: FlowPlan, 28 binding: FlowStageBinding, 29 http_request: HttpRequest, 30 ) -> FlowStageBinding | None: 31 """Process callback for this marker. This should be overridden by sub-classes. 32 If a stage should be removed, return None.""" 33 return binding
Base stage marker class, no extra attributes, and has no special handler.
def
process(unknown):
25 def process( 26 self, 27 plan: FlowPlan, 28 binding: FlowStageBinding, 29 http_request: HttpRequest, 30 ) -> FlowStageBinding | None: 31 """Process callback for this marker. This should be overridden by sub-classes. 32 If a stage should be removed, return None.""" 33 return binding
Process callback for this marker. This should be overridden by sub-classes. If a stage should be removed, return None.
36@dataclass(slots=True) 37class ReevaluateMarker(StageMarker): 38 """Reevaluate Marker, forces stage's policies to be evaluated again.""" 39 40 binding: PolicyBinding 41 42 def process( 43 self, 44 plan: FlowPlan, 45 binding: FlowStageBinding, 46 http_request: HttpRequest, 47 ) -> FlowStageBinding | None: 48 """Re-evaluate policies bound to stage, and if they fail, remove from plan""" 49 from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER 50 51 LOGGER.debug( 52 "f(plan_inst): running re-evaluation", 53 marker="ReevaluateMarker", 54 binding=binding, 55 policy_binding=self.binding, 56 ) 57 engine = PolicyEngine( 58 self.binding, plan.context.get(PLAN_CONTEXT_PENDING_USER, http_request.user) 59 ) 60 engine.use_cache = False 61 engine.request.set_http_request(http_request) 62 engine.request.context["flow_plan"] = plan 63 engine.request.context.update(plan.context) 64 engine.build() 65 result = engine.result 66 for message in result.messages: 67 add_message(http_request, INFO, message) 68 if result.passing: 69 return binding 70 LOGGER.warning( 71 "f(plan_inst): binding failed re-evaluation", 72 marker="ReevaluateMarker", 73 binding=binding, 74 messages=result.messages, 75 ) 76 return None
Reevaluate Marker, forces stage's policies to be evaluated again.
ReevaluateMarker(binding: authentik.policies.models.PolicyBinding)
def
process(unknown):
42 def process( 43 self, 44 plan: FlowPlan, 45 binding: FlowStageBinding, 46 http_request: HttpRequest, 47 ) -> FlowStageBinding | None: 48 """Re-evaluate policies bound to stage, and if they fail, remove from plan""" 49 from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER 50 51 LOGGER.debug( 52 "f(plan_inst): running re-evaluation", 53 marker="ReevaluateMarker", 54 binding=binding, 55 policy_binding=self.binding, 56 ) 57 engine = PolicyEngine( 58 self.binding, plan.context.get(PLAN_CONTEXT_PENDING_USER, http_request.user) 59 ) 60 engine.use_cache = False 61 engine.request.set_http_request(http_request) 62 engine.request.context["flow_plan"] = plan 63 engine.request.context.update(plan.context) 64 engine.build() 65 result = engine.result 66 for message in result.messages: 67 add_message(http_request, INFO, message) 68 if result.passing: 69 return binding 70 LOGGER.warning( 71 "f(plan_inst): binding failed re-evaluation", 72 marker="ReevaluateMarker", 73 binding=binding, 74 messages=result.messages, 75 ) 76 return None
Re-evaluate policies bound to stage, and if they fail, remove from plan