def set_method(self, method: str, request: Optional[HttpRequest], **kwargs): """Set method data on current flow, if possbiel""" if not request: return # Since we can't directly pass other variables to signals, and we want to log the method # and the token used, we assume we're running in a flow and set a variable in the context flow_plan: FlowPlan = request.session[SESSION_KEY_PLAN] flow_plan.context[PLAN_CONTEXT_METHOD] = method flow_plan.context[PLAN_CONTEXT_METHOD_ARGS] = cleanse_dict(sanitize_dict(kwargs)) request.session[SESSION_KEY_PLAN] = flow_plan
def new( action: Union[str, EventAction], app: Optional[str] = None, _inspect_offset: int = 1, **kwargs, ) -> "Event": """Create new Event instance from arguments. Instance is NOT saved.""" if not isinstance(action, EventAction): action = EventAction.CUSTOM_PREFIX + action if not app: app = getmodule(stack()[_inspect_offset][0]).__name__ cleaned_kwargs = cleanse_dict(sanitize_dict(kwargs)) event = Event(action=action, app=app, context=cleaned_kwargs) return event
def new( action: str | EventAction, app: Optional[str] = None, **kwargs, ) -> "Event": """Create new Event instance from arguments. Instance is NOT saved.""" if not isinstance(action, EventAction): action = EventAction.CUSTOM_PREFIX + action if not app: current = currentframe() parent = current.f_back app = parent.f_globals["__name__"] cleaned_kwargs = cleanse_dict(sanitize_dict(kwargs)) event = Event(action=action, app=app, context=cleaned_kwargs) return event
def from_http(self, request: HttpRequest, user: Optional[settings.AUTH_USER_MODEL] = None) -> "Event": """Add data from a Django-HttpRequest, allowing the creation of Events independently from requests. `user` arguments optionally overrides user from requests.""" if request: self.context["http_request"] = { "path": request.path, "method": request.method, "args": QueryDict(request.META.get("QUERY_STRING", "")), } if hasattr(request, "tenant"): tenant: Tenant = request.tenant # Because self.created only gets set on save, we can't use it's value here # hence we set self.created to now and then use it self.created = now() self.expires = self.created + timedelta_from_string( tenant.event_retention) self.tenant = sanitize_dict(model_to_dict(tenant)) if hasattr(request, "user"): original_user = None if hasattr(request, "session"): original_user = request.session.get( SESSION_IMPERSONATE_ORIGINAL_USER, None) self.user = get_user(request.user, original_user) if user: self.user = get_user(user) # Check if we're currently impersonating, and add that user if hasattr(request, "session"): if SESSION_IMPERSONATE_ORIGINAL_USER in request.session: self.user = get_user( request.session[SESSION_IMPERSONATE_ORIGINAL_USER]) self.user["on_behalf_of"] = get_user( request.session[SESSION_IMPERSONATE_USER]) # User 255.255.255.255 as fallback if IP cannot be determined self.client_ip = get_client_ip(request) # Apply GeoIP Data, when enabled self.with_geoip() # If there's no app set, we get it from the requests too if not self.app: self.app = Event._get_app_from_request(request) self.save() return self
def challenge_valid( self, response: AuthenticatorValidationChallengeResponse ) -> HttpResponse: # All validation is done by the serializer user = self.executor.plan.context.get(PLAN_CONTEXT_PENDING_USER) if not user: webauthn_device: WebAuthnDevice = response.data.get( "webauthn", None) if not webauthn_device: return self.executor.stage_ok() LOGGER.debug("Set user from userless flow", user=webauthn_device.user) self.executor.plan.context[ PLAN_CONTEXT_PENDING_USER] = webauthn_device.user self.executor.plan.context[ PLAN_CONTEXT_METHOD] = "auth_webauthn_pwl" self.executor.plan.context[ PLAN_CONTEXT_METHOD_ARGS] = cleanse_dict( sanitize_dict({ "device": webauthn_device, })) return self.executor.stage_ok()
def get_plan_context(self, plan: FlowPlan) -> dict[str, Any]: """Get the plan's context, sanitized""" return sanitize_dict(plan.context)
def default_tenant(): """Get a default value for tenant""" return sanitize_dict(model_to_dict(DEFAULT_TENANT))