policies/event_matcher: change empty values to null (#6032)

* policies/event_matcher: change empty values to null

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* migrate old default values

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens L 2023-06-21 15:49:46 +02:00 committed by GitHub
parent 17fbba2799
commit 469899233a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 152 additions and 19 deletions

View file

@ -15,7 +15,7 @@ class EventMatcherPolicySerializer(PolicySerializer):
app = ChoiceField(
choices=app_choices(),
required=False,
allow_blank=True,
allow_null=True,
help_text=_(
"Match events created by selected application. When left empty, "
"all applications are matched."
@ -24,7 +24,7 @@ class EventMatcherPolicySerializer(PolicySerializer):
model = ChoiceField(
choices=model_choices(),
required=False,
allow_blank=True,
allow_null=True,
help_text=_(
"Match events created by selected model. "
"When left empty, all models are matched. When an app is selected, "

View file

@ -0,0 +1,103 @@
# Generated by Django 4.1.7 on 2023-06-21 12:45
from django.apps.registry import Apps
from django.db import migrations, models
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
def replace_defaults(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
db_alias = schema_editor.connection.alias
eventmatcherpolicy = apps.get_model("authentik_policies_event_matcher", "eventmatcherpolicy")
for policy in eventmatcherpolicy.objects.using(db_alias).all():
changed = False
if policy.action == "":
policy.action = None
changed = True
if policy.app == "":
policy.app = None
changed = True
if policy.client_ip == "":
policy.client_ip = None
changed = True
if policy.model == "":
policy.model = None
changed = True
if not changed:
continue
policy.save()
class Migration(migrations.Migration):
dependencies = [
("authentik_policies_event_matcher", "0022_eventmatcherpolicy_model"),
]
operations = [
migrations.AlterField(
model_name="eventmatcherpolicy",
name="action",
field=models.TextField(
choices=[
("login", "Login"),
("login_failed", "Login Failed"),
("logout", "Logout"),
("user_write", "User Write"),
("suspicious_request", "Suspicious Request"),
("password_set", "Password Set"),
("secret_view", "Secret View"),
("secret_rotate", "Secret Rotate"),
("invitation_used", "Invite Used"),
("authorize_application", "Authorize Application"),
("source_linked", "Source Linked"),
("impersonation_started", "Impersonation Started"),
("impersonation_ended", "Impersonation Ended"),
("flow_execution", "Flow Execution"),
("policy_execution", "Policy Execution"),
("policy_exception", "Policy Exception"),
("property_mapping_exception", "Property Mapping Exception"),
("system_task_execution", "System Task Execution"),
("system_task_exception", "System Task Exception"),
("system_exception", "System Exception"),
("configuration_error", "Configuration Error"),
("model_created", "Model Created"),
("model_updated", "Model Updated"),
("model_deleted", "Model Deleted"),
("email_sent", "Email Sent"),
("update_available", "Update Available"),
("custom_", "Custom Prefix"),
],
default=None,
help_text="Match created events with this action type. When left empty, all action types will be matched.",
null=True,
),
),
migrations.AlterField(
model_name="eventmatcherpolicy",
name="app",
field=models.TextField(
default=None,
help_text="Match events created by selected application. When left empty, all applications are matched.",
null=True,
),
),
migrations.AlterField(
model_name="eventmatcherpolicy",
name="client_ip",
field=models.TextField(
default=None,
help_text="Matches Event's Client IP (strict matching, for network matching use an Expression Policy)",
null=True,
),
),
migrations.AlterField(
model_name="eventmatcherpolicy",
name="model",
field=models.TextField(
default=None,
help_text="Match events created by selected model. When left empty, all models are matched. When an app is selected, all the application's models are matched.",
null=True,
),
),
migrations.RunPython(replace_defaults),
]

View file

@ -42,23 +42,24 @@ class EventMatcherPolicy(Policy):
action = models.TextField(
choices=EventAction.choices,
blank=True,
null=True,
default=None,
help_text=_(
"Match created events with this action type. "
"When left empty, all action types will be matched."
),
)
app = models.TextField(
blank=True,
default="",
null=True,
default=None,
help_text=_(
"Match events created by selected application. "
"When left empty, all applications are matched."
),
)
model = models.TextField(
blank=True,
default="",
null=True,
default=None,
help_text=_(
"Match events created by selected model. "
"When left empty, all models are matched. When an app is selected, "
@ -66,7 +67,8 @@ class EventMatcherPolicy(Policy):
),
)
client_ip = models.TextField(
blank=True,
null=True,
default=None,
help_text=_(
"Matches Event's Client IP (strict matching, "
"for network matching use an Expression Policy)"
@ -113,25 +115,25 @@ class EventMatcherPolicy(Policy):
def passes_action(self, request: PolicyRequest, event: Event) -> PolicyResult | None:
"""Check if `self.action` matches"""
if self.action == "":
if self.action is None:
return None
return PolicyResult(self.action == event.action, "Action matched.")
def passes_client_ip(self, request: PolicyRequest, event: Event) -> PolicyResult | None:
"""Check if `self.client_ip` matches"""
if self.client_ip == "":
if self.client_ip is None:
return None
return PolicyResult(self.client_ip == event.client_ip, "Client IP matched.")
def passes_app(self, request: PolicyRequest, event: Event) -> PolicyResult | None:
"""Check if `self.app` matches"""
if self.app == "":
if self.app is None:
return None
return PolicyResult(self.app == event.app, "App matched.")
def passes_model(self, request: PolicyRequest, event: Event) -> PolicyResult | None:
"""Check if `self.model` is set, and pass if it matches the event's model"""
if self.model == "":
if self.model is None:
return None
event_model_info = event.context.get("model", {})
event_model = f"{event_model_info.get('app')}.{event_model_info.get('model_name')}"

View file

@ -3155,9 +3155,12 @@
"description": "When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged."
},
"action": {
"type": "string",
"type": [
"null",
"string"
],
"enum": [
"",
null,
"login",
"login_failed",
"logout",
@ -3190,14 +3193,21 @@
"description": "Match created events with this action type. When left empty, all action types will be matched."
},
"client_ip": {
"type": "string",
"type": [
"string",
"null"
],
"minLength": 1,
"title": "Client ip",
"description": "Matches Event's Client IP (strict matching, for network matching use an Expression Policy)"
},
"app": {
"type": "string",
"type": [
"null",
"string"
],
"enum": [
"",
null,
"authentik.admin",
"authentik.api",
"authentik.crypto",
@ -3251,9 +3261,12 @@
"description": "Match events created by selected application. When left empty, all applications are matched."
},
"model": {
"type": "string",
"type": [
"null",
"string"
],
"enum": [
"",
null,
"authentik_crypto.certificatekeypair",
"authentik_events.event",
"authentik_events.notificationtransport",

View file

@ -10922,6 +10922,7 @@ paths:
name: action
schema:
type: string
nullable: true
enum:
- authorize_application
- configuration_error
@ -29100,6 +29101,7 @@ components:
action:
allOf:
- $ref: '#/components/schemas/EventActions'
nullable: true
description: |-
Match created events with this action type. When left empty, all action types will be matched.
@ -29132,11 +29134,13 @@ components:
* `custom_` - Custom Prefix
client_ip:
type: string
nullable: true
description: Matches Event's Client IP (strict matching, for network matching
use an Expression Policy)
app:
allOf:
- $ref: '#/components/schemas/AppEnum'
nullable: true
description: |-
Match events created by selected application. When left empty, all applications are matched.
@ -29191,6 +29195,7 @@ components:
model:
allOf:
- $ref: '#/components/schemas/ModelEnum'
nullable: true
description: |-
Match events created by selected model. When left empty, all models are matched. When an app is selected, all the application's models are matched.
@ -29286,6 +29291,7 @@ components:
action:
allOf:
- $ref: '#/components/schemas/EventActions'
nullable: true
description: |-
Match created events with this action type. When left empty, all action types will be matched.
@ -29318,11 +29324,14 @@ components:
* `custom_` - Custom Prefix
client_ip:
type: string
nullable: true
minLength: 1
description: Matches Event's Client IP (strict matching, for network matching
use an Expression Policy)
app:
allOf:
- $ref: '#/components/schemas/AppEnum'
nullable: true
description: |-
Match events created by selected application. When left empty, all applications are matched.
@ -29377,6 +29386,7 @@ components:
model:
allOf:
- $ref: '#/components/schemas/ModelEnum'
nullable: true
description: |-
Match events created by selected model. When left empty, all models are matched. When an app is selected, all the application's models are matched.
@ -36250,6 +36260,7 @@ components:
action:
allOf:
- $ref: '#/components/schemas/EventActions'
nullable: true
description: |-
Match created events with this action type. When left empty, all action types will be matched.
@ -36282,11 +36293,14 @@ components:
* `custom_` - Custom Prefix
client_ip:
type: string
nullable: true
minLength: 1
description: Matches Event's Client IP (strict matching, for network matching
use an Expression Policy)
app:
allOf:
- $ref: '#/components/schemas/AppEnum'
nullable: true
description: |-
Match events created by selected application. When left empty, all applications are matched.
@ -36341,6 +36355,7 @@ components:
model:
allOf:
- $ref: '#/components/schemas/ModelEnum'
nullable: true
description: |-
Match events created by selected model. When left empty, all models are matched. When an app is selected, all the application's models are matched.