def get_project_user(access_token, project_id, group_code=''): """获取项目用户列表 """ # 根据 project_id 获取 project_code project_code = get_project_code_by_id(access_token, project_id) iam_client = BKIAMClient(project_code) return iam_client.get_project_users()
def __init__(self, request, project_id, resource_id, resource_name=None): self.access_token = request.user.token.access_token self.user_id = request.user.username self.project_id = project_id self.resource_id = str(resource_id) self.resource_name = resource_name self.resource_code = str(resource_id) self.err_msg = "请联系管理员添加权限" project_code = request.project.english_name self.iam_client = BKIAMClient(project_code) self.resource_id = self.tansfer_resource_id(resource_id)
def hook_perms(cls, request, project_id, cluster_list, filter_use=False): default_perms = {perm: True for perm in cls.POLICY_LIST} default_perms.update({'view': True, 'use': True, 'delete': True}) cluster_list = cluster_list or [] for data in cluster_list: data['permissions'] = default_perms return cluster_list perm_metrix = [] perm_metrix_val = [] for i in cls.POLICY_LIST: perm_metrix.append({"action_id": i, "resource_type": 'cluster'}) perm_metrix_val.append(("cluster", i)) project_code = request.project.english_name iam_client = BKIAMClient(project_code) perms = iam_client.get_multi_perm_resource( request.user.username, perm_metrix).get('data') or [] perms = {(i["resource_type"], i["action_id"]): i["resource_ids"] for i in perms} list_info = [] for info in (cluster_list or []): # 需要将id转成权限中心新的格式 resource_id = cls.tansfer_resource_id(cls, info["cluster_id"]) # 任意资源也需要添加 RESOURCE_TYPE any_res = '%s:%s' % (cls.RESOURCE_TYPE, ANY_RES) default = {p: False for p in cls.POLICY_LIST} for item in perm_metrix_val: perm_res = perms.get(item) or [] if any_res in perm_res or resource_id in perm_res: default[item[1]] = True # 将权限key转换为前端可识别的字符 # TODO: 现阶段针对集群can_create是开放的,因此做特殊处理 default['create'] = True default['view'] = default.get('cluster-readonly', False) default['use'] = default.get('cluster-manager', False) default['delete'] = default.get('cluster-manager', False) if filter_use is True and default['cluster-manager'] is False: continue info["permissions"] = default list_info.append(info) return list_info
def get_role_list(access_token, project_id, need_user=False): """获取角色列表(权限中心暂时没有角色的概念,先获取所有用户) """ # 根据 project_id 获取 project_code project_code = get_project_code_by_id(access_token, project_id) iam_client = BKIAMClient(project_code) user_res = iam_client.get_project_users() user_data = user_res.get('data') or [] role_list = [] for _u in user_data: # 所有用户都设置为项目成员 role_list.append({ "display_name": "项目成员", "role_id": 0, "role_name": "manager", "user_id": _u, "user_type": "user" }) return role_list
def verify_project_by_user(access_token, project_id, project_code, user_id): """ 验证用户是否有项目权限 """ iam_client = BKIAMClient(project_code) return iam_client.verify_project(user_id, project_code)
class PermissionMeta(object): """权限元类 """ __metaclass__ = abc.ABCMeta # 服务类型,常量 RESOURCE_TYPE = '' RES_TYPE_NAME = '' # 功能列表 POLICY_LIST = ['create', 'delete', 'view', 'edit', 'use'] CMD_NAME = { 'delete': "删除", 'create': "创建", 'use': "使用", 'edit': "编辑", 'view': "查看", 'list': "列表" } def __init__(self, request, project_id, resource_id, resource_name=None): self.access_token = request.user.token.access_token self.user_id = request.user.username self.project_id = project_id self.resource_id = str(resource_id) self.resource_name = resource_name self.resource_code = str(resource_id) self.err_msg = "请联系管理员添加权限" project_code = request.project.english_name self.iam_client = BKIAMClient(project_code) self.resource_id = self.tansfer_resource_id(resource_id) def tansfer_resource_id(self, resource_id): """resource_id 需要按照新的格式组装 """ # resource_id 需要按照新的格式组装(与资源无关则保持用:**) if resource_id != NO_RES: resource_id = f'{self.RESOURCE_TYPE}:{resource_id}' return resource_id def had_perm(self, action_id): """判断是否有权限 """ # 模板集 和 Metric 都先不做权限限制 # if self.RESOURCE_TYPE in ['templates', 'metric']: # True return True ret = self.iam_client.verify_user_perm( self.user_id, action_id, self.RESOURCE_TYPE, self.resource_id, ) return ret.get('data').get('is_pass') def can_create(self, raise_exception): """创建权限不做判断 """ # 创建权限都默认开放 return True def can_edit(self, raise_exception): """是否编辑权限 """ return True action_id = 'edit' can = self.had_perm(action_id) msg = self.get_msg(action_id) if can is False and raise_exception is True: raise NoAuthPermError(msg, self.get_err_data(action_id)) return can def can_delete(self, raise_exception): """是否使用删除 """ return True action_id = 'delete' msg = self.get_msg(action_id) if self.RESOURCE_TYPE in CLUSTER_NAMESPACE_RESOURCE_TYPE: real_action_id = 'cluster-readonly' else: real_action_id = action_id can = self.had_perm(real_action_id) if can is False and raise_exception is True: raise NoAuthPermError(msg, self.get_err_data(action_id)) return can def can_view(self, raise_exception): return True action_id = 'view' msg = self.get_msg(action_id) # 集群和命名空间因为对接RBAC时使用单独的命名规范,所以需要兼容 if self.RESOURCE_TYPE in CLUSTER_NAMESPACE_RESOURCE_TYPE: real_action_id = 'cluster-readonly' else: real_action_id = action_id can = self.had_perm(real_action_id) if can is False and raise_exception is True: raise NoAuthPermError(msg, self.get_err_data(action_id)) return can def can_use(self, raise_exception): """是否使用权限 """ return True action_id = 'use' msg = self.get_msg(action_id) # 集群和命名空间因为对接RBAC时使用单独的命名规范,所以需要兼容 if self.RESOURCE_TYPE in CLUSTER_NAMESPACE_RESOURCE_TYPE: real_action_id = 'cluster-manager' else: real_action_id = action_id can = self.had_perm(real_action_id) if can is False and raise_exception is True: raise NoAuthPermError(msg, self.get_err_data(action_id)) return can def get_msg(self, cmd): """获取消息 """ cmd_name = self.CMD_NAME[cmd] if cmd == 'create': msg = "您没有{res_type_name}的{cmd_name}权限".format( res_type_name=self.RES_TYPE_NAME, cmd_name=cmd_name) else: if self.resource_name: msg_format = "您没有{res_type_name}【{res_name}】的{cmd_name}权限" else: msg_format = "您没有{res_type_name}的{cmd_name}权限" msg = msg_format.format(res_type_name=self.RES_TYPE_NAME, res_name=self.resource_name, cmd_name=cmd_name) return msg def register(self, resource_id, resource_name): """注册资源到权限中心 """ resource_id = self.tansfer_resource_id(resource_id) ret = self.iam_client.register_res( self.user_id, self.RESOURCE_TYPE, resource_id, resource_name, ) return ret def delete(self): """删除资源 注意: resource_id必须是字符串类型 """ ret = self.iam_client.delete_res(self.RESOURCE_TYPE, self.resource_id) return ret def update_name(self, resource_name, raise_exception=False): ret = self.iam_client.update_res(self.RESOURCE_TYPE, self.resource_id, resource_name) if ret.get('code') != 0 and raise_exception is True: error_message = ('%s, %s' % (bk_error_codes.IAMError( ("权限中心更新资源接口调用失败")), ret.get('message', ''))) raise error_codes.APIError(error_message) return ret def hook_perms(self, data_list, filter_use=False, id_flag='id'): """资源列表,添加permssions dict """ # NOTE: 现阶段有项目权限,那么就有所有权限 default_perms = {perm: True for perm in self.POLICY_LIST} data_list = data_list or [] for data in data_list: data['permissions'] = default_perms return data_list # 资源的权限矩阵 perm_matrix = [{ 'action_id': i, 'resource_type': self.RESOURCE_TYPE } for i in self.POLICY_LIST] # 到权限中心获取权限信息 perms = self.iam_client.get_multi_perm_resource( self.user_id, perm_matrix, ).get('data') or [] perms = {(i['resource_type'], i['action_id']): i['resource_ids'] for i in perms} # 在列表数据中添加权限信息 new_list = [] for data in data_list: default_perm = {p: False for p in self.POLICY_LIST} # 检查权限 for p in default_perm: perm_res = perms.get((self.RESOURCE_TYPE, p)) or [] # 需要将id转成权限中心新的格式 resource_id = self.tansfer_resource_id(data[id_flag]) # 任意资源也需要添加 RESOURCE_TYPE any_res = '%s:%s' % (self.RESOURCE_TYPE, ANY_RES) # * 代表任意 if any_res in perm_res or resource_id in perm_res: default_perm[p] = True # 过滤没有使用权限的数据 if filter_use is True and default_perm['use'] is False: continue data['permissions'] = default_perm new_list.append(data) return new_list def get_err_data(self, policy_code): """获取返回给前端错误数据,权限申请使用 """ if policy_code == 'create': role = 'creator' elif policy_code in ['deploy', 'download']: role = 'manager' else: role = 'bcs_manager' data = [{ 'resource_type': self.RESOURCE_TYPE, 'resource_type_name': self.RES_TYPE_NAME, 'resource_id': self.resource_id, 'resource_code': self.resource_id, 'resource_name': self.resource_name, 'role': role, 'policy_code': policy_code, 'policy_name': self.CMD_NAME[policy_code] }] return data
def verify_project(access_token, project_id, user_id): """@note:项目标识为 project_code 而不是 project_id """ project_code = get_project_code_by_id(access_token, project_id) iam_client = BKIAMClient(project_code) return iam_client.verify_project(user_id, project_code)