2011-10-24 13 views
8

ACLがどのように機能するかはほとんど分かりません。私はそれがかなりクールだと私に多くの時間と痛みを節約することができます知っている。しかし、現在私は少し失われています。ピラミッドのすべての例は、トラバーサルを使用します。私は排他的にURLディスパッチを使用します。私はどのように私がressourceツリー構造を構築できるのか分からない。ここで横断のないピラミッドACL

はコードのサンプルです:

class QuestionFactory(object): 

    def __init__(self, request): 
     self.__acl__ = default[:] 
     self.uid = authenticated_userid(request) 

     self.qid = request.matchdict.get('id') 
     if self.qid: 
      self.question = request.db.questions.find_one({'_id': ObjectId(self.qid)}) 
      if str(self.question.get('owner')) == self.uid: 
       self.__acl__.append((Allow, userid, 'view'))  

ことは、それが動作する、ということです。しかし、私はすべてのタイプの資源のための新しい工場を定義しなければなりません。私はどのように私がトラフURLディスパッチと工場にアクセスしようとしているressourceを知っていると思いますか分からない。私はこれらの工場のそれぞれは、それ自身の特別なACLを持つような構造に

Root -\ 
     +-- account 
     +-- message 
     +-- config 
     +-- page 

を持っているだろう、ここで言っている

/accounts/{account} //Owners only but viewable by anyone 
/messages/{message} //Owners only 
/configs/{config}  //Admin only 
/pages/{page}   //Admins only but viewable by anyone 

のようなものを参照してくださいね。もう1つは、/ accountsがメインページであるということです。それはidや何も持っていません。また、/ accounts/newも特殊なケースです。これはIDではなく、新しいアイテムを作成するためのビューです。

私は、GET/PUT/DELETE/POST要件のある安らかなスタイルを使用しています。私はどのように私はressourceと右aclに自動的にURLを一致させることになっているのか分からない。上記のような特別な工場を自分のルートに定義しても問題はありません。

編集

私はそれはいくつかの例外を除いて動作するようになったんでした。私は最終的にトラバースの目的が何であるかを理解していると思います。たとえば、次のようなURLがあります:/ comments/9494f0eda/new、 /comments/{comment}/new

私たちのリソース・ツリーまたは3つのノードでNodeにする必要があります。

RootFactoryが最初に検査され、次にトラバーサルに従って検査されます。これは、その後、コメントの工場とCommentFactoryのか、私は

それをマイケル

の例のように辞書として工場を使用していないオブジェクト自体

の「新」の「コメント」RootFactoryのコメント属性を取得します

class RessourceFactory(object): 
    def __init__(self, parent, name): 

     self.__acl__ = [] 
     self.__name__ = name 
     self.__parent__ = parent 

     self.uid = parent.uid 
     self.locale = parent.locale 
     self.db = parent.db 
     self.req = parent.req 

これは私のベースのressourceオブジェクトです。すべてのステップで、親から新しい子に情報をコピーします。私は確かに私の属性を泡立てることができます。 ._ _.uidしかし、それはそれほど素晴らしいものではありません。

私がdict属性を使用していない理由です。私はそれはいくつかの理由から

/コメント

で動作させるために追加し、それは私のCommentFactoryを作成しましたが、キーの必要がなかったとして、それを返しませんでした。

だから私のルート工場はかなりは、次のようになります。項目が見つからない

class RootFactory(object): 

    def __init__(self, request): 
     self.__acl__ = default[:] 

     self.req = request 
     self.db = request.db 

     self.uid = authenticated_userid(request) 
     self.locale = request.params.get('locale', 'en') 

    def __getitem__(self, key): 

     if key == 'questions': 
      return QuestionFactory(self, 'questions') 
     elif key == 'pages': 
      return PageFactory(self, 'pages') 
     elif key == 'configs': 
      return ConfigFactory(self, 'configs') 
     elif key == 'accounts': 
      return AccountFactory(self, 'accounts') 

     return self 

場合、それは新しい工場を返さない場合は、自分自身を返すRootFactory。私のコードはマイケルのコードに基づいているので、Factoryコンストラクタの2番目のパラメータがあります。私はQuestionFactoryが「質問」を扱うことを十分に承知しているので、ここに工場の名前を付ける必要はありません。それはすでにその名前を知っているはずです。

class QuestionFactory(RessourceFactory): 
    def __init__(self, parent, name): 
     RessourceFactory.__init__(self, parent, name) 
     self.__acl__.append((Allow, 'g:admin', 'view')) 
     self.__acl__.append((Allow, 'g:admin', 'edit')) 
     self.__acl__.append((Allow, 'g:admin', 'create')) 
     self.__acl__.append((Allow, 'g:admin', 'delete')) 
     self.__acl__.append((Allow, Everyone, 'create')) 

    def __getitem__(self, key): 

     if key=='read': 
      return self 

     self.qid = key 
     self.question = self.db.questions.find_one({'_id': ObjectId(self.qid)}) 

     if str(self.question.get('owner')) == self.uid: 
      log.info('Allowd user %s' % self.uid) 
      self.__acl__.append((Allow, self.uid, 'view')) 
      self.__acl__.append((Allow, self.uid, 'edit')) 
      self.__acl__.append((Allow, self.uid, 'delete')) 

     return self 

これは、ほぼすべてのロジックが行く場所です。私が返すしない限り、私はそれ自身を返すので、それは/質問/ {ID}/*

のために働くために/ GetItem関数で質問機能するACLを設定INITでは、このRessourceFactory過去任意GetItem関数自体を指しますいくつか特別なケースのための新しい工場。そうする理由は、私のコンテキストがデータベースやオブジェクトのオブジェクトではないからです。

私のコンテキストは、ユーザーID、ロケールなどのような複数のものを処理します... aclが完了すると、すぐに使用できる新しいコンテキストオブジェクトがあります。これは、ビュー内のロジックのほとんどを削除します。

おそらく、イベントをロケールとUIDを照会するように設定することができましたが、本当にここに当てはまります。新しいものが必要な場合は、子ファクトリにコピーするためにRootFactoryとRessourceFactoryを編集するだけです。

このように、すべてのビューに何かが変更されなければならない場合、冗長性はまったくありません。

答えて

5

アカウントの所有者だけがデータを表示できるようにするオブジェクト/行レベルのセキュリティ機能に興味があるようです。私はこのトピックに関する私の以前のSOの答えと、この答えをもとに構築されたURL Dispatchのauthのた​​めに取り組んでいるチュートリアルを紹介します。具体的には、リンクされたgithubプロジェクトの2.object_securityデモと、リソースツリーを自分のサイトのレンダリングされたhtmlの一部として説明するドキュメントを見てください。 https://github.com/mmerickel/pyramid_auth_demo

http://michael.merickel.org/projects/pyramid_auth_demo/

あなたがそれらのリソースを理解する質問があれば、私はここでさらに詳しく説明させていただき

Pyramid authorization for stored items

+0

私はすでにそれをすべて読んでいます。私がタイトルで言ったように、私はトラバーサルなしでこれを達成しようとしています。私は一度試して、それは私のルートを混乱させ、何も働かなかった。私は木の階層もあるとは思わない。私はページ、メッセージなどを持っているが、実際には他のオブジェクトは関係していないからです。だから、そんなこと/ foo/bar/bazは私にはあまり話さない。 –

+0

私はいくつかのテストをしたが、それは結局働くかもしれない...明日何かを書くだろう、私は明日の試験の前に寝なければならない。 –

+0

私があなたに与えたリンクはURLディスパッチを使用しています...ピラミッドの認証システムは、オブジェクトツリーを横断することによって階層的に動作します。これがACLAuthorizationPolicyの仕組みです。私は昨晩のデモを書き直して積極的に取り組んでいるので、「すでにすべてを読んでいる」と驚いています。 ;-) –

関連する問題