Ресурс пирамиды: простым языком - PullRequest
9 голосов
/ 03 марта 2012

Я читал о способах реализации авторизации (и аутентификации) в моем недавно созданном приложении Pyramid.Я продолжаю сталкиваться с концепцией под названием «Ресурс».Я использую python-couchdb в своем приложении и вообще не использую RDBMS, следовательно, нет SQLAlchemy.Если я создаю объект Product следующим образом:

class Product(mapping.Document):
  item = mapping.TextField()
  name = mapping.TextField()
  sizes = mapping.ListField()

Может кто-нибудь сказать мне, если это также называется ресурсом?Я читал всю документацию по Пирамидам, но нигде не объясняется термин ресурс на простом простом английском языке (возможно, я просто тупой).Если это ресурс, значит ли это, что я просто вставляю свои ACL-материалы вот так:

class Product(mapping.Document):
  __acl__ = [(Allow, AUTHENTICATED, 'view')]
  item = mapping.TextField()
  name = mapping.TextField()
  sizes = mapping.ListField()

  def __getitem__(self, key):
      return <something>

Если бы я также использовал Traversal, значит ли это, что я добавил getitem функция в моем python-couchdb Класс продукта / ресурс?

Извините, это просто очень запутывает все новые термины (я пришел из Pylons 0.9.7).

Заранее спасибо.*

Ответы [ 2 ]

6 голосов
/ 03 марта 2012

Я думаю, что часть, которую вы упускаете, является частью прохождения. Продукт ресурс? Ну, это зависит от того, что производит ваш обход, это мог производить продукцию .....

Возможно, было бы лучше пройти сквозь это представление от как это настраивается при создании приложения ...

Вот типичный вид.

  @view_config(context=Product, permission="view")
  def view_product(context, request):
      pass # would do stuff  

Таким образом, это представление вызывается, когда контекст является экземпляром Product. А ТАКЖЕ если атрибут acl этого экземпляра имеет «представление» разрешение. Так как же экземпляр Product станет контекстом?

Вот где приходит магия обхода. Сама логика Обход - это просто словарь словарей. Итак, один способ, которым это может работать для вас, если у вас есть URL-адрес, как

/product/1

Каким-то образом некоторые ресурсы должны быть пройдены сегментами URL, чтобы определить контекст, чтобы можно было определить представление. Что, если у нас было что-то вроде ...

  class ProductContainer(object):
      """
      container = ProductContainer()
      container[1]
      >>> <Product(1)>
      """
      def __init__(self, request, name="product", parent=None):
          self.__name__ = name
          self.__parent__ = parent
          self._request = request

      def __getitem__(self, key):
          p = db.get_product(id=key)

          if not p:
              raise KeyError(key)
          else:
              p.__acl__ = [(Allow, Everyone,"view")]
              p.__name__ = key
              p.__parent__ = self
              return p

Теперь это описано в документации, и я пытаюсь это сварить. вплоть до основ, которые вы должны знать. ProductContainer - это объект который ведет себя как словарь. " имя " и " родитель " атрибуты необходимы пирамиде для генерации URL методы для правильной работы.

Так что теперь у нас есть ресурс, который можно просмотреть. Как мы говорим Пирамида, чтобы пройти ProductContainer? Мы делаем это через Конфигуратор объекта.

  config = Configurator()
  config.add_route(name="product",
                   path="/product/*traverse",
                   factory=ProductContainer)
  config.scan()
  application = config.make_wsgi_app()

Заводской параметр ожидает вызова и передает ему текущий запрос. Так уж получилось, что ProductContainer. init сделает это просто отлично.

Это может показаться немного большим для такого простого примера, но, надеюсь, Вы можете представить возможности. Эта модель позволяет очень модели гранулярного разрешения.

Если вы не хотите / нуждаетесь в очень детальной модели разрешений, такой как строка уровень acl, вероятно, вам не нужен обход, вместо этого вы можете использовать маршруты с одной корневой фабрикой.

  class RootFactory(object):
      def __init__(self, request):
          self._request = request
          self.__acl__ = [(Allow, Everyone, "view")]  # todo: add more acls


  @view_config(permission="view", route_name="orders")
  def view_product(context, request):
      order_id, product_id = request.matchdict["order_id"], request.matchdict["product_id"]
      pass # do what you need to with the input, the security check already happened

  config = Configurator(root_factory=RootFactory)

  config.add_route(name="orders",
                   path="/order/{order_id}/products/{product_id}")

  config.scan()
  application = config.make_wsgi_app()

примечание: я сделал пример кода из памяти, очевидно, вам необходим весь необходимый импорт и т. Д. Другими словами, это не будет работать как копирование / вставка

0 голосов
/ 04 марта 2012

Работали ли вы через http://michael.merickel.org/projects/pyramid_auth_demo/? Если нет, я подозреваю, что это может помочь. В последнем разделе http://michael.merickel.org/projects/pyramid_auth_demo/object_security.html реализован шаблон, который вам нужен (обратите внимание на пример, когда классы «модели» наследуют от ничего более сложного, чем object).

...