Can Django set permissions on apps instead of models - django

I want to have authority control over my project. Some users can see some app's entries while others can't. I want to set permissions on apps instead of models, I have searched, but only found how to set permissions on models. So, I want to know how to set permissions on apps.

You can make decorators to selectively allow users to access the page
Make this decorator
def filter_users(func):
def checker(request,*args,**kwargs):
if some_condition: #This condition will tell you whether to allow this perticular user
return func(request,*args,**kwargs)
else:
return render('invalid.html') #return a page telling the user that he is not allowed
return checker
Now just apply this decorator to all the views that you want to prevent 'some' users from accessing.
Ex:
#filter_users
def some_view(request):
#Do Something...
Now only allowed users will be able to see the view, rest all will get the invalid page
You can apply this decorator to all the views of the perticular app that you want to restrict access to

Related

Django admin add entry to specific groups

Hej!
I'm looking for a possibility to add entries by different users and groups.
In my app there are different users and different groups where one user can belong to multiple groups. The goal is that some of the groups have sensitive data so I only want members of this group to be able to read the entries but some data should be available in multiple groups.
It should also be possible to only see some information. (e.g. See the name but not the address)
For now I have the decorator #login_required for all my views and #permission_required for a persons_view. Therefore you have to be a registered user to see anything, which is great but not quite enough.
I also created groups (via the admin area) but can't filter the data for each model/view. The group either sees the data or they don't.
The registration of users is connceted to an already existing ldap system (where those groups are pre-defined. Would be great to use those!)
Is there a possibility to add entries only for a special group and view only some of the given information?
Thanks for the help!
If you want to restrict or specify a view for a group, you should use two mixins: UserPassesTestMixin and LoginRequiredMixin.
LoginRequiredMixin will just make sure the user in the request is logged in
UserPassesTestMixin will check the request from a boolean expression we define and if it returns True it will let the user in
We can set this up using a test_func method that will return either True or False
Here is an example that you can use in your view
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
class Index(LoginRequiredMixin, UserPassesTestMixin,View):
def get(self, request):
return render(request, 'nioulboy/index.html')
def test_func(self):
return self.request.user.groups.filter(name='Admin')
In the test_func method, we are returning true if the request.user has a group with the name Admin.
If it returns True, it will allow the user to view the index page if it returns False it will send back a 403 error.
for NOT class based views works this function to give permission to a whole view.
# views.py
from django.contrib.auth.decorators import login_required, user_passes_test
def user_check(user):
return user.groups.filter(name="Admin")
#user_passes_test(user_check)
#login_required
def view(request):
....

How can I set up site-wide password protection and privilege requirements on views with Django?

My Django app is meant for internal use at the company I work at; however, it needs to be set up such that only certain employees with login credentials can access any of the web pages. Furthermore, I need to be able to customize the views so that only accounts with the right privileges can access them. How would I go about this?
My gut instinct is to use the same password protection and privilege system that the admin site uses since my project is basically just meant for viewing and editing the database easily. However, Google doesn't seem to turn up any information on how to do this, and I've only been working with Django for a month and half so I don't quite have the chops to figure this out myself. Is there a way to use the admin site's password protection and privilege system or is it inaccessible?
If staff privileges are enough this can easily be done using the staff_member_required view decorator. All you need is to apply the decorator to your view
staff_member_required Example:
from django.contrib.admin.views.decorators import staff_member_required
#staff_member_required
def random_view(request):
#If the user does not have staff privileges he will be redirected to a login page
If you are looking to test more specific privileges you should use the user_passes_test decorator. See: Django User Passes Test Decorator
You apply the decorator to your view and pass a function as a parameter that validates if a user should have access to that page, if the function returns True access is given normally, otherwise the user will be redirected.
user_passes_test Example:
from django.contrib.auth.decorators import user_passes_test
def user_is_author(user)
#your test goes here, pseudo code example ignore syntax.
return user.is_author
#user_passes_test(user_is_author)
def random_view(request):
#if user passed the test the view will work normally

how can I securely perform Rest requests without authentication?

This is more a process logic question than a specific language-framework one.
I am developing a mobile app and want the user to be able to use it without having to login (i.e. try it and offer a plus to the logged users), but I don´t want other persons to make post requests from let´s say Postman or any other platform than the app without having some sort of key, so what would be the approach here?
I am thinking on basic auth with some secret username:password for guests, or some kind of token, but as I am totally new on this I am not sure if it´s the correct approach, I´ve read the authentication and permissions Django Rest Framework tutorial but haven´t found a solution
I am learning Django myself and have gotten to the more advanced topics in the subject. What you could do is create a function in your permissions.py file for this. like so:
from rest_framework import permissions
class specialMobileUserPermissions(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
if request.method in request.SAFE_METHODS:
return True
if request.user.id == whatever your mobile users id is:
return false
return obj.id == request.user.id # if the user is a subscribed user and they are logged in return true
return false # because we need a way out if none of the above works
So when dealing with permissions classes the permissions.SAFE_PERMISSIONS is a list of permissions that are non-destructive. So the first if statement asks are you a GET, HEAD, or other non data altering method. If so return true.
The second if statement checks the user id of the user that is making the request. And if that user id is equal to the user id you set for the mobile trail user it would return false, denying permissions to whatever this class is used on.
In your viewset you would need to add the permissions_classes variable like below
from . import permissions # your permissions.py file
class FooViewSet(viewsets.ViewSet):
permission_classes = (permissions.specialMobileUserPermissions,)
Unless you need extra functionality, that should be everything you need, all the way down to the imports. I hope I have helped.

Find out the currently logged in user in Django

I have created a list of 5 users. How do I find out which user has logged in currently? Also please mention, if there is any way to find out if the super-user has logged in?
My requirement is, I want to restrict the access of certain pages in the templates only to the superuser.
Current user is in request object:
def my_view(request):
current_user = request.user
It's django.contrib.auth.models.User class and it has some fields, e.g.
is_staff - Boolean. Designates whether this user can access the admin site;
is_superuser - Boolean. Designates that this user has all permissions without explicitly assigning them.
http://docs.djangoproject.com/en/1.1/topics/auth/#django.contrib.auth.models.User
So to test whether current user is superuser you can:
if user.is_active and user.is_superuser:
...
You can use it in template or pass this to template as variable via context.
Sounds like you should be using the built-in permissions system for this.
Check out the user_passes_test decorator for your views. Django snippets has a related decorator:
These decorators are based on
user_passes_test and
permission_required, but when a user
is logged in and fails the test, it
will render a 403 error instead of
redirecting to login - only anonymous
users will be asked to login.
http://www.djangosnippets.org/snippets/254/

django.contrib.auth: how to keep site and admin sessions separate?

I'm using a user profile model with a ForeignKey to the User, authenticated by django.contrib.auth.
The same auth module is of course used for the admin interface, so if a superuser/staff member is logged in to the admin interface, and enters the main site, the site will accept session cookie and authenticate him. This creates a problem because a superuser/admin doesn't need to have a UserProfile and shouldn't be recognized by the main site.
What's the easiest way to solve this, so that the sessions from admin don't carry on to the site?
I dont think there is a way to solve exactly this,
"What's the easiest way to solve this, so that the sessions from admin don't carry on to the site?"
But depending on what you wnat to do, you may try,
don't create UserProfile for superuser
if request.user.is_superuser():
UserProf.objects.create(...)
I always have the problem where I want to keep a logged in Admin user and a logged in normal user, simultaneously, when I am developing. To do this, I have two entries in /etc/hosts
127.0.0.1 uswaretech.tld
127.0.0.1 admin.uswaretech.tld
Now, normal user always logs in via uswaretech.tld and admin always via admin.uswaretech.tld so thy can both be logge din simultaneously.
From a design standpoint your idea seems like a bit of a hack, but if you really want to do this you may use a middleware.
class MyMiddleware(object):
def process_request(self, request):
if request.user.is_authenticated:
try:
UserProfile.objects.get(user=request.user)
except UserProfile.DoesNotExist:
from django.contrib.auth.models import AnonymousUser
request.user = request._cached_user = AnonymousUser()
return None
This should be at the top of the middleware list to prevent possible side-effects.
if request.session.get ('has_account', False):
return HttpResponse ("You have no account, sorry.")
Then make sure, every user of your front-end gets, if his session is initiated, the value has_account set properly.