How to define user models with multiple access level in django - python

How can a user be a member of multiple organizations and have different roles in each organization, depending on what level of access they need.

Maybe you can try this build_user, you can use it as it comes by default or you can customize custom_user it so that you can accept a more specific authentication authentication_user, in addition to defining the user model or extending the permission control, you define it in the View by validating user permissions with (request .user.username), I hope it serves you, greetings.

Related

Django Multiple Auth Models

I am working on a project where I need to have 3 types of Users.
Admin
Vendor
Customer
I want to be having seperate Models for all three of them Vendor & Customers instead of having a type field in a common User Model.
My first approach to this problem was to define all models by sub-classing the AbstractUser model
# models.py
from django.contrib.auth.models import AbstractUser
class Customer(AbstractUser):
pass
class Vendor(AbstractUser):
pass
And add a custom Authentication backend to handle the authentication of users based on the request object.
# settings.py
AUTHENTICATION_BACKENDS = ['backends.CustomAuthBackend']
And my backends.py file will contain the logic to authenticate users and use different models for each one based on the request object.
# backends.py
from __future__ import print_function
class CustomAuthBackend(object):
def authenticate(self, request, username=None, password=None):
# authenticate user based on request object
def get_user(self, user_id):
# logic to get user
However this does not work and looks like i also need to specifiy the AUTH_USER_MODEL in settings.py which is used for authentication.
Is it possible at all.Does Django allow to authenticate from 3 different tables. How can I go ahead with this ? Is there any other approach to this and what should I change ?
I have done similar staff a couple days ago, you are in the right approach. But there are a few other things needed to change to make it work. I'll explain what I did to make it success.
First, you have to custom your own user model, and you have to do it in the first place before you make the migrations. And also in the model file define different userManagers to manager different type of users. Then in your settings file you have to set AUTH_USER_MODEL and AUTHENTICATION_BACKENDS, AUTH_USER_MODEL is the default user model django will use for authentication and you can only set to one user model, but for AUTHENTICATION_BACKENDS you can have multiple backends,it's a list and django will loop every option inside to authenticate. by default it use django.contrib.auth.backends.ModelBackend, you can add your own auth backends. Check this on how to make your own authentication backend:https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#writing-an-authentication-backend.
And depends on your application, you may also need to custom the serializer function and override some classes to make it work. In my own application, I was using DRF and JWT token to authenticate, so I also override some of the function which by default use the AUTH_USER_MODEL variable. In the end, I'm able to use admin model to login the admin page and use another custom user model to authenticate the application and get the JWT token. Anyway, always reference this page: https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#customizing-authentication-in-django. Hope this can help you in your application.
django.contrib.auth is designed to work with one UserModel. Depending on what you want to achieve there are different apporaches.
If you just want to store different kind of profile/meta data for the different types of user you might use multi table inheritance - in this case you might stick with the default user model.
When it comes to different permissions based on the user type you should not solve this using separate classes. Instead use groups. This approach is much more flexible. It can nearly always happen that one person should belong to more than one group of users. When you model this based on the user classes you are in trouble.

Group level permissions in django

I have a list of custom permissions in the Permission model, a User model and a Group model. I have different set of permissions(from the Permission model) defined for each group. Each user belongs to a particular group. I want to include a permission check in my website such that whenever a user logs in and tries to go to a view, the back-end checks if the user has the permission to enter the particular view. How to implement this in my website?
Note: I am not using django REST framework.
A user has all the permissions assigned to them directly as well as those assigned to any group that they are a member of.
To restrict access to a view based on Django permissions you can:
use the permission decorator:
https://docs.djangoproject.com/en/1.11/topics/auth/default/#the-permission-required-decorator
wrap the view function (e.g. in urls.py) with user_passes_test() with a test that checks for the permission: https://docs.djangoproject.com/en/1.11/topics/auth/default/#django.contrib.auth.decorators.user_passes_test
or check explicitly with user.has_perm() (same page as the above links, just read all of it)

Model design for a user who can have roles at multiple organizations

I need a Django model where a User can have a Function with any number of Organisations. His permissions (change, view, delete) with the organization are determined by his Role. I am pretty sure I only need an "admin" and a "member" role.
This would require row-level permissions, so I decided to go with django-guardian. I am having trouble choosing the proper model design. These are the alternatives
The first one would have the advantage of creating new roles, but I don't think I need that. Also I can enforce unique_together so that a User can only have 1 function at every company. Would I set the can_change permission at the Role and infer the row level permission based on the relation between User and Organization? The would mean I do not even need django-guardian, right?
The second one looks much simpler, but maybe that is deceptive. The permissions would have to be set as soon as a User is added to an Organization and are definitely row-level.
What is the right strategy here?
To clarify: in both cases a user can be an admin of one organization and simply a member of another organization.
Use the Party Model.
A user is not a person, it's a user. Person and organization are parties. A party hasOne (or no) user.
A person hasMany (many2many) relationships with an organization:
Individual -< Relationship >- Organization
Organizations can have relationships with each other too.

Django password and authentication for non standard users

I have been asked to introduce an unusual case and I'm wondering how others would go about it.
I have users in my Django application. The model is a standard user model, authentication. etc. Each one of of these site users can add their own contacts to the system. However my new requirement is to allow their contacts to set a password (if they want to to) so that they can login to their status page (belonging to that user).
So my question is how would you do this? I already have the contact table (which belongs to one user), I'm thinking of adding in a password (optional) field, but then I'm unsure how to handle the authentication for this as they are not my users but members of my users (if that make sense).
One way would be to create another user model for contacts inheriting from AbstractBaseUser. And then creating custom auth backend that would look in both models to login user. Finaly you would have to distinguish between standard user and contact user before every action.
That is if contact user and standard user differ significantly in your application.
Or you could just create custom user in your application, that would contain is_contact attribute. This would be used for both types of users. You would set that as AUTH_USER_MODEL in settings and check before every action for the is_contact attribute to determine the outcome. You could return 403 for the contact user if he tries to access what he's not suppose to.
Or if you use permissions in your application, you could set the contact user's persmissions only to view statuses of the users that added him as a contact and nothing else.

Adding permissions to django users which have add-on models

I will be creating an intranet site with multiple roles (client-employee, client-admin, staff team member). Each role will have a model that attaches (via One-to-One or ForeignKey field) to a user with custom fields. I want each role to have it's own set of permissions (like a group).
How can I store this permissions set inside my application. Groups seem to be defined as part of the contrib.admin app rather than in code. I couldn't find anything in documentation on how to define a group.
What is the best way to handle model level permissions. Maybe I could do a check in the model if see if the user has the right role-model.
Access control lists are tricky (some say dead), but Django comes with a good default implementation in contrib.auth equipped with:
Users
Permissions: Binary (yes/no) flags designating whether a user may perform a certain task.
Groups: A generic way of applying labels and permissions to more than one user.
A more detailed introduction can be found here:
http://parand.com/say/index.php/2010/02/19/django-using-the-permission-system/

Categories