9

新しく作成した Pyramid アプリケーションに承認 (および認証) を実装する方法について読んでいます。「リソース」という概念にぶつかり続けています。アプリケーションで python-couchdb を使用していますが、RDBMS をまったく使用していないため、SQLAlchemy はありません。次のように Product オブジェクトを作成すると:

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

これがリソースとも呼ばれるかどうか教えてください。私は Pyramids のドキュメント全体を読んできましたが、リソースという用語を平易な英語で説明している箇所はどこにもありません (私は単に愚かなのかもしれません)。これがリソースである場合、これは次のように 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 Product クラス/リソースに追加することを意味しますか?

申し訳ありませんが、すべての新しい用語で本当に混乱しています (私は Pylons 0.9.7 から来ました)。

前もって感謝します。

4

2 に答える 2

6

あなたが欠けている部分はトラバーサル部分だと思います。製品はリソースですか? それはあなたのトラバーサルが何を生成するかに依存します.それは製品を生成する可能性があります.....

おそらく、ビューから、アプリケーションの作成時にどのように構成されるかまで、これを説明するのが最善かもしれません...

これが典型的なビューです。

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

したがって、コンテキストが Product のインスタンスである場合、このビューが呼び出されます。かつ、そのインスタンスのacl属性に「表示」権限がある場合。では、Product のインスタンスはどのようにしてコンテキストになるのでしょうか?

ここで、トラバーサルの魔法の出番です。トラバーサルのロジックそのものは、単なる辞書の辞書です。したがって、これが機能する1つの方法は、次のような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 生成メソッドが正しく機能するためには、「name 」属性と「parent 」属性がピラミッドに必要です。

これで、トラバースできるリソースができました。ピラミッドに ProductContainer をトラバースするように指示するにはどうすればよいでしょうか? これは Configurator オブジェクトを介して行います。

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

factory パラメーターは callable を想定し、現在のリクエストを渡します。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()

注: 私はメモリからコード例を作成しました。明らかに、必要なすべてのインポートなどが必要です。つまり、これはコピー/貼り付けとして機能しません。

于 2012-03-02T22:26:50.647 に答える
0

http://michael.merickel.org/projects/pyramid_auth_demo/に取り組みましたか? そうでない場合は、役立つ可能性があると思います。最後のセクションhttp://michael.merickel.org/projects/pyramid_auth_demo/object_security.htmlは、目的のパターンを実装しています (「モデル」クラスの例は、より複雑なものを継承していないことに注意してくださいobject)。

于 2012-03-03T22:22:42.417 に答える