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()
Related
I am trying to create a Online exam portal and I have created one admin portal for that site. I have 2 types of users in my site "Students" and "Teachers". How can I restrict students from accessing the admin portal and other views of admin panel?
In views.py in function related to your template, you can use the decorator permission_required as follows
from django.contrib.auth.decorators import permission_required
#permission_required('foo.access_my_view')
def my_view(request):
...
You have detailed instructions on how to add and modify the permissions here
I'm trying to customize allauth's default SignUpView and SignUpForm to allow me to create other users while already logged in. The default behavior prevents me from doing this: in other words, I can only sign up for a new account if I'm not authenticated.
How do I override this behavior?
I presume I'll have to override the SignupView in views.py but I'm not sure what to look for... I played around with RedirectAuthenticatedUserMixin, but to no avail.
Forms.py
from allauth.account.forms import SignupForm
class SubUserForm(SignupForm):
USER_TYPES = [
(2,'customer'),
(3,'vendor'),
(4,'supplier')
]
first_name = forms.CharField(max_length=45)
last_name = forms.CharField(max_length=45)
user_type = forms.CharField(widget=forms.Select(choices=USER_TYPES))
Views.py
from allauth.account.views import SignupView
class SubUserSignupView(SignupView):
template_name = 'accounts/new_user_signup_form.html'
form_class = SubUserForm
view_name = 'sub_user_signup'
sub_user_signup = SubUserSignupView.as_view()
urls.py
urlpatterns = [
path('sub_user/',views.sub_user_signup,name='sub_user_signup'),
]
To put in context
My app allows for a 'parent' user to sign up multiple 'children' users (called 'subuser' in the code above) using allauth. In my case, an organization can create several customers, merchants, suppliers, etc. When a parent user creates a child user, a verification email is sent to the child user, who then activates his account and is prompted to enter a password. I use 2 signup forms; the default allauth signup (for parent accounts), and a customized signup form (for children accounts), which also extends from allauth.
Although the registration flow above works well, a parent user can only sign up new children users (trigger email verification) when logged out. I'm struggling to identify what I need to prevent this from happening.
Navigate to the allauth directory, under app settings, set this to False
ACCOUNT_AUTHENTICATED_LOGIN_REDIRECTS (=True)
The default behaviour is to redirect authenticated users to LOGIN_REDIRECT_URL when they try accessing login/signup pages.
By changing this setting to False, logged in users will not be redirected when they access login/signup pages.
This also worked
Navigate to the allauth folder, under views find SignupView.
Deleting the redirectAuthenticatedUsermixin works
New issue is that you are logged in as the new user, fixing that currently.
First of all, this article maybe useful:
https://tech.serhatteker.com/post/2020-06/custom-signup-view-in-django-allauth/
The reason you can only sign up for a new account if you're not authenticated is because of this Allauth's mixin: RedirectAuthenticatedUserMixin (as suggested by Anthony M).
So, you have to override this mixin and the allauth's signup view with your own code.
It is very important that you register the url before allauth urls.
Hope it helps.
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.
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
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.