wlanslovenija / django-tastypie-mongoengine

MongoEngine support for django-tastypie.
Other
73 stars 59 forks source link

Authentication doesn't work for EmbeddedListField #70

Open deniskolokol opened 10 years ago

deniskolokol commented 10 years ago

I'm trying to setup a resource with EmbeddedListField, and it fails to Authenticate user to access the individual items.

Here is my example:

class FieldDefinitionResource(MongoEngineResource):
    class Meta:
        object_class = documents.FieldDefinition
        authentication = ApiKeyAuthentication()
        authorization = StaffAuthorization()

class SectionResource(MongoEngineResource):
    fields = EmbeddedListField(attribute='fields',
        of='myproj.api.resources.FieldDefinitionResource',
        full=True, null=True)
    class Meta:
        object_class = documents.Section
        authentication = ApiKeyAuthentication()
        authorization = StaffAuthorization()

StaffAuthorization() allows performing all actions (read, update, create, delete on both list and detail) to active users, who are is_staff or is_superuser

This request

/api/v1/section/52adcdbc02c8f1078ea68f63/?format=json&username=beta&api_key=b924d14ff71d27509a25f0d779ec45db83158199

works perfectly fine, displaying the list of fields and their resource_uri's

But this one:

/api/v1/section/52adcdbc02c8f1078ea68f63/fields/0/?format=json&username=beta&api_key=b924d14ff71d27509a25f0d779ec45db83158199

fails with 401

This happens with any of the requests: GET, PATCH, POST, etc.

After switching authorization off (i.e. authorization = Authorization()), everything works fine in both cases: /section/ and /section/section_pk/fields/field_index. Also, all the requests work fine for SectionResource with authorization on, so it's not the problem with custom StaffAuthorization.

Debugging showed that in the method read_detail of StaffAuthorization the bundle.request.user is AnonymousUser - so, it skips Authentication entirely.

mitar commented 10 years ago

Currently I do not have much time to look into this. Sorry.

deniskolokol commented 10 years ago

the last two issues are about the same problem

the problem itself and a temporary solution is described in the post here http://stackoverflow.com/questions/19794050/authentication-failing-for-mongoengineresource-with-referencefield

ghost commented 10 years ago

71 isn't really about this (it's about an extra call to authorization for normal documents, not ones embedded in lists) but #72 is. My bad for reporting a duplicate issue, I was thrown off by this bug's subject line about Authentication rather than Authorization.

In our case any non-GET request to the EmbeddedListField was being allowed. Only read_detail or read_list were being accessed in our Authorization function; none of the other functions were even being checked before the data was written and success returned to any Authenticated user.

Our hackish solution was to just add a call to the authorization features in obj_create, obj_update and obj_delete:

--- resources.py.bak    2014-01-14 12:04:08.826678379 -0500
+++ resources.py        2014-01-14 12:08:16.172309240 -0500
@@ -814,6 +814,7 @@

     def obj_create(self, bundle, **kwargs):
         try:
+            self.authorized_create_detail(self.get_object_list(bundle.request), bundle)
             bundle.obj = self._meta.object_class()

             for key, value in kwargs.items():
@@ -853,6 +854,7 @@
     # TODO: Use skip_errors?
     def obj_update(self, bundle, skip_errors=False, **kwargs):
         try:
+            self.authorized_update_detail(self.get_object_list(bundle.request), bundle)
             if not bundle.obj or not getattr(bundle.obj, 'pk', None):
                 try:
                     bundle.obj = self.obj_get(bundle=bundle, **kwargs)
@@ -880,6 +882,7 @@
             raise exceptions.ValidationError(ex.message)

     def obj_delete(self, bundle, **kwargs):
+        self.authorized_delete_detail(self.get_object_list(bundle.request), bundle)
         obj = kwargs.pop('_obj', None)

         if not getattr(obj, 'pk', None):
deniskolokol commented 10 years ago

agreed

i still hope, this will be fixed in the future

mitar commented 10 years ago

Please make a pull request with tests. I myself am using the package only for public read-only APIs so authentication has been completely untested and underdeveloped. As you can see. :-)