Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When PATCHing a resource, the authorized check is done after full_hydrate #1051

Open
jleclanche opened this issue Oct 14, 2013 · 0 comments
Open
Milestone

Comments

@jleclanche
Copy link

The problem with this piece of code (resources.py):

    def obj_update(self, bundle, skip_errors=False, **kwargs):
        """
        A ORM-specific implementation of ``obj_update``.
        """
        if not bundle.obj or not self.get_bundle_detail_data(bundle):
            try:
                lookup_kwargs = self.lookup_kwargs_with_identifiers(bundle, kwargs)
            except:
                # if there is trouble hydrating the data, fall back to just
                # using kwargs by itself (usually it only contains a "pk" key
                # and this will work fine.
                lookup_kwargs = kwargs

            try:
                bundle.obj = self.obj_get(bundle=bundle, **lookup_kwargs)
            except ObjectDoesNotExist:
                raise NotFound("A model instance matching the provided arguments could not be found.")
        bundle = self.full_hydrate(bundle)
        return self.save(bundle, skip_errors=skip_errors)

A large amount of processing, including full_hydrate(), is done before reaching self.authorized_update_detail which will check for the Authorization at that point.

This is very unfortunate because, when writing a custom Authorization resource that lets read calls through, but declines write calls to unauthenticated users (a common pattern), the following is not possible:

    def hydrate(self, bundle):
        bundle.obj.user = bundle.request.user
        return bundle

This (assuming user is a ForeignKey to a User field) will fail because Authorization.update_detail() has not been called yet to raise Unauthorized and Django will error with ValueError: Cannot assign "<SimpleLazyObject: <django.contrib.auth.models.AnonymousUser object at 0x2f59690>>": "UserProfile.user" must be a "User" instance..

This took me a while to figure out and it would really be nice if things made more sense. hydrate() being processed by users who clearly would not be let through is bad.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants