diff options
author | Yuriy Zveryanskyy <yzveryanskyy@mirantis.com> | 2013-12-12 17:23:05 +0200 |
---|---|---|
committer | Yuriy Zveryanskyy <yzveryanskyy@mirantis.com> | 2013-12-12 18:14:57 +0200 |
commit | e26d1b608cc5a05940c0b6b7fc176a0d587ba611 (patch) | |
tree | 6560b082cc3f3e3a07e932c8bd19850830244a35 | |
parent | 9751ccebfa8c3cfbbc6b38e398f35ab557d7747c (diff) | |
download | wsme-e26d1b608cc5a05940c0b6b7fc176a0d587ba611.tar.gz |
Add 'readonly' parameter to wsattr0.6
'readonly' parameter added to wsattr. If True value cannot be set from
input data. This is intended for attributes which should be only
exposed to user without possibility of change.
Change-Id: I767a29c5113891f89676c5e78adf018d5e0e4f26
-rw-r--r-- | wsme/rest/json.py | 7 | ||||
-rw-r--r-- | wsme/rest/xml.py | 6 | ||||
-rw-r--r-- | wsme/tests/test_api.py | 19 | ||||
-rw-r--r-- | wsme/types.py | 5 |
4 files changed, 33 insertions, 4 deletions
diff --git a/wsme/rest/json.py b/wsme/rest/json.py index 42a9559..9adfd6b 100644 --- a/wsme/rest/json.py +++ b/wsme/rest/json.py @@ -135,8 +135,11 @@ def fromjson(datatype, value): obj = datatype() for attrdef in wsme.types.list_attributes(datatype): if attrdef.name in value: - setattr(obj, attrdef.key, - fromjson(attrdef.datatype, value[attrdef.name])) + val_fromjson = fromjson(attrdef.datatype, value[attrdef.name]) + if getattr(attrdef, 'readonly', False): + raise InvalidInput(attrdef.name, val_fromjson, + "Cannot set read only field.") + setattr(obj, attrdef.key, val_fromjson) elif attrdef.mandatory: raise InvalidInput(attrdef.name, None, "Mandatory field missing.") diff --git a/wsme/rest/xml.py b/wsme/rest/xml.py index 9a836c3..286afa7 100644 --- a/wsme/rest/xml.py +++ b/wsme/rest/xml.py @@ -101,7 +101,11 @@ def fromxml(datatype, element): for attrdef in wsme.types.list_attributes(datatype): sub = element.find(attrdef.name) if sub is not None: - setattr(obj, attrdef.key, fromxml(attrdef.datatype, sub)) + val_fromxml = fromxml(attrdef.datatype, sub) + if getattr(attrdef, 'readonly', False): + raise InvalidInput(attrdef.name, val_fromxml, + "Cannot set read only field.") + setattr(obj, attrdef.key, val_fromxml) elif attrdef.mandatory: raise InvalidInput(attrdef.name, None, "Mandatory field missing.") diff --git a/wsme/tests/test_api.py b/wsme/tests/test_api.py index db85c51..9149cf9 100644 --- a/wsme/tests/test_api.py +++ b/wsme/tests/test_api.py @@ -287,6 +287,25 @@ Value should be one of:")) headers={'Accept': 'application/json'}) self.assertEqual(res.status_int, 400) + def test_wsattr_readonly(self): + class ComplexType(object): + attr = wsme.types.wsattr(int, readonly=True) + + class MyRoot(WSRoot): + @expose(int, body=ComplexType) + @validate(ComplexType) + def clx(self, a): + return a.attr + + r = MyRoot(['restjson']) + app = webtest.TestApp(r.wsgiapp()) + res = app.post_json('/clx', params={'attr': 1005}, expect_errors=True, + headers={'Accept': 'application/json'}) + self.assertIn('Cannot set read only field.', + res.json_body['faultstring']) + self.assertIn('1005', res.json_body['faultstring']) + self.assertEqual(res.status_int, 400) + def test_wsattr_default(self): class ComplexType(object): attr = wsme.types.wsattr(wsme.types.Enum(str, 'or', 'and'), diff --git a/wsme/types.py b/wsme/types.py index 7adef83..9701a61 100644 --- a/wsme/types.py +++ b/wsme/types.py @@ -447,7 +447,8 @@ class wsattr(object): mandatoryvalue = wsattr(int, mandatory=True) """ - def __init__(self, datatype, mandatory=False, name=None, default=Unset): + def __init__(self, datatype, mandatory=False, name=None, default=Unset, + readonly=False): #: The attribute name in the parent python class. #: Set by :func:`inspect_class` self.key = None # will be set by class inspection @@ -460,6 +461,8 @@ class wsattr(object): #: Default value. The attribute will return this instead #: of :data:`Unset` if no value has been set. self.default = default + #: If True value cannot be set from json/xml input data + self.readonly = readonly self.complextype = None |