Assign views to roles in a pre-populated group+roles fields

I have in application_user, (this is an import from a PHP application, hence 2 fields for groups, and role name for each role ID which is redundant) :

class User(AbstractUser):
    groupA_user_designation_id  = models.IntegerField(blank=False, null=True)
    groupA_user_designation_name = models.CharField(max_length=250, blank=False, null=True)
    groupB_user_designation_id = models.IntegerField(blank=False, null=True)
    groupB_user_designation_name = models.CharField(max_length=250, blank=False, null=True)

With values in the database like :

0,None,3,Management
2,Admin,1,Super Admin
0,None,1,Super Admin
0,None,2,Admin
0,None,2,Admin
0,None,1,Super Admin
6,Sales Manager,2,Admin
4,Accounts,3,Management
6,Sales Manager,3,Management
0,None,3,Management

Now I want to assign views to these role IDs so that only users with assigned roles can only get access to the views in views.py.

How do I go about this in this scenario ?

See the docs starting from Permissions and authorization. (You’ll want to read the rest of that page starting from that point.)

I’m looking at this article.

“You can define these permissions in your models.py file as follows:”

So I have permissions in all models.py files ? Or can I create class CustomUserPermissions in my application/models.py specifying permissions for all of my models (spread across 5 apps) ?

If you want.

If you want.

Or, you can use existing permissions.

Or, you can create permissions matching (by name) the roles you’re using.

See the discussion at What is the purpose of Permissions?

Keep in mind that a 'Permission' is just an arbitrary name. There really isn’t anything special about what it’s called, when you’re using them in your own views. The Permission itself does not grant authorization to do anything. It’s up to the views to apply the semantics for those permissions.

(The Django admin does rely upon the names of the Permissions for its authorization tests - but that does not mean that you need to apply the same meanings.)

Another way to think about this is that the authorization facilities form the basis for the implementation of a Role-based security system, where Groups are the Roles, and Permissions are the names of the rights being granted to those Roles.

I am using Active Directory for our company users to login to our Django-powered internal custom CRM product and we have 2 groups.

@permission_required('auth.add_edit_serviceOrder')
def add(request, customer_id, draft_id=-1):

I want it to render a custom Access Denied Page but @permission_required is redirecting to http://localhost:8000/accounts/login/?next=/service_orders/add/0/ which any I don’t want because our users are not logging in to Django’s custom login system.

That’s covered in the docs for the permissions_required decorator.
See Using the Django authentication system | Django documentation | Django

But for this to work - using Django’s groups and permissions, I would need to write a one-time setup script to create the 2 groups and set all users permissions based on the existing data (in the database containing the roles and permissions) ?

from django.contrib.auth.models import Group

group_g1 = Group.objects.create(name='Group1')
group_g1.permissions.add(add_edit_sof)
group_g1.save()

# Sample user permission setting
user = User.objects.get(id=149)
user.groups.add(group_g1)
user.save()

This is ending up super complex because of using Active Directory login instead of Django’s login system and hence need to fetch user details in the @conditional_login_required decorator and which ended up modifying the decorators and all with request not being available in @user_passes_test etc.

@user_passes_test(lambda u: is_allowed_to_add_edit_sof(u, request)) won’t work. I failed at this now - but need to deliver this asap so will circle back to django’s ecosystem later on.

I ended up with the simplest route.

    access = False

    if user.groupA_id == 1 or user.groupA_id == 3:
        access = True

    if not access:
        return render(request, 'access-denied.html', {})