flows: always show flow inspector in debug mode, don't require admin in debug (#3786)
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
884f5249d1
commit
79e8b72569
|
@ -28,6 +28,7 @@ class Capabilities(models.TextChoices):
|
||||||
CAN_SAVE_MEDIA = "can_save_media"
|
CAN_SAVE_MEDIA = "can_save_media"
|
||||||
CAN_GEO_IP = "can_geo_ip"
|
CAN_GEO_IP = "can_geo_ip"
|
||||||
CAN_IMPERSONATE = "can_impersonate"
|
CAN_IMPERSONATE = "can_impersonate"
|
||||||
|
CAN_DEBUG = "can_debug"
|
||||||
|
|
||||||
|
|
||||||
class ErrorReportingConfigSerializer(PassiveSerializer):
|
class ErrorReportingConfigSerializer(PassiveSerializer):
|
||||||
|
@ -66,6 +67,8 @@ class ConfigView(APIView):
|
||||||
caps.append(Capabilities.CAN_GEO_IP)
|
caps.append(Capabilities.CAN_GEO_IP)
|
||||||
if CONFIG.y_bool("impersonation"):
|
if CONFIG.y_bool("impersonation"):
|
||||||
caps.append(Capabilities.CAN_IMPERSONATE)
|
caps.append(Capabilities.CAN_IMPERSONATE)
|
||||||
|
if settings.DEBUG:
|
||||||
|
caps.append(Capabilities.CAN_DEBUG)
|
||||||
return caps
|
return caps
|
||||||
|
|
||||||
def get_config(self) -> ConfigSerializer:
|
def get_config(self) -> ConfigSerializer:
|
||||||
|
|
|
@ -73,17 +73,17 @@ class FlowInspectorView(APIView):
|
||||||
flow: Flow
|
flow: Flow
|
||||||
_logger: BoundLogger
|
_logger: BoundLogger
|
||||||
|
|
||||||
|
def check_permissions(self, request):
|
||||||
|
"""Always allow access when in debug mode"""
|
||||||
|
if settings.DEBUG:
|
||||||
|
return None
|
||||||
|
return super().check_permissions(request)
|
||||||
|
|
||||||
def setup(self, request: HttpRequest, flow_slug: str):
|
def setup(self, request: HttpRequest, flow_slug: str):
|
||||||
super().setup(request, flow_slug=flow_slug)
|
super().setup(request, flow_slug=flow_slug)
|
||||||
self.flow = get_object_or_404(Flow.objects.select_related(), slug=flow_slug)
|
self.flow = get_object_or_404(Flow.objects.select_related(), slug=flow_slug)
|
||||||
self._logger = get_logger().bind(flow_slug=flow_slug)
|
self._logger = get_logger().bind(flow_slug=flow_slug)
|
||||||
|
|
||||||
# pylint: disable=unused-argument, too-many-return-statements
|
|
||||||
def dispatch(self, request: HttpRequest, flow_slug: str) -> HttpResponse:
|
|
||||||
if SESSION_KEY_HISTORY not in self.request.session:
|
|
||||||
return HttpResponse(status=400)
|
|
||||||
return super().dispatch(request, flow_slug=flow_slug)
|
|
||||||
|
|
||||||
@extend_schema(
|
@extend_schema(
|
||||||
responses={
|
responses={
|
||||||
200: FlowInspectionSerializer(),
|
200: FlowInspectionSerializer(),
|
||||||
|
@ -95,7 +95,7 @@ class FlowInspectorView(APIView):
|
||||||
def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
|
def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
|
||||||
"""Get current flow state and record it"""
|
"""Get current flow state and record it"""
|
||||||
plans = []
|
plans = []
|
||||||
for plan in request.session[SESSION_KEY_HISTORY]:
|
for plan in request.session.get(SESSION_KEY_HISTORY, []):
|
||||||
plan_serializer = FlowInspectorPlanSerializer(
|
plan_serializer = FlowInspectorPlanSerializer(
|
||||||
instance=plan, context={"request": request}
|
instance=plan, context={"request": request}
|
||||||
)
|
)
|
||||||
|
|
|
@ -25809,6 +25809,7 @@ components:
|
||||||
- can_save_media
|
- can_save_media
|
||||||
- can_geo_ip
|
- can_geo_ip
|
||||||
- can_impersonate
|
- can_impersonate
|
||||||
|
- can_debug
|
||||||
type: string
|
type: string
|
||||||
CaptchaChallenge:
|
CaptchaChallenge:
|
||||||
type: object
|
type: object
|
||||||
|
|
|
@ -36,6 +36,7 @@ import PFTitle from "@patternfly/patternfly/components/Title/title.css";
|
||||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
CapabilitiesEnum,
|
||||||
ChallengeChoices,
|
ChallengeChoices,
|
||||||
ChallengeTypes,
|
ChallengeTypes,
|
||||||
CurrentTenant,
|
CurrentTenant,
|
||||||
|
@ -154,7 +155,11 @@ export class FlowExecutor extends AKElement implements StageHost {
|
||||||
super();
|
super();
|
||||||
this.ws = new WebsocketClient();
|
this.ws = new WebsocketClient();
|
||||||
this.flowSlug = window.location.pathname.split("/")[3];
|
this.flowSlug = window.location.pathname.split("/")[3];
|
||||||
this.inspectorOpen = window.location.search.includes("inspector");
|
this.inspectorOpen =
|
||||||
|
globalAK()?.config.capabilities.includes(CapabilitiesEnum.Debug) || false;
|
||||||
|
if (window.location.search.includes("inspector")) {
|
||||||
|
this.inspectorOpen = !this.inspectorOpen;
|
||||||
|
}
|
||||||
tenant().then((tenant) => (this.tenant = tenant));
|
tenant().then((tenant) => (this.tenant = tenant));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,3 +31,7 @@ This data is not cleaned, so if your flow involves inputting a password, it will
|
||||||
## Session ID
|
## Session ID
|
||||||
|
|
||||||
The unique ID for the currently used session. This can be used to debug issues with flows restarting/losing state.
|
The unique ID for the currently used session. This can be used to debug issues with flows restarting/losing state.
|
||||||
|
|
||||||
|
# Access to the inspector
|
||||||
|
|
||||||
|
By default, the inspector can only be enabled when the currently authenticated user is a superuser. When running authentik with debug-mode enabled, the inspector is enabled by default and can be accessed by both unauthenticated users and standard users.
|
||||||
|
|
Reference in a new issue