Skip to content

Commit

Permalink
Expose resource object_id
Browse files Browse the repository at this point in the history
  • Loading branch information
leplatrem committed Mar 27, 2020
1 parent f824135 commit 3d2c921
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 14 deletions.
36 changes: 26 additions & 10 deletions kinto/core/resource/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,6 @@ def __init__(self, request, context=None):
"""
self.request = request
self.context = context
self.object_id = self.request.matchdict.get("id")

content_type = str(self.request.headers.get("Content-Type")).lower()
self._is_json_patch = content_type == "application/json-patch+json"
Expand Down Expand Up @@ -252,6 +251,22 @@ def timestamp(self):
)
raise http_error(HTTPServiceUnavailable(), errno=ERRORS.BACKEND, message=error_msg)

@reify
def object_id(self):
"""Return the object id for this request. It's either in the match dict
or in the posted body.
"""
if self.request.method.lower() == "post":
try:
# Since ``id`` does not belong to schema, it is not in validated
# data. Must look up in body directly instead of request.validated.
_id = self.request.json["data"][self.model.id_field]
self._raise_400_if_invalid_id(_id)
return _id
except (KeyError, ValueError):
return None
return self.request.matchdict.get("id")

def get_parent_id(self, request):
"""Return the parent_id of the resource with regards to the current
request.
Expand Down Expand Up @@ -413,15 +428,16 @@ def plural_post(self):
:meth:`kinto.core.resource.Resource.process_object`
"""
new_object = self.request.validated["body"].get("data", {})
try:
# Since ``id`` does not belong to schema, it is not in validated
# data. Must look up in body.
id_field = self.model.id_field
new_object[id_field] = _id = self.request.json["data"][id_field]
self._raise_400_if_invalid_id(_id)
existing = self._get_object_or_404(_id)
except (HTTPNotFound, KeyError, ValueError):
existing = None

existing = None
# If id was specified, then add it to posted body and look-up
# the existing object.
if self.object_id is not None:
new_object[self.model.id_field] = self.object_id
try:
existing = self._get_object_or_404(self.object_id)
except HTTPNotFound:
pass

self._raise_412_if_modified(obj=existing)

Expand Down
2 changes: 1 addition & 1 deletion tests/core/resource/test_object_permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def setUp(self):
object_id = self.obj["id"]
self.object_uri = "/articles/{}".format(object_id)
self.permission.add_principal_to_ace(self.object_uri, "read", "account:readonly")
self.resource.object_id = object_id
self.resource.request.matchdict["id"] = object_id
self.resource.request.validated["body"] = {"data": {}}
self.resource.request.path = self.object_uri

Expand Down
5 changes: 2 additions & 3 deletions tests/core/resource/test_preconditions.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,8 @@ def test_post_if_none_match_star_fails_if_object_exists(self):
def test_post_if_none_match_star_succeeds_if_object_does_not_exist(self):
self.validated["header"].pop("If-Match")
self.validated["header"]["If-None-Match"] = "*"
self.validated["body"] = {
"data": {"id": self.resource.model.id_generator(), "field": "new"}
}
self.resource.object_id = self.resource.model.id_generator()
self.validated["body"] = {"data": {"id": self.resource.object_id, "field": "new"}}
self.resource.plural_post() # not raising.

def test_get_if_none_match_star_fails_on_plural_endpoints(self):
Expand Down

0 comments on commit 3d2c921

Please sign in to comment.