def download(request, path): """ FileCube文件的下载接口,向前端返回支持文件部分下载的数据流,支持下载暂停、断点续传和多线程并发下载 path为下载文件在FileCube系统内的表示路径 request: WSGI请求 权限控制: 通过request找到对应的session,查找里面记录的用户名,以此来进行权限判断 若用户未登录,则使用匿名账户的权限记录进行判断 """ try: username = request.session['username'] except KeyError: username = '******' # 对path合法性判断一下 path = str(path) access_list = table_access.get_access_list_by_id(username) if not db_helper.lookup_access_in_the_list(path, 'download', access_list): return HttpResponse('no download access to resource', status=403) else: tmp_actual_path = address_transfer.resolve_path_to_actual_path(path) if tmp_actual_path['state'] and not os.path.exists( tmp_actual_path['actual_path']): raise Http404('"%(path)s" does not exist' % {'path': path}) elif not tmp_actual_path['state']: raise Http404('"%(path)s" can not be resolved properly' % {'path': path}) elif os.path.isdir(tmp_actual_path['actual_path']): return HttpResponse('server does not support downloading a folder', status=403) else: # 一切均正常,开始下载 return get_file_response(request, tmp_actual_path['actual_path'])
def rename_or_move(request): """ 移动或重命名文件或文件夹 :param request: POST request.POST = {'file_type':...,'curr_path':...,'curr_name':...,'des_path':...,'des_name':...} request.session['access'] :return: HttpResponse(json.dumps({'state':...,'details':...})) state = 'failed' or 'success' details为移动成功后的文件信息{'file_id':...,'new_parent_id':...}或失败后的报错信息 """ print("移动或重命名文件") file_type = str(request.POST['file_type']) curr_path = str(request.POST['curr_path']) curr_name = str(request.POST['curr_name']) des_path = str(request.POST['des_path']) des_name = str(request.POST['des_name']) access_in_cur_dir = db_helper.lookup_access_in_the_list(curr_path, 'modify', request.session['access']) access_in_des_dir = db_helper.lookup_access_in_the_list(des_path, 'modify', request.session['access']) if access_in_des_dir and access_in_cur_dir: message = operation.rename_and_move_file(file_type, curr_path, curr_name, des_path, des_name, request.session['username']) if message['state'] == 'failed': return HttpResponse(json.dumps({'state': 'failed', 'details': message['details']})) else: conn = pymysql.connect(host=DATABASE_HOST, port=DATABASE_PORT, user=DATABASE_USER, passwd=DATABASE_PWD, db=DB_NAME, charset='utf8') cursor = conn.cursor() append_slash = "" file_id = 0 new_parent_id = 0 if file_type == 'dir': append_slash = "/" cursor.execute("SELECT ID,parent_id FROM file_tree WHERE dir ='" + des_path + des_name + append_slash + "'") query_result = cursor.fetchall() for row in query_result: file_id = row[0] new_parent_id = row[1] return HttpResponse(json.dumps({'state': 'success', 'details': {'file_id': file_id, 'new_parent_id': new_parent_id}})) elif not access_in_cur_dir: return HttpResponse(json.dumps({'state': 'failed', 'details': '当前路径下无修改权限'})) else: return HttpResponse(json.dumps({'state': 'failed', 'details': '目标路径下无修改权限'}))
def add_access_record(request): """ 增加一条权限记录 :param request: POST request.POST = {user_id, path, read, new, download, remove, modify, admin, opt} request.session['username'] :return: {'state':...,'details':...} """ try: user_id = str(request.POST['user_id']) path = str(request.POST['path']) read = request.POST['read'] == 'true' new = request.POST['new'] == 'true' download = request.POST['download'] == 'true' remove = request.POST['remove'] == 'true' modify = request.POST['modify'] == 'true' admin = request.POST['admin'] == 'true' opt = str(request.POST['opt']) except KeyError as error_msg: print(error_msg) print(traceback.format_exc()) return HttpResponse( json.dumps({ 'state': 'failed', 'details': 'POST参数错误' })) if not validate_identity(request): state = 'failed' details = '未登录' else: if not check_if_have_this_key(request.session, 'username'): raise KeyError('session 中缺少字段username') if not check_if_have_this_key(request.session, 'sys_admin'): raise KeyError('session 中缺少字段sys_admin') # 查询该用户是否能在该路径下赋予他人权限 access_list = table_access.get_access_list_by_id( request.session['username']) if not db_helper.lookup_access_in_the_list( path, 'admin', access_list) and not request.session['sys_admin']: state = 'failed' details = '用户无权限在此路径下增加权限' elif not table_user.if_user_exists(user_id): state = 'failed' details = '请检查新增权限记录中的用户名,用户不存在' elif not address_transfer.resolve_path_to_actual_path(path)['state']: state = 'failed' details = '您不能为不存在的路径赋予权限' else: print(read) table_access.modify_some_access(user_id, path, read, new, download, remove, modify, admin, opt) state = 'success' details = '成功增加一条权限记录' return HttpResponse(json.dumps({'state': state, 'details': details}))
def back_to_parent_dir(request): """ 切换到文件系统的上级目录,返回上级目录下的目录项列表 :param request: POST request.POST = {'file_dir':...} request.session['access_list'] :return: HttpResponse(json.dumps(data_list)) data_list = {'have_access':BOOL,'have_parent': BOOL or None, 'new_current_path': ..., 'file_list': ...} """ current_dir = str(request.POST['file_dir']) # TODO[柏旭] 2020-06-28 检查传入路径是否合法 temp_find_parent_dir_result = address_helper.find_parent_dir(current_dir) have_parent = temp_find_parent_dir_result['result'] if have_parent: new_current_path = temp_find_parent_dir_result['details'] # ------------------------------------------------------------------------------------------------------- if not new_current_path.endswith('/'): new_current_path += "/" have_access = False file_list = [] # 权限校验 if key_checker.check_if_have_this_key(request.session, 'access_list'): access_list = request.session['access_list'] if db_helper.lookup_access_in_the_list(new_current_path, 'read', access_list): have_access = True else: pass if have_access: actual_dir = address_transfer.resolve_path_to_actual_path(new_current_path)['actual_path'] if os.path.exists(actual_dir): filename_list = os.listdir(actual_dir) for filename in filename_list: if os.path.isdir(actual_dir + filename): file_list.append({'file_type': 'dir', 'file_name': filename, 'file_dir': new_current_path + filename, 'file_size': '-'}) else: size = table_file_tree.get_file_size(actual_dir + filename) file_list.append({'file_type': 'file', 'file_name': filename, 'file_dir': new_current_path + filename, 'file_size': size}) # ------------------------------------------------------------------------------------------------------- else: have_access = True new_current_path = current_dir file_list = None return HttpResponse(json.dumps({'have_access': have_access, 'have_parent': have_parent, 'new_current_path': new_current_path, 'file_list': file_list}))
def check_access(request): """ 检查用户是否在该路径下有上传权限 :param request: request.POST['file_dir'] :return: BOOL """ print('check_access: ------------------------------') print(request.POST) have_access = db_helper.lookup_access_in_the_list(request.POST['file_path'], 'new', request.session['access']) print(have_access) if have_access: return JsonResponse({'haveAccess': True}) else: return JsonResponse({'haveAccess': False})
def make_dir(request): """ 新建文件夹 :param request: POST request.POST = {'mkdir_path':...,'mkdir_name':...} :return: HttpResponse(json.dumps({'state':..., 'details':...})) state = 'failed' or 'success' details为成功后的文件信息{'file_id':...,'file_name':...,'file_dir':...,'new_parent_id':...} 或失败后的报错信息 """ print("开始新建文件夹") mkdir_path = str(request.POST['mkdir_path']) mkdir_name = str(request.POST['mkdir_name']) print("路径: " + mkdir_path) print("文件名: " + mkdir_name) if db_helper.lookup_access_in_the_list(mkdir_path, 'new', request.session['access']): conn = pymysql.connect(host=DATABASE_HOST, port=DATABASE_PORT, user=DATABASE_USER, passwd=DATABASE_PWD, db=DB_NAME, charset='utf8') cursor = conn.cursor() count = cursor.execute("SELECT * FROM file_tree WHERE dir='" + mkdir_path + mkdir_name + "/'") if count > 0: conn.close() return HttpResponse(json.dumps({'state': 'failed', 'details': '该路径下已存在同名文件夹'})) else: result = operation.make_dir(mkdir_path, request.session['username'], mkdir_name) if result['state'] == 'failed': print(result['details']) return HttpResponse(json.dumps({'state': 'failed', 'details': result['details']})) else: result = result['details'] print(result) file_id = result['ID'] file_name = result['name'] file_dir = result['dir'] file_parent_id = result['parent_id'] print(json.dumps({'state': 'success', 'file_info': {'file_id': file_id, 'file_name': file_name, 'file_dir': file_dir, 'file_parent_id': file_parent_id}})) conn.close() return HttpResponse(json.dumps({'state': 'success', 'file_info': {'file_id': file_id, 'file_name': file_name, 'file_dir': file_dir, 'file_parent_id': file_parent_id}})) else: return HttpResponse(json.dumps({'state': 'failed', 'details': '权限不足'}))
def get_file_list_under_dir(request): """ 展示某目录项下的目录项列表 :param request: POST request.POST = {'file_dir':...} request.session['access_list'] :return: HttpResponse(json.dumps(data_list)) data_list = {'have_access': BOOL, 'dir_exist': BOOL or None, 'file_list': BOOL or None} """ data_dir = str(request.POST['file_dir']) if not data_dir.endswith('/'): data_dir += "/" have_access = False file_list = [] # 权限校验 if key_checker.check_if_have_this_key(request.session, 'access_list'): access_list = request.session['access_list'] if db_helper.lookup_access_in_the_list(data_dir, 'read', access_list): have_access = True else: pass if have_access: actual_dir = address_transfer.resolve_path_to_actual_path(data_dir)['actual_path'] if not os.path.exists(actual_dir): data_list = {'have_access': True, 'dir_exist': False, 'file_list': file_list} else: filename_list = os.listdir(actual_dir) # print(actual_dir) for filename in filename_list: # print(actual_dir + filename) if os.path.isdir(actual_dir + filename): file_list.append({'file_type': 'dir', 'file_name': filename, 'file_dir': data_dir + filename, 'file_size': '-'}) else: size = table_file_tree.get_file_size(actual_dir + filename) file_list.append({'file_type': 'file', 'file_name': filename, 'file_dir': data_dir + filename, 'file_size': size}) data_list = {'have_access': True, 'dir_exist': True, 'file_list': file_list} else: data_list = {'have_access': False, 'dir_exist': None, 'file_list': file_list} return HttpResponse(json.dumps(data_list))
def save_txt_file(request): """ 更新txt文件内容 :param request: POST request.POST['file_dir'], request.POST['file_content'] request.session :return: HttpResponse(json.dumps({'state': 'failed' or 'success', 'details')) """ hfs_sys_basic_funcs.validate_identity(request) file_dir = str(request.POST['file_dir']) # fixme [baixu] 2020-06-28 对file_dir的合法性进行验证处理 have_access = db_helper.lookup_access_in_the_list( file_dir, 'modify', request.session['access_list']) if not have_access: state = 'failed' details = '权限不足、无法修改文件内容' else: temp_path_transfer_result = address_transfer.resolve_path_to_actual_path( file_dir) if not temp_path_transfer_result['state']: state = 'failed' details = '传入的路径无法解析' elif not os.path.exists(temp_path_transfer_result['actual_path']): state = 'failed' details = '所指定文件不存在' else: try: file = open(temp_path_transfer_result['actual_path'], 'w', encoding='utf-8') file.write(request.POST['file_content']) print(file_dir) print('--------------') print(request.POST['file_content']) file.close() state = 'success' details = '文件保存成功' except Exception as error_msg: print(error_msg) state = 'failed' details = '未知错误,请联系管理员查看日志排查' return HttpResponse(json.dumps({'state': state, 'details': details}))
def preview_file_content(request): """ 根据传来的文件路径,返回文件的内容供前端预览文件 :param request: POST request.POST['file_dir'] request.session['access_list'] :return:HttpResponse(json.dumps(data)) data = {'result': 'failed' or 'success', 'details': ’文件内容‘ or '报错信息‘} """ hfs_sys_basic_funcs.validate_identity(request) file_dir = str(request.POST['file_dir']) # fixme [baixu] 2020-06-28 对file_dir的合法性进行验证处理 have_access = db_helper.lookup_access_in_the_list( file_dir, 'read', request.session['access_list']) if not have_access: result = 'failed' details = '权限不足、无法查看文件内容' else: temp_path_transfer_result = address_transfer.resolve_path_to_actual_path( file_dir) if not temp_path_transfer_result['state']: result = 'failed' details = '传入的路径无法解析' elif not os.path.exists(temp_path_transfer_result['actual_path']): result = 'failed' details = '所指定文件不存在' else: filename = temp_path_transfer_result['actual_path'] try: fp = open(filename, 'r', encoding='utf-8') details = fp.read() fp.close() result = 'success' except IOError: result = 'failed' details = "文件打开失败,%s文件不存在" % filename except Exception as e: result = 'failed' details = '文件不支持预览、或其他未知错误' print(e) return HttpResponse(json.dumps({'result': result, 'details': details}))
def get_access_list_can_be_managed(request): """ 展示该用户在该路径下可管理的权限的列表 :param request: POST request.POST = {'current_dir':...,} :return: HttpResponse(json.dumps({'state':...,'details':...})) """ # 身份验证 if not validate_identity(request): state = 'failed' details = '已登录用户才能查看权限' else: # user_info = {'username':...,'is_sys_admin':BOOL,'root_dir':...} user_info = who_is_sending_request(request) # access_list_owned_by_userself 用户自己的权限列表 access_list_owned_by_userself = table_access.get_access_list_by_id( user_info['username']) # --------------------------------------------------- # 根据request.POST['current_dir']筛选access_list中的权限 if not check_if_have_this_key(request.POST, 'current_dir'): raise KeyError("request.POST 中不存在current_dir这一键值对") else: curr_dir = request.POST['current_dir'] # 用户在该路径下是否有管理权限? if not db_helper.lookup_access_in_the_list( curr_dir, 'admin', access_list_owned_by_userself): state = 'failed' details = '用户在该路径下没有管理权限' else: # 用户在该路径下有权限,开始筛选在该路径下可管理的权限列表(权限包含当前路径的、被当前路径包含的) state = 'success' access_list = table_access.get_access_list_excluding_id( user_info['username']) details = [] for access_record in access_list: if access_record['path'].find(curr_dir) == 0: details.append(access_record) return HttpResponse(json.dumps({'state': state, 'details': details}))
def upload(request): """ 接受前端发送过来的文件上传请求,向服务器写文件, 根据request.POST中是否含有chunk参数,来判断传过来的是一个大文件的分片还是一整个文件 :param request: POST request.POST: mode, task_id, file_path, csrfmiddlewaretoken, id, name, type, lastModifiedDate, size :return: null """ print(request.POST) print(request.FILES['file']) task = request.POST['task_id'] # 获取文件的唯一标识符 file_path = request.POST['file_path'] if not hfs_basic_function.validate_identity(request): return HttpResponseRedirect('filescube/login/') elif not db_helper.lookup_access_in_the_list(file_path, 'new', request.session['access']): # 用户在该目录下无上传权限, # fixme[baixu] 添加返回值,与前端交互 print("用户%s希望上传%s, 但他在%s下无上传权限"%(request.session['username'], request.POST['name'], file_path)) else: # 进入上传流程 actual_dir = address_transfer.resolve_path_to_actual_path(file_path)['actual_path'] upload_file = request.FILES['file'] if key_checker.check_if_have_this_key(request.POST, 'chunk'): # 前端发送过来的数据是一个大文件的某个分片 chunk = request.POST['chunk'] # 获取该分片在所有分片中的序号 filename = '%s%s' % (task, chunk) # 构造该分片的唯一标识符 with open(actual_dir + filename, 'wb') as f: for i in upload_file.chunks(): f.write(i) # 保存该分片到本地 else: # 前端发送过来的是一个完整的文件 filename = request.POST['name'] with open(actual_dir + filename, 'wb') as f: for i in upload_file.chunks(): f.write(i) # 保存该文件 return HttpResponse(json.dumps({'123':'123'}))
def remove_file(request): """ 删除文件或文件夹 :param request: POST, request.POST={'remove_path':...,'remove_name':...,'remove_file_type':...} :return: HttpResponse(json.dumps({'state':...,'remove_file_id':...})) state = 'failed' or 'success' remove_file_id: 被删除目录项的ID """ print("remove_file ——views.py 11111111111111") try: remove_path = request.POST['remove_path'] # print(remove_path) remove_name = request.POST['remove_name'] remove_file_type = request.POST['remove_file_type'] remove_file_id = -1 except Exception as error: print(error) print("POST中某参数为空 ——views.py remove_file(request)") return {'state': 'failed', 'details': 'session失效'} if not db_helper.lookup_access_in_the_list(remove_path, 'remove', request.session['access']): print("无删除权限 ——views.py remove_file(request)") return HttpResponse(json.dumps({'state': 'failed', 'details': '无权限'})) remove_dir = '' if remove_file_type == 'dir': remove_dir = remove_path + remove_name + '/' else: remove_dir = remove_path + remove_name temp_resolve_result = address_transfer.resolve_path_to_actual_path(remove_dir) if not temp_resolve_result['state'] or not os.path.exists(temp_resolve_result['actual_path']): print("待删除的路径不存在 ——views.py remove_file(request)") print(temp_resolve_result) return HttpResponse(json.dumps({'state': 'failed', 'details': '文件不存在'})) else: operation.remove_file(remove_dir, request.session['username']) print("删完了") return HttpResponse(json.dumps({'state': 'success', 'remove_file_id': str(remove_file_id)}))
def upload_part(request): """ 接受一个新的文件分片 :param request: POST :return: 上传文件界面 """ print(request.POST) task = request.POST['task_id'] # 获取文件的唯一标识符 chunk = request.POST['chunk'] # 获取该分片在所有分片中的序号 file_path = request.POST['file_path'] if not hfs_basic_function.validate_identity(request): return HttpResponseRedirect('filescube/login/') elif db_helper.lookup_access_in_the_list(request.POST['file_path'], 'new', request.session['access']): actual_dir = address_transfer.resolve_path_to_actual_path(file_path)['actual_path'] filename = '%s%s' % (task, chunk) # 构造该分片的唯一标识符 upload_file = request.FILES['file'] with open(actual_dir + filename, 'wb') as f: for i in upload_file.chunks(): f.write(i) # 保存分片到本地 else: print('无权限,忽视请求')
def get_access_under_path(user_id, path): """ 获取某用户在某一路径下的权限 :param user_id: 用户ID :param path: 路径 :return: {'state':...,'details':...} state = 'failed' or 'success' details = {'read':BOOL,'new':BOOL,'download':BOOL,'remove':BOOL,'modify':BOOL,'admin':BOOL} """ access_list = table_access.get_access_list_by_id(user_id) result = { 'read': lookup_access_in_the_list(path, 'read', access_list), 'new': lookup_access_in_the_list(path, 'new', access_list), 'download': lookup_access_in_the_list(path, 'download', access_list), 'remove': lookup_access_in_the_list(path, 'remove', access_list), 'modify': lookup_access_in_the_list(path, 'modify', access_list), 'admin': lookup_access_in_the_list(path, 'admin', access_list) } return {'state': 'success', 'details': result}
def test_lookup_access_in_the_list(self): """ 给定权限表C,确定是否有某路径A下的某项权限B 依据表C中各权限记录为 “A路径下是否有权限B” 进行判断,则很可能依据表C中权限记录C1和C2会得出不同的判断结果 冲突处理规则: 细粒度优先:C1、C2哪个记录生效范围更小,采用哪个记录的判断 比如: 一: C1记录在路径"hfs/gabulei/"下以"recursive"方式指定"read"权限为True, 而C2记录在路径"hfs/gabulei/galeha/"下以"recursive"方式指定"read"权限为False, 则路径"hfs/gabulei/galeha/111/"下没有"read"权限 二: C1记录在路径"hfs/gabulei/"下以"recursive"方式指定"read"权限为True, 而C2记录在路径"hfs/gabulei/"下以"current"方式指定"read"权限为False, 则路径"hfs/gabulei/galeha/"下没有"read"权限 若C中存在C1和C2的'path'和'opt'均完全相同的情况,函数无视即可 :return: null """ access_list_1 = [{ 'opt': 'recursive', 'path': 'hfs/gabulei/', 'read': True, 'new': True, 'download': True, 'modify': True, 'remove': True, 'admin': True }] access_list_2 = [{ 'opt': 'current', 'path': 'hfs/gabulei/', 'read': True, 'new': True, 'download': True, 'modify': True, 'remove': True, 'admin': True }] # 传入异常access参数 self.assertFalse( db_helper.lookup_access_in_the_list('hfs/galeha/', 'read and delete', access_list_1)) self.assertFalse( db_helper.lookup_access_in_the_list('hfs/galeha/', 'read and delete', access_list_2)) # 各access均能正常接受并查询 self.assertFalse( db_helper.lookup_access_in_the_list('hfs/galeha/', 'read', access_list_1)) self.assertFalse( db_helper.lookup_access_in_the_list('hfs/galeha/', 'new', access_list_1)) self.assertFalse( db_helper.lookup_access_in_the_list('hfs/galeha/', 'download', access_list_1)) self.assertFalse( db_helper.lookup_access_in_the_list('hfs/galeha/', 'modify', access_list_1)) self.assertFalse( db_helper.lookup_access_in_the_list('hfs/galeha/', 'remove', access_list_1)) self.assertFalse( db_helper.lookup_access_in_the_list('hfs/galeha/', 'admin', access_list_1)) # access表中权限指定方式为recursive self.assertFalse( db_helper.lookup_access_in_the_list('hfs/galeha/', 'read', access_list_1)) self.assertTrue( db_helper.lookup_access_in_the_list('hfs/gabulei/galeha/', 'read', access_list_1)) self.assertTrue( db_helper.lookup_access_in_the_list('hfs/gabulei/', 'read', access_list_1)) self.assertFalse( db_helper.lookup_access_in_the_list('hfs/gabulei', 'read', access_list_1)) # access表中权限指定方式为current self.assertFalse( db_helper.lookup_access_in_the_list('hfs/galeha/', 'read', access_list_2)) self.assertFalse( db_helper.lookup_access_in_the_list('hfs/gabulei/galeha/', 'read', access_list_2)) self.assertTrue( db_helper.lookup_access_in_the_list('hfs/gabulei/', 'read', access_list_2)) self.assertFalse( db_helper.lookup_access_in_the_list('hfs/gabulei', 'read', access_list_2)) # 冲突处理 access_list_3 = [{ 'opt': 'recursive', 'path': 'hfs/gabulei/', 'read': False, 'new': False, 'download': False, 'modify': False, 'remove': False, 'admin': False }, { 'opt': 'recursive', 'path': 'hfs/gabulei/galeha/', 'read': True, 'new': True, 'download': True, 'modify': True, 'remove': True, 'admin': True }] self.assertTrue( db_helper.lookup_access_in_the_list('hfs/gabulei/galeha/', 'read', access_list_3)) access_list_4 = [{ 'opt': 'recursive', 'path': 'hfs/gabulei/', 'read': True, 'new': False, 'download': False, 'modify': False, 'remove': False, 'admin': False }, { 'opt': 'recursive', 'path': 'hfs/gabulei/galeha/', 'read': False, 'new': True, 'download': True, 'modify': True, 'remove': True, 'admin': True }] self.assertFalse( db_helper.lookup_access_in_the_list('hfs/gabulei/galeha/', 'read', access_list_4)) access_list_5 = [{ 'opt': 'recursive', 'path': 'hfs/gabulei/', 'read': True, 'new': False, 'download': False, 'modify': False, 'remove': False, 'admin': False }, { 'opt': 'current', 'path': 'hfs/gabulei/', 'read': False, 'new': True, 'download': True, 'modify': True, 'remove': True, 'admin': True }] self.assertFalse( db_helper.lookup_access_in_the_list('hfs/gabulei/', 'read', access_list_5)) access_list_6 = [{ 'opt': 'recursive', 'path': 'hfs/gabulei/', 'read': False, 'new': False, 'download': False, 'modify': False, 'remove': False, 'admin': False }, { 'opt': 'current', 'path': 'hfs/gabulei/', 'read': True, 'new': True, 'download': True, 'modify': True, 'remove': True, 'admin': True }] self.assertTrue( db_helper.lookup_access_in_the_list('hfs/gabulei/', 'read', access_list_6)) # 传入的权限表中某记录键值对不全 access_list_7 = [{ 'opt': 'recursive', 'path': 'hfs/gabulei/', 'read': False, 'new': False, 'download': False, 'modify': False, 'remove': False, 'admin': False }, { 'path': 'hfs/gabulei/', 'read': True, 'new': True, 'download': True, 'modify': True, 'remove': True, 'admin': True }] self.assertRaises(AssertionError, db_helper.lookup_access_in_the_list, 'hfs/gabulei/', 'read', access_list_7)