Как формализовать функцию проверка_прав, чтобы её можно было применить к любой другой?

В основной части программы вводится команда вида "записи(арг0) добавить(арг1) "hello world"(арг2) ". Функция проверка_прав должна определить, есть ли имя текущего пользователя в списке пользователей, имеющих право выполнять данную команду. У меня возникают трудности с формулировкой обращения к этим спискам.

Права = { # Тип команды : {Название команды : [Список пользователей, имеющих право]}
    "пользователи" : [
        {"добавить" : ["админ", ]},
        {"изменить" : ["админ", ]},
        {"удалить" : ["админ", ]}
        ],
    "записи" : [
        {"добавить" : ["админ", ]},
        {"изменить" : ["админ", ]},
        {"посмотреть" : ["админ", ]},
        {"удалить" : ["админ", ]}
        ],
    "права" : [
        {"добавить" : ["админ", ]},
        {"удалить" : ["админ", ]}
        ]
    }

#Функции:

def проверка_прав(арг0, арг1):
    global Права, текущий_пользователь
    #такой способ не работает. Нужно сделать так, чтобы не было необходимости 
    #указывать конкретный индекс из списка. Но как это сделать, если у списка нет имени, 
    #чтобы можно было применить метод list.index() ?
    if текущий_пользователь in Права[арг0][арг1]:
        return True
    else:
        return False


#Пример функции, с которой должна работать проверка_прав
def изменение_прав(арг0, арг1, арг2):
#Синтаксис: "Права"_Действие_"Имя пользователя"
    global Права
    if проверка_прав(арг0, арг1) == True:
        тип_команды = input("Введите тип команды")
        право = input("Введите право")
        if (тип_команды in Права) and (право in Права[тип_команды]):
            if арг1.lower() == "добавить":
                Права[тип_команды][право].append(арг2)
            elif арг1.lower() == "удалить":
                Права[тип_команды][право].remove(арг2)
            else:
                print("Неправильный ввод")
        else:
            print("Неправильно введены тип команды или право")
    else:
        print("Недостаточно прав")

Ответы (1 шт):

Автор решения: gil9red

Взял на себя смелость сильно поменять структуру кода, т.к. считаю, что структура у ПРАВА неправильная, плюс:

  • Для упрощения проверок структуры перенес в проверка_прав и добавил исключение
  • Добавил явное использование аргументов в частности для текущего юзера

Я бы добавил проверку, того, что target_user отсутствует в ПРАВА[command_type][command_name].append(target_user), чтобы не было дубликатов, но пусть это будет заданием автору :)

# Тип команды : {Название команды : [Список пользователей, имеющих право]}
ПРАВА = {
    "пользователи": {
        "добавить": ["админ", ],
        "изменить": ["админ", ],
        "удалить": ["админ", ]
    },
    "записи": {
        "добавить": ["админ", ],
        "изменить": ["админ", ],
        "посмотреть": ["админ", ],
        "удалить": ["админ", ]
    },
    "права": {
        "добавить": ["админ", ],
        "удалить": ["админ", ]
    }
}


class InvalidCommandException(Exception):
    pass


def проверка_прав(user: str, command_type: str, command_name: str) -> bool:
    if command_type not in ПРАВА:
        raise InvalidCommandException(f'Неизвестный тип команды {command_type!r}!')

    if command_name not in ПРАВА[command_type]:
        raise InvalidCommandException(f'Неизвестная команда {command_name!r} для типа команды {command_type!r}!')

    return user in ПРАВА[command_type][command_name]


def изменение_прав(user: str, command_type: str, command_name: str, target_user: str):
    command_type = command_type.lower()
    command_name = command_name.lower()

    try:
        if not проверка_прав(user, command_type, command_name):
            print("Недостаточно прав!")
            return

        if command_name == "добавить":
            ПРАВА[command_type][command_name].append(target_user)
        elif command_name == "удалить":
            ПРАВА[command_type][command_name].remove(target_user)

    except InvalidCommandException as e:
        print(f"Неправильный ввод! {e}")


current_user = 'админ'
command_type = input("Введите тип команды: ")
command_name = input("Введите право: ")
target_user = input("Введите имя пользователя: ")

изменение_прав(current_user, command_type, command_name, target_user)

print('Структура прав:')
print(ПРАВА)

Пример работы:

  1. Хороший сценарий:

    Введите тип команды: пользователи
    Введите право: добавить
    Введите имя пользователя: модераторъ
    Структура прав:
    {'пользователи': {'добавить': ['админ', 'модераторъ'], 'изменить': ['админ'], 'удалить': ['админ']}, 'записи': {'добавить': ['админ'], 'изменить': ['админ'], 'посмотреть': ['админ'], 'удалить': ['админ']}, 'права': {'добавить': ['админ'], 'удалить': ['админ']}}
    
  2. Не поддерживаемый тип команды:

    Введите тип команды: статистика
    Введите право: посмотреть
    Введите имя пользователя: Иван
    Неправильный ввод! Неизвестный тип команды 'статистика'!
    ...
    
  3. Неизвестное название команды:

    Введите тип команды: пользователи
    Введите право: найти по айпи
    Введите имя пользователя: МОДЕРАТОРЪ!!!
    Неправильный ввод! Неизвестная команда 'найти по айпи' для типа команды 'пользователи'!
    ...
    
  4. Меняем текущего пользователя: current_user = 'хакер' и проверяем права:

    Введите тип команды: пользователи
    Введите право: добавить
    Введите имя пользователя: хакер №2
    Недостаточно прав!
    ...
    
→ Ссылка