Django queryset permissions

2024/11/17 5:54:55

I am building a quite complex Django application to be used on top of and email scanning service. The Django application is written using Python 3.5+

This application primarily uses Django Rest Framework to handle communication with the frontend in the browser.

The issue that I am currently having is that I try to implement the concept of a System Administrator, Domain Administrator and Application User

The System Administrator is basically the "normal" django superuser and is therefore capable of doing everything and see every record in the system.

The Domain Administrator is user who manages one or more email domains. I keep track of this using a Many2Many relationship between the users and the domains. The idea would then be to predefine a filter, so that the log of messages processed, will be automatically filtered to show only messages where the sender domain or the recipient domain equal a domain in the list of domains that the given user is assigned to.

The same would be true for blacklisting/whitelisting policies.

If the Domain Administrator is not assigned to any domains, then no data is shown.

The Application User is basically any authenticated user with one or more domains assigned to them, using the same Many2Many relationship as the Domain Administrator. If no domains are assigned, then no data is shown.

I have found some other solution here on Stackoverflow on making the request.user available to the QuerySet in the ModelManager, but that does not seem like the correct way to handle it.

I have looked at django-guardian, django-authority and django-permissions, but none of them seem to be affecting the QuerySet or the resulting list of objects.

Does anyone have a suggestion for Django package/addon that can be used to handle this or maybe an idea for how this could be handled?

Answer

I'm the author of django-cancan library https://github.com/pgorecki/django-cancan which strives to solve the exact problem you are describing.

The philosophy is as following: first, you determine per-user abilities, then in a view, you can check user abilities for a given object, model, or you can retrieve a queryset based on those abilities.

The declaration part looks like this:

def declare_abilities(user, ability):if not user.is_authenticated:# Allow anonymous users to view only published articlesability.can('view', Article, published=True)else:# logged in user can view any article...ability.can('view', Article)# ... and change his ownability.can('change', Article, author=user)# ... and add new onesability.can('add', Article)if user.is_superuser:# Allow superuser to view and change any articleability.can('view', Article)ability.can('change', Article)

Then you can you can check for abilites on a per-object level:

def article_detail_view(request, pk):article = Article.objects.get(pk=pk)if request.ability.can('view', article):...

or on a model level:

def article_create_view(request, pk):if request.ability.can('add', Article):...

or get a queryset with accessible objects:

def another_list_view(request, pk):articles = request.ability.queryset_for('view', Article)...
https://en.xdnf.cn/q/71258.html

Related Q&A

How to extract certain parts of a web page in Python

Target web page: http://www.immi.gov.au/skilled/general-skilled-migration/estimated-allocation-times.htmThe section I want to extract:<tr><td>Skilled &ndash; Independent (Residence) sub…

Accessing axis or figure in python ggplot

python ggplot is great, but still new, and I find the need to fallback on traditional matplotlib techniques to modify my plots. But Im not sure how to either pass an axis instance to ggplot, or get one…

Importing the same modules in different files

Supposing I have written a set of classes to be used in a python file and use them in a script (or python code in a different file). Now both the files require a set of modules to be imported. Should t…

Manually calculate AUC

How can I obtain the AUC value having fpr and tpr? Fpr and tpr are just 2 floats obtained from these formulas:my_fpr = fp / (fp + tn) my_tpr = tp / (tp + fn) my_roc_auc = auc(my_fpr, my_tpr)I know thi…

Plotly: How to make stacked bar chart from single trace?

Is it possible to have two stacked bar charts side by side each of them coming from a single column?Heres my df:Field IssuePolice Budget cuts Research Budget cuts Police Time consum…

zip function help with tuples

I am hoping someone can help me with a problem Im stuck with. I have a large number of tuples (>500) that look like this:(2,1,3,6) (1,2,5,5) (3,0,1,6) (10,1,1,4) (0,3,3,0) A snippet of my c…

Mini batch training for inputs of variable sizes

I have a list of LongTensors, and another list of labels. Im new to PyTorch and RNNs so Im quite confused as to how to implement minibatch training for the data I have. There is much more to this data,…

Python gTTS, is there a way to change the speed of the speech

It seems that on gTTS there is no option for changing the speech of the text-to-speech apart from the slow argument. I would like to speed up the sound by 5%. Any suggestion on how I can do it? Best.t…

Change QLabel text dynamically in PyQt4

My question is: how can I change the text in a label? The label is inside a layout, but setText() does not seem to work - maybe I am not doing it right. Here is my code:this is the Main windows GUI, t…

Setting figure size to be larger than screen size in matplotlib

Im trying to create figures in matplotlib that read nicely in a journal article. I have some larger figures (with subfigures) that Id like to take up nearly an entire page in portrait mode (specificall…