@@ -325,8 +325,11 @@ def _unmarshal_object(self, value, model_factory=None,
325
325
326
326
return model_factory .create (properties , name = self .model )
327
327
328
+ @requires_context
328
329
def _unmarshal_properties (self , value , one_of_schema = None ,
329
- custom_formatters = None , strict = True ):
330
+ custom_formatters = None , strict = True ,
331
+ context = None ):
332
+
330
333
all_props = self .get_all_properties ()
331
334
all_props_names = self .get_all_properties_names ()
332
335
all_req_props_names = self .get_all_required_properties_names ()
@@ -338,6 +341,21 @@ def _unmarshal_properties(self, value, one_of_schema=None,
338
341
all_req_props_names |= one_of_schema .\
339
342
get_all_required_properties_names ()
340
343
344
+ if context is UnmarshalContext .REQUEST :
345
+ forbidden_prop_names = {prop for prop in all_props_names
346
+ if all_props [prop ].read_only }
347
+ else : # Response
348
+ forbidden_prop_names = {prop for prop in all_props_names
349
+ if all_props [prop ].write_only }
350
+ all_req_props_names = all_req_props_names - forbidden_prop_names
351
+ for forbidden_prop in forbidden_prop_names :
352
+ if forbidden_prop in value :
353
+ raise InvalidSchemaProperty (
354
+ forbidden_prop ,
355
+ "Field {} is not allowed on a {} context" .format (
356
+ forbidden_prop , context .value )
357
+ )
358
+
341
359
value_props_names = value .keys ()
342
360
extra_props = set (value_props_names ) - set (all_props_names )
343
361
extra_props_allowed = self .are_additional_properties_allowed (
@@ -350,7 +368,8 @@ def _unmarshal_properties(self, value, one_of_schema=None,
350
368
for prop_name in extra_props :
351
369
prop_value = value [prop_name ]
352
370
properties [prop_name ] = self .additional_properties .unmarshal (
353
- prop_value , custom_formatters = custom_formatters )
371
+ prop_value , custom_formatters = custom_formatters ,
372
+ context = context )
354
373
355
374
for prop_name , prop in iteritems (all_props ):
356
375
try :
@@ -363,12 +382,14 @@ def _unmarshal_properties(self, value, one_of_schema=None,
363
382
prop_value = prop .default
364
383
try :
365
384
properties [prop_name ] = prop .unmarshal (
366
- prop_value , custom_formatters = custom_formatters )
385
+ prop_value , custom_formatters = custom_formatters ,
386
+ context = context )
367
387
except OpenAPISchemaError as exc :
368
388
raise InvalidSchemaProperty (prop_name , exc )
369
389
370
390
self ._validate_properties (properties , one_of_schema = one_of_schema ,
371
- custom_formatters = custom_formatters )
391
+ custom_formatters = custom_formatters ,
392
+ context = context )
372
393
373
394
return properties
374
395
@@ -559,8 +580,9 @@ def _validate_object(self, value, custom_formatters=None):
559
580
560
581
return True
561
582
583
+ @requires_context
562
584
def _validate_properties (self , value , one_of_schema = None ,
563
- custom_formatters = None ):
585
+ custom_formatters = None , context = None ):
564
586
all_props = self .get_all_properties ()
565
587
all_props_names = self .get_all_properties_names ()
566
588
all_req_props_names = self .get_all_required_properties_names ()
@@ -572,6 +594,14 @@ def _validate_properties(self, value, one_of_schema=None,
572
594
all_req_props_names |= one_of_schema .\
573
595
get_all_required_properties_names ()
574
596
597
+ if context is UnmarshalContext .REQUEST :
598
+ forbidden_prop_names = {prop for prop in all_props_names
599
+ if all_props [prop ].read_only }
600
+ else : # Response
601
+ forbidden_prop_names = {prop for prop in all_props_names
602
+ if all_props [prop ].write_only }
603
+ all_req_props_names = all_req_props_names - forbidden_prop_names
604
+
575
605
value_props_names = value .keys ()
576
606
extra_props = set (value_props_names ) - set (all_props_names )
577
607
extra_props_allowed = self .are_additional_properties_allowed (
@@ -583,7 +613,8 @@ def _validate_properties(self, value, one_of_schema=None,
583
613
for prop_name in extra_props :
584
614
prop_value = value [prop_name ]
585
615
self .additional_properties .validate (
586
- prop_value , custom_formatters = custom_formatters )
616
+ prop_value , custom_formatters = custom_formatters ,
617
+ context = context )
587
618
588
619
for prop_name , prop in iteritems (all_props ):
589
620
try :
@@ -595,7 +626,8 @@ def _validate_properties(self, value, one_of_schema=None,
595
626
continue
596
627
prop_value = prop .default
597
628
try :
598
- prop .validate (prop_value , custom_formatters = custom_formatters )
629
+ prop .validate (prop_value , custom_formatters = custom_formatters ,
630
+ context = context )
599
631
except OpenAPISchemaError as exc :
600
632
raise InvalidSchemaProperty (prop_name , original_exception = exc )
601
633
0 commit comments