Although the set of permissions provided on a record is a list, semantically it's a set -- order doesn't matter, and duplicates aren't allowed. However, in the Postgres backend, we enforce this at the DB level, so if you violate this constraint, you get a 503:
Traceback (most recent call last):
File ".../kinto/.venv/local/lib/python2.7/site-packages/pyramid/tweens.py", line 20, in excview_tween
response = handler(request)
File ".../kinto/.venv/local/lib/python2.7/site-packages/pyramid_tm/__init__.py", line 101, in tm_tween
reraise(*exc_info)
File ".../kinto/.venv/local/lib/python2.7/site-packages/pyramid_tm/__init__.py", line 83, in tm_tween
response = handler(request)
File ".../kinto/.venv/local/lib/python2.7/site-packages/pyramid/router.py", line 158, in handle_request
view_name
File ".../kinto/.venv/local/lib/python2.7/site-packages/pyramid/view.py", line 546, in _call_view
response = view_callable(context, request)
File ".../kinto/.venv/local/lib/python2.7/site-packages/pyramid/viewderivers.py", line 396, in viewresult_to_response
result = view(context, request)
File ".../kinto/.venv/local/lib/python2.7/site-packages/pyramid/viewderivers.py", line 146, in _requestonly_view
response = view(request)
File ".../kinto/kinto/plugins/default_bucket/__init__.py", line 143, in default_bucket
response = request.invoke_subrequest(subrequest)
File ".../kinto/.venv/local/lib/python2.7/site-packages/pyramid/router.py", line 211, in invoke_subrequest
response = handle_request(request)
File ".../kinto/.venv/local/lib/python2.7/site-packages/pyramid/router.py", line 158, in handle_request
view_name
File ".../kinto/.venv/local/lib/python2.7/site-packages/pyramid/view.py", line 546, in _call_view
response = view_callable(context, request)
File ".../kinto/.venv/local/lib/python2.7/site-packages/pyramid/config/views.py", line 183, in __call__
return view(context, request)
File ".../kinto/.venv/local/lib/python2.7/site-packages/pyramid/viewderivers.py", line 376, in attr_view
return view(context, request)
File ".../kinto/.venv/local/lib/python2.7/site-packages/pyramid/viewderivers.py", line 354, in predicate_wrapper
return view(context, request)
File ".../kinto/.venv/local/lib/python2.7/site-packages/pyramid/viewderivers.py", line 293, in _secured_view
return view(context, request)
File ".../kinto/.venv/local/lib/python2.7/site-packages/pyramid/viewderivers.py", line 425, in rendered_view
result = view(context, request)
File ".../kinto/.venv/local/lib/python2.7/site-packages/pyramid/viewderivers.py", line 146, in _requestonly_view
response = view(request)
File ".../kinto/.venv/local/lib/python2.7/site-packages/cornice/service.py", line 571, in wrapper
response = view_()
File ".../kinto/.venv/local/lib/python2.7/site-packages/cliquet/resource/__init__.py", line 470, in patch
unique_fields=unique_fields)
File ".../kinto/.venv/local/lib/python2.7/site-packages/cliquet/resource/model.py", line 319, in update_record
self.permission.replace_object_permissions(perm_object_id, permissions)
File ".../kinto/.venv/local/lib/python2.7/site-packages/cliquet/permission/postgresql/__init__.py", line 323, in replace_object_permissions
conn.execute(insert_query, placeholders)
File "/usr/lib/python2.7/contextlib.py", line 35, in __exit__
self.gen.throw(type, value, traceback)
File ".../kinto/.venv/local/lib/python2.7/site-packages/cliquet/storage/postgresql/client.py", line 53, in connect
raise exceptions.BackendError(original=e)
BackendError: IntegrityError: (psycopg2.IntegrityError) duplicate key value violates unique constraint "access_control_entries_pkey"
DETAIL: Key (object_id, permission, principal)=(/buckets/aae43625-24d3-6a73-6304-215c5a137355/collections/tasks/records/2f7ae492-d7a4-4f7b-a2c5-70fa2f9b938e, read, a) already exists.
[SQL: '\n WITH new_aces AS (\n VALUES (%(perm_0)s, %(principal_0)s),(%(perm_0)s, %(principal_1)s)\n )\n INSERT INTO access_control_entries(object_id, permission, principal)\n SELECT %(object_id)s, column1, column2\n FROM new_aces;\n '] [parameters: {'principal_0': u'a', 'principal_1': u'a', 'object_id': u'/buckets/aae43625-24d3-6a73-6304-215c5a137355/collections/tasks/records/2f7ae492-d7a4-4f7b-a2c5-70fa2f9b938e', 'perm_0': 'read'}] lang=None uid=73c905cd97587c23f498f0dd2cb5d8c65f895896c8fd71e79f1fc06a6813d9df
I think the fix is to turn each permissions list into a set before calling replace_object_permissions.
Although the set of permissions provided on a record is a list, semantically it's a set -- order doesn't matter, and duplicates aren't allowed. However, in the Postgres backend, we enforce this at the DB level, so if you violate this constraint, you get a 503:
produces in the log:
I think the fix is to turn each permissions
list
into aset
before callingreplace_object_permissions
.