From 2b4174f5f63f5bf28c6112edba84a755f23380eb Mon Sep 17 00:00:00 2001 From: Alexei Date: Mon, 24 Apr 2023 17:59:21 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D1=81=D1=82=D1=83=D0=BF=20=D0=BA?= =?UTF-8?q?=20=D0=BA=D0=BD=D0=BE=D0=BF=D0=BA=D0=B0=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bot_modules/access.py | 31 +++++--- bot_modules/groups.py | 62 ++++++++++----- bot_modules/profile.py | 22 ++++-- bot_modules/projects.py | 130 +++++++++++++++++++------------ bot_modules/start.py | 21 +++-- bot_sys/keyboard.py | 34 +++++---- bot_sys/user_access.py | 198 ++++++++++++++++++++++++------------------------ 7 files changed, 289 insertions(+), 209 deletions(-) diff --git a/bot_modules/access.py b/bot_modules/access.py index 0746133..b37c30c 100644 --- a/bot_modules/access.py +++ b/bot_modules/access.py @@ -58,10 +58,13 @@ help_button_name = "📰 Информация по редактированию # --------------------------------------------------------- # Работа с кнопками -def GetEditAccessKeyboardButtons(a_UserAccess): - cur_buttons = [sql_request_button_name, help_button_name] +def GetEditAccessKeyboardButtons(a_UserGroups): + cur_buttons = [ + keyboard.ButtonWithAccess(sql_request_button_name, user_access.AccessMode.EDIT, GetAccess()), + keyboard.ButtonWithAccess(help_button_name, user_access.AccessMode.VIEW, GetAccess()) + ] mods = [start] - return keyboard.MakeKeyboard(keyboard.GetButtons(mods, a_UserAccess) + cur_buttons) + return keyboard.MakeKeyboard(keyboard.GetButtons(mods) + cur_buttons) # --------------------------------------------------------- # Обработка сообщений @@ -69,13 +72,20 @@ def GetEditAccessKeyboardButtons(a_UserAccess): # Приветствие async def AccessStart(a_Message): user_id = str(a_Message.from_user.id) - user_access = GetUserAccess(a_Message.from_user.id) - await bot.send_message(user_id, access_start_message, reply_markup = GetEditAccessKeyboardButtons(user_access)) + user_groups = groups.GetUserGroupData(user_id) + await bot.send_message(user_id, access_start_message, reply_markup = GetEditAccessKeyboardButtons(user_groups)) # --------------------------------------------------------- # Работа с базой данных -def GetModAccessList(): - return bot_db.SelectBDTemplate(table_name)() +def GetModuleAccessList(): + return bot_bd.SelectBDTemplate(table_name)() + +def GetAccessForModule(a_ModuleName): + alist = GetModuleAccessList() + for i in alist: + if i[0] == a_ModuleName: + return i[1] + return '' # --------------------------------------------------------- # API @@ -87,9 +97,12 @@ def GetUserAccess(a_UserID): def GetInitBDCommands(): return init_bd_cmds +def GetAccess(): + return GetAccessForModule(module_name) + # Доступные кнопки -def GetButtonNames(a_UserAccess): - return [access_button_name] +def GetModuleButtons(): + return [keyboard.ButtonWithAccess(access_button_name, user_access.AccessMode.VIEW, GetAccess())] # Обработка кнопок def RegisterHandlers(dp : Dispatcher): diff --git a/bot_modules/groups.py b/bot_modules/groups.py index c35e757..671209c 100644 --- a/bot_modules/groups.py +++ b/bot_modules/groups.py @@ -3,7 +3,7 @@ # Группы пользователей -from bot_sys import bot_bd, log, config, keyboard +from bot_sys import bot_bd, log, config, keyboard, user_access from bot_modules import start, access from aiogram import Bot, types from aiogram.dispatcher import FSMContext @@ -20,6 +20,8 @@ class FSMRequestToBD(StatesGroup): # --------------------------------------------------------- # БД +module_name = 'groups' + init_bd_cmds = ["""CREATE TABLE IF NOT EXISTS user_groups( group_id INTEGER PRIMARY KEY NOT NULL, groupName TEXT, @@ -30,7 +32,7 @@ init_bd_cmds = ["""CREATE TABLE IF NOT EXISTS user_groups( group_id INTEGER, UNIQUE(user_id, group_id) );""", -"INSERT OR IGNORE INTO module_access (modName, modAccess) VALUES ('groups', 'other=-');" +f"INSERT OR IGNORE INTO module_access (modName, modAccess) VALUES ('{module_name}', 'other=-');" ] # --------------------------------------------------------- @@ -72,13 +74,19 @@ canсel_button_name = "📰 Отменить" # --------------------------------------------------------- # Работа с кнопками -def GetEditGroupKeyboardButtons(a_UserAccess): - cur_buttons = [sql_request_button_name, help_button_name] +def GetEditGroupKeyboardButtons(a_UserGroups): + cur_buttons = [ + keyboard.ButtonWithAccess(sql_request_button_name, user_access.AccessMode.EDIT, GetAccess()), + keyboard.ButtonWithAccess(help_button_name, user_access.AccessMode.VIEW, GetAccess()) + ] mods = [start] - return keyboard.MakeKeyboard(keyboard.GetButtons(mods, a_UserAccess) + cur_buttons) + return keyboard.MakeKeyboard(keyboard.GetButtons(mods) + cur_buttons, a_UserGroups) -def GetCancelKeyboardButtons(a_UserAccess): - return keyboard.MakeKeyboard([canсel_button_name]) +def GetCancelKeyboardButtons(a_UserGroups): + cur_buttons = [ + keyboard.ButtonWithAccess(canсel_button_name, user_access.AccessMode.VIEW, GetAccess()) + ] + return keyboard.MakeKeyboard(cur_buttons, a_UserGroups) # --------------------------------------------------------- # Обработка сообщений @@ -86,29 +94,33 @@ def GetCancelKeyboardButtons(a_UserAccess): # Приветствие async def GroupStart(a_Message): user_id = str(a_Message.from_user.id) - user_access = access.GetUserAccess(a_Message.from_user.id) - await bot.send_message(user_id, group_start_message, reply_markup = GetEditGroupKeyboardButtons(user_access)) + user_groups = GetUserGroupData(user_id) + await bot.send_message(user_id, group_start_message, reply_markup = GetEditGroupKeyboardButtons(user_groups)) async def RequestToBDCancel(a_Message : types.message, state : FSMContext): - user_access = access.GetUserAccess(a_Message.from_user.id) + user_id = str(a_Message.from_user.id) + user_groups = GetUserGroupData(user_id) await state.finish() - await a_Message.answer(request_cancel_message, reply_markup = GetEditGroupKeyboardButtons(user_access)) + await a_Message.answer(request_cancel_message, reply_markup = GetEditGroupKeyboardButtons(user_groups)) def HelpTemplate(a_HelpMessage, a_GetButtonsFunc): async def Help(a_Message : types.message): - user_access = access.GetUserAccess(a_Message.from_user.id) - await a_Message.answer(a_HelpMessage, reply_markup = a_GetButtonsFunc(user_access)) #, parse_mode='Markdown') + user_id = str(a_Message.from_user.id) + user_groups = GetUserGroupData(user_id) + await a_Message.answer(a_HelpMessage, reply_markup = a_GetButtonsFunc(user_groups)) #, parse_mode='Markdown') return Help def RequestToBDTemplate(a_StartMessage): async def RequestToBDStart(a_Message : types.message): - user_access = access.GetUserAccess(a_Message.from_user.id) + user_id = str(a_Message.from_user.id) + user_groups = GetUserGroupData(user_id) await FSMRequestToBD.sqlRequest.set() - await a_Message.answer(a_StartMessage, reply_markup = GetCancelKeyboardButtons(user_access), parse_mode='Markdown') + await a_Message.answer(a_StartMessage, reply_markup = GetCancelKeyboardButtons(user_groups), parse_mode='Markdown') return RequestToBDStart async def RequestToBD(a_Message : types.message, state : FSMContext): - user_access = access.GetUserAccess(a_Message.from_user.id) + user_id = str(a_Message.from_user.id) + user_groups = GetUserGroupData(user_id) result = '' async with state.proxy() as prjData: sql_request = a_Message.text @@ -116,16 +128,21 @@ async def RequestToBD(a_Message : types.message, state : FSMContext): result = bot_bd.SQLRequestToBDCommit(sql_request) log.Success(f'Результат запроса [{sql_request}] от пользователя {a_Message.from_user.id} следующий [{result}].') await state.finish() - await a_Message.answer(str(result), reply_markup = GetEditGroupKeyboardButtons(user_access)) + await a_Message.answer(str(result), reply_markup = GetEditGroupKeyboardButtons(user_groups)) # --------------------------------------------------------- # Работа с базой данных групп def GetGroupIDForUser(a_UserID): - return bot_bd.SQLRequestToBD1('SELECT group_id FROM user_in_groups WHERE user_id = ?', a_UserID) + return bot_bd.SQLRequestToBD1('SELECT group_id FROM user_in_groups WHERE user_id = ?', [a_UserID]) def GetGroupNamesForUser(a_UserID): - return bot_bd.SQLRequestToBD1('SELECT groupName FROM user_groups WHERE group_id=(SELECT group_id FROM user_in_groups WHERE user_id = ?)', a_UserID) + return bot_bd.SQLRequestToBD1('SELECT groupName FROM user_groups WHERE group_id=(SELECT group_id FROM user_in_groups WHERE user_id = ?)', [a_UserID]) + +def GetUserGroupData(a_UserID): + r = GetGroupNamesForUser(a_UserID) + print(r) + return user_access.UserGroups(a_UserID, r) # --------------------------------------------------------- # API @@ -134,9 +151,12 @@ def GetGroupNamesForUser(a_UserID): def GetInitBDCommands(): return init_bd_cmds +def GetAccess(): + return access.GetAccessForModule(module_name) + # Доступные кнопки -def GetButtonNames(a_UserAccess): - return [user_group_button_name] +def GetModuleButtons(): + return [keyboard.ButtonWithAccess(user_group_button_name, user_access.AccessMode.VIEW, GetAccess())] # Обработка кнопок def RegisterHandlers(dp : Dispatcher): diff --git a/bot_modules/profile.py b/bot_modules/profile.py index 9738c90..c94ddca 100644 --- a/bot_modules/profile.py +++ b/bot_modules/profile.py @@ -3,8 +3,8 @@ # Профиль пользователя -from bot_sys import bot_bd, log, config, keyboard -from bot_modules import start +from bot_sys import bot_bd, log, config, keyboard, user_access +from bot_modules import start, access, groups from aiogram import Bot, types import sqlite3 @@ -15,12 +15,14 @@ bot = Bot(token=config.GetTelegramBotApiToken(), parse_mode=types.ParseMode.HTML # --------------------------------------------------------- # БД +module_name = 'profile' + init_bd_cmds = ["""CREATE TABLE IF NOT EXISTS users( user_id INTEGER, userName TEXT, UNIQUE(user_id) );""", -"INSERT OR IGNORE INTO module_access (modName, modAccess) VALUES ('profile', 'other=+');" +f"INSERT OR IGNORE INTO module_access (modName, modAccess) VALUES ('{module_name}', 'other=+');" ] # --------------------------------------------------------- @@ -38,9 +40,9 @@ user_profile_button_name = "📰 Профиль" # --------------------------------------------------------- # Работа с кнопками -def GetStartKeyboardButtons(a_UserAccess): +def GetStartKeyboardButtons(a_UserGroups): mods = [start] - return keyboard.MakeKeyboardForMods(mods, a_UserAccess) + return keyboard.MakeKeyboardForMods(mods, a_UserGroups) # --------------------------------------------------------- # Обработка сообщений @@ -48,11 +50,12 @@ def GetStartKeyboardButtons(a_UserAccess): # Отображение профиля пользователя async def ProfileOpen(a_Message): user_id = str(a_Message.from_user.id) + user_group = groups.GetUserGroupData(user_id) user_info = GetUserInfo(user_id) msg = profile_message if not user_info is None: msg = msg.replace('@user_id', str(user_info[0])).replace('@user_name', str(user_info[1])) - await bot.send_message(user_id, msg, reply_markup = GetStartKeyboardButtons(None)) + await bot.send_message(user_id, msg, reply_markup = GetStartKeyboardButtons(user_group)) # --------------------------------------------------------- # Работа с базой данных пользователей @@ -76,9 +79,12 @@ def GetUserInfo(a_UserID): def GetInitBDCommands(): return init_bd_cmds +def GetAccess(): + return access.GetAccessForModule(module_name) + # Доступные кнопки -def GetButtonNames(a_UserAccess): - return [user_profile_button_name] +def GetModuleButtons(): + return [keyboard.ButtonWithAccess(user_profile_button_name, user_access.AccessMode.VIEW, GetAccess())] # Обработка кнопок def RegisterHandlers(dp : Dispatcher): diff --git a/bot_modules/projects.py b/bot_modules/projects.py index 39ff3a2..39820cf 100644 --- a/bot_modules/projects.py +++ b/bot_modules/projects.py @@ -3,8 +3,8 @@ # Проекты -from bot_sys import bot_bd, log, config, keyboard -from bot_modules import start, access +from bot_sys import bot_bd, log, config, keyboard, user_access +from bot_modules import start, access, groups from aiogram import Bot, types from aiogram.dispatcher import FSMContext from aiogram.dispatcher.filters.state import State, StatesGroup @@ -145,18 +145,30 @@ select_to_edit_project_callback_prefix = 'sel_to_edit_project:' # --------------------------------------------------------- # Работа с кнопками -def GetEditProjectKeyboardButtons(a_UserAccess): - proj_buttons = [list_project_button_name, add_project_button_name, del_project_button_name, edit_project_button_name] +def GetEditProjectKeyboardButtons(a_UserGroups): + cur_buttons = [ + keyboard.ButtonWithAccess(list_project_button_name, user_access.AccessMode.VIEW, GetAccess()), + keyboard.ButtonWithAccess(add_project_button_name, user_access.AccessMode.ADD, GetAccess()), + keyboard.ButtonWithAccess(del_project_button_name, user_access.AccessMode.DELETE, GetAccess()), + keyboard.ButtonWithAccess(edit_project_button_name, user_access.AccessMode.EDIT, GetAccess()) + ] mods = [start] - return keyboard.MakeKeyboard(keyboard.GetButtons(mods, a_UserAccess) + proj_buttons) - -def GetCancelKeyboardButtons(a_UserAccess): - return keyboard.MakeKeyboard([projects_canсel_button_name]) - -def GetSkipAndCancelKeyboardButtons(a_UserAccess): - return keyboard.MakeKeyboard([projects_skip_button_name, projects_canсel_button_name]) - -def GetProjectsListKeyboardButtons(a_UserAccess, a_Prefix): + return keyboard.MakeKeyboard(keyboard.GetButtons(mods) + cur_buttons, a_UserGroups) + +def GetCancelKeyboardButtons(a_UserGroups): + cur_buttons = [ + keyboard.ButtonWithAccess(projects_canсel_button_name, user_access.AccessMode.VIEW, GetAccess()), + ] + return keyboard.MakeKeyboard(cur_buttons, a_UserGroups) + +def GetSkipAndCancelKeyboardButtons(a_UserGroups): + cur_buttons = [ + keyboard.ButtonWithAccess(projects_skip_button_name, user_access.AccessMode.VIEW, GetAccess()), + keyboard.ButtonWithAccess(projects_canсel_button_name, user_access.AccessMode.VIEW, GetAccess()), + ] + return keyboard.MakeKeyboard(cur_buttons, a_UserGroups) + +def GetProjectsListKeyboardButtons(a_UserGroups, a_Prefix): projects = GetProjectList() projects_button_list = [] for t in projects: @@ -168,9 +180,10 @@ def GetProjectsListKeyboardButtons(a_UserAccess, a_Prefix): # Отображение всех проектов async def ProjectsOpen(a_Message : types.message): - user_access = access.GetUserAccess(a_Message.from_user.id) - await bot.send_message(a_Message.from_user.id, base_project_message, reply_markup = GetEditProjectKeyboardButtons(user_access)) - await bot.send_message(a_Message.from_user.id, select_project_message, reply_markup = GetProjectsListKeyboardButtons(user_access, select_project_callback_prefix)) + user_id = str(a_Message.from_user.id) + user_group = groups.GetUserGroupData(user_id) + await bot.send_message(a_Message.from_user.id, base_project_message, reply_markup = GetEditProjectKeyboardButtons(user_group)) + await bot.send_message(a_Message.from_user.id, select_project_message, reply_markup = GetProjectsListKeyboardButtons(user_group, select_project_callback_prefix)) def GetProjectData(a_ProjectID): project = GetProject(a_ProjectID) @@ -184,36 +197,40 @@ def GetProjectData(a_ProjectID): async def ShowProject(a_CallbackQuery : types.CallbackQuery): project_id = str(a_CallbackQuery.data).replace(select_project_callback_prefix, '') - user_access = access.GetUserAccess(a_CallbackQuery.from_user.id) + user_id = str(a_CallbackQuery.from_user.id) + user_group = groups.GetUserGroupData(user_id) msg, photo_id, name, desc = GetProjectData(project_id) if msg != '': - await bot.send_message(a_CallbackQuery.from_user.id, msg, reply_markup = GetEditProjectKeyboardButtons(user_access)) + await bot.send_message(a_CallbackQuery.from_user.id, msg, reply_markup = GetEditProjectKeyboardButtons(user_group)) return msg = project_open_message.replace('@proj_name', name).replace('@proj_desk', desc) if photo_id == '0': - await bot.send_message(a_CallbackQuery.from_user.id, msg, reply_markup = GetEditProjectKeyboardButtons(user_access)) + await bot.send_message(a_CallbackQuery.from_user.id, msg, reply_markup = GetEditProjectKeyboardButtons(user_group)) else: - await bot.send_photo(a_CallbackQuery.from_user.id, photo_id, msg, reply_markup = GetEditProjectKeyboardButtons(user_access)) + await bot.send_photo(a_CallbackQuery.from_user.id, photo_id, msg, reply_markup = GetEditProjectKeyboardButtons(user_group)) # Создание нового проекта async def ProjectCreateCancel(a_Message : types.message, state : FSMContext): - user_access = access.GetUserAccess(a_Message.from_user.id) + user_id = str(a_Message.from_user.id) + user_group = groups.GetUserGroupData(user_id) await state.finish() - await a_Message.answer(project_cancel_create_message, reply_markup = GetEditProjectKeyboardButtons(user_access)) + await a_Message.answer(project_cancel_create_message, reply_markup = GetEditProjectKeyboardButtons(user_group)) async def ProjectCreate(a_Message : types.message): - user_access = access.GetUserAccess(a_Message.from_user.id) + user_id = str(a_Message.from_user.id) + user_group = groups.GetUserGroupData(user_id) await FSMCreateProject.prjPhoto.set() - await a_Message.answer(project_create_message_1, reply_markup = GetSkipAndCancelKeyboardButtons(user_access)) + await a_Message.answer(project_create_message_1, reply_markup = GetSkipAndCancelKeyboardButtons(user_group)) async def PhotoLoad(a_Message : types.message, state : FSMContext, a_FileID): - user_access = access.GetUserAccess(a_Message.from_user.id) + user_id = str(a_Message.from_user.id) + user_group = groups.GetUserGroupData(user_id) async with state.proxy() as prjData: prjData['photo'] = a_FileID await FSMCreateProject.next() - await a_Message.answer(project_create_message_2, reply_markup = GetCancelKeyboardButtons(user_access)) + await a_Message.answer(project_create_message_2, reply_markup = GetCancelKeyboardButtons(user_group)) async def ProjectPhotoLoad(a_Message : types.message, state : FSMContext): await PhotoLoad(a_Message, state, a_Message.photo[0].file_id) @@ -222,14 +239,16 @@ async def ProjectPhotoSkip(a_Message : types.message, state : FSMContext): await PhotoLoad(a_Message, state, 0) async def ProjectNameLoad(a_Message : types.message, state : FSMContext): - user_access = access.GetUserAccess(a_Message.from_user.id) + user_id = str(a_Message.from_user.id) + user_group = groups.GetUserGroupData(user_id) async with state.proxy() as prjData: prjData['name'] = a_Message.text await FSMCreateProject.next() - await a_Message.answer(project_create_message_3, reply_markup = GetCancelKeyboardButtons(user_access)) + await a_Message.answer(project_create_message_3, reply_markup = GetCancelKeyboardButtons(user_group)) async def ProjectDescLoad(a_Message : types.message, state : FSMContext): - user_access = access.GetUserAccess(a_Message.from_user.id) + user_id = str(a_Message.from_user.id) + user_group = groups.GetUserGroupData(user_id) async with state.proxy() as prjData: prjData['desc'] = a_Message.text prjPhoto = prjData['photo'] @@ -238,30 +257,34 @@ async def ProjectDescLoad(a_Message : types.message, state : FSMContext): AddProject(prjPhoto, prjName, prjDesc) log.Success(f'Добавлен проект {prjName} пользователем {a_Message.from_user.id}.') await state.finish() - await a_Message.answer(project_success_create_message, reply_markup = GetEditProjectKeyboardButtons(user_access)) + await a_Message.answer(project_success_create_message, reply_markup = GetEditProjectKeyboardButtons(user_group)) # Редактирование проекта async def ProjectSelectForEdit(a_Message : types.message): - user_access = access.GetUserAccess(a_Message.from_user.id) - await bot.send_message(a_Message.from_user.id, project_select_to_edit_message, reply_markup = GetProjectsListKeyboardButtons(user_access, select_to_edit_project_callback_prefix)) + user_id = str(a_Message.from_user.id) + user_group = groups.GetUserGroupData(user_id) + await bot.send_message(a_Message.from_user.id, project_select_to_edit_message, reply_markup = GetProjectsListKeyboardButtons(user_group, select_to_edit_project_callback_prefix)) async def ProjectEditCancel(a_Message : types.message, state : FSMContext): - user_access = access.GetUserAccess(a_Message.from_user.id) + user_id = str(a_Message.from_user.id) + user_group = groups.GetUserGroupData(user_id) await state.finish() - await a_Message.answer(project_cancel_edit_message, reply_markup = GetEditProjectKeyboardButtons(user_access)) + await a_Message.answer(project_cancel_edit_message, reply_markup = GetEditProjectKeyboardButtons(user_group)) async def ProjectEdit(a_CallbackQuery : types.CallbackQuery, state : FSMContext): - user_access = access.GetUserAccess(a_CallbackQuery.from_user.id) + user_id = str(a_CallbackQuery.from_user.id) + user_group = groups.GetUserGroupData(user_id) await FSMEditProject.prjID.set() prjID = str(a_CallbackQuery.data).replace(select_to_edit_project_callback_prefix, '') async with state.proxy() as prjData: prjData['prjID'] = prjID await FSMEditProject.next() - await bot.send_message(a_CallbackQuery.from_user.id, project_edit_message_1, reply_markup = GetSkipAndCancelKeyboardButtons(user_access)) + await bot.send_message(a_CallbackQuery.from_user.id, project_edit_message_1, reply_markup = GetSkipAndCancelKeyboardButtons(user_group)) async def PhotoEditLoad(a_Message : types.message, state : FSMContext, a_FileID): - user_access = access.GetUserAccess(a_Message.from_user.id) + user_id = str(a_Message.from_user.id) + user_group = groups.GetUserGroupData(user_id) project_id = 0 async with state.proxy() as prjData: prjData['photo'] = a_FileID @@ -269,9 +292,9 @@ async def PhotoEditLoad(a_Message : types.message, state : FSMContext, a_FileID) await FSMEditProject.next() msg, photo_id, name, desc = GetProjectData(project_id) if msg != '': - await bot.send_message(a_Message.from_user.id, msg, reply_markup = GetEditProjectKeyboardButtons(user_access)) + await bot.send_message(a_Message.from_user.id, msg, reply_markup = GetEditProjectKeyboardButtons(user_group)) return - await a_Message.answer(project_edit_message_2.replace('@proj_name', name), reply_markup = GetSkipAndCancelKeyboardButtons(user_access)) + await a_Message.answer(project_edit_message_2.replace('@proj_name', name), reply_markup = GetSkipAndCancelKeyboardButtons(user_group)) async def ProjectEditPhotoLoad(a_Message : types.message, state : FSMContext): await PhotoEditLoad(a_Message, state, a_Message.photo[0].file_id) @@ -282,22 +305,24 @@ async def ProjectEditPhotoSkip(a_Message : types.message, state : FSMContext): project_id = prjData['prjID'] msg, photo_id, name, desc = GetProjectData(project_id) if msg != '': - await bot.send_message(a_Message.from_user.id, msg, reply_markup = GetEditProjectKeyboardButtons(user_access)) + await bot.send_message(a_Message.from_user.id, msg, reply_markup = GetEditProjectKeyboardButtons(user_group)) return await PhotoEditLoad(a_Message, state, photo_id) async def EditNameSkip(a_Message : types.message, state : FSMContext, a_Name): - user_access = access.GetUserAccess(a_Message.from_user.id) + user_id = str(a_Message.from_user.id) + user_group = groups.GetUserGroupData(user_id) async with state.proxy() as prjData: prjData['name'] = a_Name await FSMEditProject.next() - await a_Message.answer(project_edit_message_3, reply_markup = GetSkipAndCancelKeyboardButtons(user_access)) + await a_Message.answer(project_edit_message_3, reply_markup = GetSkipAndCancelKeyboardButtons(user_group)) async def ProjectEditNameLoad(a_Message : types.message, state : FSMContext): await EditNameSkip(a_Message, state, a_Message.text) async def ProjectEditDescLoad(a_Message : types.message, state : FSMContext): - user_access = access.GetUserAccess(a_Message.from_user.id) + user_id = str(a_Message.from_user.id) + user_group = groups.GetUserGroupData(user_id) async with state.proxy() as prjData: prjData['desc'] = a_Message.text project_id = prjData['prjID'] @@ -307,20 +332,22 @@ async def ProjectEditDescLoad(a_Message : types.message, state : FSMContext): EditProject(project_id, prjPhoto, prjName, prjDesc) log.Success(f'Изменён проект {prjName} пользователем {a_Message.from_user.id}.') await state.finish() - await a_Message.answer(project_success_edit_message, reply_markup = GetEditProjectKeyboardButtons(user_access)) + await a_Message.answer(project_success_edit_message, reply_markup = GetEditProjectKeyboardButtons(user_group)) # Удаление проекта async def ProjectDelete(a_Message : types.message): - user_access = access.GetUserAccess(a_Message.from_user.id) - await bot.send_message(a_Message.from_user.id, project_select_to_delete_message, reply_markup = GetProjectsListKeyboardButtons(user_access, delete_project_callback_prefix)) + user_id = str(a_Message.from_user.id) + user_group = groups.GetUserGroupData(user_id) + await bot.send_message(a_Message.from_user.id, project_select_to_delete_message, reply_markup = GetProjectsListKeyboardButtons(user_group, delete_project_callback_prefix)) async def prjDelete(a_CallbackQuery : types.CallbackQuery): - user_access = access.GetUserAccess(a_CallbackQuery.from_user.id) + user_id = str(a_CallbackQuery.from_user.id) + user_group = groups.GetUserGroupData(user_id) projectID = str(a_CallbackQuery.data).replace(delete_project_callback_prefix, '') DelProject(projectID) log.Success(f'Проект №{projectID} был удалён пользователем {a_CallbackQuery.from_user.id}.') - await bot.send_message(a_CallbackQuery.from_user.id, project_success_delete_message, reply_markup = GetEditProjectKeyboardButtons(user_access)) + await bot.send_message(a_CallbackQuery.from_user.id, project_success_delete_message, reply_markup = GetEditProjectKeyboardButtons(user_group)) # --------------------------------------------------------- # Работа с базой данных проектов @@ -369,9 +396,12 @@ def DelProject(a_ProjectID): def GetInitBDCommands(): return init_bd_cmds +def GetAccess(): + return access.GetAccessForModule(module_name) + # Доступные кнопки -def GetButtonNames(a_UserAccess): - return [projects_button_name] +def GetModuleButtons(): + return [keyboard.ButtonWithAccess(projects_button_name, user_access.AccessMode.VIEW, GetAccess())] # Обработка кнопок def RegisterHandlers(dp : Dispatcher): diff --git a/bot_modules/start.py b/bot_modules/start.py index 87662f9..e7fc911 100644 --- a/bot_modules/start.py +++ b/bot_modules/start.py @@ -3,15 +3,17 @@ # Стартовое меню -from bot_sys import log, config, keyboard +from bot_sys import log, config, keyboard, user_access from bot_modules import profile, projects, groups, access from aiogram.dispatcher import Dispatcher # --------------------------------------------------------- # БД +module_name = 'start' + init_bd_cmds = [ -"INSERT OR IGNORE INTO module_access (modName, modAccess) VALUES ('start', 'other=+');" +f"INSERT OR IGNORE INTO module_access (modName, modAccess) VALUES ('{module_name}', 'other=+');" ] # --------------------------------------------------------- @@ -28,9 +30,9 @@ start_menu_button_name = "☰ Главное меню" # --------------------------------------------------------- # Работа с кнопками -def GetStartKeyboardButtons(a_UserAccess): +def GetStartKeyboardButtons(a_UserGroups): mods = [profile, projects, groups, access] - return keyboard.MakeKeyboardForMods(mods, a_UserAccess) + return keyboard.MakeKeyboardForMods(mods, a_UserGroups) # --------------------------------------------------------- # Обработка сообщений @@ -38,11 +40,11 @@ def GetStartKeyboardButtons(a_UserAccess): # Первичное привестивие async def StartMenu(a_Message): user_id = int(a_Message.from_user.id) - user_access = access.GetUserAccess(user_id) + user_group = groups.GetUserGroupData(user_id) user_name = str(a_Message.from_user.username) profile.AddUser(user_id, user_name) log.Info(f'Пользователь {user_id} {user_name} авторизовался в боте') - await a_Message.answer(start_message, reply_markup=GetStartKeyboardButtons(user_access), parse_mode='HTML') + await a_Message.answer(start_message, reply_markup=GetStartKeyboardButtons(user_group), parse_mode='HTML') # --------------------------------------------------------- # API @@ -51,9 +53,12 @@ async def StartMenu(a_Message): def GetInitBDCommands(): return init_bd_cmds +def GetAccess(): + return access.GetAccessForModule(module_name) + # Имена доступных кнопок -def GetButtonNames(a_UserAccess): - return [start_menu_button_name] +def GetModuleButtons(): + return [keyboard.ButtonWithAccess(start_menu_button_name, user_access.AccessMode.VIEW, GetAccess())] # Обработка кнопок def RegisterHandlers(dp : Dispatcher): diff --git a/bot_sys/keyboard.py b/bot_sys/keyboard.py index 9d53696..b900aa4 100644 --- a/bot_sys/keyboard.py +++ b/bot_sys/keyboard.py @@ -3,33 +3,39 @@ # Работа с кнопками и клавиатурой +from bot_sys import user_access from aiogram import types, Bot, Dispatcher from aiogram.types import ReplyKeyboardRemove, ReplyKeyboardMarkup, KeyboardButton, InlineKeyboardMarkup, InlineKeyboardButton -def GetButtons(a_ModList, a_UserAccess): - names = [] +class ButtonWithAccess: + def __init__(self, a_Label, a_AccessMode : user_access.AccessMode, a_AccessString): + self.label = a_Label + self.access_mode = a_AccessMode + self.access_string = a_AccessString + +def GetButtons(a_ModList): + buttons = [] for m in a_ModList: - n = m.GetButtonNames(a_UserAccess) - if not n is None or len(n) != 0: - names += n - return names + b = m.GetModuleButtons() + if not b is None or len(b) != 0: + buttons += b + return buttons -def MakeKeyboard(a_ButtonList): +def MakeKeyboard(a_ButtonList : [ButtonWithAccess], a_UserGroups): key = types.ReplyKeyboardMarkup(resize_keyboard = True) for b in a_ButtonList: - k = types.KeyboardButton(b) - key.add(k) + if user_access.CheckAccessString(b.access_string, a_UserGroups, b.access_mode): + k = types.KeyboardButton(b.label) + key.add(k) return key def MakeKeyboardRemove(): return types.ReplyKeyboardRemove() -def MakeKeyboardForMods(a_ModList, a_UserAccess): - names = GetButtons(a_ModList, a_UserAccess) - return MakeKeyboard(names) - buttons = GetButtons(a_ModList, a_UserAccess) - return MakeKeyboard(buttons) +def MakeKeyboardForMods(a_ModList, a_UserGroups): + buttons = GetButtons(a_ModList) + return MakeKeyboard(buttons, a_UserGroups) class Button: def __init__(self, a_Label, a_CallBackData): diff --git a/bot_sys/user_access.py b/bot_sys/user_access.py index 501714c..63a4bdd 100644 --- a/bot_sys/user_access.py +++ b/bot_sys/user_access.py @@ -34,7 +34,7 @@ class AccessMode(Enum): DELETE = 'd' ACCEES_EDIT = 'r' -class UserAccess: +class UserGroups: def __init__(self, a_UserID : str, a_GroupNamesList : [str]): self.user_id = a_UserID self.group_names_list = a_GroupNamesList @@ -49,9 +49,9 @@ def CheckAccessItem(a_AccessItem : str, a_AccessMode : AccessMode): return False return False -# Возвращает возможность доступа пользователю a_UserAccessData в элемент с правами a_AccessValue по режиму доступа a_AccessMode -def CheckAccessString(a_AccessValue : str, a_UserAccessData : UserAccess, a_AccessMode : AccessMode): - if a_UserAccessData.user_id in config.GetRootIDs(): +# Возвращает возможность доступа пользователю a_UserGroups в элемент с правами a_AccessValue по режиму доступа a_AccessMode +def CheckAccessString(a_AccessValue : str, a_UserGroups : UserGroups, a_AccessMode : AccessMode): + if a_UserGroups.user_id in config.GetRootIDs(): return True for i in a_AccessValue.split(';'): d = i.split('=') @@ -59,105 +59,105 @@ def CheckAccessString(a_AccessValue : str, a_UserAccessData : UserAccess, a_Acce continue name = d[0] access = d[1] - if name == a_UserAccessData.user_id or name in a_UserAccessData.group_names_list or name == 'other': + if name == a_UserGroups.user_id or name in a_UserGroups.group_names_list or name == 'other': if CheckAccessItem(access, a_AccessMode): return True return False def Test(): for am in AccessMode.ADD, AccessMode.DELETE, AccessMode.EDIT, AccessMode.VIEW, AccessMode.ACCEES_EDIT: - assert CheckAccessString('1234=+', UserAccess('1234', []), am) - assert not CheckAccessString('1234=-', UserAccess('1234', []), am) - assert CheckAccessString('1234=+;gr1=+', UserAccess('1234', ['gr1']), am) - assert CheckAccessString('1234=-;gr1=+', UserAccess('1234', ['gr1']), am) - assert not CheckAccessString('1234=+', UserAccess('123', []), am) - assert not CheckAccessString('1234=-', UserAccess('123', []), am) - assert not CheckAccessString('1234=+;gr1=+', UserAccess('123', ['gr']), am) - assert not CheckAccessString('1234=-;gr1=+', UserAccess('123', ['gr']), am) - assert not CheckAccessString('1234=+;gr=+', UserAccess('123', ['gr1']), am) - assert not CheckAccessString('1234=-;gr=+', UserAccess('123', ['gr1']), am) - - assert CheckAccessString('123=-;1234=a', UserAccess('1234', []), AccessMode.ADD) - assert CheckAccessString('123=-;1234=d', UserAccess('1234', []), AccessMode.DELETE) - assert CheckAccessString('123=-;1234=e', UserAccess('1234', []), AccessMode.EDIT) - assert CheckAccessString('123=-;1234=r', UserAccess('1234', []), AccessMode.ACCEES_EDIT) - assert CheckAccessString('123=-;1234=v', UserAccess('1234', []), AccessMode.VIEW) - assert CheckAccessString('123=-;gr1=a', UserAccess('1234', ['gr1']), AccessMode.ADD) - assert CheckAccessString('123=-;gr1=d', UserAccess('1234', ['gr1']), AccessMode.DELETE) - assert CheckAccessString('123=-;gr1=e', UserAccess('1234', ['gr1']), AccessMode.EDIT) - assert CheckAccessString('123=-;gr1=r', UserAccess('1234', ['gr1']), AccessMode.ACCEES_EDIT) - assert CheckAccessString('123=-;gr1=v', UserAccess('1234', ['gr1']), AccessMode.VIEW) - assert CheckAccessString('123=-;1234=daver', UserAccess('1234', []), AccessMode.ADD) - assert CheckAccessString('123=-;1234=dav', UserAccess('1234', []), AccessMode.DELETE) - assert CheckAccessString('123=-;1234=edv', UserAccess('1234', []), AccessMode.EDIT) - assert CheckAccessString('123=-;1234=rav', UserAccess('1234', []), AccessMode.ACCEES_EDIT) - assert CheckAccessString('123=-;1234=va', UserAccess('1234', []), AccessMode.VIEW) - assert CheckAccessString('123=-;gr1=avr', UserAccess('1234', ['gr1']), AccessMode.ADD) - assert CheckAccessString('123=-;gr1=daver', UserAccess('1234', ['gr1']), AccessMode.DELETE) - assert CheckAccessString('123=-;gr1=eva', UserAccess('1234', ['gr1']), AccessMode.EDIT) - assert CheckAccessString('123=-;gr1=re', UserAccess('1234', ['gr1']), AccessMode.ACCEES_EDIT) - assert CheckAccessString('123=-;gr1=vad', UserAccess('1234', ['gr1']), AccessMode.VIEW) - - assert not CheckAccessString('123=-;1234=d', UserAccess('1234', []), AccessMode.ADD) - assert not CheckAccessString('123=-;1234=a', UserAccess('1234', []), AccessMode.DELETE) - assert not CheckAccessString('123=-;1234=r', UserAccess('1234', []), AccessMode.EDIT) - assert not CheckAccessString('123=-;1234=v', UserAccess('1234', []), AccessMode.ACCEES_EDIT) - assert not CheckAccessString('123=-;1234=e', UserAccess('1234', []), AccessMode.VIEW) - assert not CheckAccessString('123=-;gr1=d', UserAccess('1234', ['gr']), AccessMode.ADD) - assert not CheckAccessString('123=-;gr1=a', UserAccess('1234', ['gr']), AccessMode.DELETE) - assert not CheckAccessString('123=-;gr1=v', UserAccess('1234', ['gr']), AccessMode.EDIT) - assert not CheckAccessString('123=-;gr1=e', UserAccess('1234', ['gr']), AccessMode.ACCEES_EDIT) - assert not CheckAccessString('123=-;gr1=r', UserAccess('1234', ['gr']), AccessMode.VIEW) - assert not CheckAccessString('123=-;1234=dver', UserAccess('1234', []), AccessMode.ADD) - assert not CheckAccessString('123=-;1234=av', UserAccess('1234', []), AccessMode.DELETE) - assert not CheckAccessString('123=-;1234=dv', UserAccess('1234', []), AccessMode.EDIT) - assert not CheckAccessString('123=-;1234=av', UserAccess('1234', []), AccessMode.ACCEES_EDIT) - assert not CheckAccessString('123=-;1234=a', UserAccess('1234', []), AccessMode.VIEW) - assert not CheckAccessString('123=-;gr1=vr', UserAccess('1234', ['gr']), AccessMode.ADD) - assert not CheckAccessString('123=-;gr1=aver', UserAccess('1234', ['gr']), AccessMode.DELETE) - assert not CheckAccessString('123=-;gr1=va', UserAccess('1234', ['gr']), AccessMode.EDIT) - assert not CheckAccessString('123=-;gr1=ea', UserAccess('1234', ['gr']), AccessMode.ACCEES_EDIT) - assert not CheckAccessString('123=-;gr1=ad', UserAccess('1234', ['gr']), AccessMode.VIEW) - - assert CheckAccessString('123=-;other=a', UserAccess('1234', []), AccessMode.ADD) - assert CheckAccessString('123=-;other=d', UserAccess('1234', []), AccessMode.DELETE) - assert CheckAccessString('123=-;other=e', UserAccess('1234', []), AccessMode.EDIT) - assert CheckAccessString('123=-;other=r', UserAccess('1234', []), AccessMode.ACCEES_EDIT) - assert CheckAccessString('123=-;other=v', UserAccess('1234', []), AccessMode.VIEW) - assert CheckAccessString('123=-;other=a', UserAccess('1234', ['gr1']), AccessMode.ADD) - assert CheckAccessString('123=-;other=d', UserAccess('1234', ['gr1']), AccessMode.DELETE) - assert CheckAccessString('123=-;other=e', UserAccess('1234', ['gr1']), AccessMode.EDIT) - assert CheckAccessString('123=-;other=r', UserAccess('1234', ['gr1']), AccessMode.ACCEES_EDIT) - assert CheckAccessString('123=-;other=v', UserAccess('1234', ['gr1']), AccessMode.VIEW) - assert CheckAccessString('123=-;other=daver', UserAccess('1234', []), AccessMode.ADD) - assert CheckAccessString('123=-;other=dav', UserAccess('1234', []), AccessMode.DELETE) - assert CheckAccessString('123=-;other=edv', UserAccess('1234', []), AccessMode.EDIT) - assert CheckAccessString('123=-;other=rav', UserAccess('1234', []), AccessMode.ACCEES_EDIT) - assert CheckAccessString('123=-;other=va', UserAccess('1234', []), AccessMode.VIEW) - assert CheckAccessString('123=-;other=avr', UserAccess('1234', ['gr1']), AccessMode.ADD) - assert CheckAccessString('123=-;other=daver', UserAccess('1234', ['gr1']), AccessMode.DELETE) - assert CheckAccessString('123=-;other=eva', UserAccess('1234', ['gr1']), AccessMode.EDIT) - assert CheckAccessString('123=-;other=re', UserAccess('1234', ['gr1']), AccessMode.ACCEES_EDIT) - assert CheckAccessString('123=-;other=vad', UserAccess('1234', ['gr1']), AccessMode.VIEW) - - assert not CheckAccessString('123=-;other=d', UserAccess('1234', []), AccessMode.ADD) - assert not CheckAccessString('123=-;other=a', UserAccess('1234', []), AccessMode.DELETE) - assert not CheckAccessString('123=-;other=r', UserAccess('1234', []), AccessMode.EDIT) - assert not CheckAccessString('123=-;other=v', UserAccess('1234', []), AccessMode.ACCEES_EDIT) - assert not CheckAccessString('123=-;other=e', UserAccess('1234', []), AccessMode.VIEW) - assert not CheckAccessString('123=-;gr1=d;other=-', UserAccess('1234', ['gr']), AccessMode.ADD) - assert not CheckAccessString('123=-;gr1=a;other=-', UserAccess('1234', ['gr']), AccessMode.DELETE) - assert not CheckAccessString('123=-;gr1=v;other=-', UserAccess('1234', ['gr']), AccessMode.EDIT) - assert not CheckAccessString('123=-;gr1=e;other=-', UserAccess('1234', ['gr']), AccessMode.ACCEES_EDIT) - assert not CheckAccessString('123=-;gr1=r;other=-', UserAccess('1234', ['gr']), AccessMode.VIEW) - assert not CheckAccessString('123=-;other=dver', UserAccess('1234', []), AccessMode.ADD) - assert not CheckAccessString('123=-;other=av', UserAccess('1234', []), AccessMode.DELETE) - assert not CheckAccessString('123=-;other=dv', UserAccess('1234', []), AccessMode.EDIT) - assert not CheckAccessString('123=-;other=av', UserAccess('1234', []), AccessMode.ACCEES_EDIT) - assert not CheckAccessString('123=-;other=a', UserAccess('1234', []), AccessMode.VIEW) - assert not CheckAccessString('123=-;other=vr', UserAccess('1234', ['gr']), AccessMode.ADD) - assert not CheckAccessString('123=-;other=aver', UserAccess('1234', ['gr']), AccessMode.DELETE) - assert not CheckAccessString('123=-;other=va', UserAccess('1234', ['gr']), AccessMode.EDIT) - assert not CheckAccessString('123=-;other=ea', UserAccess('1234', ['gr']), AccessMode.ACCEES_EDIT) - assert not CheckAccessString('123=-;other=ad', UserAccess('1234', ['gr']), AccessMode.VIEW) + assert CheckAccessString('1234=+', UserGroups('1234', []), am) + assert not CheckAccessString('1234=-', UserGroups('1234', []), am) + assert CheckAccessString('1234=+;gr1=+', UserGroups('1234', ['gr1']), am) + assert CheckAccessString('1234=-;gr1=+', UserGroups('1234', ['gr1']), am) + assert not CheckAccessString('1234=+', UserGroups('123', []), am) + assert not CheckAccessString('1234=-', UserGroups('123', []), am) + assert not CheckAccessString('1234=+;gr1=+', UserGroups('123', ['gr']), am) + assert not CheckAccessString('1234=-;gr1=+', UserGroups('123', ['gr']), am) + assert not CheckAccessString('1234=+;gr=+', UserGroups('123', ['gr1']), am) + assert not CheckAccessString('1234=-;gr=+', UserGroups('123', ['gr1']), am) + + assert CheckAccessString('123=-;1234=a', UserGroups('1234', []), AccessMode.ADD) + assert CheckAccessString('123=-;1234=d', UserGroups('1234', []), AccessMode.DELETE) + assert CheckAccessString('123=-;1234=e', UserGroups('1234', []), AccessMode.EDIT) + assert CheckAccessString('123=-;1234=r', UserGroups('1234', []), AccessMode.ACCEES_EDIT) + assert CheckAccessString('123=-;1234=v', UserGroups('1234', []), AccessMode.VIEW) + assert CheckAccessString('123=-;gr1=a', UserGroups('1234', ['gr1']), AccessMode.ADD) + assert CheckAccessString('123=-;gr1=d', UserGroups('1234', ['gr1']), AccessMode.DELETE) + assert CheckAccessString('123=-;gr1=e', UserGroups('1234', ['gr1']), AccessMode.EDIT) + assert CheckAccessString('123=-;gr1=r', UserGroups('1234', ['gr1']), AccessMode.ACCEES_EDIT) + assert CheckAccessString('123=-;gr1=v', UserGroups('1234', ['gr1']), AccessMode.VIEW) + assert CheckAccessString('123=-;1234=daver', UserGroups('1234', []), AccessMode.ADD) + assert CheckAccessString('123=-;1234=dav', UserGroups('1234', []), AccessMode.DELETE) + assert CheckAccessString('123=-;1234=edv', UserGroups('1234', []), AccessMode.EDIT) + assert CheckAccessString('123=-;1234=rav', UserGroups('1234', []), AccessMode.ACCEES_EDIT) + assert CheckAccessString('123=-;1234=va', UserGroups('1234', []), AccessMode.VIEW) + assert CheckAccessString('123=-;gr1=avr', UserGroups('1234', ['gr1']), AccessMode.ADD) + assert CheckAccessString('123=-;gr1=daver', UserGroups('1234', ['gr1']), AccessMode.DELETE) + assert CheckAccessString('123=-;gr1=eva', UserGroups('1234', ['gr1']), AccessMode.EDIT) + assert CheckAccessString('123=-;gr1=re', UserGroups('1234', ['gr1']), AccessMode.ACCEES_EDIT) + assert CheckAccessString('123=-;gr1=vad', UserGroups('1234', ['gr1']), AccessMode.VIEW) + + assert not CheckAccessString('123=-;1234=d', UserGroups('1234', []), AccessMode.ADD) + assert not CheckAccessString('123=-;1234=a', UserGroups('1234', []), AccessMode.DELETE) + assert not CheckAccessString('123=-;1234=r', UserGroups('1234', []), AccessMode.EDIT) + assert not CheckAccessString('123=-;1234=v', UserGroups('1234', []), AccessMode.ACCEES_EDIT) + assert not CheckAccessString('123=-;1234=e', UserGroups('1234', []), AccessMode.VIEW) + assert not CheckAccessString('123=-;gr1=d', UserGroups('1234', ['gr']), AccessMode.ADD) + assert not CheckAccessString('123=-;gr1=a', UserGroups('1234', ['gr']), AccessMode.DELETE) + assert not CheckAccessString('123=-;gr1=v', UserGroups('1234', ['gr']), AccessMode.EDIT) + assert not CheckAccessString('123=-;gr1=e', UserGroups('1234', ['gr']), AccessMode.ACCEES_EDIT) + assert not CheckAccessString('123=-;gr1=r', UserGroups('1234', ['gr']), AccessMode.VIEW) + assert not CheckAccessString('123=-;1234=dver', UserGroups('1234', []), AccessMode.ADD) + assert not CheckAccessString('123=-;1234=av', UserGroups('1234', []), AccessMode.DELETE) + assert not CheckAccessString('123=-;1234=dv', UserGroups('1234', []), AccessMode.EDIT) + assert not CheckAccessString('123=-;1234=av', UserGroups('1234', []), AccessMode.ACCEES_EDIT) + assert not CheckAccessString('123=-;1234=a', UserGroups('1234', []), AccessMode.VIEW) + assert not CheckAccessString('123=-;gr1=vr', UserGroups('1234', ['gr']), AccessMode.ADD) + assert not CheckAccessString('123=-;gr1=aver', UserGroups('1234', ['gr']), AccessMode.DELETE) + assert not CheckAccessString('123=-;gr1=va', UserGroups('1234', ['gr']), AccessMode.EDIT) + assert not CheckAccessString('123=-;gr1=ea', UserGroups('1234', ['gr']), AccessMode.ACCEES_EDIT) + assert not CheckAccessString('123=-;gr1=ad', UserGroups('1234', ['gr']), AccessMode.VIEW) + + assert CheckAccessString('123=-;other=a', UserGroups('1234', []), AccessMode.ADD) + assert CheckAccessString('123=-;other=d', UserGroups('1234', []), AccessMode.DELETE) + assert CheckAccessString('123=-;other=e', UserGroups('1234', []), AccessMode.EDIT) + assert CheckAccessString('123=-;other=r', UserGroups('1234', []), AccessMode.ACCEES_EDIT) + assert CheckAccessString('123=-;other=v', UserGroups('1234', []), AccessMode.VIEW) + assert CheckAccessString('123=-;other=a', UserGroups('1234', ['gr1']), AccessMode.ADD) + assert CheckAccessString('123=-;other=d', UserGroups('1234', ['gr1']), AccessMode.DELETE) + assert CheckAccessString('123=-;other=e', UserGroups('1234', ['gr1']), AccessMode.EDIT) + assert CheckAccessString('123=-;other=r', UserGroups('1234', ['gr1']), AccessMode.ACCEES_EDIT) + assert CheckAccessString('123=-;other=v', UserGroups('1234', ['gr1']), AccessMode.VIEW) + assert CheckAccessString('123=-;other=daver', UserGroups('1234', []), AccessMode.ADD) + assert CheckAccessString('123=-;other=dav', UserGroups('1234', []), AccessMode.DELETE) + assert CheckAccessString('123=-;other=edv', UserGroups('1234', []), AccessMode.EDIT) + assert CheckAccessString('123=-;other=rav', UserGroups('1234', []), AccessMode.ACCEES_EDIT) + assert CheckAccessString('123=-;other=va', UserGroups('1234', []), AccessMode.VIEW) + assert CheckAccessString('123=-;other=avr', UserGroups('1234', ['gr1']), AccessMode.ADD) + assert CheckAccessString('123=-;other=daver', UserGroups('1234', ['gr1']), AccessMode.DELETE) + assert CheckAccessString('123=-;other=eva', UserGroups('1234', ['gr1']), AccessMode.EDIT) + assert CheckAccessString('123=-;other=re', UserGroups('1234', ['gr1']), AccessMode.ACCEES_EDIT) + assert CheckAccessString('123=-;other=vad', UserGroups('1234', ['gr1']), AccessMode.VIEW) + + assert not CheckAccessString('123=-;other=d', UserGroups('1234', []), AccessMode.ADD) + assert not CheckAccessString('123=-;other=a', UserGroups('1234', []), AccessMode.DELETE) + assert not CheckAccessString('123=-;other=r', UserGroups('1234', []), AccessMode.EDIT) + assert not CheckAccessString('123=-;other=v', UserGroups('1234', []), AccessMode.ACCEES_EDIT) + assert not CheckAccessString('123=-;other=e', UserGroups('1234', []), AccessMode.VIEW) + assert not CheckAccessString('123=-;gr1=d;other=-', UserGroups('1234', ['gr']), AccessMode.ADD) + assert not CheckAccessString('123=-;gr1=a;other=-', UserGroups('1234', ['gr']), AccessMode.DELETE) + assert not CheckAccessString('123=-;gr1=v;other=-', UserGroups('1234', ['gr']), AccessMode.EDIT) + assert not CheckAccessString('123=-;gr1=e;other=-', UserGroups('1234', ['gr']), AccessMode.ACCEES_EDIT) + assert not CheckAccessString('123=-;gr1=r;other=-', UserGroups('1234', ['gr']), AccessMode.VIEW) + assert not CheckAccessString('123=-;other=dver', UserGroups('1234', []), AccessMode.ADD) + assert not CheckAccessString('123=-;other=av', UserGroups('1234', []), AccessMode.DELETE) + assert not CheckAccessString('123=-;other=dv', UserGroups('1234', []), AccessMode.EDIT) + assert not CheckAccessString('123=-;other=av', UserGroups('1234', []), AccessMode.ACCEES_EDIT) + assert not CheckAccessString('123=-;other=a', UserGroups('1234', []), AccessMode.VIEW) + assert not CheckAccessString('123=-;other=vr', UserGroups('1234', ['gr']), AccessMode.ADD) + assert not CheckAccessString('123=-;other=aver', UserGroups('1234', ['gr']), AccessMode.DELETE) + assert not CheckAccessString('123=-;other=va', UserGroups('1234', ['gr']), AccessMode.EDIT) + assert not CheckAccessString('123=-;other=ea', UserGroups('1234', ['gr']), AccessMode.ACCEES_EDIT) + assert not CheckAccessString('123=-;other=ad', UserGroups('1234', ['gr']), AccessMode.VIEW)