Userena group based categorization on signup/registration - python

I would like to separate users into two different groups, sellers or buyers, at signup. I'm using django-userena and for the authentication and registration of users. I'm thinking of using a clone of the same signup view except with a different url tied to it.
So whoever signs up at url(r'^account/signup/seller/$) linked to a seller signup button will be added to the seller group
and whoever signs up at url(r'^account/signup/$) linked to a buyer signup button will be added to the buyer group.
Note: I will be using this grouping to grant access to view functions in another django app in my project via signals/decorators.
in my accounts/form.py file, I have:
class SellerSignupFormExtra(SignupForm):
def save(self):
new_user = super(SignupFormExtra, self).save()
new_user.groups.add(Group.objects.get(name=‌​'seller'))
return new_user
and I added this to accounts/urls.py file
url(r'^accounts/signup/seller$', 'userena_views.signup', {'signup_form': SellerSignupFormExtra}),
So my question is that can I add the other users that click the buyer signup button by doing the same thing I did for sellers above or is their a better way to achieve this so that I remain DRY.

Related

Creating Groups and Modifying View Access Django

I am building a web app using Django 3.0.7 and Python 3.8 that will use some business intelligence tool, like Tableau or Power BI, as a reporting source.
There is absolutely no issue with the code I am using, however I need to be able to reduce visibility to certain pages, based on a created group. For example:
If I have three pages/dashboards:
127.0.0.1:8000/director/report1, 127.0.0.1:8000/manager/report2, 127.0.0.1:8000/employee/report3
and I have three users:
Director, Manager, Employee
How can I create the site in such a way that when a user registers to the site, their profile is created and subsequently assigned a group THEN restrict access to certain pages based on the user group (this would be easier than assigning permission to every user). For example:
The user Director would belong to a group called, directors, and would have access to 127.0.0.1:8000/director/report1, 127.0.0.1:8000/manager/report2, 127.0.0.1:8000/employee/report3.
The user Manager would belong to a group called, managers, and have access to 127.0.0.1:8000/manager/report2, 127.0.0.1:8000/employee/report3.
The user Employee would belong to a group called, employees, and have access to 127.0.0.1:8000/employee/report3.
I found some information related to permissions here: https://docs.djangoproject.com/en/2.1/_modules/django/contrib/auth/decorators/ but I cannot find information related to creating groups AND assigning permissions.
You could extend the default user class in django with a new model named staff and add a charfield with director, manager and employee as given below:
from django.contrib.auth.models import User
class Staff(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
DIRECTOR = "DR"
MANAGER = "MG"
EMPLOYEE = "EM"
DESIGNATION_CHOICES = [
(DIRECTOR, "Director"),
(MANAGER, "Manager"),
(EMPLOYEE, "Employee"),
]
designation = models.CharField(
max_length=2,
choices=DEISGNATION_CHOICES,
default=DIRECTOR,
)
Then you can provide the necessary if,else conditions in your views which will prevent/allow members of certain category to make requests for certain pages.
One way to implement this could be:
#assuming you are using this view function corresponding to '/director/' url
def director_page(request):
if request.user.is_authenticated:
user = request.user
staff = Staff_objects.get(user__id=1)
if staff.designation == "Director":
...#allow director to proceed
else:
...#return an error response
else:
... # Do something for anonymous users.

Django: phone verification for inactive account

I'd like to implement phone verification with pyotp in my view class-based Django (2.5) project.
After new users sign up (specifying name, phone, e-mail and password) in RegisterView, they should be redirected to GetAccessCodeView with an input field for verification code and a hidden field with a secure token. For generating and sending the code and the token I have to pass there a newly created user instanse from RegisterView to GetAccessCodeView.
How can I do that? Currently newly created users have is_active field set to False (it should become True after code succesful verification), thus cannot be authorized by default, so without changing login procedure, it is impossible to use request.user directly. But if I let inactive users to log in, then all the login_required views will let unconfirmed users to open corresponding pages. Should I write is_active check for each view manually or maybe Django has some ready stuff like 'login_and_active_required'? Or maybe there is some different solution?

Creating two separate registration forms in Web2py?

So I want to create two registration forms side by side. One for users and other for employees. So basically the index page will have something like "Click here if you are a user" and "Click here if you are an employee". It will redirect to the appropriate registration page. I want the user registration to be just like how the built in web2py registration is. For the employee registration I want the following fields:
Name 2. Store Name 3. Store Type 4. Zip Code
I am really new to web2py so not sure how to implement this. Could someone please tell me how I should go about creating a registration.py model for this? Also I want the index to redirect to these two links as appropriate:
[app]/user/register
[app]/employee/register
Also what would my controller file look like? Would I need a separate controller for user and the employee?
Your question is not quite clear. Do you want to show two forms side by side OR do you want to redirect to the appropriate registration page?
Let's assume you opt for the second option as you described in your question. I'm also assuming that for whatever reason, employees and users are not the same as i understood from your question.
First create the employee table in models:
STORE_TYPE = ['Department store', 'Discount store', 'Warehouse store', 'Mom-And-Pop', 'Boutique']
db.define_table('employee',
Field('first_name'),
Field('last_name'),
Field('store_name'),
Field('store_type', requires=IS_IN_SET(STORE_TYPE)),
Field('zip_code'),
auth.signature)
Then in the controller just ask the user if she is an employee or user:
def index():
form = SQLFORM.factory(Field('user_or_employee', requires = IS_IN_SET(['user', 'employee']))).process()
if form.accepted:
if form.vars.user_or_employee == 'user':
redirect(URL('user/register'))
elif form.vars.user_or_employee == 'employee':
redirect(URL('employee_register'))
return locals()
If the user is a 'user' then you'll redirect them to the user/register as wished. if they are an 'employee' then redirect them to index/employee_register
def employee_register():
form = SQLFORM(db.employee)
if form.process().accepted:
redirect(URL('welcome')) # or whatever function you wish...
return locals()
From there you can take it by yourself.
Don't forget to create the views. For index and for default/employee-register.html. In both views you should include the forms you've created, something like that:
{{extend 'layout.html'}}
<h2>Please Register to Continue</h2>
{{=form}}

User authentication to specific users

Hello i use #login_required to restrict access to some pages that stores bookmarks for users, but in some cases i want the user to access only his bookmarks and must be stopped if he try to enter a url that edits a bookmark that belongs to another user. how can i do that?
#login_required can help you make sure the user is logged in to even access the view.
Once the view is accessed you could check to make sure the user is allowed to access the bookmarks, and only fetch bookmarks they are allowed to access
for example if your url looked something like
/bookmarks/ and corresponds to function bookmarks
#loggin_required
def bookmarks():
# only fetch book makrs for this user
bookmarks = Bookmarks.objects.filter(user=request.user)
This will make sure user is logged in to access the url and that book marks are only displayed for the user that is viewing the page. You could add some sort of permission system if some users can view other users bookmarks
if this view were to show all book marks for a user and you wanted to provide a url to edit bookmarks or something like
bookmarks/{{ bookmark_id }}/edit that maps to edit_bookmark
#login_required
def edit_bookmark(bookmark_id):
# user is guarenteed to be logged in so request.user is available
# your permission system will depend on how you authenticate whether a user can edit
# a bookmark or not
# CHECK if user has permission to edit bookmark
pass

django: keep each users data separate

I am trying to workout how / the best, most secure way to keep a user's data separate within a django site that I need to write.
Here is an example of what I need to do...
example app ToDoList
Using django contrib.auth to manage users / passwords etc, I will have the following users
tom
jim
lee
There will be a ToDo model (in my real app there will be additional models)
class ToDo(models.Model):
user = models.ForeignKey(User)
description = models.CharField(max_length=20)
details = models.CharField(max_length=50)
created = models.DateTimeField('created on')
The issue that I am having - and may be over thinking this: How would this be locked down so tom can only see Tom's todo list, lee can only see his todo list and so on...
I have seen a few posts stating that you could use filter in every query, or use urls, so the url could look like www.domain.com/username/todo
But either way I am not sure if this is the right way / best way, or bonkers in terms of stopping users seeing each others data
cheers
Richard
One approach is to filter the ToDo items by the currently logged in user:
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from your_app.models import ToDo
#login_required
def todos_for_user(request):
todos = ToDo.objects.filter(user=request.user)
return render(request, 'todos/index.html', {'todos' : todos})
This locks down the view for authenticated users only, and filtering by the logged in user from the request, another user, even if logged in, can't access another user's ToDo records. Hope that helps you out.
Make url like www.domain.com/username/todo is one way to implement it, but it doesn't guarantee you achieve security.
What you should do keep your user's login information in a session data after user login, and every time you check certain view,
check whether that particular user has right to see this view.
using user's login info (ID, or username) when querying user's Todo list.
And I guess this link will help you to do your job.
Sessions, Users, and Registration.

Categories

Resources