Django view visible only to admin - django

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.

Related

Give access to Django Admin (staff status) by adding to Group

To give a user the ability to login to the Django Admin, we set their staff flag.
Is there a way to make a "staff" Group where everyone put into it gains access to the admin page without manually setting staff status?
You can override the Django Admin site (follow the doc, it's pretty amazing).
During the time, create a custom admin site class and override it's has_permission(...) method
from django.contrib import admin
class MyCustomAdminSite(admin.AdminSite):
def has_permission(self, request):
has_perm = super().has_permission(request)
if has_perm:
return True
return request.user.groups.filter(name="YourGroupName").exists()

Flask Admin custom permissions for items in the nav

I'm having trouble figuring out how to add custom permissions to nav items, such that certain items will show up when the user is logged in / logged out, or other parameters are met (such as the user is part of a certain organization).
Any help or examples would be greatly appreciated.
With flask_security package you are able to set roles to users and check them in flask_admin views as follows:
from http import HTTPStatus
from flask_admin.contrib.sqla import ModelView
from flask_security import current_user, url_for_security
from flask import abort, redirect, request
class AdminSecurityMixin:
allowed_roles = []
def is_accessible(self):
return current_user.is_active and current_user.is_authenticated and \
(current_user.has_role('admin') or any(current_user.has_role(r) for r in self.allowed_roles))
def _handle_view(self, name, **kwargs):
if not self.is_accessible():
# if user is logged in, but can't view the admin, reject access
if current_user.is_authenticated:
abort(HTTPStatus.FORBIDDEN)
# otherwise redirect to the admin login view
# the next parameter is so we can redirect them after they'ved
# logged in to where they wanted to go originally
return redirect(url_for_security('login', next=request.url))
return None
class SecuredModelView(AdminSecurityMixin, ModelView):
allowed_roles = ['custom_role']
Now model registered with SecuredModelView will be accessible in admin panel only to users who are logged in and have assigned custom_role or admin role.
Roles can be created and added to existing users with following commands:
$ flask roles create custom_role
$ flask roles add <your user email> custom_role
I guess you already have a database with at least a user table.
I think you just want to design templates.
I invite you to follow this Flask tutorial about templates. It will introduce you Jinja, a templating language.

Can Django set permissions on apps instead of models

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

Django-Allauth, Multiple login redirect url

I have a question, how can I add more than one LOGIN_REDIRECT_URL in settings or in views for my differents users.
For example, I have: Administrators, Human Resources, Teachers, students... etc
and for each I need redirect to a different url, panel admin for Admin etc.
I need add groups? or not?
Thanks for your help!
django-allauth get the login redirect URL from method get_login_redirect_url defined in account adapter you can define your custom adapter and override this:
my_app/adapter.py
from allauth.account.adapter import DefaultAccountAdapter
class AccountAdapter(DefaultAccountAdapter):
def get_login_redirect_url(self, request):
url = super(AccountAdapter, self).get_login_redirect_url(request)
user = request.user
'''
# pseudocode, change it to actual logic
# check user role and return a different URL
role = get_user_role(user)
if role == 'student':
url = student_login_redirect_url
if role == 'teacher':
url = teacher_login_redirect_url
'''
return url
Now tell allauth to use our custom adapter by defining the ACCOUNT_ADAPTER in settings.py:
ACCOUNT_ADAPTER = 'my_app.adapter.AccountAdapter'

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