plone.restapi icon indicating copy to clipboard operation
plone.restapi copied to clipboard

Serializer should use plone.app.uuid.utils.uuidToObject

Open mauritsvanrees opened this issue 2 years ago • 0 comments

Compare these two imports:

https://github.com/plone/plone.restapi/blob/b86c20cca15120be62b73ed24f944db22d189f44/src/plone/restapi/services/content/utils.py#L4

https://github.com/plone/plone.restapi/blob/b86c20cca15120be62b73ed24f944db22d189f44/src/plone/restapi/serializer/utils.py#L1

We should use the one from plone.app.uuid in both places, as I want to deprecate the one from plone.outputfilters. In fact, I have already deprecated it as small cleanup in a larger PR, but will revert that for now.

Problem is that then two tests fail, because the plone.app.uuid one does a security check. Sample failure:

Error in test test_resolveuid_serialize_take_care_of_primary_fields (plone.restapi.tests.test_resolveuid.TestBlocksResolveUID)
Traceback (most recent call last):
  File "/Users/maurits/.pyenv/versions/3.10.1/lib/python3.10/unittest/case.py", line 59, in testPartExecutor
    yield
  File "/Users/maurits/.pyenv/versions/3.10.1/lib/python3.10/unittest/case.py", line 591, in run
    self._callTestMethod(testMethod)
  File "/Users/maurits/.pyenv/versions/3.10.1/lib/python3.10/unittest/case.py", line 549, in _callTestMethod
    method()
  File "/Users/maurits/community/plone-coredev/6.0/src/plone.restapi/src/plone/restapi/tests/test_resolveuid.py", line 346, in test_resolveuid_serialize_take_care_of_primary_fields
    value = self.serialize("blocks", blocks)
  File "/Users/maurits/community/plone-coredev/6.0/src/plone.restapi/src/plone/restapi/tests/test_resolveuid.py", line 242, in serialize
    return serializer()
  File "/Users/maurits/community/plone-coredev/6.0/src/plone.restapi/src/plone/restapi/serializer/blocks.py", line 72, in __call__
    block_value = handler(block_value)
  File "/Users/maurits/community/plone-coredev/6.0/src/plone.restapi/src/plone/restapi/serializer/blocks.py", line 94, in __call__
    value[field] = uid_to_url(link)
  File "/Users/maurits/community/plone-coredev/6.0/src/plone.restapi/src/plone/restapi/serializer/utils.py", line 28, in uid_to_url
    target_object = uuidToObject(uid)
  File "/Users/maurits/community/plone-coredev/6.0/src/plone.app.uuid/plone/app/uuid/utils.py", line 91, in uuidToObject
    return parent.restrictedTraverse(final_path)
  File "/Users/maurits/community/plone-coredev/6.0/src/Zope/src/OFS/Traversable.py", line 364, in restrictedTraverse
    return self.unrestrictedTraverse(path, default, restricted=True)
  File "/Users/maurits/community/plone-coredev/6.0/src/Zope/src/OFS/Traversable.py", line 296, in unrestrictedTraverse
    next = guarded_getattr(obj, name)
   - __traceback_info__: ([], 'doc_primary_field_url')
  File "/Users/maurits/shared-eggs/cp310/AccessControl-5.3.1-py3.10-macosx-10.15-x86_64.egg/AccessControl/ImplPython.py", line 598, in validate
    return policy.validate(accessed, container, name, value,
  File "/Users/maurits/shared-eggs/cp310/AccessControl-5.3.1-py3.10-macosx-10.15-x86_64.egg/AccessControl/ImplPython.py", line 486, in validate
    raise Unauthorized(name, value)
AccessControl.unauthorized.Unauthorized: You are not allowed to access 'doc_primary_field_url' in this context

In this failing test we are anonymous because we logout. If I comment out this line so we are authenticated as the test user, the uuidToObject call works fine, but the test surprisingly goes wrong in a different way:

ailure in test test_resolveuid_serialize_take_care_of_primary_fields (plone.restapi.tests.test_resolveuid.TestBlocksResolveUID)
Traceback (most recent call last):
  File "/Users/maurits/.pyenv/versions/3.10.1/lib/python3.10/unittest/case.py", line 59, in testPartExecutor
    yield
  File "/Users/maurits/.pyenv/versions/3.10.1/lib/python3.10/unittest/case.py", line 591, in run
    self._callTestMethod(testMethod)
  File "/Users/maurits/.pyenv/versions/3.10.1/lib/python3.10/unittest/case.py", line 549, in _callTestMethod
    method()
  File "/Users/maurits/community/plone-coredev/6.0/src/plone.restapi/src/plone/restapi/tests/test_resolveuid.py", line 347, in test_resolveuid_serialize_take_care_of_primary_fields
    self.assertEqual(
  File "/Users/maurits/.pyenv/versions/3.10.1/lib/python3.10/unittest/case.py", line 845, in assertEqual
    assertion_func(first, second, msg=msg)
  File "/Users/maurits/.pyenv/versions/3.10.1/lib/python3.10/unittest/case.py", line 1226, in assertMultiLineEqual
    self.fail(self._formatMessage(msg, standardMsg))
  File "/Users/maurits/.pyenv/versions/3.10.1/lib/python3.10/unittest/case.py", line 675, in fail
    raise self.failureException(msg)
AssertionError: 'http[15 chars]/doc_primary_field_url' != 'http[15 chars]/doc_primary_field_url/@@download/test_primary_namedfile_field'
- http://nohost/plone/doc_primary_field_url
+ http://nohost/plone/doc_primary_field_url/@@download/test_primary_namedfile_field

This is because the IObjectPrimaryFieldTarget adapter for the object is found, but calling it returns nothing, so we get the original url, instead of a direct download link. I have no idea why this would suddenly fail, where with the original code it worked fine, also for anonymous.

mauritsvanrees avatar Jun 09 '22 23:06 mauritsvanrees