5
5
from normandy .base .api .serializers import UserSerializer
6
6
from normandy .recipes import filters
7
7
from normandy .recipes .api .fields import ActionImplementationHyperlinkField
8
- from normandy .recipes .models import Action , ApprovalRequest , Recipe , RecipeRevision
8
+ from normandy .recipes .models import (
9
+ Action ,
10
+ ApprovalRequest ,
11
+ EnabledState ,
12
+ Recipe ,
13
+ RecipeRevision ,
14
+ Signature ,
15
+ )
9
16
from normandy .recipes .validators import JSONSchemaValidator
10
17
11
18
19
+ class CustomizableSerializerMixin :
20
+ """Serializer Mixin that allows callers to exclude fields on instance of this serializer."""
21
+
22
+ def __init__ (self , * args , ** kwargs ):
23
+ exclude_fields = kwargs .pop ("exclude_fields" , [])
24
+ super ().__init__ (* args , ** kwargs )
25
+
26
+ if exclude_fields :
27
+ for field in exclude_fields :
28
+ self .fields .pop (field )
29
+
30
+
12
31
class ActionSerializer (serializers .ModelSerializer ):
13
32
arguments_schema = serializers .JSONField ()
14
33
implementation_url = ActionImplementationHyperlinkField ()
@@ -28,83 +47,106 @@ class Meta:
28
47
fields = ["approved" , "approver" , "comment" , "created" , "creator" , "id" ]
29
48
30
49
50
+ class EnabledStateSerializer (CustomizableSerializerMixin , serializers .ModelSerializer ):
51
+ creator = UserSerializer ()
52
+
53
+ class Meta :
54
+ model = EnabledState
55
+ fields = ["revision_id" , "created" , "creator" , "enabled" , "carryover_from" ]
56
+
57
+
31
58
class RecipeRevisionSerializer (serializers .ModelSerializer ):
59
+ action = serializers .SerializerMethodField (read_only = True )
32
60
approval_request = ApprovalRequestSerializer (read_only = True )
33
61
comment = serializers .CharField (required = False )
62
+ creator = UserSerializer (source = "user" , read_only = True )
34
63
date_created = serializers .DateTimeField (source = "created" , read_only = True )
64
+ enabled_states = EnabledStateSerializer (many = True , exclude_fields = ["revision_id" ])
35
65
recipe = serializers .SerializerMethodField (read_only = True )
36
- user = UserSerializer ()
37
66
38
67
class Meta :
39
68
model = RecipeRevision
40
69
fields = [
70
+ "action" ,
41
71
"approval_request" ,
72
+ "arguments" ,
73
+ "bug_number" ,
42
74
"comment" ,
43
75
"date_created" ,
76
+ "enabled_states" ,
77
+ "enabled" ,
78
+ "extra_filter_expression" ,
79
+ "filter_expression" ,
80
+ "filter_object" ,
44
81
"id" ,
45
- "recipe" ,
46
- "user" ,
47
82
"identicon_seed" ,
83
+ "name" ,
84
+ "recipe" ,
85
+ "creator" ,
86
+ "updated" ,
48
87
]
49
88
50
89
def get_recipe (self , instance ):
51
- serializer = RecipeSerializer (
52
- instance .serializable_recipe ,
53
- exclude_fields = ["latest_revision" , "approved_revision" , "approval_request" ],
90
+ serializer = RecipeLinkSerializer (instance .recipe )
91
+ return serializer .data
92
+
93
+ def get_action (self , instance ):
94
+ serializer = ActionSerializer (
95
+ instance .action , read_only = True , context = {"request" : self .context .get ("request" )}
54
96
)
55
97
return serializer .data
56
98
57
99
58
- class RecipeSerializer (serializers .ModelSerializer ):
59
- action = serializers .SerializerMethodField (read_only = True )
100
+ class SignatureSerializer (serializers .ModelSerializer ):
101
+ timestamp = serializers .DateTimeField (read_only = True )
102
+ signature = serializers .ReadOnlyField ()
103
+ x5u = serializers .ReadOnlyField ()
104
+ public_key = serializers .ReadOnlyField ()
105
+
106
+ class Meta :
107
+ model = Signature
108
+ fields = ["timestamp" , "signature" , "x5u" , "public_key" ]
109
+
110
+
111
+ class RecipeSerializer (CustomizableSerializerMixin , serializers .ModelSerializer ):
112
+ # read-only fields
113
+ approved_revision = RecipeRevisionSerializer (read_only = True )
114
+ latest_revision = RecipeRevisionSerializer (read_only = True )
115
+ signature = SignatureSerializer (read_only = True )
116
+
117
+ # write-only fields
60
118
action_id = serializers .PrimaryKeyRelatedField (
61
119
source = "action" , queryset = Action .objects .all (), write_only = True
62
120
)
63
- approval_request = ApprovalRequestSerializer (read_only = True )
64
- approved_revision = RecipeRevisionSerializer (read_only = True )
65
- arguments = serializers .JSONField ()
66
- enabled = serializers .BooleanField (read_only = True )
67
- extra_filter_expression = serializers .CharField (required = False , allow_blank = True )
68
- filter_expression = serializers .CharField (read_only = True )
69
- filter_object = serializers .JSONField (required = False )
70
- last_updated = serializers .DateTimeField (read_only = True )
71
- latest_revision = RecipeRevisionSerializer (read_only = True )
72
- name = serializers .CharField ()
73
- identicon_seed = serializers .CharField (required = False )
74
- comment = serializers .CharField (required = False )
75
- bug_number = serializers .IntegerField (required = False )
121
+ arguments = serializers .JSONField (write_only = True )
122
+ extra_filter_expression = serializers .CharField (
123
+ required = False , allow_blank = True , write_only = True
124
+ )
125
+ filter_object = serializers .JSONField (required = False , write_only = True )
126
+ name = serializers .CharField (write_only = True )
127
+ identicon_seed = serializers .CharField (required = False , write_only = True )
128
+ comment = serializers .CharField (required = False , write_only = True )
129
+ bug_number = serializers .IntegerField (required = False , write_only = True )
76
130
77
131
class Meta :
78
132
model = Recipe
79
133
fields = [
80
- "action" ,
81
- "action_id" ,
82
- "approval_request" ,
134
+ # read-only
83
135
"approved_revision" ,
136
+ "id" ,
137
+ "latest_revision" ,
138
+ "signature" ,
139
+ # write-only
140
+ "action_id" ,
84
141
"arguments" ,
85
- "enabled" ,
86
142
"extra_filter_expression" ,
87
- "filter_expression" ,
88
143
"filter_object" ,
89
- "id" ,
90
- "is_approved" ,
91
- "last_updated" ,
92
- "latest_revision" ,
93
144
"name" ,
94
145
"identicon_seed" ,
95
146
"comment" ,
96
147
"bug_number" ,
97
148
]
98
149
99
- def __init__ (self , * args , ** kwargs ):
100
- exclude_fields = kwargs .pop ("exclude_fields" , [])
101
- super ().__init__ (* args , ** kwargs )
102
-
103
- if exclude_fields :
104
- for field in exclude_fields :
105
- if field in self .fields :
106
- self .fields .pop (field )
107
-
108
150
def get_action (self , instance ):
109
151
serializer = ActionSerializer (
110
152
instance .action , read_only = True , context = {"request" : self .context .get ("request" )}
@@ -244,3 +286,8 @@ def validate_filter_object(self, value):
244
286
raise serializers .ValidationError (errors )
245
287
246
288
return value
289
+
290
+
291
+ class RecipeLinkSerializer (RecipeSerializer ):
292
+ class Meta (RecipeSerializer .Meta ):
293
+ fields = ["approved_revision_id" , "id" , "latest_revision_id" ]
0 commit comments