diff --git a/cmdb-api/api/commands/click_common_setting.py b/cmdb-api/api/commands/click_common_setting.py index ddd370bc..37e8ffe8 100644 --- a/cmdb-api/api/commands/click_common_setting.py +++ b/cmdb-api/api/commands/click_common_setting.py @@ -4,7 +4,7 @@ from werkzeug.datastructures import MultiDict from api.lib.common_setting.acl import ACLManager -from api.lib.common_setting.employee import EmployeeAddForm +from api.lib.common_setting.employee import EmployeeAddForm, GrantEmployeeACLPerm from api.lib.common_setting.resp_format import ErrFormat from api.models.common_setting import Employee, Department @@ -158,50 +158,11 @@ def create_acl_role_with_department(): def init_backend_resource(self): 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=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 ['公司信息', '公司架构', '通知设置']: - 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) + if acl_rid == 0: + return + GrantEmployeeACLPerm(acl).grant_by_rid(acl_rid, True) @staticmethod def check_app(app_name): diff --git a/cmdb-api/api/lib/common_setting/employee.py b/cmdb-api/api/lib/common_setting/employee.py index c543b2b8..ca7173f2 100644 --- a/cmdb-api/api/lib/common_setting/employee.py +++ b/cmdb-api/api/lib/common_setting/employee.py @@ -141,7 +141,7 @@ def add_employee_from_acl_created(**kwargs): def add(**kwargs): try: res = CreateEmployee().create_single(**kwargs) - refresh_employee_acl_info.apply_async(args=(), queue=ACL_QUEUE) + refresh_employee_acl_info.apply_async(args=(res.employee_id,), queue=ACL_QUEUE) return res except Exception as e: abort(400, str(e)) @@ -577,7 +577,6 @@ def get_employee_notice_by_ids(employee_ids): @staticmethod def import_employee(employee_list): res = CreateEmployee().batch_create(employee_list) - refresh_employee_acl_info.apply_async(args=(), queue=ACL_QUEUE) return res @staticmethod @@ -788,9 +787,11 @@ def create_single_with_import(self, **kwargs): if existed: return existed - return Employee.create( + res = Employee.create( **kwargs ) + refresh_employee_acl_info.apply_async(args=(res.employee_id,), queue=ACL_QUEUE) + return res @staticmethod def get_department_by_name(d_name): @@ -897,3 +898,75 @@ class EmployeeUpdateByUidForm(Form): avatar = StringField(validators=[]) sex = StringField(validators=[]) mobile = StringField(validators=[]) + + +class GrantEmployeeACLPerm(object): + """ + Grant ACL Permission After Create New Employee + """ + + def __init__(self, acl=None): + self.perms_by_create_resources_type = ['read', 'grant', 'delete', 'update'] + self.perms_by_common_grant = ['read'] + self.resource_name_list = ['公司信息', '公司架构', '通知设置'] + + self.acl = acl if acl else self.check_app('backend') + self.resources_types = self.acl.get_all_resources_types() + self.resources_type = self.get_resources_type() + self.resource_list = self.acl.get_resource_by_type(None, None, self.resources_type['id']) + + @staticmethod + def check_app(app_name): + acl = ACLManager(app_name) + payload = dict( + name=app_name, + description=app_name + ) + app = acl.validate_app() + if not app: + acl.create_app(payload) + return acl + + def get_resources_type(self): + results = list(filter(lambda t: t['name'] == '操作权限', self.resources_types['groups'])) + if len(results) == 0: + payload = dict( + app_id=self.acl.app_name, + name='操作权限', + description='', + perms=self.perms_by_create_resources_type + ) + resource_type = self.acl.create_resources_type(payload) + else: + resource_type = results[0] + resource_type_id = resource_type['id'] + existed_perms = self.resources_types.get('id2perms', {}).get(resource_type_id, []) + existed_perms = [p['name'] for p in existed_perms] + new_perms = [] + for perm in self.perms_by_create_resources_type: + if perm not in existed_perms: + new_perms.append(perm) + if len(new_perms) > 0: + resource_type['perms'] = existed_perms + new_perms + self.acl.update_resources_type(resource_type_id, resource_type) + + return resource_type + + def grant(self, rid_list): + [self.grant_by_rid(rid) for rid in rid_list if rid > 0] + + def grant_by_rid(self, rid, is_admin=False): + for name in self.resource_name_list: + resource = list(filter(lambda r: r['name'] == name, self.resource_list)) + if len(resource) == 0: + payload = dict( + type_id=self.resources_type['id'], + app_id=self.acl.app_name, + name=name, + ) + resource = self.acl.create_resource(payload) + else: + resource = resource[0] + + perms = self.perms_by_create_resources_type if is_admin else self.perms_by_common_grant + self.acl.grant_resource(rid, resource['id'], perms) diff --git a/cmdb-api/api/tasks/common_setting.py b/cmdb-api/api/tasks/common_setting.py index c1c560e8..44706df6 100644 --- a/cmdb-api/api/tasks/common_setting.py +++ b/cmdb-api/api/tasks/common_setting.py @@ -80,7 +80,7 @@ def edit_employee_department_in_acl(e_list, new_d_id, op_uid): @celery.task(name="common_setting.refresh_employee_acl_info", queue=ACL_QUEUE) @flush_db @reconnect_db -def refresh_employee_acl_info(): +def refresh_employee_acl_info(current_employee_id=None): acl = ACLManager('acl') role_map = {role['name']: role for role in acl.get_all_roles()} @@ -90,8 +90,12 @@ def refresh_employee_acl_info(): query = Employee.query.filter(*criterion).order_by( Employee.created_at.desc() ) + current_employee_rid = 0 for em in query.all(): + if current_employee_id and em.employee_id == current_employee_id: + current_employee_rid = em.acl_rid if em.acl_rid else 0 + if em.acl_uid and em.acl_rid: continue role = role_map.get(em.username, None) @@ -105,6 +109,9 @@ def refresh_employee_acl_info(): if not em.acl_rid: params['acl_rid'] = role.get('id', 0) + if current_employee_id and em.employee_id == current_employee_id: + current_employee_rid = params['acl_rid'] if params.get('acl_rid', 0) else 0 + try: em.update(**params) current_app.logger.info( @@ -113,3 +120,12 @@ def refresh_employee_acl_info(): except Exception as e: current_app.logger.error(str(e)) continue + + if current_employee_rid and current_employee_rid > 0: + try: + from api.lib.common_setting.employee import GrantEmployeeACLPerm + + GrantEmployeeACLPerm().grant_by_rid(current_employee_rid, False) + current_app.logger.info(f"GrantEmployeeACLPerm success, current_employee_rid: {current_employee_rid}") + except Exception as e: + current_app.logger.error(str(e))