From 30477f736e282cd22296f14f4ac030ae5d07cf56 Mon Sep 17 00:00:00 2001
From: simontigers <47096077+simontigers@users.noreply.github.com>
Date: Thu, 12 Oct 2023 16:02:35 +0800
Subject: [PATCH] fix: common perms (#200)

---
 cmdb-api/api/commands/click_common_setting.py | 47 ++++++++++++++-----
 cmdb-api/api/lib/common_setting/acl.py        | 19 ++++++++
 2 files changed, 53 insertions(+), 13 deletions(-)

diff --git a/cmdb-api/api/commands/click_common_setting.py b/cmdb-api/api/commands/click_common_setting.py
index ebbd882..ffd454f 100644
--- a/cmdb-api/api/commands/click_common_setting.py
+++ b/cmdb-api/api/commands/click_common_setting.py
@@ -165,31 +165,48 @@ class InitDepartment(object):
         acl = self.check_app('backend')
         resources_types = acl.get_all_resources_types()
 
+        perms = ['read', 'grant', 'delete', 'update']
+
+        acl_rid = self.get_admin_user_rid()
+
         results = list(filter(lambda t: t['name'] == '操作权限', resources_types['groups']))
         if len(results) == 0:
             payload = dict(
                 app_id=acl.app_name,
                 name='操作权限',
                 description='',
-                perms=['read', 'grant', 'delete', 'update']
+                perms=perms
             )
             resource_type = acl.create_resources_type(payload)
         else:
             resource_type = results[0]
+            resource_type_id = resource_type['id']
+            existed_perms = resources_types.get('id2perms', {}).get(resource_type_id, [])
+            existed_perms = [p['name'] for p in existed_perms]
+            new_perms = []
+            for perm in perms:
+                if perm not in existed_perms:
+                    new_perms.append(perm)
+            if len(new_perms) > 0:
+                resource_type['perms'] = existed_perms + new_perms
+                acl.update_resources_type(resource_type_id, resource_type)
+
+        resource_list = acl.get_resource_by_type(None, None, resource_type['id'])
 
         for name in ['公司信息', '公司架构', '通知设置']:
-            payload = dict(
-                type_id=resource_type['id'],
-                app_id=acl.app_name,
-                name=name,
-            )
-            try:
-                acl.create_resource(payload)
-            except Exception as e:
-                if '已经存在' in str(e):
-                    pass
-                else:
-                    raise Exception(e)
+            target = list(filter(lambda r: r['name'] == name, resource_list))
+            if len(target) == 0:
+                payload = dict(
+                    type_id=resource_type['id'],
+                    app_id=acl.app_name,
+                    name=name,
+                )
+                resource = acl.create_resource(payload)
+            else:
+                resource = target[0]
+
+            if acl_rid > 0:
+                acl.grant_resource(acl_rid, resource['id'], perms)
 
     def check_app(self, app_name):
         acl = ACLManager(app_name)
@@ -210,6 +227,10 @@ class InitDepartment(object):
                 return acl
             raise Exception(e)
 
+    def get_admin_user_rid(self):
+        admin = Employee.get_by(first=True, username='admin', to_dict=False)
+        return admin.acl_rid if admin else 0
+
 
 @click.command()
 @with_appcontext
diff --git a/cmdb-api/api/lib/common_setting/acl.py b/cmdb-api/api/lib/common_setting/acl.py
index 99e1860..3cdf6dc 100644
--- a/cmdb-api/api/lib/common_setting/acl.py
+++ b/cmdb-api/api/lib/common_setting/acl.py
@@ -7,6 +7,7 @@ from api.lib.perm.acl.cache import RoleCache, AppCache
 from api.lib.perm.acl.role import RoleCRUD, RoleRelationCRUD
 from api.lib.perm.acl.user import UserCRUD
 from api.lib.perm.acl.resource import ResourceTypeCRUD, ResourceCRUD
+from api.lib.perm.acl.permission import PermissionCRUD
 
 
 class ACLManager(object):
@@ -109,8 +110,26 @@ class ACLManager(object):
             id2perms=id2perms
         )
 
+    def create_resources_type(self, payload):
+        payload['app_id'] = self.validate_app().id
+        rt = ResourceTypeCRUD.add(**payload)
+
+        return rt.to_dict()
+
+    def update_resources_type(self, _id, payload):
+        rt = ResourceTypeCRUD.update(_id, **payload)
+
+        return rt.to_dict()
+
     def create_resource(self, payload):
         payload['app_id'] = self.validate_app().id
         resource = ResourceCRUD.add(**payload)
 
         return resource.to_dict()
+
+    def get_resource_by_type(self, q, u, rt_id, page=1, page_size=999999):
+        numfound, res = ResourceCRUD.search(q, u, self.validate_app().id, rt_id, page, page_size)
+        return res
+
+    def grant_resource(self, rid, resource_id, perms):
+        PermissionCRUD.grant(rid, perms, resource_id=resource_id, group_id=None)