def validate_perms_rbac(self, request, obj_uuid, mode=PERMS_R, perms2=None, obj_owner_for_delete=None): user, roles = self.get_user_roles(request) if has_role(self.cloud_admin_role, roles): return (True, 'RWX') if has_role(self.global_read_only_role, roles) and mode == PERMS_R: return (True, 'R') # Get request scope env = request.headers.environ domain_id = env.get('HTTP_X_DOMAIN_ID') domain_name = env.get('HTTP_X_DOMAIN_NAME') project_id = env.get('HTTP_X_PROJECT_ID') project_name = env.get('HTTP_X_PROJECT_NAME') # retrieve object permissions if missing if not perms2: try: perms2 = self._server_mgr._db_conn.uuid_to_obj_perms2(obj_uuid) except NoIdError: return True, '' owner = perms2['owner'].replace('-','') perms = perms2['owner_access'] << 6 perms |= perms2['global_access'] # build perms mask = 07 if project_id == owner: mask |= 0700 share_items = perms2['share'] shares = [item['tenant'] for item in share_items] for item in share_items: # item['tenant'] => [share-type, uuid] # allow access if domain or project from token matches configured # sharing information share_type, share_uuid = shareinfo_from_perms2_tenant(item['tenant']) share_uuid = share_uuid.replace('-','') if ((share_type == 'tenant' and project_id == share_uuid) or (share_type == 'domain' and domain_id == share_uuid)): perms = perms | item['tenant_access'] << 3 mask |= 0070 break mode_mask = mode | mode << 3 | mode << 6 ok = (mask & perms & mode_mask) if (ok and obj_owner_for_delete): obj_owner_for_delete = obj_owner_for_delete.replace('-','') ok = (project_id == obj_owner_for_delete) granted = ok & 07 | (ok >> 3) & 07 | (ok >> 6) & 07 msg = ("RBAC: %s (%s:%s) mode=%03o mask=%03o perms=%03o, " "(user=%s(%s)/owner=%s/shares=%s)" % ('+++' if ok else '---', self.mode_str[mode], obj_uuid, mode_mask, mask, perms, project_id, project_name, owner, shares)) self._server_mgr.config_log(msg, level=SandeshLevel.SYS_DEBUG) if not ok: msg = ("RBAC: %s doesn't have %s permission in project '%s'" % (user, self.mode_str2[mode], owner)) self._server_mgr.config_log(msg, level=SandeshLevel.SYS_NOTICE) err_msg = ("Permission Denied for %s to %s operation in domain '%s' " "and project '%s'" % (roles, self.mode_str2[mode], domain_name, project_name)) if ok: return True, self.mode_str[granted] else: return False, (403, err_msg)
def validate_perms_rbac(self, request, obj_uuid, mode=PERMS_R, perms2=None, obj_owner_for_delete=None): user, roles = self.get_user_roles(request) if has_role(self.cloud_admin_role, roles): return (True, 'RWX') if has_role(self.global_read_only_role, roles) and mode == PERMS_R: return (True, 'R') # Get request scope env = request.headers.environ domain_id = env.get('HTTP_X_DOMAIN_ID') domain_name = env.get('HTTP_X_DOMAIN_NAME') project_id = env.get('HTTP_X_PROJECT_ID') project_name = env.get('HTTP_X_PROJECT_NAME') # retrieve object permissions if missing if not perms2: try: perms2 = self._server_mgr._db_conn.uuid_to_obj_perms2(obj_uuid) except NoIdError: return True, '' owner = perms2['owner'].replace('-', '') perms = perms2['owner_access'] << 6 perms |= perms2['global_access'] # build perms mask = 07 if project_id == owner: mask |= 0700 share_items = perms2['share'] shares = [item['tenant'] for item in share_items] for item in share_items: # item['tenant'] => [share-type, uuid] # allow access if domain or project from token matches configured # sharing information share_type, share_uuid = shareinfo_from_perms2_tenant( item['tenant']) share_uuid = share_uuid.replace('-', '') if ((share_type == 'tenant' and project_id == share_uuid) or (share_type == 'domain' and domain_id == share_uuid)): perms = perms | item['tenant_access'] << 3 mask |= 0070 break mode_mask = mode | mode << 3 | mode << 6 ok = (mask & perms & mode_mask) if (ok and obj_owner_for_delete): obj_owner_for_delete = obj_owner_for_delete.replace('-', '') ok = (project_id == obj_owner_for_delete) granted = ok & 07 | (ok >> 3) & 07 | (ok >> 6) & 07 msg = ( "RBAC: %s (%s:%s) mode=%03o mask=%03o perms=%03o, " "(user=%s(%s)/owner=%s/shares=%s)" % ('+++' if ok else '---', self.mode_str[mode], obj_uuid, mode_mask, mask, perms, project_id, project_name, owner, shares)) self._server_mgr.config_log(msg, level=SandeshLevel.SYS_DEBUG) if not ok: msg = ("RBAC: %s doesn't have %s permission in project '%s'" % (user, self.mode_str2[mode], owner)) self._server_mgr.config_log(msg, level=SandeshLevel.SYS_NOTICE) err_msg = ("Permission Denied for %s to %s operation in domain '%s' " "and project '%s'" % (roles, self.mode_str2[mode], domain_name, project_name)) if ok: return True, self.mode_str[granted] else: return False, (403, err_msg)