Написание CherryPy Decorator для авторизации

У меня есть приложение cherrypy, и на некоторых из представлений я хочу начать, позволяя только определенным пользователям просматривать их и отправляя кого-либо еще на страницу, требующую авторизации.

Есть ли способ сделать это с помощью специального декоратора? Я думаю, что это будет самый элегантный вариант.

Вот основной пример того, что я хочу сделать:

class MyApp:
    @authorization_required
    def view_page1(self,appID):
        ... do some stuff ...
        return html

def authorization_required(func):
    #what do I put here?

Также может ли функция authorization_required при вызове в качестве декоратора принимать такие параметры, как allow_group1, allow_group2? Или мне нужен отдельный декоратор для каждой группы?

2 ответа

Решение

Хорошо, в этом случае ваш декоратор будет выглядеть примерно так:

# without any parameters
def authentication_required(f):
    @functools.wraps(f)
    def _authentication_required(*args, **kwargs):
        # Do you login stuff here
        return f(*args, **kwargs)
    return _authentication_required

# With parameters
def authentication_required(*allowed_groups):
    def _authentication_required(f):
        @functools.wraps(f)
        def __authentication_required(*args, **kwargs):
            # Do you login stuff here
            return f(*args, **kwargs)
        return __authentication_required
    return _authentication_required

Вы действительно не хотите писать собственные декораторы для CherryPy. Вместо этого вы хотите написать новый инструмент:

def myauth(allowed_groups=None, debug=False):
    # Do your auth here...
    authlib.auth(...)
cherrypy.tools.myauth = cherrypy.Tool("on_start_resource", myauth)

См. http://docs.cherrypy.org/en/latest/extend.html для дальнейшего обсуждения. Это имеет несколько преимуществ по сравнению с написанием собственного декоратора:

  1. Вы получаете декоратор бесплатно из инструмента: @cherrypy.tools.myauth(allowed_groups=['me'])и он уже знает, как не затереть cherrypy.exposed на ту же функцию.
  2. Вы можете применять инструменты для каждого обработчика (с декоратором), для каждого дерева контроллера (через _cp_config) или per-URI-дерево (в конфигурационных файлах или файлах). Вы даже можете смешивать их и предоставлять базовую функцию через декораторы, а затем переопределять их поведение в файлах конфигурации.
  3. Если файл конфигурации отключает вашу функцию, вы не платите за производительность, вызывая функцию декоратора, просто чтобы проверить, отключена ли она.
  4. Вы не забудете добавить аргумент 'debug', как во всех встроенных инструментах.;)
  5. Ваша функция может быть запущена раньше (или позже, если это то, что вам нужно), чем пользовательский декоратор, выбрав другую "точку".
  6. Ваша функция может работать в нескольких точках подключения, если это необходимо.
Другие вопросы по тегам