Написание CherryPy Decorator для авторизации - PullRequest
6 голосов
/ 21 июля 2010

У меня есть приложение 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 ]

14 голосов
/ 22 июля 2010

Вы действительно не хотите писать собственные декораторы для 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#tools для дальнейшего обсуждения. Это дает несколько преимуществ по сравнению с написанием пользовательского декоратора:

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

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

# 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
...