Skip to content

Commit

Permalink
fix: grant common perm after create new employee (#394)
Browse files Browse the repository at this point in the history
  • Loading branch information
simontigers authored Feb 4, 2024
1 parent 498feee commit 0f404fe
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 47 deletions.
47 changes: 4 additions & 43 deletions cmdb-api/api/commands/click_common_setting.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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):
Expand Down
79 changes: 76 additions & 3 deletions cmdb-api/api/lib/common_setting/employee.py
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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)
18 changes: 17 additions & 1 deletion cmdb-api/api/tasks/common_setting.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()}

Expand All @@ -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)
Expand All @@ -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(
Expand All @@ -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))

0 comments on commit 0f404fe

Please sign in to comment.