Permission granular control

Browse the catalog

 

Simple control

Check whether you have permission, the easiest way is to directly for loop

  {% if "users/add" in permissions_list%}

For example: check whether the user has permission to add users, if so, display the add user button, if not, hide it.

{% if "users/add" in request.actions %}
    <button class="btn btn-primary">Add user</button>
    {% endif %}

get rid of table control

Change the database structure

In order to easily know what permissions users have and which permissions to show users, we need permission groups to distinguish them.

Add a new table permission group table.

# Permissions table
class Permission(models.Model):
    title = models.CharField(max_length=32)
    url = models.CharField(max_length=32)
    action=models.CharField(max_length=32,default="")
    group=models.ForeignKey(to="PermissionGroup",default=1)

    def __str__(self):
        return self.title

# Rights Groups
class PermissionGroup(models.Model):
    title=models.CharField(max_length=32)
    def __str__(self):
        return self.title

We usually see the list page first. Whether to display the addition, whether to display the editing, or whether to display the deletion on this page needs to be judged.
   With or without adding permission, with or without deletion permission, with or without editing permission, we can give each url a code name  

dict = {
    1:{ codename
          /users/                 list
       /users/add/        add
       /users/del(\d+)/      del
       /users/edit(\d+)/       edit
    }
  }  

Enter permission data through admin

class PerConfig(admin.ModelAdmin):
    list_display = ["title","url","action","group"]    #显示字段


admin.site.register(UserInfo)
admin.site.register(Role)
admin.site.register(Permission,PerConfig) #Bind PerConfig class
admin.site.register(PermissionGroup)

With permission groups, you can view permissions directly by action.

For example: check whether the user has permission to add users, if so, display the add user button, if not, hide it.

{% if "add" in request.actions %}
    <button class="btn btn-primary">Add user</button>
    {% endif %}

Simple class control

Through the instantiated object of the class, you can directly use "." to call the method in the class for simple operations.

views.py

class Per(object):
    def __init__(self, actions):
        self.actions = actions

    def add(self):
        return "add" in self.actions

    def delete(self):
        return "delete" in self.actions

    def edit(self):
        return "edit" in self.actions

    def list(self):
        return "list" in self.actions  

If you want to see what permissions the logged in user has on the user table, you can instantiate an object.

For example: check whether the user has permission to add users, if so, display the add user button, if not, hide it.

{% if per.add %}
    <button class="btn btn-primary">Add user</button>
    {% endif %}

Login authentication

#Query all the permissions of the currently logged-in user, according to the url, group id, display the operations to be performed by each permission, and deduplicate the permission list
    permissions = user.roles.all().values("permissions__url", "permissions__group_id", "permissions__action").distinct()
    print("permissions",permissions)
    #All permissions of the currently logged in user are as follows:
    '''permissions <QuerySet
    [{'permissions__url': '/users/',
    'permissions__action': 'list',
    'permissions__group_id': 1},

    {'permissions__url': '/users/add',
     'permissions__action': 'add',
     'permissions__group_id': 1},

     {'permissions__url': '/users/delete/(\\d+)',
     'permissions__action': 'delete',
     'permissions__group_id': 1},

     {'permissions__url': '/roles/',
     'permissions__action': 'list',
     'permissions__group_id': 2},

     {'permissions__url': '/users/edit/(\\d+)',
      'permissions__action': 'edit',
       'permissions__group_id': 1}]>
    '''  

The above data is not very convenient for us to use. How can we get the data we want? We can store them in the form of a dictionary, which is convenient for us to query.

permission_dict={} #Create an empty dictionary
    for item in permissions: #loop through each permission
        gid=item.get("permissions__group_id") #Get the group id and use the group as the key of the dictionary
        if not gid in permission_dict: #If there is no group as a key, create a new key name and add data
            permission_dict[gid]={
                "urls":[item["permissions__url"],],
                "actions":[item["permissions__action"],],
            }
        else: #Add data directly if there is a key
            permission_dict[gid]["urls"].append(item["permissions__url"])
            permission_dict[gid]["actions"].append(item["permissions__action"])
    print(permission_dict)
    #Register the permission dictionary in the session, which is convenient for later query
    request.session["permission_dict"]=permission_dict  

You will get the following data:

'''{{'1':
    {'urls': ['/users/', '/users/add', '/users/delete/(\\d+)', '/users/edit/(\\d+)'],
    'actions': ['list', 'add', 'delete', 'edit']},
    '2': {'urls': ['/roles/'],
    'actions': ['list']}}
'''  

Middleware check permission

With the permission_dict dictionary registered in the session, we can easily query the permissions that each user has.

  '''Permission check two'''
        permission_dict=request.session.get("permission_dict") #Register the permission dictionary in the session
        print(permission_dict)
        for item in permission_dict.values(): #loop by group
            urls=item["urls"] #urls are all urls in each group
            for rule in urls: #traverse all urls
                rule="^%s$"%rule # String concatenation redefines permissions
                ret=re.match(rule,current_path) #match the current path by rule
                if ret: #match successful
                    print("actions",item["actions"])
                    request.actions=item["actions"] #Set attributes to the object, and then call request.actions to get all the permissions of the current user on the current table

                    return None
        return HttpResponse("Sorry, you don't have access!")

  

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325404552&siteId=291194637
Recommended