diff options
author | Aleksey Lim <alsroot@sugarlabs.org> | 2012-11-02 09:06:54 (GMT) |
---|---|---|
committer | Aleksey Lim <alsroot@sugarlabs.org> | 2012-11-02 09:06:54 (GMT) |
commit | d03ccb79029b91298053f33db0ac6a1ca6e0fe3d (patch) | |
tree | e31793cb88bf9844425d3bf50801a573375caf03 | |
parent | 999f9fdb84de46c3a1341f415e4075b4d9c7179d (diff) |
Call property setter on creation even if there is no create permissions
-rw-r--r-- | active_document/metadata.py | 2 | ||||
-rw-r--r-- | active_document/volume.py | 24 | ||||
-rwxr-xr-x | tests/units/volume.py | 19 |
3 files changed, 33 insertions, 12 deletions
diff --git a/active_document/metadata.py b/active_document/metadata.py index 42715dc..f0e54e0 100644 --- a/active_document/metadata.py +++ b/active_document/metadata.py @@ -132,7 +132,7 @@ class Property(object): reprcast=None, default=None): self.setter = None self.on_get = lambda self, x: x - self.on_set = lambda self, x: x + self.on_set = None self._name = name self._permissions = permissions self._typecast = typecast diff --git a/active_document/volume.py b/active_document/volume.py index 70f3341..d5b7f92 100644 --- a/active_document/volume.py +++ b/active_document/volume.py @@ -137,6 +137,10 @@ class VolumeCommands(CommandsProcessor): enforce('guid' not in doc.props, env.Forbidden, "Property 'guid' cannot be set manually") self.before_create(request, doc.props) + for prop in directory.metadata.values(): + if prop.on_set is not None and \ + not prop.permissions & env.ACCESS_CREATE: + doc[prop.name] = prop.on_set(doc, prop.default) doc.guid = directory.create(doc.props) return doc.guid @@ -231,21 +235,19 @@ class VolumeCommands(CommandsProcessor): for name, value in request.content.items(): prop = directory.metadata[name] - value = prop.on_set(doc, value) - + if isinstance(prop, BlobProperty) and access == env.ACCESS_WRITE: + if doc.meta(name) is None: + prop.assert_access(env.ACCESS_CREATE) + else: + prop.assert_access(env.ACCESS_WRITE) + else: + prop.assert_access(access) + if prop.on_set is not None: + value = prop.on_set(doc, value) if isinstance(prop, BlobProperty): enforce(PropertyMeta.is_blob(value), 'Invalid BLOB value') - if access == env.ACCESS_WRITE: - if doc.meta(name) is None: - blob_access = env.ACCESS_CREATE - else: - blob_access = env.ACCESS_WRITE - else: - blob_access = access - prop.assert_access(blob_access) blobs.append((name, value)) else: - prop.assert_access(access) if prop.localized and isinstance(value, basestring): value = {(request.accept_language or self._lang)[0]: value} doc.props[name] = value diff --git a/tests/units/volume.py b/tests/units/volume.py index 0c79343..3977b2b 100755 --- a/tests/units/volume.py +++ b/tests/units/volume.py @@ -853,6 +853,25 @@ class VolumeTest(tests.Test): sorted([{'prop': '1'}, {'prop': '2'}]), sorted(self.call('GET', document='testdocument', reply='prop', group_by='prop')['result'])) + def test_CallSetterEvenIfThereIsNoCreatePermissions(self): + + class TestDocument(Document): + + @active_property(slot=1, permissions=ad.ACCESS_READ, default=0) + def prop(self, value): + return value + + @prop.setter + def prop(self, value): + return value + 1 + + self.volume = SingleVolume(tests.tmpdir, [TestDocument]) + + self.assertRaises(ad.Forbidden, self.call, 'POST', document='testdocument', content={'prop': 1}) + + guid = self.call('POST', document='testdocument', content={}) + self.assertEqual('1', self.call('GET', document='testdocument', guid=guid, prop='prop')) + def call(self, method, document=None, guid=None, prop=None, accept_language=None, content=None, content_stream=None, if_modified_since=None, **kwargs): |