You're calling key.get()
inside the _pre_get_hook
, which means it will be called recursively. That you're checking whether the user is in the can_put
list, inside the get check suggests your logic is wrong, but checking against the can_get
list will have to be done after the entity has been fetched, in _post_get_hook
perhaps.
Row level access authorization in google app engine ndb hooks (maximum recursion)
Вопрос
I'm searching for some hints on how to implement row level access into a google app engine application using ndb hooks. As far as I know there is no out of the box authorization available, so I did add three attributes to the model: can_put, can_get and can_delete. Then I did add three ndb hooks: _pre_put_hook(), _pre_get_hook() and _pre_delete_hook().
PUT does work, but GET raises a RuntimeError (maximum recursion).
How can I get past the maximum recursion issue?
So far I do have got the following model:
import logging
import endpoints
from google.appengine.ext import ndb
class Location(ndb.Model):
name = ndb.StringProperty(required=True)
description = ndb.TextProperty()
address = ndb.StringProperty(required=True)
can_put = ndb.UserProperty(repeated=True)
can_get = ndb.UserProperty(repeated=True)
can_delete = ndb.UserProperty(repeated=True)
created = ndb.DateTimeProperty(auto_now_add=True)
modified = ndb.DateTimeProperty(auto_now=True)
def _pre_put_hook(self):
current_user = endpoints.get_current_user()
if not current_user:
logging.debug("Location put: Invalid token.")
raise endpoints.UnauthorizedException("Invalid token.")
if self.key.id() is None:
self.can_get.append(current_user)
self.can_put.append(current_user)
self.can_delete.append(current_user)
else:
location = self.key.get()
if not current_user in location.can_put:
logging.debug("Location put: Permission denied.")
raise endpoints.ForbiddenException("Permission denied.")
@classmethod
def _pre_get_hook(cls, key):
current_user = endpoints.get_current_user()
if not current_user:
logging.debug("Location get: Invalid token.")
raise endpoints.UnauthorizedException("Invalid token.")
location = key.get()
if not current_user in location.can_get:
logging.debug("Location get: Permission denied.")
raise endpoints.ForbiddenException("Permission denied.")
@classmethod
def _pre_delete_hook(cls, key):
current_user = endpoints.get_current_user()
if not current_user:
logging.debug("Location delete: Invalid token.")
raise endpoints.UnauthorizedException("Invalid token.")
location = key.get()
if not current_user in location.can_delete:
logging.debug("Location delete: Permission denied.")
raise endpoints.ForbiddenException("Permission denied.")
But when I do run a GET operation through the API explorer I do get the following:
RuntimeError: maximum recursion depth exceeded while calling a Python object
Решение
Не связан с StackOverflow