Coverage for backend/django/core/auxiliary/serializers/FlowsheetSerializer.py: 95%
68 statements
« prev ^ index » next coverage.py v7.10.7, created at 2026-06-23 21:51 +0000
« prev ^ index » next coverage.py v7.10.7, created at 2026-06-23 21:51 +0000
1from rest_framework import serializers
2from drf_spectacular.utils import extend_schema_field
3from core.auxiliary.models.Flowsheet import Flowsheet
4from core.auxiliary.enums.FlowsheetTemplateType import FlowsheetTemplateType
5from authentication.user.AccessTable import AccessTable
6from authentication.user.models import User
9class OwnerSerializer(serializers.ModelSerializer):
10 class Meta:
11 model = User
12 fields = [
13 'id',
14 'email',
15 'first_name',
16 'last_name'
17 ]
18 read_only_fields = [
19 'id',
20 'email',
21 'first_name',
22 'last_name'
23 ]
26class FlowsheetAccessSerializer(serializers.Serializer):
27 is_owner = serializers.BooleanField()
28 read_only = serializers.BooleanField()
29 can_edit = serializers.BooleanField()
30 can_share = serializers.BooleanField()
31 can_copy = serializers.BooleanField()
32 can_export = serializers.BooleanField()
33 can_manage_template_settings = serializers.BooleanField()
36class FlowsheetSerializer(serializers.ModelSerializer):
37 owner = OwnerSerializer(read_only=True)
38 access = serializers.SerializerMethodField()
40 class Meta:
41 model = Flowsheet
42 fields = "__all__"
43 read_only_fields = ['owner']
45 def _get_user_access_row(self, flowsheet: Flowsheet, user: User | None):
46 if user is None or not user.is_authenticated: 46 ↛ 47line 46 didn't jump to line 47 because the condition on line 46 was never true
47 return None
49 prefetched_access_entries = getattr(flowsheet, "current_user_access_entries", None)
50 if prefetched_access_entries is not None:
51 return prefetched_access_entries[0] if prefetched_access_entries else None
53 return AccessTable.objects.filter(flowsheet=flowsheet, user=user).first()
55 @extend_schema_field(FlowsheetAccessSerializer)
56 def get_access(self, obj: Flowsheet):
57 """
58 Expose frontend-facing capability flags derived from the same ownership /
59 share rules that the backend enforces for mutations.
60 """
61 request = self.context.get("request")
62 user: User | None = getattr(request, "user", None)
63 access_row = self._get_user_access_row(obj, user)
65 is_owner = bool(user and user.is_authenticated and obj.owner_id == user.id)
66 can_edit_public_template = bool(
67 user
68 and user.is_authenticated
69 and user.is_staff
70 and obj.flowsheet_template_type == FlowsheetTemplateType.PublicTemplate
71 )
72 has_direct_access = is_owner or access_row is not None
73 has_read_access = has_direct_access or can_edit_public_template
75 if is_owner or can_edit_public_template:
76 read_only = False
77 elif access_row is not None: 77 ↛ 80line 77 didn't jump to line 80 because the condition on line 77 was always true
78 read_only = bool(access_row.read_only)
79 else:
80 read_only = True
82 can_edit = has_read_access and not read_only
83 can_share = is_owner and obj.flowsheet_template_type == FlowsheetTemplateType.NotTemplate
84 can_copy = has_read_access or obj.flowsheet_template_type == FlowsheetTemplateType.PublicTemplate
85 can_export = has_read_access
87 if obj.flowsheet_template_type == FlowsheetTemplateType.PublicTemplate:
88 can_manage_template_settings = bool(user and user.is_authenticated and user.is_staff)
89 else:
90 can_manage_template_settings = is_owner
92 return {
93 "is_owner": is_owner,
94 "read_only": read_only,
95 "can_edit": can_edit,
96 "can_share": can_share,
97 "can_copy": can_copy,
98 "can_export": can_export,
99 "can_manage_template_settings": can_manage_template_settings,
100 }
102 def create(self, validated_data):
103 context = self.context
104 request = context["request"]
105 owner = request.user
107 validated_data["owner"] = owner
109 # Return primary key of Flowsheet
110 return Flowsheet.create(**validated_data)
112 def validate(self, attrs):
113 context = self.context
114 request = context["request"]
115 owner = request.user
117 if owner is None:
118 raise serializers.ValidationError("Flowsheet must have an owner")
120 return super().validate(attrs)