19

「アイテム」の所有権を考慮した承認ポリシーを作成しようとしています。たとえば、一部のユーザー X がアイテム A、B、C を「所有」しているとします。これらは のような URL を介してアクセスされます/item/{item}/some_options

{item}認可ポリシー オブジェクト (permits() 呼び出し)に関する情報を取得するにはどうすればよいですか? 追加情報をコンテキストに入れるのは良い考えです (私はルートベースのルーティングのみを行っています)。どうすればいいですか?

4

1 に答える 1

52

ACLAuthorizationPolicyこれは、この目的のために設計されたカスタム リソース ツリーを使用して、URL ディスパッチと組み合わせて使用​​できます。

たとえば、オブジェクトに対するFooアクセス許可と、オブジェクトに対するアクセス許可がありBarます。これらの ACL は、次の URL を使用してリソース ツリーをトラバースすることで見つけることができます。

/foos/{obj}
/bars/{obj}

リソース ツリーは権限の階層になり、ツリー内の任意の場所で__acl__リソース オブジェクトにを配置できます。

root                       (Root)
|- foos                    (FooContainer)
|  `- {obj}                (Foo)
`- bars                    (BarContainer)
   `- {obj}                (Bar)

この階層をリソース ツリーで表すことができます。

class Root(dict):
    # this is the root factory, you can set an __acl__ here for all resources
    __acl__ = [
        (Allow, 'admin', ALL_PERMISSIONS),
    ]
    def __init__(self, request):
        self.request = request
        self['foos'] = FooContainer(self, 'foos')
        self['bars'] = BarContainer(self, 'bars')

class FooContainer(object):
    # set ACL here for *all* objects of type Foo
    __acl__ = [
    ]

    def __init__(self, parent, name):
        self.__parent__ = parent
        self.__name__ = name

    def __getitem__(self, key):
        # get a database connection
        s = DBSession()
        obj = s.query(Foo).filter_by(id=key).scalar()
        if obj is None:
            raise KeyError
        obj.__parent__ = self
        obj.__name__ = key
        return obj

class Foo(object):
    # this __acl__ is computed dynamically based on the specific object
    @property
    def __acl__(self):
        acls = [(Allow, 'u:%d' % o.id, 'view') for o in self.owners]
        return acls

    owners = relation('FooOwner')

class Bar(object):
    # allow any authenticated user to view Bar objects
    __acl__ = [
        (Allow, Authenticated, 'view')
    ]

このような設定で、ルート パターンをリソース ツリーにマッピングできます。

config = Configurator()
config.add_route('item_options', '/item/{item}/some_options',
                 # tell pyramid where in the resource tree to go for this url
                 traverse='/foos/{item}')

また、ルートを特定のビューにマップする必要があります。

config.add_view(route_name='item_options', view='.views.options_view',
                permission='view', renderer='item_options.mako')

これで、ビューを定義し、読み込まれたコンテキスト オブジェクトを使用できるようになりました。ビューが実行された場合、ユーザーは適切な権限を持っていることがわかります。

def options_view(request):
    foo = request.context
    return {
        'foo': foo,
    }

この設定を使用すると、デフォルトの が使用ACLAuthorizationPolicyされ、URL Dispatch を使用してオブジェクトに行レベルのアクセス許可が提供されます。また、オブジェクト__parent__が子にプロパティを設定するため、ポリシーは系統をバブルアップし、親からアクセス許可を継承することにも注意してください。これは、単に ACE を ACL に入れるDENY_ALLか、コンテキストの系統を使用しないカスタム ポリシーを作成することで回避できます。

* 更新 * この投稿を Github の実際のデモに変えました。うまくいけば、それは誰かを助けます。 https://github.com/mmerickel/pyramid_auth_demo

* 更新 * ピラミッドの認証および承認システムに関する完全なチュートリアルをここに書きました: http://michael.merickel.org/projects/pyramid_auth_demo/

于 2011-04-23T03:12:46.117 に答える