flows: denied action (#3194)
This commit is contained in:
		
							
								
								
									
										10
									
								
								.vscode/tasks.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								.vscode/tasks.json
									
									
									
									
										vendored
									
									
								
							| @ -46,6 +46,16 @@ | |||||||
|             "args": ["install"], |             "args": ["install"], | ||||||
|             "group": "build", |             "group": "build", | ||||||
|         }, |         }, | ||||||
|  |         { | ||||||
|  |             "label": "authentik: i18n-extract", | ||||||
|  |             "command": "poetry", | ||||||
|  |             "args": [ | ||||||
|  |                 "run", | ||||||
|  |                 "make", | ||||||
|  |                 "i18n-extract" | ||||||
|  |             ], | ||||||
|  |             "group": "build", | ||||||
|  |         }, | ||||||
|         { |         { | ||||||
|             "label": "authentik[website]: format", |             "label": "authentik[website]: format", | ||||||
|             "command": "make", |             "command": "make", | ||||||
|  | |||||||
| @ -11,14 +11,13 @@ from authentik.lib.generators import generate_id | |||||||
| from authentik.tenants.models import Tenant | from authentik.tenants.models import Tenant | ||||||
|  |  | ||||||
|  |  | ||||||
| def create_test_flow(designation: FlowDesignation = FlowDesignation.STAGE_CONFIGURATION) -> Flow: | def create_test_flow( | ||||||
|  |     designation: FlowDesignation = FlowDesignation.STAGE_CONFIGURATION, **kwargs | ||||||
|  | ) -> Flow: | ||||||
|     """Generate a flow that can be used for testing""" |     """Generate a flow that can be used for testing""" | ||||||
|     uid = generate_id(10) |     uid = generate_id(10) | ||||||
|     return Flow.objects.create( |     return Flow.objects.create( | ||||||
|         name=uid, |         name=uid, title=uid, slug=slugify(uid), designation=designation, **kwargs | ||||||
|         title=uid, |  | ||||||
|         slug=slugify(uid), |  | ||||||
|         designation=designation, |  | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | |||||||
| @ -73,6 +73,7 @@ class FlowSerializer(ModelSerializer): | |||||||
|             "compatibility_mode", |             "compatibility_mode", | ||||||
|             "export_url", |             "export_url", | ||||||
|             "layout", |             "layout", | ||||||
|  |             "denied_action", | ||||||
|         ] |         ] | ||||||
|         extra_kwargs = { |         extra_kwargs = { | ||||||
|             "background": {"read_only": True}, |             "background": {"read_only": True}, | ||||||
| @ -110,8 +111,8 @@ class FlowViewSet(UsedByMixin, ModelViewSet): | |||||||
|     serializer_class = FlowSerializer |     serializer_class = FlowSerializer | ||||||
|     lookup_field = "slug" |     lookup_field = "slug" | ||||||
|     ordering = ["slug", "name"] |     ordering = ["slug", "name"] | ||||||
|     search_fields = ["name", "slug", "designation", "title"] |     search_fields = ["name", "slug", "designation", "title", "denied_action"] | ||||||
|     filterset_fields = ["flow_uuid", "name", "slug", "designation"] |     filterset_fields = ["flow_uuid", "name", "slug", "designation", "denied_action"] | ||||||
|  |  | ||||||
|     @permission_required(None, ["authentik_flows.view_flow_cache"]) |     @permission_required(None, ["authentik_flows.view_flow_cache"]) | ||||||
|     @extend_schema(responses={200: CacheSerializer(many=False)}) |     @extend_schema(responses={200: CacheSerializer(many=False)}) | ||||||
|  | |||||||
							
								
								
									
										26
									
								
								authentik/flows/migrations/0023_flow_denied_action.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								authentik/flows/migrations/0023_flow_denied_action.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | |||||||
|  | # Generated by Django 4.0.5 on 2022-07-02 12:42 | ||||||
|  |  | ||||||
|  | from django.db import migrations, models | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|  |     dependencies = [ | ||||||
|  |         ("authentik_flows", "0022_flow_layout"), | ||||||
|  |     ] | ||||||
|  |  | ||||||
|  |     operations = [ | ||||||
|  |         migrations.AddField( | ||||||
|  |             model_name="flow", | ||||||
|  |             name="denied_action", | ||||||
|  |             field=models.TextField( | ||||||
|  |                 choices=[ | ||||||
|  |                     ("message_continue", "Message Continue"), | ||||||
|  |                     ("message", "Message"), | ||||||
|  |                     ("continue", "Continue"), | ||||||
|  |                 ], | ||||||
|  |                 default="message_continue", | ||||||
|  |                 help_text="Configure what should happen when a flow denies access to a user.", | ||||||
|  |             ), | ||||||
|  |         ), | ||||||
|  |     ] | ||||||
| @ -5,7 +5,6 @@ from typing import TYPE_CHECKING, Optional | |||||||
| from uuid import uuid4 | from uuid import uuid4 | ||||||
|  |  | ||||||
| from django.db import models | from django.db import models | ||||||
| from django.http import HttpRequest |  | ||||||
| from django.utils.translation import gettext_lazy as _ | from django.utils.translation import gettext_lazy as _ | ||||||
| from model_utils.managers import InheritanceManager | from model_utils.managers import InheritanceManager | ||||||
| from rest_framework.serializers import BaseSerializer | from rest_framework.serializers import BaseSerializer | ||||||
| @ -40,6 +39,14 @@ class InvalidResponseAction(models.TextChoices): | |||||||
|     RESTART_WITH_CONTEXT = "restart_with_context" |     RESTART_WITH_CONTEXT = "restart_with_context" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class FlowDeniedAction(models.TextChoices): | ||||||
|  |     """Configure what response is given to denied flow executions""" | ||||||
|  |  | ||||||
|  |     MESSAGE_CONTINUE = "message_continue" | ||||||
|  |     MESSAGE = "message" | ||||||
|  |     CONTINUE = "continue" | ||||||
|  |  | ||||||
|  |  | ||||||
| class FlowDesignation(models.TextChoices): | class FlowDesignation(models.TextChoices): | ||||||
|     """Designation of what a Flow should be used for. At a later point, this |     """Designation of what a Flow should be used for. At a later point, this | ||||||
|     should be replaced by a database entry.""" |     should be replaced by a database entry.""" | ||||||
| @ -139,6 +146,12 @@ class Flow(SerializerModel, PolicyBindingModel): | |||||||
|         ), |         ), | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|  |     denied_action = models.TextField( | ||||||
|  |         choices=FlowDeniedAction.choices, | ||||||
|  |         default=FlowDeniedAction.MESSAGE_CONTINUE, | ||||||
|  |         help_text=_("Configure what should happen when a flow denies access to a user."), | ||||||
|  |     ) | ||||||
|  |  | ||||||
|     @property |     @property | ||||||
|     def background_url(self) -> str: |     def background_url(self) -> str: | ||||||
|         """Get the URL to the background image. If the name is /static or starts with http |         """Get the URL to the background image. If the name is /static or starts with http | ||||||
| @ -157,23 +170,6 @@ class Flow(SerializerModel, PolicyBindingModel): | |||||||
|  |  | ||||||
|         return FlowSerializer |         return FlowSerializer | ||||||
|  |  | ||||||
|     @staticmethod |  | ||||||
|     def with_policy(request: HttpRequest, **flow_filter) -> Optional["Flow"]: |  | ||||||
|         """Get a Flow by `**flow_filter` and check if the request from `request` can access it.""" |  | ||||||
|         from authentik.policies.engine import PolicyEngine |  | ||||||
|  |  | ||||||
|         flows = Flow.objects.filter(**flow_filter).order_by("slug") |  | ||||||
|         for flow in flows: |  | ||||||
|             engine = PolicyEngine(flow, request.user, request) |  | ||||||
|             engine.build() |  | ||||||
|             result = engine.result |  | ||||||
|             if result.passing: |  | ||||||
|                 LOGGER.debug("with_policy: flow passing", flow=flow) |  | ||||||
|                 return flow |  | ||||||
|             LOGGER.warning("with_policy: flow not passing", flow=flow, messages=result.messages) |  | ||||||
|         LOGGER.debug("with_policy: no flow found", filters=flow_filter) |  | ||||||
|         return None |  | ||||||
|  |  | ||||||
|     def __str__(self) -> str: |     def __str__(self) -> str: | ||||||
|         return f"Flow {self.name} ({self.slug})" |         return f"Flow {self.name} ({self.slug})" | ||||||
|  |  | ||||||
|  | |||||||
| @ -6,14 +6,21 @@ from django.test.client import RequestFactory | |||||||
| from django.urls import reverse | from django.urls import reverse | ||||||
|  |  | ||||||
| from authentik.core.models import User | from authentik.core.models import User | ||||||
|  | from authentik.core.tests.utils import create_test_flow | ||||||
| from authentik.flows.exceptions import FlowNonApplicableException | from authentik.flows.exceptions import FlowNonApplicableException | ||||||
| from authentik.flows.markers import ReevaluateMarker, StageMarker | from authentik.flows.markers import ReevaluateMarker, StageMarker | ||||||
| from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding, InvalidResponseAction | from authentik.flows.models import ( | ||||||
|  |     FlowDeniedAction, | ||||||
|  |     FlowDesignation, | ||||||
|  |     FlowStageBinding, | ||||||
|  |     InvalidResponseAction, | ||||||
|  | ) | ||||||
| from authentik.flows.planner import FlowPlan, FlowPlanner | from authentik.flows.planner import FlowPlan, FlowPlanner | ||||||
| from authentik.flows.stage import PLAN_CONTEXT_PENDING_USER_IDENTIFIER, StageView | from authentik.flows.stage import PLAN_CONTEXT_PENDING_USER_IDENTIFIER, StageView | ||||||
| from authentik.flows.tests import FlowTestCase | from authentik.flows.tests import FlowTestCase | ||||||
| from authentik.flows.views.executor import NEXT_ARG_NAME, SESSION_KEY_PLAN, FlowExecutorView | from authentik.flows.views.executor import NEXT_ARG_NAME, SESSION_KEY_PLAN, FlowExecutorView | ||||||
| from authentik.lib.config import CONFIG | from authentik.lib.config import CONFIG | ||||||
|  | from authentik.lib.generators import generate_id | ||||||
| from authentik.policies.dummy.models import DummyPolicy | from authentik.policies.dummy.models import DummyPolicy | ||||||
| from authentik.policies.models import PolicyBinding | from authentik.policies.models import PolicyBinding | ||||||
| from authentik.policies.reputation.models import ReputationPolicy | from authentik.policies.reputation.models import ReputationPolicy | ||||||
| @ -47,12 +54,10 @@ class TestFlowExecutor(FlowTestCase): | |||||||
|     ) |     ) | ||||||
|     def test_existing_plan_diff_flow(self): |     def test_existing_plan_diff_flow(self): | ||||||
|         """Check that a plan for a different flow cancels the current plan""" |         """Check that a plan for a different flow cancels the current plan""" | ||||||
|         flow = Flow.objects.create( |         flow = create_test_flow( | ||||||
|             name="test-existing-plan-diff", |             FlowDesignation.AUTHENTICATION, | ||||||
|             slug="test-existing-plan-diff", |  | ||||||
|             designation=FlowDesignation.AUTHENTICATION, |  | ||||||
|         ) |         ) | ||||||
|         stage = DummyStage.objects.create(name="dummy") |         stage = DummyStage.objects.create(name=generate_id()) | ||||||
|         binding = FlowStageBinding(target=flow, stage=stage, order=0) |         binding = FlowStageBinding(target=flow, stage=stage, order=0) | ||||||
|         plan = FlowPlan(flow_pk=flow.pk.hex + "a", bindings=[binding], markers=[StageMarker()]) |         plan = FlowPlan(flow_pk=flow.pk.hex + "a", bindings=[binding], markers=[StageMarker()]) | ||||||
|         session = self.client.session |         session = self.client.session | ||||||
| @ -77,10 +82,8 @@ class TestFlowExecutor(FlowTestCase): | |||||||
|     ) |     ) | ||||||
|     def test_invalid_non_applicable_flow(self): |     def test_invalid_non_applicable_flow(self): | ||||||
|         """Tests that a non-applicable flow returns the correct error message""" |         """Tests that a non-applicable flow returns the correct error message""" | ||||||
|         flow = Flow.objects.create( |         flow = create_test_flow( | ||||||
|             name="test-non-applicable", |             FlowDesignation.AUTHENTICATION, | ||||||
|             slug="test-non-applicable", |  | ||||||
|             designation=FlowDesignation.AUTHENTICATION, |  | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         CONFIG.update_from_dict({"domain": "testserver"}) |         CONFIG.update_from_dict({"domain": "testserver"}) | ||||||
| @ -98,12 +101,15 @@ class TestFlowExecutor(FlowTestCase): | |||||||
|         "authentik.flows.views.executor.to_stage_response", |         "authentik.flows.views.executor.to_stage_response", | ||||||
|         TO_STAGE_RESPONSE_MOCK, |         TO_STAGE_RESPONSE_MOCK, | ||||||
|     ) |     ) | ||||||
|     def test_invalid_empty_flow(self): |     @patch( | ||||||
|         """Tests that an empty flow returns the correct error message""" |         "authentik.policies.engine.PolicyEngine.result", | ||||||
|         flow = Flow.objects.create( |         POLICY_RETURN_FALSE, | ||||||
|             name="test-empty", |     ) | ||||||
|             slug="test-empty", |     def test_invalid_non_applicable_flow_continue(self): | ||||||
|             designation=FlowDesignation.AUTHENTICATION, |         """Tests that a non-applicable flow that should redirect""" | ||||||
|  |         flow = create_test_flow( | ||||||
|  |             FlowDesignation.AUTHENTICATION, | ||||||
|  |             denied_action=FlowDeniedAction.CONTINUE, | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         CONFIG.update_from_dict({"domain": "testserver"}) |         CONFIG.update_from_dict({"domain": "testserver"}) | ||||||
| @ -119,10 +125,8 @@ class TestFlowExecutor(FlowTestCase): | |||||||
|     ) |     ) | ||||||
|     def test_invalid_flow_redirect(self): |     def test_invalid_flow_redirect(self): | ||||||
|         """Tests that an invalid flow still redirects""" |         """Tests that an invalid flow still redirects""" | ||||||
|         flow = Flow.objects.create( |         flow = create_test_flow( | ||||||
|             name="test-empty", |             FlowDesignation.AUTHENTICATION, | ||||||
|             slug="test-empty", |  | ||||||
|             designation=FlowDesignation.AUTHENTICATION, |  | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         CONFIG.update_from_dict({"domain": "testserver"}) |         CONFIG.update_from_dict({"domain": "testserver"}) | ||||||
| @ -132,18 +136,33 @@ class TestFlowExecutor(FlowTestCase): | |||||||
|         self.assertEqual(response.status_code, 302) |         self.assertEqual(response.status_code, 302) | ||||||
|         self.assertEqual(response.url, reverse("authentik_core:root-redirect")) |         self.assertEqual(response.url, reverse("authentik_core:root-redirect")) | ||||||
|  |  | ||||||
|  |     @patch( | ||||||
|  |         "authentik.flows.views.executor.to_stage_response", | ||||||
|  |         TO_STAGE_RESPONSE_MOCK, | ||||||
|  |     ) | ||||||
|  |     def test_invalid_empty_flow(self): | ||||||
|  |         """Tests that an empty flow returns the correct error message""" | ||||||
|  |         flow = create_test_flow( | ||||||
|  |             FlowDesignation.AUTHENTICATION, | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |         CONFIG.update_from_dict({"domain": "testserver"}) | ||||||
|  |         response = self.client.get( | ||||||
|  |             reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}), | ||||||
|  |         ) | ||||||
|  |         self.assertEqual(response.status_code, 302) | ||||||
|  |         self.assertEqual(response.url, reverse("authentik_core:root-redirect")) | ||||||
|  |  | ||||||
|     def test_multi_stage_flow(self): |     def test_multi_stage_flow(self): | ||||||
|         """Test a full flow with multiple stages""" |         """Test a full flow with multiple stages""" | ||||||
|         flow = Flow.objects.create( |         flow = create_test_flow( | ||||||
|             name="test-full", |             FlowDesignation.AUTHENTICATION, | ||||||
|             slug="test-full", |  | ||||||
|             designation=FlowDesignation.AUTHENTICATION, |  | ||||||
|         ) |         ) | ||||||
|         FlowStageBinding.objects.create( |         FlowStageBinding.objects.create( | ||||||
|             target=flow, stage=DummyStage.objects.create(name="dummy1"), order=0 |             target=flow, stage=DummyStage.objects.create(name=generate_id()), order=0 | ||||||
|         ) |         ) | ||||||
|         FlowStageBinding.objects.create( |         FlowStageBinding.objects.create( | ||||||
|             target=flow, stage=DummyStage.objects.create(name="dummy2"), order=1 |             target=flow, stage=DummyStage.objects.create(name=generate_id()), order=1 | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         exec_url = reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}) |         exec_url = reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}) | ||||||
| @ -170,19 +189,19 @@ class TestFlowExecutor(FlowTestCase): | |||||||
|     ) |     ) | ||||||
|     def test_reevaluate_remove_last(self): |     def test_reevaluate_remove_last(self): | ||||||
|         """Test planner with re-evaluate (last stage is removed)""" |         """Test planner with re-evaluate (last stage is removed)""" | ||||||
|         flow = Flow.objects.create( |         flow = create_test_flow( | ||||||
|             name="test-default-context", |             FlowDesignation.AUTHENTICATION, | ||||||
|             slug="test-default-context", |         ) | ||||||
|             designation=FlowDesignation.AUTHENTICATION, |         false_policy = DummyPolicy.objects.create( | ||||||
|  |             name=generate_id(), result=False, wait_min=1, wait_max=2 | ||||||
|         ) |         ) | ||||||
|         false_policy = DummyPolicy.objects.create(result=False, wait_min=1, wait_max=2) |  | ||||||
|  |  | ||||||
|         binding = FlowStageBinding.objects.create( |         binding = FlowStageBinding.objects.create( | ||||||
|             target=flow, stage=DummyStage.objects.create(name="dummy1"), order=0 |             target=flow, stage=DummyStage.objects.create(name=generate_id()), order=0 | ||||||
|         ) |         ) | ||||||
|         binding2 = FlowStageBinding.objects.create( |         binding2 = FlowStageBinding.objects.create( | ||||||
|             target=flow, |             target=flow, | ||||||
|             stage=DummyStage.objects.create(name="dummy2"), |             stage=DummyStage.objects.create(name=generate_id()), | ||||||
|             order=1, |             order=1, | ||||||
|             re_evaluate_policies=True, |             re_evaluate_policies=True, | ||||||
|         ) |         ) | ||||||
| @ -217,24 +236,24 @@ class TestFlowExecutor(FlowTestCase): | |||||||
|  |  | ||||||
|     def test_reevaluate_remove_middle(self): |     def test_reevaluate_remove_middle(self): | ||||||
|         """Test planner with re-evaluate (middle stage is removed)""" |         """Test planner with re-evaluate (middle stage is removed)""" | ||||||
|         flow = Flow.objects.create( |         flow = create_test_flow( | ||||||
|             name="test-default-context", |             FlowDesignation.AUTHENTICATION, | ||||||
|             slug="test-default-context", |         ) | ||||||
|             designation=FlowDesignation.AUTHENTICATION, |         false_policy = DummyPolicy.objects.create( | ||||||
|  |             name=generate_id(), result=False, wait_min=1, wait_max=2 | ||||||
|         ) |         ) | ||||||
|         false_policy = DummyPolicy.objects.create(result=False, wait_min=1, wait_max=2) |  | ||||||
|  |  | ||||||
|         binding = FlowStageBinding.objects.create( |         binding = FlowStageBinding.objects.create( | ||||||
|             target=flow, stage=DummyStage.objects.create(name="dummy1"), order=0 |             target=flow, stage=DummyStage.objects.create(name=generate_id()), order=0 | ||||||
|         ) |         ) | ||||||
|         binding2 = FlowStageBinding.objects.create( |         binding2 = FlowStageBinding.objects.create( | ||||||
|             target=flow, |             target=flow, | ||||||
|             stage=DummyStage.objects.create(name="dummy2"), |             stage=DummyStage.objects.create(name=generate_id()), | ||||||
|             order=1, |             order=1, | ||||||
|             re_evaluate_policies=True, |             re_evaluate_policies=True, | ||||||
|         ) |         ) | ||||||
|         binding3 = FlowStageBinding.objects.create( |         binding3 = FlowStageBinding.objects.create( | ||||||
|             target=flow, stage=DummyStage.objects.create(name="dummy3"), order=2 |             target=flow, stage=DummyStage.objects.create(name=generate_id()), order=2 | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         PolicyBinding.objects.create(policy=false_policy, target=binding2, order=0) |         PolicyBinding.objects.create(policy=false_policy, target=binding2, order=0) | ||||||
| @ -277,24 +296,24 @@ class TestFlowExecutor(FlowTestCase): | |||||||
|  |  | ||||||
|     def test_reevaluate_keep(self): |     def test_reevaluate_keep(self): | ||||||
|         """Test planner with re-evaluate (everything is kept)""" |         """Test planner with re-evaluate (everything is kept)""" | ||||||
|         flow = Flow.objects.create( |         flow = create_test_flow( | ||||||
|             name="test-default-context", |             FlowDesignation.AUTHENTICATION, | ||||||
|             slug="test-default-context", |         ) | ||||||
|             designation=FlowDesignation.AUTHENTICATION, |         true_policy = DummyPolicy.objects.create( | ||||||
|  |             name=generate_id(), result=True, wait_min=1, wait_max=2 | ||||||
|         ) |         ) | ||||||
|         true_policy = DummyPolicy.objects.create(result=True, wait_min=1, wait_max=2) |  | ||||||
|  |  | ||||||
|         binding = FlowStageBinding.objects.create( |         binding = FlowStageBinding.objects.create( | ||||||
|             target=flow, stage=DummyStage.objects.create(name="dummy1"), order=0 |             target=flow, stage=DummyStage.objects.create(name=generate_id()), order=0 | ||||||
|         ) |         ) | ||||||
|         binding2 = FlowStageBinding.objects.create( |         binding2 = FlowStageBinding.objects.create( | ||||||
|             target=flow, |             target=flow, | ||||||
|             stage=DummyStage.objects.create(name="dummy2"), |             stage=DummyStage.objects.create(name=generate_id()), | ||||||
|             order=1, |             order=1, | ||||||
|             re_evaluate_policies=True, |             re_evaluate_policies=True, | ||||||
|         ) |         ) | ||||||
|         binding3 = FlowStageBinding.objects.create( |         binding3 = FlowStageBinding.objects.create( | ||||||
|             target=flow, stage=DummyStage.objects.create(name="dummy3"), order=2 |             target=flow, stage=DummyStage.objects.create(name=generate_id()), order=2 | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         PolicyBinding.objects.create(policy=true_policy, target=binding2, order=0) |         PolicyBinding.objects.create(policy=true_policy, target=binding2, order=0) | ||||||
| @ -347,30 +366,30 @@ class TestFlowExecutor(FlowTestCase): | |||||||
|  |  | ||||||
|     def test_reevaluate_remove_consecutive(self): |     def test_reevaluate_remove_consecutive(self): | ||||||
|         """Test planner with re-evaluate (consecutive stages are removed)""" |         """Test planner with re-evaluate (consecutive stages are removed)""" | ||||||
|         flow = Flow.objects.create( |         flow = create_test_flow( | ||||||
|             name="test-default-context", |             FlowDesignation.AUTHENTICATION, | ||||||
|             slug="test-default-context", |         ) | ||||||
|             designation=FlowDesignation.AUTHENTICATION, |         false_policy = DummyPolicy.objects.create( | ||||||
|  |             name=generate_id(), result=False, wait_min=1, wait_max=2 | ||||||
|         ) |         ) | ||||||
|         false_policy = DummyPolicy.objects.create(result=False, wait_min=1, wait_max=2) |  | ||||||
|  |  | ||||||
|         binding = FlowStageBinding.objects.create( |         binding = FlowStageBinding.objects.create( | ||||||
|             target=flow, stage=DummyStage.objects.create(name="dummy1"), order=0 |             target=flow, stage=DummyStage.objects.create(name=generate_id()), order=0 | ||||||
|         ) |         ) | ||||||
|         binding2 = FlowStageBinding.objects.create( |         binding2 = FlowStageBinding.objects.create( | ||||||
|             target=flow, |             target=flow, | ||||||
|             stage=DummyStage.objects.create(name="dummy2"), |             stage=DummyStage.objects.create(name=generate_id()), | ||||||
|             order=1, |             order=1, | ||||||
|             re_evaluate_policies=True, |             re_evaluate_policies=True, | ||||||
|         ) |         ) | ||||||
|         binding3 = FlowStageBinding.objects.create( |         binding3 = FlowStageBinding.objects.create( | ||||||
|             target=flow, |             target=flow, | ||||||
|             stage=DummyStage.objects.create(name="dummy3"), |             stage=DummyStage.objects.create(name=generate_id()), | ||||||
|             order=2, |             order=2, | ||||||
|             re_evaluate_policies=True, |             re_evaluate_policies=True, | ||||||
|         ) |         ) | ||||||
|         binding4 = FlowStageBinding.objects.create( |         binding4 = FlowStageBinding.objects.create( | ||||||
|             target=flow, stage=DummyStage.objects.create(name="dummy4"), order=2 |             target=flow, stage=DummyStage.objects.create(name=generate_id()), order=2 | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         PolicyBinding.objects.create(policy=false_policy, target=binding2, order=0) |         PolicyBinding.objects.create(policy=false_policy, target=binding2, order=0) | ||||||
| @ -415,13 +434,11 @@ class TestFlowExecutor(FlowTestCase): | |||||||
|  |  | ||||||
|     def test_stageview_user_identifier(self): |     def test_stageview_user_identifier(self): | ||||||
|         """Test PLAN_CONTEXT_PENDING_USER_IDENTIFIER""" |         """Test PLAN_CONTEXT_PENDING_USER_IDENTIFIER""" | ||||||
|         flow = Flow.objects.create( |         flow = create_test_flow( | ||||||
|             name="test-default-context", |             FlowDesignation.AUTHENTICATION, | ||||||
|             slug="test-default-context", |  | ||||||
|             designation=FlowDesignation.AUTHENTICATION, |  | ||||||
|         ) |         ) | ||||||
|         FlowStageBinding.objects.create( |         FlowStageBinding.objects.create( | ||||||
|             target=flow, stage=DummyStage.objects.create(name="dummy"), order=0 |             target=flow, stage=DummyStage.objects.create(name=generate_id()), order=0 | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         ident = "test-identifier" |         ident = "test-identifier" | ||||||
| @ -443,10 +460,8 @@ class TestFlowExecutor(FlowTestCase): | |||||||
|  |  | ||||||
|     def test_invalid_restart(self): |     def test_invalid_restart(self): | ||||||
|         """Test flow that restarts on invalid entry""" |         """Test flow that restarts on invalid entry""" | ||||||
|         flow = Flow.objects.create( |         flow = create_test_flow( | ||||||
|             name="restart-on-invalid", |             FlowDesignation.AUTHENTICATION, | ||||||
|             slug="restart-on-invalid", |  | ||||||
|             designation=FlowDesignation.AUTHENTICATION, |  | ||||||
|         ) |         ) | ||||||
|         # Stage 0 is a deny stage that is added dynamically |         # Stage 0 is a deny stage that is added dynamically | ||||||
|         # when the reputation policy says so |         # when the reputation policy says so | ||||||
|  | |||||||
| @ -10,6 +10,7 @@ from django.http import Http404, HttpRequest, HttpResponse, HttpResponseRedirect | |||||||
| from django.http.request import QueryDict | from django.http.request import QueryDict | ||||||
| from django.shortcuts import get_object_or_404, redirect | from django.shortcuts import get_object_or_404, redirect | ||||||
| from django.template.response import TemplateResponse | from django.template.response import TemplateResponse | ||||||
|  | from django.urls import reverse | ||||||
| from django.utils.decorators import method_decorator | from django.utils.decorators import method_decorator | ||||||
| from django.views.decorators.clickjacking import xframe_options_sameorigin | from django.views.decorators.clickjacking import xframe_options_sameorigin | ||||||
| from django.views.generic import View | from django.views.generic import View | ||||||
| @ -37,6 +38,7 @@ from authentik.flows.exceptions import EmptyFlowException, FlowNonApplicableExce | |||||||
| from authentik.flows.models import ( | from authentik.flows.models import ( | ||||||
|     ConfigurableStage, |     ConfigurableStage, | ||||||
|     Flow, |     Flow, | ||||||
|  |     FlowDeniedAction, | ||||||
|     FlowDesignation, |     FlowDesignation, | ||||||
|     FlowStageBinding, |     FlowStageBinding, | ||||||
|     FlowToken, |     FlowToken, | ||||||
| @ -54,6 +56,7 @@ from authentik.lib.sentry import SentryIgnoredException | |||||||
| from authentik.lib.utils.errors import exception_to_string | from authentik.lib.utils.errors import exception_to_string | ||||||
| from authentik.lib.utils.reflection import all_subclasses, class_to_path | from authentik.lib.utils.reflection import all_subclasses, class_to_path | ||||||
| from authentik.lib.utils.urls import is_url_absolute, redirect_with_qs | from authentik.lib.utils.urls import is_url_absolute, redirect_with_qs | ||||||
|  | from authentik.policies.engine import PolicyEngine | ||||||
| from authentik.tenants.models import Tenant | from authentik.tenants.models import Tenant | ||||||
|  |  | ||||||
| LOGGER = get_logger() | LOGGER = get_logger() | ||||||
| @ -131,12 +134,20 @@ class FlowExecutorView(APIView): | |||||||
|  |  | ||||||
|     def handle_invalid_flow(self, exc: BaseException) -> HttpResponse: |     def handle_invalid_flow(self, exc: BaseException) -> HttpResponse: | ||||||
|         """When a flow is non-applicable check if user is on the correct domain""" |         """When a flow is non-applicable check if user is on the correct domain""" | ||||||
|         if NEXT_ARG_NAME in self.request.GET: |         if self.flow.denied_action in [ | ||||||
|             if not is_url_absolute(self.request.GET.get(NEXT_ARG_NAME)): |             FlowDeniedAction.CONTINUE, | ||||||
|  |             FlowDeniedAction.MESSAGE_CONTINUE, | ||||||
|  |         ]: | ||||||
|  |             next_url = self.request.GET.get(NEXT_ARG_NAME) | ||||||
|  |             if next_url and not is_url_absolute(next_url): | ||||||
|                 self._logger.debug("f(exec): Redirecting to next on fail") |                 self._logger.debug("f(exec): Redirecting to next on fail") | ||||||
|                 return redirect(self.request.GET.get(NEXT_ARG_NAME)) |                 return to_stage_response(self.request, redirect(next_url)) | ||||||
|  |         if self.flow.denied_action == FlowDeniedAction.CONTINUE: | ||||||
|  |             return to_stage_response( | ||||||
|  |                 self.request, redirect(reverse("authentik_core:root-redirect")) | ||||||
|  |             ) | ||||||
|         message = exc.__doc__ if exc.__doc__ else str(exc) |         message = exc.__doc__ if exc.__doc__ else str(exc) | ||||||
|         return self.stage_invalid(error_message=message) |         return to_stage_response(self.request, self.stage_invalid(error_message=message)) | ||||||
|  |  | ||||||
|     def _check_flow_token(self, key: str) -> Optional[FlowPlan]: |     def _check_flow_token(self, key: str) -> Optional[FlowPlan]: | ||||||
|         """Check if the user is using a flow token to restore a plan""" |         """Check if the user is using a flow token to restore a plan""" | ||||||
| @ -187,7 +198,7 @@ class FlowExecutorView(APIView): | |||||||
|                     self.plan = self._initiate_plan() |                     self.plan = self._initiate_plan() | ||||||
|                 except FlowNonApplicableException as exc: |                 except FlowNonApplicableException as exc: | ||||||
|                     self._logger.warning("f(exec): Flow not applicable to current user", exc=exc) |                     self._logger.warning("f(exec): Flow not applicable to current user", exc=exc) | ||||||
|                     return to_stage_response(self.request, self.handle_invalid_flow(exc)) |                     return self.handle_invalid_flow(exc) | ||||||
|                 except EmptyFlowException as exc: |                 except EmptyFlowException as exc: | ||||||
|                     self._logger.warning("f(exec): Flow is empty", exc=exc) |                     self._logger.warning("f(exec): Flow is empty", exc=exc) | ||||||
|                     # To match behaviour with loading an empty flow plan from cache, |                     # To match behaviour with loading an empty flow plan from cache, | ||||||
| @ -470,6 +481,20 @@ class ToDefaultFlow(View): | |||||||
|  |  | ||||||
|     designation: Optional[FlowDesignation] = None |     designation: Optional[FlowDesignation] = None | ||||||
|  |  | ||||||
|  |     def flow_by_policy(self, request: HttpRequest, **flow_filter) -> Optional[Flow]: | ||||||
|  |         """Get a Flow by `**flow_filter` and check if the request from `request` can access it.""" | ||||||
|  |         flows = Flow.objects.filter(**flow_filter).order_by("slug") | ||||||
|  |         for flow in flows: | ||||||
|  |             engine = PolicyEngine(flow, request.user, request) | ||||||
|  |             engine.build() | ||||||
|  |             result = engine.result | ||||||
|  |             if result.passing: | ||||||
|  |                 LOGGER.debug("flow_by_policy: flow passing", flow=flow) | ||||||
|  |                 return flow | ||||||
|  |             LOGGER.warning("flow_by_policy: flow not passing", flow=flow, messages=result.messages) | ||||||
|  |         LOGGER.debug("flow_by_policy: no flow found", filters=flow_filter) | ||||||
|  |         return None | ||||||
|  |  | ||||||
|     def dispatch(self, request: HttpRequest) -> HttpResponse: |     def dispatch(self, request: HttpRequest) -> HttpResponse: | ||||||
|         tenant: Tenant = request.tenant |         tenant: Tenant = request.tenant | ||||||
|         flow = None |         flow = None | ||||||
| @ -480,7 +505,7 @@ class ToDefaultFlow(View): | |||||||
|             flow = tenant.flow_invalidation |             flow = tenant.flow_invalidation | ||||||
|         # If no flow was set, get the first based on slug and policy |         # If no flow was set, get the first based on slug and policy | ||||||
|         if not flow: |         if not flow: | ||||||
|             flow = Flow.with_policy(request, designation=self.designation) |             flow = self.flow_by_policy(request, designation=self.designation) | ||||||
|         # If we still don't have a flow, 404 |         # If we still don't have a flow, 404 | ||||||
|         if not flow: |         if not flow: | ||||||
|             raise Http404 |             raise Http404 | ||||||
|  | |||||||
| @ -1,10 +1,18 @@ | |||||||
| """error utils""" | """error utils""" | ||||||
| from traceback import format_tb | from traceback import extract_tb | ||||||
|  |  | ||||||
| TRACEBACK_HEADER = "Traceback (most recent call last):\n" | from authentik.lib.utils.reflection import class_to_path | ||||||
|  |  | ||||||
|  | TRACEBACK_HEADER = "Traceback (most recent call last):" | ||||||
|  |  | ||||||
|  |  | ||||||
| def exception_to_string(exc: Exception) -> str: | def exception_to_string(exc: Exception) -> str: | ||||||
|     """Convert exception to string stackrace""" |     """Convert exception to string stackrace""" | ||||||
|     # Either use passed original exception or whatever we have |     # Either use passed original exception or whatever we have | ||||||
|     return TRACEBACK_HEADER + "".join(format_tb(exc.__traceback__)) + str(exc) |     return "\n".join( | ||||||
|  |         [ | ||||||
|  |             TRACEBACK_HEADER, | ||||||
|  |             *[x.rstrip() for x in extract_tb(exc.__traceback__).format()], | ||||||
|  |             f"{class_to_path(exc.__class__)}: {str(exc)}", | ||||||
|  |         ] | ||||||
|  |     ) | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ msgid "" | |||||||
| msgstr "" | msgstr "" | ||||||
| "Project-Id-Version: PACKAGE VERSION\n" | "Project-Id-Version: PACKAGE VERSION\n" | ||||||
| "Report-Msgid-Bugs-To: \n" | "Report-Msgid-Bugs-To: \n" | ||||||
| "POT-Creation-Date: 2022-06-30 20:17+0000\n" | "POT-Creation-Date: 2022-07-02 15:10+0000\n" | ||||||
| "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | ||||||
| "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | ||||||
| "Language-Team: LANGUAGE <LL@li.org>\n" | "Language-Team: LANGUAGE <LL@li.org>\n" | ||||||
| @ -217,7 +217,7 @@ msgid "Powered by authentik" | |||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/core/views/apps.py:48 | #: authentik/core/views/apps.py:48 | ||||||
| #: authentik/providers/oauth2/views/authorize.py:356 | #: authentik/providers/oauth2/views/authorize.py:364 | ||||||
| #: authentik/providers/saml/views/sso.py:69 | #: authentik/providers/saml/views/sso.py:69 | ||||||
| #, python-format | #, python-format | ||||||
| msgid "You're about to sign into %(application)s." | msgid "You're about to sign into %(application)s." | ||||||
| @ -336,56 +336,60 @@ msgstr "" | |||||||
| msgid "Notification Webhook Mappings" | msgid "Notification Webhook Mappings" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/events/monitored_tasks.py:197 | #: authentik/events/monitored_tasks.py:191 | ||||||
| msgid "Task has not been run yet." | msgid "Task has not been run yet." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/flows/api/flows.py:227 authentik/flows/api/flows.py:249 | #: authentik/flows/api/flows.py:228 authentik/flows/api/flows.py:250 | ||||||
| #, python-format | #, python-format | ||||||
| msgid "Policy (%(type)s)" | msgid "Policy (%(type)s)" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/flows/api/flows.py:258 | #: authentik/flows/api/flows.py:259 | ||||||
| #, python-format | #, python-format | ||||||
| msgid "Stage (%(type)s)" | msgid "Stage (%(type)s)" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/flows/api/flows.py:373 | #: authentik/flows/api/flows.py:374 | ||||||
| #, python-format | #, python-format | ||||||
| msgid "Flow not applicable to current user/request: %(messages)s" | msgid "Flow not applicable to current user/request: %(messages)s" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/flows/models.py:108 | #: authentik/flows/models.py:117 | ||||||
| msgid "Visible in the URL." | msgid "Visible in the URL." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/flows/models.py:110 | #: authentik/flows/models.py:119 | ||||||
| msgid "Shown as the Title in Flow pages." | msgid "Shown as the Title in Flow pages." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/flows/models.py:128 | #: authentik/flows/models.py:137 | ||||||
| msgid "Background shown during execution" | msgid "Background shown during execution" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/flows/models.py:135 | #: authentik/flows/models.py:144 | ||||||
| msgid "" | msgid "" | ||||||
| "Enable compatibility mode, increases compatibility with password managers on " | "Enable compatibility mode, increases compatibility with password managers on " | ||||||
| "mobile devices." | "mobile devices." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/flows/models.py:180 | #: authentik/flows/models.py:152 | ||||||
|  | msgid "Configure what should happen when a flow denies access to a user." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
|  | #: authentik/flows/models.py:178 | ||||||
| msgid "Flow" | msgid "Flow" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/flows/models.py:181 | #: authentik/flows/models.py:179 | ||||||
| msgid "Flows" | msgid "Flows" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/flows/models.py:211 | #: authentik/flows/models.py:209 | ||||||
| msgid "Evaluate policies when the Stage is present to the user." | msgid "Evaluate policies when the Stage is present to the user." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/flows/models.py:218 | #: authentik/flows/models.py:216 | ||||||
| msgid "" | msgid "" | ||||||
| "Configure how the flow executor should handle an invalid response to a " | "Configure how the flow executor should handle an invalid response to a " | ||||||
| "challenge. RETRY returns the error message and a similar challenge to the " | "challenge. RETRY returns the error message and a similar challenge to the " | ||||||
| @ -393,19 +397,19 @@ msgid "" | |||||||
| "RESTART_WITH_CONTEXT restarts the flow while keeping the current context." | "RESTART_WITH_CONTEXT restarts the flow while keeping the current context." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/flows/models.py:242 | #: authentik/flows/models.py:240 | ||||||
| msgid "Flow Stage Binding" | msgid "Flow Stage Binding" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/flows/models.py:243 | #: authentik/flows/models.py:241 | ||||||
| msgid "Flow Stage Bindings" | msgid "Flow Stage Bindings" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/flows/models.py:293 | #: authentik/flows/models.py:291 | ||||||
| msgid "Flow Token" | msgid "Flow Token" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/flows/models.py:294 | #: authentik/flows/models.py:292 | ||||||
| msgid "Flow Tokens" | msgid "Flow Tokens" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| @ -833,7 +837,7 @@ msgstr "" | |||||||
| msgid "OAuth2 Tokens" | msgid "OAuth2 Tokens" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/providers/oauth2/views/authorize.py:410 | #: authentik/providers/oauth2/views/authorize.py:418 | ||||||
| #: authentik/providers/saml/views/flows.py:86 | #: authentik/providers/saml/views/flows.py:86 | ||||||
| #, python-format | #, python-format | ||||||
| msgid "Redirecting to %(app)s..." | msgid "Redirecting to %(app)s..." | ||||||
| @ -856,42 +860,42 @@ msgstr "" | |||||||
| msgid "authentik API Access on behalf of your user" | msgid "authentik API Access on behalf of your user" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/providers/proxy/models.py:52 | #: authentik/providers/proxy/models.py:47 | ||||||
| msgid "Validate SSL Certificates of upstream servers" | msgid "Validate SSL Certificates of upstream servers" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/providers/proxy/models.py:53 | #: authentik/providers/proxy/models.py:48 | ||||||
| msgid "Internal host SSL Validation" | msgid "Internal host SSL Validation" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/providers/proxy/models.py:59 | #: authentik/providers/proxy/models.py:54 | ||||||
| msgid "" | msgid "" | ||||||
| "Enable support for forwardAuth in traefik and nginx auth_request. Exclusive " | "Enable support for forwardAuth in traefik and nginx auth_request. Exclusive " | ||||||
| "with internal_host." | "with internal_host." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/providers/proxy/models.py:77 | #: authentik/providers/proxy/models.py:72 | ||||||
| msgid "Set HTTP-Basic Authentication" | msgid "Set HTTP-Basic Authentication" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/providers/proxy/models.py:79 | #: authentik/providers/proxy/models.py:74 | ||||||
| msgid "" | msgid "" | ||||||
| "Set a custom HTTP-Basic Authentication header based on values from authentik." | "Set a custom HTTP-Basic Authentication header based on values from authentik." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/providers/proxy/models.py:84 | #: authentik/providers/proxy/models.py:79 | ||||||
| msgid "HTTP-Basic Username Key" | msgid "HTTP-Basic Username Key" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/providers/proxy/models.py:94 | #: authentik/providers/proxy/models.py:89 | ||||||
| msgid "HTTP-Basic Password Key" | msgid "HTTP-Basic Password Key" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/providers/proxy/models.py:149 | #: authentik/providers/proxy/models.py:144 | ||||||
| msgid "Proxy Provider" | msgid "Proxy Provider" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/providers/proxy/models.py:150 | #: authentik/providers/proxy/models.py:145 | ||||||
| msgid "Proxy Providers" | msgid "Proxy Providers" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| @ -996,77 +1000,77 @@ msgstr "" | |||||||
| msgid "Used recovery-link to authenticate." | msgid "Used recovery-link to authenticate." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/sources/ldap/models.py:32 | #: authentik/sources/ldap/models.py:33 | ||||||
| msgid "Server URI" | msgid "Server URI" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/sources/ldap/models.py:40 | #: authentik/sources/ldap/models.py:41 | ||||||
| msgid "" | msgid "" | ||||||
| "Optionally verify the LDAP Server's Certificate against the CA Chain in this " | "Optionally verify the LDAP Server's Certificate against the CA Chain in this " | ||||||
| "keypair." | "keypair." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/sources/ldap/models.py:45 | #: authentik/sources/ldap/models.py:46 | ||||||
| msgid "Bind CN" | msgid "Bind CN" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/sources/ldap/models.py:47 | #: authentik/sources/ldap/models.py:48 | ||||||
| msgid "Enable Start TLS" | msgid "Enable Start TLS" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/sources/ldap/models.py:49 | #: authentik/sources/ldap/models.py:50 | ||||||
| msgid "Base DN" | msgid "Base DN" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/sources/ldap/models.py:51 | #: authentik/sources/ldap/models.py:52 | ||||||
| msgid "Prepended to Base DN for User-queries." | msgid "Prepended to Base DN for User-queries." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/sources/ldap/models.py:52 | #: authentik/sources/ldap/models.py:53 | ||||||
| msgid "Addition User DN" | msgid "Addition User DN" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/sources/ldap/models.py:56 | #: authentik/sources/ldap/models.py:57 | ||||||
| msgid "Prepended to Base DN for Group-queries." | msgid "Prepended to Base DN for Group-queries." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/sources/ldap/models.py:57 | #: authentik/sources/ldap/models.py:58 | ||||||
| msgid "Addition Group DN" | msgid "Addition Group DN" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/sources/ldap/models.py:63 | #: authentik/sources/ldap/models.py:64 | ||||||
| msgid "Consider Objects matching this filter to be Users." | msgid "Consider Objects matching this filter to be Users." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/sources/ldap/models.py:66 | #: authentik/sources/ldap/models.py:67 | ||||||
| msgid "Field which contains members of a group." | msgid "Field which contains members of a group." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/sources/ldap/models.py:70 | #: authentik/sources/ldap/models.py:71 | ||||||
| msgid "Consider Objects matching this filter to be Groups." | msgid "Consider Objects matching this filter to be Groups." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/sources/ldap/models.py:73 | #: authentik/sources/ldap/models.py:74 | ||||||
| msgid "Field which contains a unique Identifier." | msgid "Field which contains a unique Identifier." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/sources/ldap/models.py:80 | #: authentik/sources/ldap/models.py:81 | ||||||
| msgid "Property mappings used for group creation/updating." | msgid "Property mappings used for group creation/updating." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/sources/ldap/models.py:145 | #: authentik/sources/ldap/models.py:149 | ||||||
| msgid "LDAP Source" | msgid "LDAP Source" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/sources/ldap/models.py:146 | #: authentik/sources/ldap/models.py:150 | ||||||
| msgid "LDAP Sources" | msgid "LDAP Sources" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/sources/ldap/models.py:169 | #: authentik/sources/ldap/models.py:173 | ||||||
| msgid "LDAP Property Mapping" | msgid "LDAP Property Mapping" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: authentik/sources/ldap/models.py:170 | #: authentik/sources/ldap/models.py:174 | ||||||
| msgid "LDAP Property Mappings" | msgid "LDAP Property Mappings" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
|  | |||||||
							
								
								
									
										30
									
								
								schema.yml
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								schema.yml
									
									
									
									
									
								
							| @ -5140,6 +5140,15 @@ paths: | |||||||
|       operationId: flows_instances_list |       operationId: flows_instances_list | ||||||
|       description: Flow Viewset |       description: Flow Viewset | ||||||
|       parameters: |       parameters: | ||||||
|  |       - in: query | ||||||
|  |         name: denied_action | ||||||
|  |         schema: | ||||||
|  |           type: string | ||||||
|  |           enum: | ||||||
|  |           - continue | ||||||
|  |           - message | ||||||
|  |           - message_continue | ||||||
|  |         description: Configure what should happen when a flow denies access to a user. | ||||||
|       - in: query |       - in: query | ||||||
|         name: designation |         name: designation | ||||||
|         schema: |         schema: | ||||||
| @ -20656,6 +20665,12 @@ components: | |||||||
|       - branding_title |       - branding_title | ||||||
|       - matched_domain |       - matched_domain | ||||||
|       - ui_footer_links |       - ui_footer_links | ||||||
|  |     DeniedActionEnum: | ||||||
|  |       enum: | ||||||
|  |       - message_continue | ||||||
|  |       - message | ||||||
|  |       - continue | ||||||
|  |       type: string | ||||||
|     DenyStage: |     DenyStage: | ||||||
|       type: object |       type: object | ||||||
|       description: DenyStage Serializer |       description: DenyStage Serializer | ||||||
| @ -21571,6 +21586,11 @@ components: | |||||||
|           readOnly: true |           readOnly: true | ||||||
|         layout: |         layout: | ||||||
|           $ref: '#/components/schemas/LayoutEnum' |           $ref: '#/components/schemas/LayoutEnum' | ||||||
|  |         denied_action: | ||||||
|  |           allOf: | ||||||
|  |           - $ref: '#/components/schemas/DeniedActionEnum' | ||||||
|  |           description: Configure what should happen when a flow denies access to a | ||||||
|  |             user. | ||||||
|       required: |       required: | ||||||
|       - background |       - background | ||||||
|       - cache_count |       - cache_count | ||||||
| @ -21708,6 +21728,11 @@ components: | |||||||
|             managers on mobile devices. |             managers on mobile devices. | ||||||
|         layout: |         layout: | ||||||
|           $ref: '#/components/schemas/LayoutEnum' |           $ref: '#/components/schemas/LayoutEnum' | ||||||
|  |         denied_action: | ||||||
|  |           allOf: | ||||||
|  |           - $ref: '#/components/schemas/DeniedActionEnum' | ||||||
|  |           description: Configure what should happen when a flow denies access to a | ||||||
|  |             user. | ||||||
|       required: |       required: | ||||||
|       - designation |       - designation | ||||||
|       - name |       - name | ||||||
| @ -27269,6 +27294,11 @@ components: | |||||||
|             managers on mobile devices. |             managers on mobile devices. | ||||||
|         layout: |         layout: | ||||||
|           $ref: '#/components/schemas/LayoutEnum' |           $ref: '#/components/schemas/LayoutEnum' | ||||||
|  |         denied_action: | ||||||
|  |           allOf: | ||||||
|  |           - $ref: '#/components/schemas/DeniedActionEnum' | ||||||
|  |           description: Configure what should happen when a flow denies access to a | ||||||
|  |             user. | ||||||
|     PatchedFlowStageBindingRequest: |     PatchedFlowStageBindingRequest: | ||||||
|       type: object |       type: object | ||||||
|       description: FlowStageBinding Serializer |       description: FlowStageBinding Serializer | ||||||
|  | |||||||
| @ -789,6 +789,10 @@ msgstr "Standardmäßig werden für Quellen nur Symbole angezeigt. Aktiviere die | |||||||
| msgid "CA which the endpoint's Certificate is verified against. Can be left empty for no validation." | msgid "CA which the endpoint's Certificate is verified against. Can be left empty for no validation." | ||||||
| msgstr "CA, anhand derer das Zertifikat des Endpunkts überprüft wird. Kann leer gelassen werden, um keine Validierung durchzuführen." | msgstr "CA, anhand derer das Zertifikat des Endpunkts überprüft wird. Kann leer gelassen werden, um keine Validierung durchzuführen." | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "CONTINUE will either follow the ?next parameter or redirect to the default interface." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/providers/ldap/LDAPProviderForm.ts | #: src/pages/providers/ldap/LDAPProviderForm.ts | ||||||
| msgid "Cached binding, flow is executed and session is cached in memory. Flow is executed when session expires." | msgid "Cached binding, flow is executed and session is cached in memory. Flow is executed when session expires." | ||||||
| msgstr "" | msgstr "" | ||||||
| @ -1530,6 +1534,10 @@ msgstr "Deaktivieren" | |||||||
| msgid "Debug" | msgid "Debug" | ||||||
| msgstr "Debuggen" | msgstr "Debuggen" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "Decides the response when a policy denies access to this flow for a user." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/flows/FlowForm.ts | #: src/pages/flows/FlowForm.ts | ||||||
| msgid "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." | msgid "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." | ||||||
| msgstr "Entscheidet, wofür dieser Flow verwendet wird. Beispielsweise wird der Authentifizierungsablauf umgeleitet, wenn ein nicht authentifizierter Benutzer authentik besucht." | msgstr "Entscheidet, wofür dieser Flow verwendet wird. Beispielsweise wird der Authentifizierungsablauf umgeleitet, wenn ein nicht authentifizierter Benutzer authentik besucht." | ||||||
| @ -1627,6 +1635,10 @@ msgstr "" | |||||||
| msgid "Delete {0}" | msgid "Delete {0}" | ||||||
| msgstr "{0} löschen" | msgstr "{0} löschen" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "Denied action" | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts | #: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts | ||||||
| msgid "Deny the user access" | msgid "Deny the user access" | ||||||
| msgstr "Dem Benutzer den Zugang verweigern" | msgstr "Dem Benutzer den Zugang verweigern" | ||||||
| @ -3174,6 +3186,14 @@ msgstr "Logs" | |||||||
| msgid "Long-running operations which authentik executes in the background." | msgid "Long-running operations which authentik executes in the background." | ||||||
| msgstr "Langlaufende Operationen, die Authentik im Hintergrund ausführt." | msgstr "Langlaufende Operationen, die Authentik im Hintergrund ausführt." | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "MESSAGE will notify the user the flow isn't applicable." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "MESSAGE_CONTINUE will follow the ?next parameter if set, otherwise show a message." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/user/user-settings/UserSettingsPage.ts | #: src/user/user-settings/UserSettingsPage.ts | ||||||
| msgid "MFA Devices" | msgid "MFA Devices" | ||||||
| msgstr "Multifaktor-Authentifzierungs Geräte" | msgstr "Multifaktor-Authentifzierungs Geräte" | ||||||
| @ -4262,13 +4282,17 @@ msgid "Quick actions" | |||||||
| msgstr "Schnellaktionen" | msgstr "Schnellaktionen" | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RESTART restarts the flow from the beginning, while keeping the flow context." | #~ msgid "RESTART restarts the flow from the beginning, while keeping the flow context." | ||||||
| msgstr "RESTART startet den Flow von Anfang an neu, während der Flow-Kontext beibehalten wird." | #~ msgstr "RESTART startet den Flow von Anfang an neu, während der Flow-Kontext beibehalten wird." | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RESTART restarts the flow from the beginning." | msgid "RESTART restarts the flow from the beginning." | ||||||
| msgstr "RESTART startet den Flow von Anfang an neu." | msgstr "RESTART startet den Flow von Anfang an neu." | ||||||
|  |  | ||||||
|  | #: src/pages/flows/StageBindingForm.ts | ||||||
|  | msgid "RESTART_WITH_CONTEXT restarts the flow from the beginning, while keeping the flow context." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RETRY returns the error message and a similar challenge to the executor." | msgid "RETRY returns the error message and a similar challenge to the executor." | ||||||
| msgstr "RETRY gibt die Fehlermeldung und eine ähnliche Aufforderung an den Executor zurück." | msgstr "RETRY gibt die Fehlermeldung und eine ähnliche Aufforderung an den Executor zurück." | ||||||
|  | |||||||
| @ -786,6 +786,10 @@ msgstr "By default, only icons are shown for sources. Enable this to show their | |||||||
| msgid "CA which the endpoint's Certificate is verified against. Can be left empty for no validation." | msgid "CA which the endpoint's Certificate is verified against. Can be left empty for no validation." | ||||||
| msgstr "CA which the endpoint's Certificate is verified against. Can be left empty for no validation." | msgstr "CA which the endpoint's Certificate is verified against. Can be left empty for no validation." | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "CONTINUE will either follow the ?next parameter or redirect to the default interface." | ||||||
|  | msgstr "CONTINUE will either follow the ?next parameter or redirect to the default interface." | ||||||
|  |  | ||||||
| #: src/pages/providers/ldap/LDAPProviderForm.ts | #: src/pages/providers/ldap/LDAPProviderForm.ts | ||||||
| msgid "Cached binding, flow is executed and session is cached in memory. Flow is executed when session expires." | msgid "Cached binding, flow is executed and session is cached in memory. Flow is executed when session expires." | ||||||
| msgstr "Cached binding, flow is executed and session is cached in memory. Flow is executed when session expires." | msgstr "Cached binding, flow is executed and session is cached in memory. Flow is executed when session expires." | ||||||
| @ -1542,6 +1546,10 @@ msgstr "Deactivate" | |||||||
| msgid "Debug" | msgid "Debug" | ||||||
| msgstr "Debug" | msgstr "Debug" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "Decides the response when a policy denies access to this flow for a user." | ||||||
|  | msgstr "Decides the response when a policy denies access to this flow for a user." | ||||||
|  |  | ||||||
| #: src/pages/flows/FlowForm.ts | #: src/pages/flows/FlowForm.ts | ||||||
| msgid "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." | msgid "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." | ||||||
| msgstr "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." | msgstr "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." | ||||||
| @ -1645,6 +1653,10 @@ msgstr "" | |||||||
| msgid "Delete {0}" | msgid "Delete {0}" | ||||||
| msgstr "Delete {0}" | msgstr "Delete {0}" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "Denied action" | ||||||
|  | msgstr "Denied action" | ||||||
|  |  | ||||||
| #: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts | #: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts | ||||||
| msgid "Deny the user access" | msgid "Deny the user access" | ||||||
| msgstr "Deny the user access" | msgstr "Deny the user access" | ||||||
| @ -3226,6 +3238,14 @@ msgstr "Logs" | |||||||
| msgid "Long-running operations which authentik executes in the background." | msgid "Long-running operations which authentik executes in the background." | ||||||
| msgstr "Long-running operations which authentik executes in the background." | msgstr "Long-running operations which authentik executes in the background." | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "MESSAGE will notify the user the flow isn't applicable." | ||||||
|  | msgstr "MESSAGE will notify the user the flow isn't applicable." | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "MESSAGE_CONTINUE will follow the ?next parameter if set, otherwise show a message." | ||||||
|  | msgstr "MESSAGE_CONTINUE will follow the ?next parameter if set, otherwise show a message." | ||||||
|  |  | ||||||
| #: src/user/user-settings/UserSettingsPage.ts | #: src/user/user-settings/UserSettingsPage.ts | ||||||
| msgid "MFA Devices" | msgid "MFA Devices" | ||||||
| msgstr "MFA Devices" | msgstr "MFA Devices" | ||||||
| @ -4332,13 +4352,17 @@ msgid "Quick actions" | |||||||
| msgstr "Quick actions" | msgstr "Quick actions" | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RESTART restarts the flow from the beginning, while keeping the flow context." | #~ msgid "RESTART restarts the flow from the beginning, while keeping the flow context." | ||||||
| msgstr "RESTART restarts the flow from the beginning, while keeping the flow context." | #~ msgstr "RESTART restarts the flow from the beginning, while keeping the flow context." | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RESTART restarts the flow from the beginning." | msgid "RESTART restarts the flow from the beginning." | ||||||
| msgstr "RESTART restarts the flow from the beginning." | msgstr "RESTART restarts the flow from the beginning." | ||||||
|  |  | ||||||
|  | #: src/pages/flows/StageBindingForm.ts | ||||||
|  | msgid "RESTART_WITH_CONTEXT restarts the flow from the beginning, while keeping the flow context." | ||||||
|  | msgstr "RESTART_WITH_CONTEXT restarts the flow from the beginning, while keeping the flow context." | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RETRY returns the error message and a similar challenge to the executor." | msgid "RETRY returns the error message and a similar challenge to the executor." | ||||||
| msgstr "RETRY returns the error message and a similar challenge to the executor." | msgstr "RETRY returns the error message and a similar challenge to the executor." | ||||||
|  | |||||||
| @ -779,6 +779,10 @@ msgstr "De forma predeterminada, solo se muestran los iconos de las fuentes. Act | |||||||
| msgid "CA which the endpoint's Certificate is verified against. Can be left empty for no validation." | msgid "CA which the endpoint's Certificate is verified against. Can be left empty for no validation." | ||||||
| msgstr "CA con la que se verifica el certificado del punto final. Se puede dejar vacío para que no se valide." | msgstr "CA con la que se verifica el certificado del punto final. Se puede dejar vacío para que no se valide." | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "CONTINUE will either follow the ?next parameter or redirect to the default interface." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/providers/ldap/LDAPProviderForm.ts | #: src/pages/providers/ldap/LDAPProviderForm.ts | ||||||
| msgid "Cached binding, flow is executed and session is cached in memory. Flow is executed when session expires." | msgid "Cached binding, flow is executed and session is cached in memory. Flow is executed when session expires." | ||||||
| msgstr "" | msgstr "" | ||||||
| @ -1521,6 +1525,10 @@ msgstr "Desactivar" | |||||||
| msgid "Debug" | msgid "Debug" | ||||||
| msgstr "Depurar" | msgstr "Depurar" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "Decides the response when a policy denies access to this flow for a user." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/flows/FlowForm.ts | #: src/pages/flows/FlowForm.ts | ||||||
| msgid "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." | msgid "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." | ||||||
| msgstr "Decide para qué se utiliza este flujo. Por ejemplo, el flujo de autenticación se redirige a cuando un usuario no autenticado visita authentick." | msgstr "Decide para qué se utiliza este flujo. Por ejemplo, el flujo de autenticación se redirige a cuando un usuario no autenticado visita authentick." | ||||||
| @ -1618,6 +1626,10 @@ msgstr "" | |||||||
| msgid "Delete {0}" | msgid "Delete {0}" | ||||||
| msgstr "Eliminar {0}" | msgstr "Eliminar {0}" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "Denied action" | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts | #: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts | ||||||
| msgid "Deny the user access" | msgid "Deny the user access" | ||||||
| msgstr "Denegar el acceso al usuario" | msgstr "Denegar el acceso al usuario" | ||||||
| @ -3167,6 +3179,14 @@ msgstr "troncos" | |||||||
| msgid "Long-running operations which authentik executes in the background." | msgid "Long-running operations which authentik executes in the background." | ||||||
| msgstr "Operaciones de larga ejecución que authentik se ejecuta en segundo plano." | msgstr "Operaciones de larga ejecución que authentik se ejecuta en segundo plano." | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "MESSAGE will notify the user the flow isn't applicable." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "MESSAGE_CONTINUE will follow the ?next parameter if set, otherwise show a message." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/user/user-settings/UserSettingsPage.ts | #: src/user/user-settings/UserSettingsPage.ts | ||||||
| msgid "MFA Devices" | msgid "MFA Devices" | ||||||
| msgstr "Dispositivos de MFA" | msgstr "Dispositivos de MFA" | ||||||
| @ -4255,13 +4275,17 @@ msgid "Quick actions" | |||||||
| msgstr "Acciones rápidas" | msgstr "Acciones rápidas" | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RESTART restarts the flow from the beginning, while keeping the flow context." | #~ msgid "RESTART restarts the flow from the beginning, while keeping the flow context." | ||||||
| msgstr "RESTART reinicia el flujo desde el principio, a la vez que mantiene el contexto del flujo." | #~ msgstr "RESTART reinicia el flujo desde el principio, a la vez que mantiene el contexto del flujo." | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RESTART restarts the flow from the beginning." | msgid "RESTART restarts the flow from the beginning." | ||||||
| msgstr "RESTART reinicia el flujo desde el principio." | msgstr "RESTART reinicia el flujo desde el principio." | ||||||
|  |  | ||||||
|  | #: src/pages/flows/StageBindingForm.ts | ||||||
|  | msgid "RESTART_WITH_CONTEXT restarts the flow from the beginning, while keeping the flow context." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RETRY returns the error message and a similar challenge to the executor." | msgid "RETRY returns the error message and a similar challenge to the executor." | ||||||
| msgstr "RETRY devuelve el mensaje de error y un desafío similar para el ejecutor." | msgstr "RETRY devuelve el mensaje de error y un desafío similar para el ejecutor." | ||||||
|  | |||||||
| @ -785,6 +785,10 @@ msgstr "" | |||||||
| msgid "CA which the endpoint's Certificate is verified against. Can be left empty for no validation." | msgid "CA which the endpoint's Certificate is verified against. Can be left empty for no validation." | ||||||
| msgstr "AC auprès de laquelle le certificat du terminal est vérifié. Peut être laissé vide en l'absence de validation." | msgstr "AC auprès de laquelle le certificat du terminal est vérifié. Peut être laissé vide en l'absence de validation." | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "CONTINUE will either follow the ?next parameter or redirect to the default interface." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/providers/ldap/LDAPProviderForm.ts | #: src/pages/providers/ldap/LDAPProviderForm.ts | ||||||
| msgid "Cached binding, flow is executed and session is cached in memory. Flow is executed when session expires." | msgid "Cached binding, flow is executed and session is cached in memory. Flow is executed when session expires." | ||||||
| msgstr "" | msgstr "" | ||||||
| @ -1535,6 +1539,10 @@ msgstr "Désactiver" | |||||||
| msgid "Debug" | msgid "Debug" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "Decides the response when a policy denies access to this flow for a user." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/flows/FlowForm.ts | #: src/pages/flows/FlowForm.ts | ||||||
| msgid "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." | msgid "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." | ||||||
| msgstr "Détermine l'usage de ce flux. Par exemple, un flux d'authentification est la destination d'un visiteur d'authentik non authentifié." | msgstr "Détermine l'usage de ce flux. Par exemple, un flux d'authentification est la destination d'un visiteur d'authentik non authentifié." | ||||||
| @ -1630,6 +1638,10 @@ msgstr "Supprimer l'utilisateur en attente. ATTENTION, cette étape ne demande a | |||||||
| msgid "Delete {0}" | msgid "Delete {0}" | ||||||
| msgstr "Supprimer {0}" | msgstr "Supprimer {0}" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "Denied action" | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts | #: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts | ||||||
| msgid "Deny the user access" | msgid "Deny the user access" | ||||||
| msgstr "Refuser l'accès à l'utilisateu" | msgstr "Refuser l'accès à l'utilisateu" | ||||||
| @ -3198,6 +3210,14 @@ msgstr "Logs" | |||||||
| msgid "Long-running operations which authentik executes in the background." | msgid "Long-running operations which authentik executes in the background." | ||||||
| msgstr "Opérations de longue durée qu'Authentik exécute en arrière-plan." | msgstr "Opérations de longue durée qu'Authentik exécute en arrière-plan." | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "MESSAGE will notify the user the flow isn't applicable." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "MESSAGE_CONTINUE will follow the ?next parameter if set, otherwise show a message." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/user/user-settings/UserSettingsPage.ts | #: src/user/user-settings/UserSettingsPage.ts | ||||||
| msgid "MFA Devices" | msgid "MFA Devices" | ||||||
| msgstr "" | msgstr "" | ||||||
| @ -4291,13 +4311,17 @@ msgid "Quick actions" | |||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RESTART restarts the flow from the beginning, while keeping the flow context." | #~ msgid "RESTART restarts the flow from the beginning, while keeping the flow context." | ||||||
| msgstr "REDÉMARRER redémarre le flux depuis le début, en gardant le contexte du flux." | #~ msgstr "REDÉMARRER redémarre le flux depuis le début, en gardant le contexte du flux." | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RESTART restarts the flow from the beginning." | msgid "RESTART restarts the flow from the beginning." | ||||||
| msgstr "REDÉMARRER redémarre le flux depuis le début." | msgstr "REDÉMARRER redémarre le flux depuis le début." | ||||||
|  |  | ||||||
|  | #: src/pages/flows/StageBindingForm.ts | ||||||
|  | msgid "RESTART_WITH_CONTEXT restarts the flow from the beginning, while keeping the flow context." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RETRY returns the error message and a similar challenge to the executor." | msgid "RETRY returns the error message and a similar challenge to the executor." | ||||||
| msgstr "RETRY indiquer le message d'erreur et présenter un challenge similaire à l'utilisateur" | msgstr "RETRY indiquer le message d'erreur et présenter un challenge similaire à l'utilisateur" | ||||||
|  | |||||||
| @ -776,6 +776,10 @@ msgstr "Domyślnie dla źródeł wyświetlane są tylko ikony. Włącz tę opcj | |||||||
| msgid "CA which the endpoint's Certificate is verified against. Can be left empty for no validation." | msgid "CA which the endpoint's Certificate is verified against. Can be left empty for no validation." | ||||||
| msgstr "CA względem którego weryfikowany jest certyfikat. Można pozostawić puste, aby nie sprawdzać poprawności." | msgstr "CA względem którego weryfikowany jest certyfikat. Można pozostawić puste, aby nie sprawdzać poprawności." | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "CONTINUE will either follow the ?next parameter or redirect to the default interface." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/providers/ldap/LDAPProviderForm.ts | #: src/pages/providers/ldap/LDAPProviderForm.ts | ||||||
| msgid "Cached binding, flow is executed and session is cached in memory. Flow is executed when session expires." | msgid "Cached binding, flow is executed and session is cached in memory. Flow is executed when session expires." | ||||||
| msgstr "" | msgstr "" | ||||||
| @ -1518,6 +1522,10 @@ msgstr "Dezaktywuj" | |||||||
| msgid "Debug" | msgid "Debug" | ||||||
| msgstr "Debug" | msgstr "Debug" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "Decides the response when a policy denies access to this flow for a user." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/flows/FlowForm.ts | #: src/pages/flows/FlowForm.ts | ||||||
| msgid "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." | msgid "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." | ||||||
| msgstr "Decyduje, do czego służy ten przepływ. Na przykład przepływ uwierzytelniania służy do przekierowania  nieuwierzytelnionego użytkownika który odwiedza authentik." | msgstr "Decyduje, do czego służy ten przepływ. Na przykład przepływ uwierzytelniania służy do przekierowania  nieuwierzytelnionego użytkownika który odwiedza authentik." | ||||||
| @ -1615,6 +1623,10 @@ msgstr "" | |||||||
| msgid "Delete {0}" | msgid "Delete {0}" | ||||||
| msgstr "Usuń {0}" | msgstr "Usuń {0}" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "Denied action" | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts | #: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts | ||||||
| msgid "Deny the user access" | msgid "Deny the user access" | ||||||
| msgstr "Odmów użytkownikowi dostępu" | msgstr "Odmów użytkownikowi dostępu" | ||||||
| @ -3164,6 +3176,14 @@ msgstr "Logi" | |||||||
| msgid "Long-running operations which authentik executes in the background." | msgid "Long-running operations which authentik executes in the background." | ||||||
| msgstr "Długotrwałe operacje, które authentik wykonuje w tle." | msgstr "Długotrwałe operacje, które authentik wykonuje w tle." | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "MESSAGE will notify the user the flow isn't applicable." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "MESSAGE_CONTINUE will follow the ?next parameter if set, otherwise show a message." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/user/user-settings/UserSettingsPage.ts | #: src/user/user-settings/UserSettingsPage.ts | ||||||
| msgid "MFA Devices" | msgid "MFA Devices" | ||||||
| msgstr "Urządzenia MFA" | msgstr "Urządzenia MFA" | ||||||
| @ -4252,13 +4272,17 @@ msgid "Quick actions" | |||||||
| msgstr "Szybkie akcje" | msgstr "Szybkie akcje" | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RESTART restarts the flow from the beginning, while keeping the flow context." | #~ msgid "RESTART restarts the flow from the beginning, while keeping the flow context." | ||||||
| msgstr "RESTART ponownie uruchamia przepływ od początku, zachowując kontekst przepływu." | #~ msgstr "RESTART ponownie uruchamia przepływ od początku, zachowując kontekst przepływu." | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RESTART restarts the flow from the beginning." | msgid "RESTART restarts the flow from the beginning." | ||||||
| msgstr "RESTART ponownie uruchamia przepływ od początku." | msgstr "RESTART ponownie uruchamia przepływ od początku." | ||||||
|  |  | ||||||
|  | #: src/pages/flows/StageBindingForm.ts | ||||||
|  | msgid "RESTART_WITH_CONTEXT restarts the flow from the beginning, while keeping the flow context." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RETRY returns the error message and a similar challenge to the executor." | msgid "RETRY returns the error message and a similar challenge to the executor." | ||||||
| msgstr "RETRY zwraca komunikat o błędzie i podobne wyzwanie do executora." | msgstr "RETRY zwraca komunikat o błędzie i podobne wyzwanie do executora." | ||||||
|  | |||||||
| @ -778,6 +778,10 @@ msgstr "" | |||||||
| msgid "CA which the endpoint's Certificate is verified against. Can be left empty for no validation." | msgid "CA which the endpoint's Certificate is verified against. Can be left empty for no validation." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "CONTINUE will either follow the ?next parameter or redirect to the default interface." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/providers/ldap/LDAPProviderForm.ts | #: src/pages/providers/ldap/LDAPProviderForm.ts | ||||||
| msgid "Cached binding, flow is executed and session is cached in memory. Flow is executed when session expires." | msgid "Cached binding, flow is executed and session is cached in memory. Flow is executed when session expires." | ||||||
| msgstr "" | msgstr "" | ||||||
| @ -1530,6 +1534,10 @@ msgstr "" | |||||||
| msgid "Debug" | msgid "Debug" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "Decides the response when a policy denies access to this flow for a user." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/flows/FlowForm.ts | #: src/pages/flows/FlowForm.ts | ||||||
| msgid "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." | msgid "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." | ||||||
| msgstr "" | msgstr "" | ||||||
| @ -1631,6 +1639,10 @@ msgstr "" | |||||||
| msgid "Delete {0}" | msgid "Delete {0}" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "Denied action" | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts | #: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts | ||||||
| msgid "Deny the user access" | msgid "Deny the user access" | ||||||
| msgstr "" | msgstr "" | ||||||
| @ -3208,6 +3220,14 @@ msgstr "" | |||||||
| msgid "Long-running operations which authentik executes in the background." | msgid "Long-running operations which authentik executes in the background." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "MESSAGE will notify the user the flow isn't applicable." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "MESSAGE_CONTINUE will follow the ?next parameter if set, otherwise show a message." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/user/user-settings/UserSettingsPage.ts | #: src/user/user-settings/UserSettingsPage.ts | ||||||
| msgid "MFA Devices" | msgid "MFA Devices" | ||||||
| msgstr "" | msgstr "" | ||||||
| @ -4312,13 +4332,17 @@ msgid "Quick actions" | |||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RESTART restarts the flow from the beginning, while keeping the flow context." | #~ msgid "RESTART restarts the flow from the beginning, while keeping the flow context." | ||||||
| msgstr "" | #~ msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RESTART restarts the flow from the beginning." | msgid "RESTART restarts the flow from the beginning." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/StageBindingForm.ts | ||||||
|  | msgid "RESTART_WITH_CONTEXT restarts the flow from the beginning, while keeping the flow context." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RETRY returns the error message and a similar challenge to the executor." | msgid "RETRY returns the error message and a similar challenge to the executor." | ||||||
| msgstr "" | msgstr "" | ||||||
|  | |||||||
| @ -779,6 +779,10 @@ msgstr "Varsayılan olarak, kaynaklar için yalnızca simgeler gösterilir. Tam | |||||||
| msgid "CA which the endpoint's Certificate is verified against. Can be left empty for no validation." | msgid "CA which the endpoint's Certificate is verified against. Can be left empty for no validation." | ||||||
| msgstr "Uç noktanın Sertifikası karşı doğrulanan CA. Doğrulama yapılmadan boş bırakılabilir." | msgstr "Uç noktanın Sertifikası karşı doğrulanan CA. Doğrulama yapılmadan boş bırakılabilir." | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "CONTINUE will either follow the ?next parameter or redirect to the default interface." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/providers/ldap/LDAPProviderForm.ts | #: src/pages/providers/ldap/LDAPProviderForm.ts | ||||||
| msgid "Cached binding, flow is executed and session is cached in memory. Flow is executed when session expires." | msgid "Cached binding, flow is executed and session is cached in memory. Flow is executed when session expires." | ||||||
| msgstr "" | msgstr "" | ||||||
| @ -1521,6 +1525,10 @@ msgstr "Devre dışı bırak" | |||||||
| msgid "Debug" | msgid "Debug" | ||||||
| msgstr "Hata Ayıklama" | msgstr "Hata Ayıklama" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "Decides the response when a policy denies access to this flow for a user." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/flows/FlowForm.ts | #: src/pages/flows/FlowForm.ts | ||||||
| msgid "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." | msgid "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." | ||||||
| msgstr "Bu Akış'ın ne için kullanıldığına karar verir. Örneğin, kimliği doğrulanmamış bir kullanıcı authentik ziyaret ettiğinde kimlik doğrulama akışı yönlendirir." | msgstr "Bu Akış'ın ne için kullanıldığına karar verir. Örneğin, kimliği doğrulanmamış bir kullanıcı authentik ziyaret ettiğinde kimlik doğrulama akışı yönlendirir." | ||||||
| @ -1618,6 +1626,10 @@ msgstr "" | |||||||
| msgid "Delete {0}" | msgid "Delete {0}" | ||||||
| msgstr "{0} Sil" | msgstr "{0} Sil" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "Denied action" | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts | #: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts | ||||||
| msgid "Deny the user access" | msgid "Deny the user access" | ||||||
| msgstr "Kullanıcı erişimini engelle" | msgstr "Kullanıcı erişimini engelle" | ||||||
| @ -3168,6 +3180,14 @@ msgstr "Günlükler" | |||||||
| msgid "Long-running operations which authentik executes in the background." | msgid "Long-running operations which authentik executes in the background." | ||||||
| msgstr "authentik'in arka planda yürüttüğü uzun süreli işlemler." | msgstr "authentik'in arka planda yürüttüğü uzun süreli işlemler." | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "MESSAGE will notify the user the flow isn't applicable." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "MESSAGE_CONTINUE will follow the ?next parameter if set, otherwise show a message." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/user/user-settings/UserSettingsPage.ts | #: src/user/user-settings/UserSettingsPage.ts | ||||||
| msgid "MFA Devices" | msgid "MFA Devices" | ||||||
| msgstr "MFA Cihazları" | msgstr "MFA Cihazları" | ||||||
| @ -4257,13 +4277,17 @@ msgid "Quick actions" | |||||||
| msgstr "Hızlı eylemler" | msgstr "Hızlı eylemler" | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RESTART restarts the flow from the beginning, while keeping the flow context." | #~ msgid "RESTART restarts the flow from the beginning, while keeping the flow context." | ||||||
| msgstr "RESTART, akış bağlamını korurken akışı baştan yeniden başlatır." | #~ msgstr "RESTART, akış bağlamını korurken akışı baştan yeniden başlatır." | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RESTART restarts the flow from the beginning." | msgid "RESTART restarts the flow from the beginning." | ||||||
| msgstr "RESTART, akışı baştan yeniden başlatır." | msgstr "RESTART, akışı baştan yeniden başlatır." | ||||||
|  |  | ||||||
|  | #: src/pages/flows/StageBindingForm.ts | ||||||
|  | msgid "RESTART_WITH_CONTEXT restarts the flow from the beginning, while keeping the flow context." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RETRY returns the error message and a similar challenge to the executor." | msgid "RETRY returns the error message and a similar challenge to the executor." | ||||||
| msgstr "RETRY hata iletisi ve yürütücünün benzer bir meydan okuma döndürür." | msgstr "RETRY hata iletisi ve yürütücünün benzer bir meydan okuma döndürür." | ||||||
|  | |||||||
| @ -774,6 +774,10 @@ msgstr "默认情况下,只为源显示图标。启用此选项可显示它们 | |||||||
| msgid "CA which the endpoint's Certificate is verified against. Can be left empty for no validation." | msgid "CA which the endpoint's Certificate is verified against. Can be left empty for no validation." | ||||||
| msgstr "验证端点证书所依据的 CA。可以留空,表示不进行验证。" | msgstr "验证端点证书所依据的 CA。可以留空,表示不进行验证。" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "CONTINUE will either follow the ?next parameter or redirect to the default interface." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/providers/ldap/LDAPProviderForm.ts | #: src/pages/providers/ldap/LDAPProviderForm.ts | ||||||
| msgid "Cached binding, flow is executed and session is cached in memory. Flow is executed when session expires." | msgid "Cached binding, flow is executed and session is cached in memory. Flow is executed when session expires." | ||||||
| msgstr "缓存绑定,流程与会话会在内存中执行与缓存。会话过期时执行流程。" | msgstr "缓存绑定,流程与会话会在内存中执行与缓存。会话过期时执行流程。" | ||||||
| @ -1516,6 +1520,10 @@ msgstr "停用" | |||||||
| msgid "Debug" | msgid "Debug" | ||||||
| msgstr "调试" | msgstr "调试" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "Decides the response when a policy denies access to this flow for a user." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/flows/FlowForm.ts | #: src/pages/flows/FlowForm.ts | ||||||
| msgid "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." | msgid "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." | ||||||
| msgstr "决定此流程的用途。例如,当未经身份验证的用户访问 authentik 时,会重定向到身份验证流程。" | msgstr "决定此流程的用途。例如,当未经身份验证的用户访问 authentik 时,会重定向到身份验证流程。" | ||||||
| @ -1613,6 +1621,10 @@ msgstr "" | |||||||
| msgid "Delete {0}" | msgid "Delete {0}" | ||||||
| msgstr "删除 {0}" | msgstr "删除 {0}" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "Denied action" | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts | #: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts | ||||||
| msgid "Deny the user access" | msgid "Deny the user access" | ||||||
| msgstr "拒绝用户访问" | msgstr "拒绝用户访问" | ||||||
| @ -3150,6 +3162,14 @@ msgstr "日志" | |||||||
| msgid "Long-running operations which authentik executes in the background." | msgid "Long-running operations which authentik executes in the background." | ||||||
| msgstr "authentik 在后台执行的长时间运行的操作。" | msgstr "authentik 在后台执行的长时间运行的操作。" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "MESSAGE will notify the user the flow isn't applicable." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "MESSAGE_CONTINUE will follow the ?next parameter if set, otherwise show a message." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/user/user-settings/UserSettingsPage.ts | #: src/user/user-settings/UserSettingsPage.ts | ||||||
| msgid "MFA Devices" | msgid "MFA Devices" | ||||||
| msgstr "MFA 设备" | msgstr "MFA 设备" | ||||||
| @ -4228,13 +4248,17 @@ msgid "Quick actions" | |||||||
| msgstr "快速操作" | msgstr "快速操作" | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RESTART restarts the flow from the beginning, while keeping the flow context." | #~ msgid "RESTART restarts the flow from the beginning, while keeping the flow context." | ||||||
| msgstr "RESTART 从头开始重新启动流程,同时保留流程上下文。" | #~ msgstr "RESTART 从头开始重新启动流程,同时保留流程上下文。" | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RESTART restarts the flow from the beginning." | msgid "RESTART restarts the flow from the beginning." | ||||||
| msgstr "RESTART 从头开始重新启动流程。" | msgstr "RESTART 从头开始重新启动流程。" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/StageBindingForm.ts | ||||||
|  | msgid "RESTART_WITH_CONTEXT restarts the flow from the beginning, while keeping the flow context." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RETRY returns the error message and a similar challenge to the executor." | msgid "RETRY returns the error message and a similar challenge to the executor." | ||||||
| msgstr "RETRY 向执行器返回错误消息和类似的质询。" | msgstr "RETRY 向执行器返回错误消息和类似的质询。" | ||||||
|  | |||||||
| @ -776,6 +776,10 @@ msgstr "默认情况下,只为源显示图标。启用此选项可显示他们 | |||||||
| msgid "CA which the endpoint's Certificate is verified against. Can be left empty for no validation." | msgid "CA which the endpoint's Certificate is verified against. Can be left empty for no validation." | ||||||
| msgstr "验证终端节点证书所依据的 CA。可以留空以表示不进行验证。" | msgstr "验证终端节点证书所依据的 CA。可以留空以表示不进行验证。" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "CONTINUE will either follow the ?next parameter or redirect to the default interface." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/providers/ldap/LDAPProviderForm.ts | #: src/pages/providers/ldap/LDAPProviderForm.ts | ||||||
| msgid "Cached binding, flow is executed and session is cached in memory. Flow is executed when session expires." | msgid "Cached binding, flow is executed and session is cached in memory. Flow is executed when session expires." | ||||||
| msgstr "" | msgstr "" | ||||||
| @ -1518,6 +1522,10 @@ msgstr "停用" | |||||||
| msgid "Debug" | msgid "Debug" | ||||||
| msgstr "调试" | msgstr "调试" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "Decides the response when a policy denies access to this flow for a user." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/flows/FlowForm.ts | #: src/pages/flows/FlowForm.ts | ||||||
| msgid "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." | msgid "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." | ||||||
| msgstr "决定此 Flow 的用途。例如,当未经身份验证的用户访问 authentik 时,身份验证流程将重定向到。" | msgstr "决定此 Flow 的用途。例如,当未经身份验证的用户访问 authentik 时,身份验证流程将重定向到。" | ||||||
| @ -1615,6 +1623,10 @@ msgstr "" | |||||||
| msgid "Delete {0}" | msgid "Delete {0}" | ||||||
| msgstr "删除 {0}" | msgstr "删除 {0}" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "Denied action" | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts | #: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts | ||||||
| msgid "Deny the user access" | msgid "Deny the user access" | ||||||
| msgstr "拒绝用户访问" | msgstr "拒绝用户访问" | ||||||
| @ -3154,6 +3166,14 @@ msgstr "日志" | |||||||
| msgid "Long-running operations which authentik executes in the background." | msgid "Long-running operations which authentik executes in the background." | ||||||
| msgstr "authentik 在后台执行的长时间运行的操作。" | msgstr "authentik 在后台执行的长时间运行的操作。" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "MESSAGE will notify the user the flow isn't applicable." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "MESSAGE_CONTINUE will follow the ?next parameter if set, otherwise show a message." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/user/user-settings/UserSettingsPage.ts | #: src/user/user-settings/UserSettingsPage.ts | ||||||
| msgid "MFA Devices" | msgid "MFA Devices" | ||||||
| msgstr "MFA 设备" | msgstr "MFA 设备" | ||||||
| @ -4233,13 +4253,17 @@ msgid "Quick actions" | |||||||
| msgstr "快速行动" | msgstr "快速行动" | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RESTART restarts the flow from the beginning, while keeping the flow context." | #~ msgid "RESTART restarts the flow from the beginning, while keeping the flow context." | ||||||
| msgstr "RESTART 从头开始重新启动流程,同时保留流程上下文。" | #~ msgstr "RESTART 从头开始重新启动流程,同时保留流程上下文。" | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RESTART restarts the flow from the beginning." | msgid "RESTART restarts the flow from the beginning." | ||||||
| msgstr "RESTART 从头开始重新启动流程。" | msgstr "RESTART 从头开始重新启动流程。" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/StageBindingForm.ts | ||||||
|  | msgid "RESTART_WITH_CONTEXT restarts the flow from the beginning, while keeping the flow context." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RETRY returns the error message and a similar challenge to the executor." | msgid "RETRY returns the error message and a similar challenge to the executor." | ||||||
| msgstr "RETRY 向执行器返回错误消息和类似的质询。" | msgstr "RETRY 向执行器返回错误消息和类似的质询。" | ||||||
|  | |||||||
| @ -776,6 +776,10 @@ msgstr "默认情况下,只为源显示图标。启用此选项可显示他们 | |||||||
| msgid "CA which the endpoint's Certificate is verified against. Can be left empty for no validation." | msgid "CA which the endpoint's Certificate is verified against. Can be left empty for no validation." | ||||||
| msgstr "验证终端节点证书所依据的 CA。可以留空以表示不进行验证。" | msgstr "验证终端节点证书所依据的 CA。可以留空以表示不进行验证。" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "CONTINUE will either follow the ?next parameter or redirect to the default interface." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/providers/ldap/LDAPProviderForm.ts | #: src/pages/providers/ldap/LDAPProviderForm.ts | ||||||
| msgid "Cached binding, flow is executed and session is cached in memory. Flow is executed when session expires." | msgid "Cached binding, flow is executed and session is cached in memory. Flow is executed when session expires." | ||||||
| msgstr "" | msgstr "" | ||||||
| @ -1518,6 +1522,10 @@ msgstr "停用" | |||||||
| msgid "Debug" | msgid "Debug" | ||||||
| msgstr "调试" | msgstr "调试" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "Decides the response when a policy denies access to this flow for a user." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/flows/FlowForm.ts | #: src/pages/flows/FlowForm.ts | ||||||
| msgid "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." | msgid "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." | ||||||
| msgstr "决定此 Flow 的用途。例如,当未经身份验证的用户访问 authentik 时,身份验证流程将重定向到。" | msgstr "决定此 Flow 的用途。例如,当未经身份验证的用户访问 authentik 时,身份验证流程将重定向到。" | ||||||
| @ -1615,6 +1623,10 @@ msgstr "" | |||||||
| msgid "Delete {0}" | msgid "Delete {0}" | ||||||
| msgstr "删除 {0}" | msgstr "删除 {0}" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "Denied action" | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts | #: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts | ||||||
| msgid "Deny the user access" | msgid "Deny the user access" | ||||||
| msgstr "拒绝用户访问" | msgstr "拒绝用户访问" | ||||||
| @ -3154,6 +3166,14 @@ msgstr "日志" | |||||||
| msgid "Long-running operations which authentik executes in the background." | msgid "Long-running operations which authentik executes in the background." | ||||||
| msgstr "authentik 在后台执行的长时间运行的操作。" | msgstr "authentik 在后台执行的长时间运行的操作。" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "MESSAGE will notify the user the flow isn't applicable." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/FlowForm.ts | ||||||
|  | msgid "MESSAGE_CONTINUE will follow the ?next parameter if set, otherwise show a message." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/user/user-settings/UserSettingsPage.ts | #: src/user/user-settings/UserSettingsPage.ts | ||||||
| msgid "MFA Devices" | msgid "MFA Devices" | ||||||
| msgstr "MFA 设备" | msgstr "MFA 设备" | ||||||
| @ -4233,13 +4253,17 @@ msgid "Quick actions" | |||||||
| msgstr "快速行动" | msgstr "快速行动" | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RESTART restarts the flow from the beginning, while keeping the flow context." | #~ msgid "RESTART restarts the flow from the beginning, while keeping the flow context." | ||||||
| msgstr "RESTART 从头开始重新启动流程,同时保留流程上下文。" | #~ msgstr "RESTART 从头开始重新启动流程,同时保留流程上下文。" | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RESTART restarts the flow from the beginning." | msgid "RESTART restarts the flow from the beginning." | ||||||
| msgstr "RESTART 从头开始重新启动流程。" | msgstr "RESTART 从头开始重新启动流程。" | ||||||
|  |  | ||||||
|  | #: src/pages/flows/StageBindingForm.ts | ||||||
|  | msgid "RESTART_WITH_CONTEXT restarts the flow from the beginning, while keeping the flow context." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: src/pages/flows/StageBindingForm.ts | #: src/pages/flows/StageBindingForm.ts | ||||||
| msgid "RETRY returns the error message and a similar challenge to the executor." | msgid "RETRY returns the error message and a similar challenge to the executor." | ||||||
| msgstr "RETRY 向执行器返回错误消息和类似的质询。" | msgstr "RETRY 向执行器返回错误消息和类似的质询。" | ||||||
|  | |||||||
| @ -1,3 +1,4 @@ | |||||||
|  | import { DeniedActionEnum } from "@goauthentik/api/dist/models/DeniedActionEnum.js"; | ||||||
| import { DEFAULT_CONFIG, config } from "@goauthentik/web/api/Config"; | import { DEFAULT_CONFIG, config } from "@goauthentik/web/api/Config"; | ||||||
| import "@goauthentik/web/elements/forms/HorizontalFormElement"; | import "@goauthentik/web/elements/forms/HorizontalFormElement"; | ||||||
| import { ModelForm } from "@goauthentik/web/elements/forms/ModelForm"; | import { ModelForm } from "@goauthentik/web/elements/forms/ModelForm"; | ||||||
| @ -120,6 +121,27 @@ export class FlowForm extends ModelForm<Flow, string> { | |||||||
|         `; |         `; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     renderDeniedAction(): TemplateResult { | ||||||
|  |         return html` <option | ||||||
|  |                 value=${DeniedActionEnum.MessageContinue} | ||||||
|  |                 ?selected=${this.instance?.deniedAction === DeniedActionEnum.MessageContinue} | ||||||
|  |             > | ||||||
|  |                 ${t`MESSAGE_CONTINUE will follow the ?next parameter if set, otherwise show a message.`} | ||||||
|  |             </option> | ||||||
|  |             <option | ||||||
|  |                 value=${DeniedActionEnum.Continue} | ||||||
|  |                 ?selected=${this.instance?.deniedAction === DeniedActionEnum.Continue} | ||||||
|  |             > | ||||||
|  |                 ${t`CONTINUE will either follow the ?next parameter or redirect to the default interface.`} | ||||||
|  |             </option> | ||||||
|  |             <option | ||||||
|  |                 value=${DeniedActionEnum.Message} | ||||||
|  |                 ?selected=${this.instance?.deniedAction === DeniedActionEnum.Message} | ||||||
|  |             > | ||||||
|  |                 ${t`MESSAGE will notify the user the flow isn't applicable.`} | ||||||
|  |             </option>`; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     renderLayout(): TemplateResult { |     renderLayout(): TemplateResult { | ||||||
|         return html` |         return html` | ||||||
|             <option |             <option | ||||||
| @ -218,6 +240,18 @@ export class FlowForm extends ModelForm<Flow, string> { | |||||||
|                     ${t`Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik.`} |                     ${t`Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik.`} | ||||||
|                 </p> |                 </p> | ||||||
|             </ak-form-element-horizontal> |             </ak-form-element-horizontal> | ||||||
|  |             <ak-form-element-horizontal | ||||||
|  |                 label=${t`Denied action`} | ||||||
|  |                 ?required=${true} | ||||||
|  |                 name="deniedAction" | ||||||
|  |             > | ||||||
|  |                 <select class="pf-c-form-control"> | ||||||
|  |                     ${this.renderDeniedAction()} | ||||||
|  |                 </select> | ||||||
|  |                 <p class="pf-c-form__helper-text"> | ||||||
|  |                     ${t`Decides the response when a policy denies access to this flow for a user.`} | ||||||
|  |                 </p> | ||||||
|  |             </ak-form-element-horizontal> | ||||||
|             <ak-form-element-horizontal label=${t`Layout`} ?required=${true} name="layout"> |             <ak-form-element-horizontal label=${t`Layout`} ?required=${true} name="layout"> | ||||||
|                 <select class="pf-c-form-control"> |                 <select class="pf-c-form-control"> | ||||||
|                     ${this.renderLayout()} |                     ${this.renderLayout()} | ||||||
|  | |||||||
| @ -193,7 +193,7 @@ export class StageBindingForm extends ModelForm<FlowStageBinding, string> { | |||||||
|                         ?selected=${this.instance?.invalidResponseAction === |                         ?selected=${this.instance?.invalidResponseAction === | ||||||
|                         InvalidResponseActionEnum.RestartWithContext} |                         InvalidResponseActionEnum.RestartWithContext} | ||||||
|                     > |                     > | ||||||
|                         ${t`RESTART restarts the flow from the beginning, while keeping the flow context.`} |                         ${t`RESTART_WITH_CONTEXT restarts the flow from the beginning, while keeping the flow context.`} | ||||||
|                     </option> |                     </option> | ||||||
|                 </select> |                 </select> | ||||||
|                 <p class="pf-c-form__helper-text"> |                 <p class="pf-c-form__helper-text"> | ||||||
|  | |||||||
| @ -20,6 +20,14 @@ Flows can have policies assigned to them. These policies determine if the curren | |||||||
|  |  | ||||||
| Keep in mind that in certain circumstances, policies cannot match against users and groups as there is no authenticated user yet. | Keep in mind that in certain circumstances, policies cannot match against users and groups as there is no authenticated user yet. | ||||||
|  |  | ||||||
|  | ### Denied action | ||||||
|  |  | ||||||
|  | Configure what happens when access to a flow is denied by a policy. By default, authentik will redirect to a `?next` parameter if set, and otherwise show an error message. | ||||||
|  |  | ||||||
|  | -   `MESSAGE_CONTINUE`: Show a message if no `?next` parameter is set, otherwise redirect. | ||||||
|  | -   `MESSAGE`: Always show error message. | ||||||
|  | -   `CONTINUE`: Always redirect, either to `?next` if set, otherwise to the default interface. | ||||||
|  |  | ||||||
| ## Designation | ## Designation | ||||||
|  |  | ||||||
| Flows are designated for a single purpose. This designation changes when a flow is used. The following designations are available: | Flows are designated for a single purpose. This designation changes when a flow is used. The following designations are available: | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Jens L
					Jens L