This repository has been archived on 2024-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
authentik/passbook/policies/api.py

86 lines
2.9 KiB
Python
Raw Normal View History

2020-05-14 11:51:05 +00:00
"""policy API Views"""
from rest_framework.serializers import ModelSerializer, SerializerMethodField
from rest_framework.utils.model_meta import get_field_info
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet
2020-05-14 11:51:05 +00:00
from passbook.lib.api import InheritancePrimaryKeyRelatedField
from passbook.policies.forms import GENERAL_FIELDS
from passbook.policies.models import Policy, PolicyBinding, PolicyBindingModel
2020-05-14 11:51:05 +00:00
class PolicyBindingSerializer(ModelSerializer):
"""PolicyBinding Serializer"""
# Because we're not interested in the PolicyBindingModel's PK but rather the subclasses PK,
# we have to manually declare this field
target = InheritancePrimaryKeyRelatedField(
queryset=PolicyBindingModel.objects.all().select_subclasses(),
source="target.pk",
required=True,
)
def update(self, instance, validated_data):
info = get_field_info(instance)
# Simply set each attribute on the instance, and then save it.
# Note that unlike `.create()` we don't need to treat many-to-many
# relationships as being a special case. During updates we already
# have an instance pk for the relationships to be associated with.
m2m_fields = []
for attr, value in validated_data.items():
if attr in info.relations and info.relations[attr].to_many:
m2m_fields.append((attr, value))
else:
if attr == "target":
instance.target_pk = value["pk"].pbm_uuid
else:
setattr(instance, attr, value)
instance.save()
# Note that many-to-many fields are set after updating instance.
# Setting m2m fields triggers signals which could potentially change
# updated instance and we do not want it to collide with .update()
for attr, value in m2m_fields:
field = getattr(instance, attr)
field.set(value)
return instance
2020-05-14 11:51:05 +00:00
class Meta:
model = PolicyBinding
fields = ["pk", "policy", "target", "enabled", "order", "timeout"]
2020-05-14 11:51:05 +00:00
class PolicyBindingViewSet(ModelViewSet):
"""PolicyBinding Viewset"""
queryset = PolicyBinding.objects.all()
serializer_class = PolicyBindingSerializer
class PolicySerializer(ModelSerializer):
"""Policy Serializer"""
__type__ = SerializerMethodField(method_name="get_type")
def get_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", "")
class Meta:
model = Policy
fields = ["pk"] + GENERAL_FIELDS + ["__type__"]
class PolicyViewSet(ReadOnlyModelViewSet):
"""Policy Viewset"""
queryset = Policy.objects.all()
serializer_class = PolicySerializer
def get_queryset(self):
return Policy.objects.select_subclasses()