django-object-permissions Vs django-guardian Vs django-authority
Asked Answered
I

2

38

I've found 3 row-level permission solutions for Django 1.2+

Could someone tell if there is any recommended more than the others, what are their main differences, etc.?

Iatrochemistry answered 18/6, 2012 at 12:10 Comment(1)
i was reading about django extensions and found out they do custom permissions as well? im confused, do they? which is the default go-to for permissions on django nowadays? django-extensions.readthedocs.io/en/latest/…Youlandayoulton
R
26

I'll start this by saying we use none of these for object level permission - we use our own custom method and I really wish we hadn't. If you can avoid object level permissions at all, do so, they are a pain to organise.

This is how I evaluate the 3 apps you've mentioned.

Active Development:

  1. django-guardian (1 week ago)
  2. django-object-permissions (1 year ago)
  3. django-authority (nearly 2 years ago)

API

  1. django-guardian (save an instance of a defined model)
  2. django-object-permissions (register permissions)
  3. django-authority (define classes)

The above are in order by the way.

I'd recommend guardian purely on API alone, but the fact that it is still being developed where the others aren't usually means a big win.

Rhinitis answered 18/6, 2012 at 12:28 Comment(4)
would you consider re adjusting this for 2019?Youlandayoulton
@Youlandayoulton by all means, feel free to edit my answer! I'll review if you want to change it up.Rhinitis
Would you mind updating the answer?Carrolcarroll
@MartinThoma feel free to propose edits to the answer.Rhinitis
T
21

As for Aug '13, django-object-permissions has been superseded by django-permission. The 3 projects are on active development.

Personally, I prefer authority or permission, which uses methods for checking permissions (runtime), rather than django-guardian which uses database to keep the permissions (attached upon object creation, f.e.).

-- EDIT --

Examples from the docs.

django-guardian

joe = User.objects.create(username='joe')
task = Task.objects.create(summary='Some job', content='', reported_by=boss)
joe.has_perm('view_task', task)
>> False
assign_perm('view_task', joe, task)
joe.has_perm('view_task', task)
>> True

You assign the permission and keep it in database.

django-authority

Declaration:

class FlatpagePermission(permissions.BasePermission):
    label = 'flatpage_permission'
    checks = ('morning_flatpage_check',)

    def morning_flatpage_check(self, flatpage):
        hour = int(datetime.datetime.now().strftime("%H"))
        if hour >= 8 and hour <= 12 and flatpage.url == '/about/':
            return True
        return False

authority.register(Flatpage, FlatpagePermission)

Usage:

def my_view(request):
    check = FlatPagePermission(request.user)
    flatpage_object = Flatpage.objects.get(url='/homepage/')
    if check.morning_flatpage_check(flatpage=flatpage_object):
        print "Yay, you can change *this* flatpage!"

It also wraps standard django permissions, but you can see the flexibility in the above custom permission which -AFAIK- you cannot do in guardian.

Common Usecase

A Student can belong to Classroom(s).

guardian:

  1. When Student is assigned to new Classroom, attach permission 'attend_classroom' to Student over Classroom object.
  2. When Student is removed from Classroom, remove 'attend_classroom' permission to Student over Classroom object.
  3. When accessing Classroom, check 'attend_classroom' permission.

authority:

  1. Define custom permission ClassroomPermission.can_attend_classroom(), which will query if Student belongs to Classroom.
  2. When accessing Classroom, check ClassroomPermission.can_attend_classroom()

Authority keeps the checking logic in a separate file. Guardian needs attach/detaching permissions though the rest of the code.

Twyla answered 19/8, 2013 at 5:18 Comment(9)
I don't really understand what you mean by runtime vs object creation. Presumably they both use the database to store permissions, and they both use an API to retrieve them.Ounce
@RobertGrant: I added a couple of examples for clarity.Twyla
Okay, I think you're saying that the way Authority works is you define a custom method for each combination of object type and permission type, where you write the code to check if someone has a permission, whereas in Guardian you say user.has_perm('classroom.attend_classroom')?Ounce
Do the recommendations here remain true today? Authority looks pretty close to what I want, class-based security voters, but no activity for over a year… are there any alternatives?Galingale
django-permission looks pretty good, I think I am going to give that a go over authority, and see if I can just ignore the db permissions and use the custom class-based stuffGalingale
I migrated from guardian to authority because, in my case, it was error prone to maintain it. It's easier for new devs to understand a protected view than to persist permissions in service classes (logic is spread). Please contribute to this Question with your findings if they apply :)Twyla
Would you mind updating the answer now that we have django 4 / 2022?Carrolcarroll
sorry @Martin Thoma, it's been years i haven't used django and i am out of the loop currentlyTwyla
No problem, I just thought I give it a shot! Thank you for coming back 🤗Carrolcarroll

© 2022 - 2024 — McMap. All rights reserved.