Django uses dingtalk to expand user systems

Source: Internet
Author: User
Django uses dingtalk to expand user system user Architecture

Description
Based on Django's built-in user and group, combined with the dingtalk user system to meet actual needs. Group relationship: the dingtalk Department group is related to the system group through many-to-many relationship. Then, set the scheduled task. If a dingtalk Department group is associated with the system group, the user in the user group is automatically added to the corresponding system group. Group Relationship 2: The Custom permission group is related to the system group through many-to-many relationship. The user-defined permission information is queried based on the user's system group name for determination.
Version
Django==2.0.9jsonfield==2.0.2
Create Table Structure
  • Dingtalk Department table
  • Extended user table
  • Custom permission Group
  • Dingtalk token info table
From Django. DB import modelsfrom Django. contrib. auth. models import abstractuser, group, userfrom jsonfield import jsonfieldclass dept (models. model): name = models. charfield (max_length = 128, verbose_name = 'department name',) group = models. manytomanyfield (to = group, blank = true) parentid = models. charfield (max_length = 128, verbose_name = 'department Level 1 id', blank = true, null = true) parentname1 = models. charfield (max_length = 128, verbose_name = 'department Level 1 name', blank = true, null = true) parentname2 = models. charfield (max_length = 128, verbose_name = 'department Level 2 name', blank = true, null = true) parentname3 = models. charfield (max_length = 128, verbose_name = 'department Level 3 name', blank = true, null = true) parentname4 = models. charfield (max_length = 128, verbose_name = 'department Level 4 name', blank = true, null = true) Class meta: db_table = "Dept" verbose_name = "dingtalk Department" verbose_name_plural = verbose_name def _ STR _ (Self): return self. nameclass users (abstractuser): Position = models. charfield (max_length = 64, verbose_name = 'position information', blank = true, null = true) unionid = models. charfield (max_length = 64, verbose_name = 'dingtalk unionid', blank = true, null = true) USERID = models. charfield (max_length = 64, verbose_name = 'dingtalk userid', blank = true, null = true) dingid = models. charfield (max_length = 64, verbose_name = 'dingdingid', blank = true, null = true) Avatar = models. charfield (max_length = 256, verbose_name = 'Avatar ', blank = true, null = true) mobile = models. charfield (max_length = 11, verbose_name = 'phone', blank = true, null = true) isboss = models. booleanfield (verbose_name = 'Whether it is boss', default = false,) is_ding_admin = models. booleanfield (verbose_name = 'Whether it is dingtalk admin', default = false,) ding_group = models. manytomanyfield (to = Dept, blank = true, verbose_name = 'dingtalk group', related_name = 'dept') Class meta: db_table = 'users' verbose_name = 'user information' verbose_name_plural = verbose_name def _ STR _ (Self): return self. username class request (models. model): Request = models. charfield (max_length = 16, verbose_name = 'request type (uppercase) ') Class meta: db_table = "request" verbose_name = "request type" verbose_name_plural = verbose_name def _ STR _ (Self): return self. requestclass rolepermission (models. model): Role = models. charfield (max_length = 32, verbose_name = 'Role group') group = models. manytomanyfield (group, verbose_name = 'user system group', related_name = 'roles', blank = true) Table = models. charfield (max_length = 32, verbose_name = 'table name') Request = models. manytomanyfield (request, verbose_name = 'request', related_name = 'Re',) Permission = jsonfield (max_length = 1024, verbose_name = 'permission condition') level = models. integerfield (verbose_name = 'permission precedence 'in the same table, default = '1') Class meta: db_table = "role_permission" verbose_name = "Custom permission group" verbose_name_plural = verbose_name def _ STR _ (Self): return self. roleclass dingdingtoken (models. model): dingding_choices = ('0', 'logon authentication token'), ('1', 'address book token'),) appid = models. charfield (max_length = 128, verbose_name = 'appid ') appsecret = models. charfield (max_length = 128, verbose_name = 'appsecret') access_token = models. charfield (max_length = 128, verbose_name = 'Access _ token', blank = true, null = true) type = models. charfield (choices = dingding_choices, max_length = 16, verbose_name = 'dingtalk token type') up_time = models. datetimefield (auto_now = true, verbose_name = 'Update Time') Class meta: db_table = "dingding_token" verbose_name = "dingtalk token" verbose_name_plural = verbose_name def _ STR _ (Self ): return self. appid
Example of a custom permission Group

  • Take asset as an Example

    Table Name asset field group (group: Dev, OPS)
  • Add in the request table

    Get (read-only)
    Post (update and delete)

  • Add in rolepermission

    Role asset read-only group
    System group asset read-only group
    Table Name assset
    Request get
    Permission condition {"group": 'dev '}
    Level 1 (if the system group has multiple permissions for the same table, the highest permission is determined based on the level)

Add the system group asset read-only to the system O & M department of the dingtalk department, so that users under the system O & M Department automatically have the read-only asset permission.

Obtain dingtalk Information

First, register the dingtalk user and department in the user and dingtalk Department tables.

Regularly update dingtalk user dingtalk Department

Import timeimport requestsfrom test. models import dingdingtoken, users, deptdef ding_book_token (): "Address Book token: Return:" ding = dingdingtoken. objects. get (type = '1') app_id = ding. appid app_secret = ding. appsecret token = requests. get (f'https: // oapi.dingtalk.com/gettoken? Corpid = {app_id} & correntcret = {app_secret} ') Ding. access_token = token. JSON () ["access_token"] Ding. save () def ding_get_user_info (): "updates dingtalk user information, according to department ID: Return:" "access_token = dingdingtoken. objects. get (type = '1 '). access_token list_ids = Dept. objects. all () for u in list_ids: if u. ID <1000: Continue user_list_requests = requests. get (f'https: // oapi.dingtalk.com/user/simplelist? Access_token = {access_token} & department_id = {u. id} ') user_list = user_list_requests.json () ['userlist'] For I in user_list: user_info_request = requests. get (f'https: // oapi.dingtalk.com/user/get? Access_token = {access_token} & userid = {I ["userid"]} ') user_info = user_info_request.json () Try: username = I ['name'] print (username) users. objects. update_or_create (userid = I ['userid'], ults = {'username': username, 'email ': user_info ['email'] If 'email 'in user_info.keys () else '', 'position': user_info ['position'], 'unionid': user_info ['unionid'], 'dingid': user_info ['dingid'], 'mobile': user_info ['Mobile'], 'is _ activity': user_info ['active'], 'isbos': user_info ['isbos'], 'Avatar ': user_info ['Avatar'], 'Is _ ding_admin ': user_info ['isadmin']}) cannot exception as E: users. objects. update_or_create (userid = I ['userid'], ults = {'username': F "{I ['name']} {(user_info ['mobile']) [-4:]} ", 'email ': user_info ['email'] If 'email 'in user_info.keys () else', 'position ': user_info ['position'], 'unionid ': User_info ['unionid'], 'dingid': user_info ['dingid'], 'mobile': user_info ['mobile'], 'is _ active ': user_info ['active'], 'isbos': user_info ['isbos'], 'Avatar ': user_info ['Avatar'], 'is _ ding_admin ': user_info ['isadmin']}) u = users. objects. get (userid = I ['userid']) U. ding_group.set (user_info ['department ']) U. save () time. sleep (0.2) def ding_book_update (): Ding = dingdingtoken. objects. filter (type = '1' ). First () print (Ding) If Ding: token = ding. access_token Department = requests. Get (F "https://oapi.dingtalk.com/department/list? Access_token = {token} ") for I in department. JSON () ['department ']: If I ['id'] = 1: Dept. objects. update_or_create (ID = I ['id'], ults = {'name': '', 'parentid': '0',}) else: parent_name2 = ''parent_name3 = ''parent_name4 = ''try: parent = Dept. objects. get (ID = I ['parentid']) parent_id1 = parent. parentid parent_name1 = parent. name try: parent2 = Dept. objects. get (ID = parent_id1) parent_name2 = parent2.name parent_id2 = parent2.parentid try: parent3 = Dept. objects. get (ID = parent_id2) parent_name3 = parent3.name parent_id3 = parent3.parentid try: parent4 = Dept. objects. get (ID = parent_id3) parent_name4 = parent4.name failed t exception as E: parent_name4 = ''failed t exception as E: parent_name3 ='' failed t exception as E: parent_name2 = ''failed t exception as E: parent_name1 ='' Dept. objects. update_or_create (ID = I ['id'], ults = {'name': I ['name'], 'parentid': I ['parentid'], 'parentname1 ': parent_name1, 'parentname2': parent_name2, 'parentname3': parent_name3, 'parentname4': parent_name4 })

Schedule the task and update the correspondence between the dingtalk Department group and the system group.

Def ding_user_group_update (): "updates the permission relationship between the user dingtalk group and the system group: Return:" For I in users. objects. all (): g_list = [] for D in I. ding_group.all (): If D. group. all (): For g in D. group. all (): g_list.append (G. ID) old_list = [] for o in I. groups. all (): old_list.append (O. ID) If old_list! = G_list: Print (I. username, 'user group updated ') I. Groups. Set (g_list) I. Save ()

Dingtalk Logon

Http://blog.51cto.com/hequan/2304690

Admin settings

From Django. contrib import adminfrom test. models import request, rolepermission, dingdingtoken, users, deptfrom Django. contrib. auth. admin import useradminclass dingdingtokenadmin (Admin. modeladmin): list_display = ('appid ', 'type', 'Access _ token', 'Up _ Time') Class rolepermissionadmin (Admin. modeladmin): list_display = ('role', 'table', 'show _ group', 'permission', 'level',) @ classmethod def show_group (self, OBJ ): return [I. name For I in OBJ. group. all ()] filter_horizontal = ('group',) Class deptadmin (Admin. modeladmin): @ classmethod def show_group (self, OBJ): return [I. name For I in OBJ. group. all ()] list_display = ('id', 'name', 'show _ group', 'parentname1', 'parentname2', 'parentname3', 'parentname4 ', 'parentid',) search_fields = ('id', 'name') list_display_links = ('id', 'name') filter_horizontal = ('group',) Class usersadmin (useradmin): fieldsets = (none, {'fields': ('username', 'Password')}), ('basic information', {'fields ': ('first _ name', 'last _ name', 'email ')}), ('authorization', {'fields': ('is _ activity ', 'Is _ staff ', 'is _ superuser', 'groups', 'user _ permissions ')}), ('logon time', {'fields ': ('Last _ login', 'date _ joined')}), ('dingtalk information', {'fields': ('position', 'unionid', 'dingid ', 'userid', 'Avatar ', 'mobile', 'isbos', 'is _ ding_admin', 'ding _ group')}),) Admin. site. register (users, usersadmin) Admin. site. register (request) Admin. site. register (rolepermission, rolepermissionadmin) Admin. site. register (dingdingtoken, dingdingtokenadmin) Admin. site. register (Dept, deptadmin) Admin. site. site_header = 'o & M management backend 'admin. site. site_title = admin. site. site_header

Permission judgment

Import jsonfrom test. models import rolepermissionfrom functools import wrapsfrom Django. shortcuts import httpresponsefrom Django. DB. models import qdef role_permission_get_list (function): "list page: Param function: Return:" @ wraps (function) def wrapped (Self): User = self. request. user groups = [x ['name'] for X in self. request. user. groups. values ()] REQUEST_TYPE = self. request. method model = STR (SEL F. model. _ Meta ). split (". ") [1] filter_dict = {} not_list = ['page', 'order _ by', 'csrfmiddlewaretoken '] For K, V in dict (self. request. get ). items (): If [I for I in V if I! = ''] And (k not in not_list): If '_ in' in K: filter_dict [k] = V else: filter_dict [k] = V [0] if not user. is_superuser: role_groups = rolepermission. objects. filter (Q (group _ name _ in = groups) & Q (request _ Request = REQUEST_TYPE) & Q (Table = model )). values_list ('table', 'request _ request', 'permission', 'level '). order_by ('-level '). first () permission_dict = JSON. loads (role_groups [2]) If permission_dict: If filter_dict: For K, V in permission_dict.items (): If '_ in' in K: K1 = K. replace ('_ in', '') If' _ GT 'in K: K1 = K. replace ('_ GT', '') If '_ lt' in K: K1 = K. replace ('_ lt', '') else: K1 = K if K1 in List (filter_dict.keys (): del filter_dict [k1] If filter_dict: filter_dict.update (** permission_dict) else: Print ('query condition is blank after processing, default authorization') filter_dict = permission_dict else: Print ('query condition is blank, default authorization') filter_dict = permission_dict else: print ('no authorization') filter_dict = {'id':-1} self. filter_dict = self. filter_dict self. queryset = self. model. objects. filter (** filter_dict) order_by_val = self. request. get. get ('order _ by ', '') If order_by_val: Self. queryset = self. queryset. order_by (order_by_val) If self. queryset else self. queryset result = function (Self) return result return wrappeddef role_permission_detail (function): "details page: Param function: Return:" @ wraps (function) def wrapped (self, request, * ARGs, ** kwargs): User = self. request. user if not user. is_superuser: groups = [x ['name'] for X in self. request. user. groups. values ()] REQUEST_TYPE = self. request. method model = STR (self. model. _ Meta ). split (". ") [1] PK = self. kwargs. get (self. pk_url_kwarg, none) role_groups = rolepermission. objects. filter (Q (group _ name _ in = groups) & Q (request _ Request = REQUEST_TYPE) & Q (Table = model )). values_list ('table', 'request _ request', 'permission', 'level '). order_by ('-level '). first () permission_dict = JSON. loads (role_groups [2]) if PK: permission_dict ['id'] = pk obj = self. model. objects. filter (** permission_dict ). count () if not OBJ: Return httpresponse (status = 403) Result = function (self, request, * ARGs, ** kwargs) return result return wrappeddef role_permission_update_delete (function ): "Update and delete: Param function: Return:" @ wraps (function) def wrapped (self, request): User = self. request. user if not user. is_superuser: groups = [x ['name'] for X in self. request. user. groups. values ()] REQUEST_TYPE = self. request. method model = STR (self. model. _ Meta ). split (". ") [1] PK = self. request. post. get ('nid', none) role_groups = rolepermission. objects. filter (Q (group _ name _ in = groups) & Q (request _ Request = REQUEST_TYPE) & Q (Table = model )). values_list ('table', 'request _ request', 'permission', 'level '). order_by ('-level '). first () permission_dict = JSON. loads (role_groups [2]) if PK: permission_dict ['id'] = PK else: instance = (self. get_form_kwargs () ['instance'] permission_dict ['id'] = instance. id OBJ = self. model. objects. filter (** permission_dict ). count () if not OBJ: ret = {'status': None, 'error': "No permission, deny", 'msg ': 'Without permission, rejected '} return httpresponse (JSON. dumps (RET) Result = function (self, request) return result return wrapped for example @ role_permission_get_listdef get_context_data (self, ** kwargs ):

Django uses dingtalk to expand user systems

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.