You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
To complete proper support for creating new objects (i.e. POST methods), it isn't sufficient to just use DRF filter_backends against a given model. There isn't a model yet created. There are probably several approaches, but the one I recommend (that has been working well in a different app) is the following:
Add a get_parent_object() view method
(May need cached at the view/request level because it'll get called several times)
Add a custom DRF Permission class:
To check if a user is allowed to do a POST request by:
Get parent object from view, if available (for example, if the URL contains a related (parent) field's PK, that would be the parent object to get). In some cases, I default to the current user as the parent (like a root-level object).
Check if the user is allowed to add the new model/object (ie: does the user have the "add_{model}" permission by checking the parent object's policy implicitly like allow(user, "add_case", client))
Pairing this permission class with the Filter backend should cover add (POST), view (GET), change (PUT/PATCH), and delete (DELETE) actions that need checked.
To support this more generic approach, models may need a few details embedded on their class like:
Create a custom meta class like class AuthorizeMeta:
Define if model supports authorization directly (has its own policies) or if a parent (related) object/field should be used (one that does support authorization). This can help support ancillary models that may not need their own policy, but can piggyback on its parent - ie: to add an ancillary model, check if the user can "change" the parent object.
The permission/filter classes and/or lower level functions can inspect the model's meta class to see if it needs to find this related/parent object instead.
A generic approach obviously can be very powerful, but can be complex to implement. Your use case may vary.
As extensions to this approach, I also have implemented elsewhere things like:
A decorator like authorized_view to apply to the APIView or GenericAPIView (subclasses) which will auto-add the base authorization filter and permission classes, if one isn't explicitly added to the view's filter_backends or permission_classes.
Custom permission and filter classes that act like a manual authorization marker, which indicates to the decorator not to add the filter and/or permission class. I have to use this in cases where I need to manually check policies within the get() etc handlers with information that just isn't feasible to expose through generic permission or filter classes.
The text was updated successfully, but these errors were encountered:
To complete proper support for creating new objects (i.e. POST methods), it isn't sufficient to just use DRF
filter_backends
against a given model. There isn't a model yet created. There are probably several approaches, but the one I recommend (that has been working well in a different app) is the following:get_parent_object()
view methodallow(user, "add_case", client)
)To support this more generic approach, models may need a few details embedded on their class like:
class AuthorizeMeta
:A generic approach obviously can be very powerful, but can be complex to implement. Your use case may vary.
As extensions to this approach, I also have implemented elsewhere things like:
authorized_view
to apply to theAPIView
orGenericAPIView
(subclasses) which will auto-add the base authorization filter and permission classes, if one isn't explicitly added to the view'sfilter_backends
orpermission_classes
.get()
etc handlers with information that just isn't feasible to expose through generic permission or filter classes.The text was updated successfully, but these errors were encountered: