diff --git a/authentik/core/api/sources.py b/authentik/core/api/sources.py index 9e8b814e0..0e0c6bf9d 100644 --- a/authentik/core/api/sources.py +++ b/authentik/core/api/sources.py @@ -25,7 +25,7 @@ class SourceSerializer(ModelSerializer, MetaNameSerializer): class Meta: model = Source - fields = SOURCE_SERIALIZER_FIELDS = [ + fields = [ "pk", "name", "slug", diff --git a/authentik/policies/api.py b/authentik/policies/api.py index 99e51dc58..1428b433a 100644 --- a/authentik/policies/api.py +++ b/authentik/policies/api.py @@ -12,7 +12,6 @@ from rest_framework.serializers import ( ) from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet -from authentik.policies.forms import GENERAL_FIELDS from authentik.policies.models import Policy, PolicyBinding, PolicyBindingModel @@ -49,22 +48,28 @@ class PolicyBindingModelForeignKey(PrimaryKeyRelatedField): class PolicySerializer(ModelSerializer): """Policy Serializer""" - __type__ = SerializerMethodField(method_name="get_type") + _resolve_inheritance: bool - def get_type(self, obj): + def __init__(self, *args, resolve_inheritance: bool = True, **kwargs): + super().__init__(*args, **kwargs) + self._resolve_inheritance = resolve_inheritance + + object_type = SerializerMethodField() + + def get_object_type(self, obj): """Get object type so that we know which API Endpoint to use to get the full object""" - return obj._meta.object_name.lower().replace("policy", "") + return obj._meta.object_name.lower().replace("provider", "") def to_representation(self, instance: Policy): # pyright: reportGeneralTypeIssues=false - if instance.__class__ == Policy: + if instance.__class__ == Policy or not self._resolve_inheritance: return super().to_representation(instance) - return instance.serializer(instance=instance).data + return instance.serializer(instance=instance, resolve_inheritance=False).data class Meta: model = Policy - fields = ["pk"] + GENERAL_FIELDS + ["__type__"] + fields = ["pk", "name", "execution_logging", "object_type"] depth = 3 diff --git a/authentik/policies/dummy/api.py b/authentik/policies/dummy/api.py index 009524ab8..aa75a2b3a 100644 --- a/authentik/policies/dummy/api.py +++ b/authentik/policies/dummy/api.py @@ -1,17 +1,16 @@ """Dummy Policy API Views""" -from rest_framework.serializers import ModelSerializer from rest_framework.viewsets import ModelViewSet +from authentik.policies.api import PolicySerializer from authentik.policies.dummy.models import DummyPolicy -from authentik.policies.forms import GENERAL_SERIALIZER_FIELDS -class DummyPolicySerializer(ModelSerializer): +class DummyPolicySerializer(PolicySerializer): """Dummy Policy Serializer""" class Meta: model = DummyPolicy - fields = GENERAL_SERIALIZER_FIELDS + ["result", "wait_min", "wait_max"] + fields = PolicySerializer.Meta.fields + ["result", "wait_min", "wait_max"] class DummyPolicyViewSet(ModelViewSet): diff --git a/authentik/policies/dummy/forms.py b/authentik/policies/dummy/forms.py index bccdd107c..ed6dae995 100644 --- a/authentik/policies/dummy/forms.py +++ b/authentik/policies/dummy/forms.py @@ -4,16 +4,16 @@ from django import forms from django.utils.translation import gettext as _ from authentik.policies.dummy.models import DummyPolicy -from authentik.policies.forms import GENERAL_FIELDS +from authentik.policies.forms import PolicyForm -class DummyPolicyForm(forms.ModelForm): +class DummyPolicyForm(PolicyForm): """DummyPolicyForm Form""" class Meta: model = DummyPolicy - fields = GENERAL_FIELDS + ["result", "wait_min", "wait_max"] + fields = PolicyForm.Meta.fields + ["result", "wait_min", "wait_max"] widgets = { "name": forms.TextInput(), } diff --git a/authentik/policies/event_matcher/api.py b/authentik/policies/event_matcher/api.py index ffb5e22c8..df81d25f8 100644 --- a/authentik/policies/event_matcher/api.py +++ b/authentik/policies/event_matcher/api.py @@ -1,17 +1,16 @@ """Event Matcher Policy API""" -from rest_framework.serializers import ModelSerializer from rest_framework.viewsets import ModelViewSet +from authentik.policies.api import PolicySerializer from authentik.policies.event_matcher.models import EventMatcherPolicy -from authentik.policies.forms import GENERAL_SERIALIZER_FIELDS -class EventMatcherPolicySerializer(ModelSerializer): +class EventMatcherPolicySerializer(PolicySerializer): """Event Matcher Policy Serializer""" class Meta: model = EventMatcherPolicy - fields = GENERAL_SERIALIZER_FIELDS + [ + fields = PolicySerializer.Meta.fields + [ "action", "client_ip", "app", diff --git a/authentik/policies/event_matcher/forms.py b/authentik/policies/event_matcher/forms.py index 822a0c6e0..e9707f5db 100644 --- a/authentik/policies/event_matcher/forms.py +++ b/authentik/policies/event_matcher/forms.py @@ -4,16 +4,16 @@ from django import forms from django.utils.translation import gettext_lazy as _ from authentik.policies.event_matcher.models import EventMatcherPolicy -from authentik.policies.forms import GENERAL_FIELDS +from authentik.policies.forms import PolicyForm -class EventMatcherPolicyForm(forms.ModelForm): +class EventMatcherPolicyForm(PolicyForm): """EventMatcherPolicy Form""" class Meta: model = EventMatcherPolicy - fields = GENERAL_FIELDS + [ + fields = PolicyForm.Meta.fields + [ "action", "client_ip", "app", diff --git a/authentik/policies/expiry/api.py b/authentik/policies/expiry/api.py index 820ca7f63..3fb9c410e 100644 --- a/authentik/policies/expiry/api.py +++ b/authentik/policies/expiry/api.py @@ -1,17 +1,16 @@ """Password Expiry Policy API Views""" -from rest_framework.serializers import ModelSerializer from rest_framework.viewsets import ModelViewSet +from authentik.policies.api import PolicySerializer from authentik.policies.expiry.models import PasswordExpiryPolicy -from authentik.policies.forms import GENERAL_SERIALIZER_FIELDS -class PasswordExpiryPolicySerializer(ModelSerializer): +class PasswordExpiryPolicySerializer(PolicySerializer): """Password Expiry Policy Serializer""" class Meta: model = PasswordExpiryPolicy - fields = GENERAL_SERIALIZER_FIELDS + ["days", "deny_only"] + fields = PolicySerializer.Meta.fields + ["days", "deny_only"] class PasswordExpiryPolicyViewSet(ModelViewSet): diff --git a/authentik/policies/expiry/forms.py b/authentik/policies/expiry/forms.py index 223c00e76..08631358d 100644 --- a/authentik/policies/expiry/forms.py +++ b/authentik/policies/expiry/forms.py @@ -4,16 +4,16 @@ from django import forms from django.utils.translation import gettext as _ from authentik.policies.expiry.models import PasswordExpiryPolicy -from authentik.policies.forms import GENERAL_FIELDS +from authentik.policies.forms import PolicyForm -class PasswordExpiryPolicyForm(forms.ModelForm): +class PasswordExpiryPolicyForm(PolicyForm): """Edit PasswordExpiryPolicy instances""" class Meta: model = PasswordExpiryPolicy - fields = GENERAL_FIELDS + ["days", "deny_only"] + fields = PolicyForm.Meta.fields + ["days", "deny_only"] widgets = { "name": forms.TextInput(), "order": forms.NumberInput(), diff --git a/authentik/policies/expression/api.py b/authentik/policies/expression/api.py index c02f945a2..8728be5ea 100644 --- a/authentik/policies/expression/api.py +++ b/authentik/policies/expression/api.py @@ -1,17 +1,16 @@ """Expression Policy API""" -from rest_framework.serializers import ModelSerializer from rest_framework.viewsets import ModelViewSet +from authentik.policies.api import PolicySerializer from authentik.policies.expression.models import ExpressionPolicy -from authentik.policies.forms import GENERAL_SERIALIZER_FIELDS -class ExpressionPolicySerializer(ModelSerializer): +class ExpressionPolicySerializer(PolicySerializer): """Group Membership Policy Serializer""" class Meta: model = ExpressionPolicy - fields = GENERAL_SERIALIZER_FIELDS + ["expression"] + fields = PolicySerializer.Meta.fields + ["expression"] class ExpressionPolicyViewSet(ModelViewSet): diff --git a/authentik/policies/expression/forms.py b/authentik/policies/expression/forms.py index 505c6ec37..4bf2c9a5a 100644 --- a/authentik/policies/expression/forms.py +++ b/authentik/policies/expression/forms.py @@ -5,10 +5,10 @@ from django import forms from authentik.admin.fields import CodeMirrorWidget from authentik.policies.expression.evaluator import PolicyEvaluator from authentik.policies.expression.models import ExpressionPolicy -from authentik.policies.forms import GENERAL_FIELDS +from authentik.policies.forms import PolicyForm -class ExpressionPolicyForm(forms.ModelForm): +class ExpressionPolicyForm(PolicyForm): """ExpressionPolicy Form""" template_name = "policy/expression/form.html" @@ -22,7 +22,7 @@ class ExpressionPolicyForm(forms.ModelForm): class Meta: model = ExpressionPolicy - fields = GENERAL_FIELDS + [ + fields = PolicyForm.Meta.fields + [ "expression", ] widgets = { diff --git a/authentik/policies/forms.py b/authentik/policies/forms.py index b737ec817..5148e349d 100644 --- a/authentik/policies/forms.py +++ b/authentik/policies/forms.py @@ -5,9 +5,6 @@ from django import forms from authentik.lib.widgets import GroupedModelChoiceField from authentik.policies.models import Policy, PolicyBinding, PolicyBindingModel -GENERAL_FIELDS = ["name", "execution_logging"] -GENERAL_SERIALIZER_FIELDS = ["pk", "name"] - class PolicyBindingForm(forms.ModelForm): """Form to edit Policy to PolicyBindingModel Binding""" @@ -29,3 +26,12 @@ class PolicyBindingForm(forms.ModelForm): model = PolicyBinding fields = ["enabled", "policy", "target", "order", "timeout"] + + +class PolicyForm(forms.ModelForm): + """Base Policy form""" + + class Meta: + + model = Policy + fields = ["name", "execution_logging"] diff --git a/authentik/policies/group_membership/api.py b/authentik/policies/group_membership/api.py index 6aa5e2986..671b1654d 100644 --- a/authentik/policies/group_membership/api.py +++ b/authentik/policies/group_membership/api.py @@ -1,17 +1,16 @@ """Group Membership Policy API""" -from rest_framework.serializers import ModelSerializer from rest_framework.viewsets import ModelViewSet -from authentik.policies.forms import GENERAL_SERIALIZER_FIELDS +from authentik.policies.api import PolicySerializer from authentik.policies.group_membership.models import GroupMembershipPolicy -class GroupMembershipPolicySerializer(ModelSerializer): +class GroupMembershipPolicySerializer(PolicySerializer): """Group Membership Policy Serializer""" class Meta: model = GroupMembershipPolicy - fields = GENERAL_SERIALIZER_FIELDS + [ + fields = PolicySerializer.Meta.fields + [ "group", ] diff --git a/authentik/policies/group_membership/forms.py b/authentik/policies/group_membership/forms.py index 250f74ca6..6fa3e8761 100644 --- a/authentik/policies/group_membership/forms.py +++ b/authentik/policies/group_membership/forms.py @@ -2,17 +2,17 @@ from django import forms -from authentik.policies.forms import GENERAL_FIELDS +from authentik.policies.forms import PolicyForm from authentik.policies.group_membership.models import GroupMembershipPolicy -class GroupMembershipPolicyForm(forms.ModelForm): +class GroupMembershipPolicyForm(PolicyForm): """GroupMembershipPolicy Form""" class Meta: model = GroupMembershipPolicy - fields = GENERAL_FIELDS + [ + fields = PolicyForm.Meta.fields + [ "group", ] widgets = { diff --git a/authentik/policies/hibp/api.py b/authentik/policies/hibp/api.py index ab0ff1ff7..02f91f4fb 100644 --- a/authentik/policies/hibp/api.py +++ b/authentik/policies/hibp/api.py @@ -1,17 +1,16 @@ """Source API Views""" -from rest_framework.serializers import ModelSerializer from rest_framework.viewsets import ModelViewSet -from authentik.policies.forms import GENERAL_SERIALIZER_FIELDS +from authentik.policies.api import PolicySerializer from authentik.policies.hibp.models import HaveIBeenPwendPolicy -class HaveIBeenPwendPolicySerializer(ModelSerializer): +class HaveIBeenPwendPolicySerializer(PolicySerializer): """Have I Been Pwned Policy Serializer""" class Meta: model = HaveIBeenPwendPolicy - fields = GENERAL_SERIALIZER_FIELDS + ["password_field", "allowed_count"] + fields = PolicySerializer.Meta.fields + ["password_field", "allowed_count"] class HaveIBeenPwendPolicyViewSet(ModelViewSet): diff --git a/authentik/policies/hibp/forms.py b/authentik/policies/hibp/forms.py index e389847f5..62708ac9a 100644 --- a/authentik/policies/hibp/forms.py +++ b/authentik/policies/hibp/forms.py @@ -2,17 +2,17 @@ from django import forms -from authentik.policies.forms import GENERAL_FIELDS +from authentik.policies.forms import PolicyForm from authentik.policies.hibp.models import HaveIBeenPwendPolicy -class HaveIBeenPwnedPolicyForm(forms.ModelForm): +class HaveIBeenPwnedPolicyForm(PolicyForm): """Edit HaveIBeenPwendPolicy instances""" class Meta: model = HaveIBeenPwendPolicy - fields = GENERAL_FIELDS + ["password_field", "allowed_count"] + fields = PolicyForm.Meta.fields + ["password_field", "allowed_count"] widgets = { "name": forms.TextInput(), "password_field": forms.TextInput(), diff --git a/authentik/policies/password/api.py b/authentik/policies/password/api.py index 5dae9b47f..050b41a3f 100644 --- a/authentik/policies/password/api.py +++ b/authentik/policies/password/api.py @@ -1,17 +1,16 @@ """Password Policy API Views""" -from rest_framework.serializers import ModelSerializer from rest_framework.viewsets import ModelViewSet -from authentik.policies.forms import GENERAL_SERIALIZER_FIELDS +from authentik.policies.api import PolicySerializer from authentik.policies.password.models import PasswordPolicy -class PasswordPolicySerializer(ModelSerializer): +class PasswordPolicySerializer(PolicySerializer): """Password Policy Serializer""" class Meta: model = PasswordPolicy - fields = GENERAL_SERIALIZER_FIELDS + [ + fields = PolicySerializer.Meta.fields + [ "password_field", "amount_uppercase", "amount_lowercase", diff --git a/authentik/policies/password/forms.py b/authentik/policies/password/forms.py index 2707da69b..df2de293f 100644 --- a/authentik/policies/password/forms.py +++ b/authentik/policies/password/forms.py @@ -3,17 +3,17 @@ from django import forms from django.utils.translation import gettext as _ -from authentik.policies.forms import GENERAL_FIELDS +from authentik.policies.forms import PolicyForm from authentik.policies.password.models import PasswordPolicy -class PasswordPolicyForm(forms.ModelForm): +class PasswordPolicyForm(PolicyForm): """PasswordPolicy Form""" class Meta: model = PasswordPolicy - fields = GENERAL_FIELDS + [ + fields = PolicyForm.Meta.fields + [ "password_field", "amount_uppercase", "amount_lowercase", diff --git a/authentik/policies/reputation/api.py b/authentik/policies/reputation/api.py index 2a5fd7c7b..23eb78c41 100644 --- a/authentik/policies/reputation/api.py +++ b/authentik/policies/reputation/api.py @@ -1,17 +1,20 @@ """Source API Views""" -from rest_framework.serializers import ModelSerializer from rest_framework.viewsets import ModelViewSet -from authentik.policies.forms import GENERAL_SERIALIZER_FIELDS +from authentik.policies.api import PolicySerializer from authentik.policies.reputation.models import ReputationPolicy -class ReputationPolicySerializer(ModelSerializer): +class ReputationPolicySerializer(PolicySerializer): """Reputation Policy Serializer""" class Meta: model = ReputationPolicy - fields = GENERAL_SERIALIZER_FIELDS + ["check_ip", "check_username", "threshold"] + fields = PolicySerializer.Meta.fields + [ + "check_ip", + "check_username", + "threshold", + ] class ReputationPolicyViewSet(ModelViewSet): diff --git a/authentik/policies/reputation/forms.py b/authentik/policies/reputation/forms.py index ce3a23ed0..c3adecb16 100644 --- a/authentik/policies/reputation/forms.py +++ b/authentik/policies/reputation/forms.py @@ -2,17 +2,17 @@ from django import forms from django.utils.translation import gettext_lazy as _ -from authentik.policies.forms import GENERAL_FIELDS +from authentik.policies.forms import PolicyForm from authentik.policies.reputation.models import ReputationPolicy -class ReputationPolicyForm(forms.ModelForm): +class ReputationPolicyForm(PolicyForm): """Form to edit ReputationPolicy""" class Meta: model = ReputationPolicy - fields = GENERAL_FIELDS + ["check_ip", "check_username", "threshold"] + fields = PolicyForm.Meta.fields + ["check_ip", "check_username", "threshold"] widgets = { "name": forms.TextInput(), "value": forms.TextInput(), diff --git a/swagger.yaml b/swagger.yaml index 350410702..bc842bad9 100755 --- a/swagger.yaml +++ b/swagger.yaml @@ -8626,8 +8626,8 @@ definitions: description: When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged. type: boolean - __type__: - title: 'type ' + object_type: + title: Object type type: string readOnly: true PolicyBinding: @@ -8680,6 +8680,15 @@ definitions: title: Name type: string x-nullable: true + execution_logging: + title: Execution logging + description: When this option is enabled, all executions of this policy will + be logged. By default, only execution errors are logged. + type: boolean + object_type: + title: Object type + type: string + readOnly: true result: title: Result type: boolean @@ -8706,6 +8715,15 @@ definitions: title: Name type: string x-nullable: true + execution_logging: + title: Execution logging + description: When this option is enabled, all executions of this policy will + be logged. By default, only execution errors are logged. + type: boolean + object_type: + title: Object type + type: string + readOnly: true action: title: Action description: Match created events with this action type. When left empty, @@ -8801,6 +8819,15 @@ definitions: title: Name type: string x-nullable: true + execution_logging: + title: Execution logging + description: When this option is enabled, all executions of this policy will + be logged. By default, only execution errors are logged. + type: boolean + object_type: + title: Object type + type: string + readOnly: true expression: title: Expression type: string @@ -8818,6 +8845,15 @@ definitions: title: Name type: string x-nullable: true + execution_logging: + title: Execution logging + description: When this option is enabled, all executions of this policy will + be logged. By default, only execution errors are logged. + type: boolean + object_type: + title: Object type + type: string + readOnly: true group: title: Group type: string @@ -8836,6 +8872,15 @@ definitions: title: Name type: string x-nullable: true + execution_logging: + title: Execution logging + description: When this option is enabled, all executions of this policy will + be logged. By default, only execution errors are logged. + type: boolean + object_type: + title: Object type + type: string + readOnly: true password_field: title: Password field description: Field key to check, field keys defined in Prompt stages are available. @@ -8861,6 +8906,15 @@ definitions: title: Name type: string x-nullable: true + execution_logging: + title: Execution logging + description: When this option is enabled, all executions of this policy will + be logged. By default, only execution errors are logged. + type: boolean + object_type: + title: Object type + type: string + readOnly: true password_field: title: Password field description: Field key to check, field keys defined in Prompt stages are available. @@ -8909,6 +8963,15 @@ definitions: title: Name type: string x-nullable: true + execution_logging: + title: Execution logging + description: When this option is enabled, all executions of this policy will + be logged. By default, only execution errors are logged. + type: boolean + object_type: + title: Object type + type: string + readOnly: true days: title: Days type: integer @@ -8930,6 +8993,15 @@ definitions: title: Name type: string x-nullable: true + execution_logging: + title: Execution logging + description: When this option is enabled, all executions of this policy will + be logged. By default, only execution errors are logged. + type: boolean + object_type: + title: Object type + type: string + readOnly: true check_ip: title: Check ip type: boolean