def requires_admin(func):
def wrapper(*args, **kwargs):
if not is_admin(get_current_user()): # Предполагаем, что есть функция is_admin
raise PermissionError("Требуются права администратора")
return func(*args, **kwargs)
return wrapper
class MyClass:
@requires_admin
def sensitive_operation(self):
# ... код, требующий прав администратора ...
pass
Декораторы - мощный инструмент в Python, позволяющий модифицировать поведение функций или методов, не изменяя их исходный код. В контексте управления доступом к методам и свойствам класса, декораторы позволяют реализовать логику авторизации и аутентификации, проверяя, имеет ли пользователь необходимые права для выполнения определенной операции или доступа к определенным данным.
Пример реализации декоратора для управления доступом:
import functools
def requires_permission(permission_level):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
# Получаем объект self (экземпляр класса)
self = args[0]
# Предполагаем, что у пользователя есть атрибут 'permissions' (словарь или список)
if permission_level in self.permissions:
return func(*args, **kwargs)
else:
return "Ошибка: Недостаточно прав для выполнения этой операции."
return wrapper
return decorator
class MyClass:
def __init__(self, permissions):
self.permissions = permissions
@requires_permission("admin")
def sensitive_operation(self, data):
return f"Выполнена секретная операция с данными: {data}"
@requires_permission("user")
def view_public_data(self):
return "Общедоступные данные"
# Пример использования:
user_with_admin_rights = MyClass({"admin": True, "user": True})
user_with_user_rights = MyClass({"user": True})
print(user_with_admin_rights.sensitive_operation("Super Secret Data"))
print(user_with_user_rights.sensitive_operation("Super Secret Data"))
print(user_with_user_rights.view_public_data())
Разъяснения:
requires_permission(permission_level)
: Это декоратор, принимающий уровень доступа (например, "admin", "user") в качестве аргумента. Он создает и возвращает другой декоратор (decorator
).decorator(func)
: Этот внутренний декоратор принимает функцию (метод класса) в качестве аргумента.@functools.wraps(func)
: Этот декоратор сохраняет метаданные оригинальной функции (func
), такие как имя, docstring и т.д. Это важно для интроспекции и отладки.wrapper(*args, **kwargs)
: Это обертка вокруг оригинальной функции. Здесь реализуется логика проверки прав доступа.self = args[0]
: В методах класса, первым аргументом всегда является self
(экземпляр класса). Мы получаем доступ к нему, чтобы проверить права пользователя.self.permissions
: Предполагается, что у экземпляра класса есть атрибут permissions
, который содержит информацию о правах доступа пользователя (например, словарь или список разрешений).wrapper
проверяется, есть ли у пользователя необходимый уровень доступа в атрибуте self.permissions
. Если права есть, вызывается оригинальная функция func(*args, **kwargs)
и возвращается ее результат. В противном случае, возвращается сообщение об ошибке.Альтернативные подходы:
@property
, @setter
и @deleter
для контроля доступа к атрибутам класса. Например, можно разрешить чтение атрибута всем, но изменение - только администраторам.Flask-Principal
для Flask), которые предоставляют готовые решения для управления доступом на основе ролей и разрешений.Важно: Управление доступом должно быть реализовано с учетом контекста вашего приложения. Приведенный пример демонстрирует общую идею, но конкретная реализация может отличаться в зависимости от требований безопасности и архитектуры.