policies: specify failure result (#6887)

This commit is contained in:
Jens L 2023-09-14 20:38:22 +02:00 committed by GitHub
parent 687bc3a4b4
commit 895c6a349c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 83 additions and 7 deletions

View File

@ -77,6 +77,7 @@ class PolicyBindingSerializer(ModelSerializer):
"enabled", "enabled",
"order", "order",
"timeout", "timeout",
"failure_result",
] ]
def validate(self, attrs: OrderedDict) -> OrderedDict: def validate(self, attrs: OrderedDict) -> OrderedDict:

View File

@ -0,0 +1,26 @@
# Generated by Django 4.2.5 on 2023-09-13 18:07
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_policies", "0010_alter_policy_name"),
]
operations = [
migrations.AddField(
model_name="policybinding",
name="failure_result",
field=models.BooleanField(
default=False, help_text="Result if the Policy execution fails."
),
),
migrations.AlterField(
model_name="policybinding",
name="timeout",
field=models.PositiveIntegerField(
default=30, help_text="Timeout after which Policy execution is terminated."
),
),
]

View File

@ -85,9 +85,12 @@ class PolicyBinding(SerializerModel):
default=False, default=False,
help_text=_("Negates the outcome of the policy. Messages are unaffected."), help_text=_("Negates the outcome of the policy. Messages are unaffected."),
) )
timeout = models.IntegerField( timeout = models.PositiveIntegerField(
default=30, help_text=_("Timeout after which Policy execution is terminated.") default=30, help_text=_("Timeout after which Policy execution is terminated.")
) )
failure_result = models.BooleanField(
default=False, help_text=_("Result if the Policy execution fails.")
)
order = models.IntegerField() order = models.IntegerField()

View File

@ -98,8 +98,8 @@ class PolicyProcess(PROCESS_CLASS):
# Create policy exception event, only when we're not debugging # Create policy exception event, only when we're not debugging
if not self.request.debug: if not self.request.debug:
self.create_event(EventAction.POLICY_EXCEPTION, message=error_string) self.create_event(EventAction.POLICY_EXCEPTION, message=error_string)
LOGGER.debug("P_ENG(proc): error", exc=src_exc) LOGGER.debug("P_ENG(proc): error, using failure result", exc=src_exc)
policy_result = PolicyResult(False, str(src_exc)) policy_result = PolicyResult(self.binding.failure_result, str(src_exc))
policy_result.source_binding = self.binding policy_result.source_binding = self.binding
should_cache = self.request.should_cache should_cache = self.request.should_cache
if should_cache: if should_cache:

View File

@ -97,6 +97,17 @@ class TestPolicyEngine(TestCase):
self.assertEqual(result.passing, False) self.assertEqual(result.passing, False)
self.assertEqual(result.messages, ("division by zero",)) self.assertEqual(result.messages, ("division by zero",))
def test_engine_policy_error_failure(self):
"""Test policy raising an error flag"""
pbm = PolicyBindingModel.objects.create()
PolicyBinding.objects.create(
target=pbm, policy=self.policy_raises, order=0, failure_result=True
)
engine = PolicyEngine(pbm, self.user)
result = engine.build().result
self.assertEqual(result.passing, True)
self.assertEqual(result.messages, ("division by zero",))
def test_engine_policy_type(self): def test_engine_policy_type(self):
"""Test invalid policy type""" """Test invalid policy type"""
pbm = PolicyBindingModel.objects.create() pbm = PolicyBindingModel.objects.create()

View File

@ -3650,10 +3650,15 @@
}, },
"timeout": { "timeout": {
"type": "integer", "type": "integer",
"minimum": -2147483648, "minimum": 0,
"maximum": 2147483647, "maximum": 2147483647,
"title": "Timeout", "title": "Timeout",
"description": "Timeout after which Policy execution is terminated." "description": "Timeout after which Policy execution is terminated."
},
"failure_result": {
"type": "boolean",
"title": "Failure result",
"description": "Result if the Policy execution fails."
} }
}, },
"required": [] "required": []

View File

@ -35954,8 +35954,11 @@ components:
timeout: timeout:
type: integer type: integer
maximum: 2147483647 maximum: 2147483647
minimum: -2147483648 minimum: 0
description: Timeout after which Policy execution is terminated. description: Timeout after which Policy execution is terminated.
failure_result:
type: boolean
description: Result if the Policy execution fails.
PatchedPromptRequest: PatchedPromptRequest:
type: object type: object
description: Prompt Serializer description: Prompt Serializer
@ -37046,8 +37049,11 @@ components:
timeout: timeout:
type: integer type: integer
maximum: 2147483647 maximum: 2147483647
minimum: -2147483648 minimum: 0
description: Timeout after which Policy execution is terminated. description: Timeout after which Policy execution is terminated.
failure_result:
type: boolean
description: Result if the Policy execution fails.
required: required:
- group_obj - group_obj
- order - order
@ -37085,8 +37091,11 @@ components:
timeout: timeout:
type: integer type: integer
maximum: 2147483647 maximum: 2147483647
minimum: -2147483648 minimum: 0
description: Timeout after which Policy execution is terminated. description: Timeout after which Policy execution is terminated.
failure_result:
type: boolean
description: Result if the Policy execution fails.
required: required:
- order - order
- target - target

View File

@ -3,6 +3,7 @@ import { first, groupBy } from "@goauthentik/common/utils";
import "@goauthentik/components/ak-toggle-group"; import "@goauthentik/components/ak-toggle-group";
import "@goauthentik/elements/forms/HorizontalFormElement"; import "@goauthentik/elements/forms/HorizontalFormElement";
import { ModelForm } from "@goauthentik/elements/forms/ModelForm"; import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
import "@goauthentik/elements/forms/Radio";
import "@goauthentik/elements/forms/SearchSelect"; import "@goauthentik/elements/forms/SearchSelect";
import { msg } from "@lit/localize"; import { msg } from "@lit/localize";
@ -298,6 +299,26 @@ export class PolicyBindingForm extends ModelForm<PolicyBinding, string> {
required required
/> />
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="failureResult" label=${msg("Failure result")}>
<ak-radio
.options=${[
{
label: msg("Pass"),
value: true,
},
{
label: msg("Don't pass"),
value: false,
default: true,
},
]}
.value=${this.instance?.failureResult}
>
</ak-radio>
<p class="pf-c-form__helper-text">
${msg("Result used when policy execution fails.")}
</p>
</ak-form-element-horizontal>
</form>`; </form>`;
} }
} }