Django privilege to template - django

I have a separate control panel which will manage some user information and other data .Also in Django Group i have 3 groups such as 1) Owners ,2)Developers , 3 )Clients .
I have to give an access privilege of this control-panel template to only Group owner and Developers .
Template Name : control_panel.html
View : control-panel(request) : yet to implement the code for this .
Model : accessing 3 tables with product information and its prices

If I were you, I would not tie access to groups, but rather to permissions, this way it is much more granular, and you can later allow other groups access to this view, by adding a permission to that group. In this case all you have to do is decorate your view like this:
from django.contrib.auth.decorators import permission_required
#permission_required('some_permission')
def control_panel(request):
# here goes your view
But if you prefer to use groups, you can do it like this:
from django.contrib.auth.decorators import user_passes_test
#user_passes_test(labmda u: 'Owners' in u.groups.values_list('name', flat=True))
def control_panel(request):
# here goes your view

I implemented this way . this is more efficient method to do
#permission_required('admin.some_permission',login_url="/admin/permission_required_error")
def control_panel(request):#your code here
If the user dont have the permission then it will redirect to the login_url location . Here we can Show the Description about this permission .
In the login_url View :
def permission_required_error(request):
context={}
next_page = request.GET.get('next', '')
context={'next_page':next_page}
return render_to_response ('permission_required_error.html', context, context_instance=RequestContext(request))

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):
....

Django UserPassesTestMixin confusion/questions?

I am currently working on an admin dashboard, which include specific views for company administrators only which are labeled as Business users.
The app is going to have about 10 views, and I had a few questions in regards to the UserPassesTestMixin
Basically, all of my views would include this,
def test_func(self):
return self.request.user.user_type == 'Business'
To make sure the users are Business users I am protecting the views that way.
A couple questions that I am having trouble solving on my own are:
Now with that being repeated say 10 times, is there a cleaner way to do this, rather than having
def test_func in every CBV?
The other question that comes up, if the user doesn't pass test, it redirects to the login page, which I don't really like either. These views are all returning json. If the user does not pass test, I would like to just send them to something like,
JsonResponse({'message': 'Only company administrators have access to this view'})
How would I able to change that redirect only if the user does not pass test? Keeping in mind that these views also inherit from LoginRequiredMixin as well, in which if the user is not logged in I want to keep the original redirect to the login page in tact.
Any help with this is very appreciated. This side of Django is something fairly new to me!
Now with that being repeated say 10 times, is there a cleaner way to do this, rather than having def test_func in every CBV?
Yes, you can simply make a mixin that implements the check:
from django.contrib.auth.mixins import UserPassesTestMixin
class BusinessUserMixin(LoginRequiredMixin, UserPassesTestMixin):
def test_func(self):
return self.request.user.user_type == 'Business'
def handle_no_permission(self):
return JsonResponse(
{'message': 'Only company administrators have access to this view'}
)
and then you use this mixin in your views, for example:
class MyView1(BusinessUserMixin, ListView):
# …
pass
class MyView2(BusinessUserMixin, DetailView):
# …
pass
class MyView3(BusinessUserMixin, CreateView):
# …
pass
if the user doesn't pass test, it redirects to the login page, which I don't really like either. These views are all returning json. If the user does not pass test, I would like to just send them to something like.
You can override the handle_no_permission method as well, the view will return the result of this method as result when the test fails.

Django view visible only to admin

I have a view in my django backend which I want only admin to see.
#api_view(('GET',))
def get_analytics(request):
# Number of users who dogged in once to our system today
login_count= User.objects.filter(last_login__startswith=timezone.now().date()).count()
data = {}
data['login_count'] = login_count
return JSONResponse(data)
It's a function based view. How can I make it visible only to admin? it's corresponding url I hit from my angular app to get and render the data.
You can also use the below decorator
from django.contrib.admin.views.decorators import staff_member_required
#staff_member_required
You can add IsAdminUser permission class to your view to restrict access to only admin users. Only users with admin permissions will be granted access then. Others will be denied access.
#api_view(('GET',))
#permission_classes((IsAdminUser, )) # add the permission class
def get_analytics(request):
...
return JSONResponse(data)
When the permissions fail, then either an exceptions.PermissionDenied or exceptions.NotAuthenticated exception will be raised depending on some conditions.

Doing User Profiles In Django

I'm trying to set up user profiles in my site so we have:
www.example.com/someuser
www.example.com/anotheruser2
in my urls.py
url(r'^(?P<profile>[0-9A-Fa-f]{1,36})/', 'site.views.profile),
and my view:
def profile(request, profile):
... do something ...
There are two questions:
Is this the correct way to do this or is there a better way?
How should I handle other urls, like "aboutus", etc.
For Point 2, I would do:
url(r'^aboutus/', 'site.views.aboutus'),
url(r'^(?P<profile>[0-9A-Fa-f]{1,36})/', 'site.views.profile),
So now profile will be the catchall for everything else in the site, and I have to check for a valid profile then throw a 404 if a password is not found.
Again, is there a better way to do this?
It's not a good idea to use site.views.profile as a catchall. It's not good separation of responsibilities, it shouldn't be its job. How about something like this instead:
url(r'^profile/$', 'site.views.profile_self'),
url(r'^profile/(?P<profile_name>[0-9A-Fa-f]{1,36})/$', 'site.views.profile'),
url(r'^aboutus/', 'site.views.aboutus'),
For the catchall, use a custom 404 page, or you could let the server raise a 404 error.
accounts/models.py
from django.db import models
class User():
def get_profile(self):
return UserProfile.objects.get_or_create(user_id=self.id)
class UserProfile(models.Model):
user = models.OneToOneField(User)
# another fields
accounts/urls.py
url(r'^profile/$', 'site.views.profile'),
accounts/views.py
from django.contrib.auth.decorators import login_required
#login_required
def profile(request):
# get current logged user profile
profile = request.user.get_profile()
this way the user logged only can see his own profile.
and for the point 2, what's wrong with this?
url(r'^about_us/$', 'site.views.about_us'),
--UPDATE--
ah, ok. then, you are right. but why not with the username?
accounts/urls.py
url(r'^(?P<username>[-\w]+)/$', 'site.views.profile'),

django multiple admin instances and locking down access to a particular instance

I have several admin instances running on a site - one for each country, that the site supports.
However, if a user logs into one admin, they are automatically able to access other instances.
I need to make the auth code aware of which admin the user has logged into and prevent access to other admin systems.
Any ideas how this can be done?
You can use middleware to check for user permissions to access certain areas of admin site. Checkout this snippet. (You might want to know more about handling custom permissions in Django.)
If you need something more universal, you can use the code example below. The idea is simple: it uses custom functions to find out about user permissions and to give an appropriate response:
#coding: utf-8
# Note that RESTRICTED_URLS tuple takes three parameters: url regex, function to check
# whether user has certain permission, and a function to redirect the user to a certain
# page if he doesn't have sufficient rights.
import re
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
from django.http import HttpResponseRedirect
from django.contrib import messages
from backend.models import Professional
from django.contrib.auth.decorators import permission_required
def calculate_forbidden_response(request, view_func,view_args,view_kwargs):
if not request.user.is_authenticated():
return permission_required('')(view_func)(request,*view_args,**view_kwargs)
elif request.user.has_perm('backend.p_add_professional'):
messages.error(request, _('You need permission Spam to enter this cabinet.'))
return HttpResponseRedirect('/some_help_page_about_permissions.html')
def check_professional_permission(request):
return request.user.has_perm('backend.p_access_professional_cabinet')
RESTRICTED_URLS = (
(r'/professional/(.*)$', check_professional_permission, calculate_forbidden_response),
)
RESTRICTED_URLS_EXCEPTIONS = ()
class CheckPermissionMiddleware(object):
def __init__(self):
self.restricted = tuple([(re.compile(url[0]), url[1], url[2]) for url in RESTRICTED_URLS])
self.exceptions = tuple([re.compile(url) for url in RESTRICTED_URLS_EXCEPTIONS])
def process_view(self,request,view_func,view_args,view_kwargs):
if request.user.is_superuser:
return None
for path in self.exceptions:
if path.match(request.path): return None
for rule in self.restricted:
url, permission = rule[0], rule[1]
calculated_response = rule[2]
if url.match(request.path):
if not permission(request):
return calculated_response(request, view_func,view_args,view_kwargs)
else:
return None
return None