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( app = ChoiceField(
choices=app_choices(), choices=app_choices(),
required=False, required=False,
allow_blank=True, allow_null=True,
help_text=_( help_text=_(
"Match events created by selected application. When left empty, " "Match events created by selected application. When left empty, "
"all applications are matched." "all applications are matched."
@ -24,7 +24,7 @@ class EventMatcherPolicySerializer(PolicySerializer):
model = ChoiceField( model = ChoiceField(
choices=model_choices(), choices=model_choices(),
required=False, required=False,
allow_blank=True, allow_null=True,
help_text=_( help_text=_(
"Match events created by selected model. " "Match events created by selected model. "
"When left empty, all models are matched. When an app is selected, " "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( action = models.TextField(
choices=EventAction.choices, choices=EventAction.choices,
blank=True, null=True,
default=None,
help_text=_( help_text=_(
"Match created events with this action type. " "Match created events with this action type. "
"When left empty, all action types will be matched." "When left empty, all action types will be matched."
), ),
) )
app = models.TextField( app = models.TextField(
blank=True, null=True,
default="", default=None,
help_text=_( help_text=_(
"Match events created by selected application. " "Match events created by selected application. "
"When left empty, all applications are matched." "When left empty, all applications are matched."
), ),
) )
model = models.TextField( model = models.TextField(
blank=True, null=True,
default="", default=None,
help_text=_( help_text=_(
"Match events created by selected model. " "Match events created by selected model. "
"When left empty, all models are matched. When an app is selected, " "When left empty, all models are matched. When an app is selected, "
@ -66,7 +67,8 @@ class EventMatcherPolicy(Policy):
), ),
) )
client_ip = models.TextField( client_ip = models.TextField(
blank=True, null=True,
default=None,
help_text=_( help_text=_(
"Matches Event's Client IP (strict matching, " "Matches Event's Client IP (strict matching, "
"for network matching use an Expression Policy)" "for network matching use an Expression Policy)"
@ -113,25 +115,25 @@ class EventMatcherPolicy(Policy):
def passes_action(self, request: PolicyRequest, event: Event) -> PolicyResult | None: def passes_action(self, request: PolicyRequest, event: Event) -> PolicyResult | None:
"""Check if `self.action` matches""" """Check if `self.action` matches"""
if self.action == "": if self.action is None:
return None return None
return PolicyResult(self.action == event.action, "Action matched.") return PolicyResult(self.action == event.action, "Action matched.")
def passes_client_ip(self, request: PolicyRequest, event: Event) -> PolicyResult | None: def passes_client_ip(self, request: PolicyRequest, event: Event) -> PolicyResult | None:
"""Check if `self.client_ip` matches""" """Check if `self.client_ip` matches"""
if self.client_ip == "": if self.client_ip is None:
return None return None
return PolicyResult(self.client_ip == event.client_ip, "Client IP matched.") return PolicyResult(self.client_ip == event.client_ip, "Client IP matched.")
def passes_app(self, request: PolicyRequest, event: Event) -> PolicyResult | None: def passes_app(self, request: PolicyRequest, event: Event) -> PolicyResult | None:
"""Check if `self.app` matches""" """Check if `self.app` matches"""
if self.app == "": if self.app is None:
return None return None
return PolicyResult(self.app == event.app, "App matched.") return PolicyResult(self.app == event.app, "App matched.")
def passes_model(self, request: PolicyRequest, event: Event) -> PolicyResult | None: 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""" """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 return None
event_model_info = event.context.get("model", {}) event_model_info = event.context.get("model", {})
event_model = f"{event_model_info.get('app')}.{event_model_info.get('model_name')}" 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." "description": "When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged."
}, },
"action": { "action": {
"type": "string", "type": [
"null",
"string"
],
"enum": [ "enum": [
"", null,
"login", "login",
"login_failed", "login_failed",
"logout", "logout",
@ -3190,14 +3193,21 @@
"description": "Match created events with this action type. When left empty, all action types will be matched." "description": "Match created events with this action type. When left empty, all action types will be matched."
}, },
"client_ip": { "client_ip": {
"type": "string", "type": [
"string",
"null"
],
"minLength": 1,
"title": "Client ip", "title": "Client ip",
"description": "Matches Event's Client IP (strict matching, for network matching use an Expression Policy)" "description": "Matches Event's Client IP (strict matching, for network matching use an Expression Policy)"
}, },
"app": { "app": {
"type": "string", "type": [
"null",
"string"
],
"enum": [ "enum": [
"", null,
"authentik.admin", "authentik.admin",
"authentik.api", "authentik.api",
"authentik.crypto", "authentik.crypto",
@ -3251,9 +3261,12 @@
"description": "Match events created by selected application. When left empty, all applications are matched." "description": "Match events created by selected application. When left empty, all applications are matched."
}, },
"model": { "model": {
"type": "string", "type": [
"null",
"string"
],
"enum": [ "enum": [
"", null,
"authentik_crypto.certificatekeypair", "authentik_crypto.certificatekeypair",
"authentik_events.event", "authentik_events.event",
"authentik_events.notificationtransport", "authentik_events.notificationtransport",

View file

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