Hello, Florent!

On Monday January 26, 2009 13:55:07 Florent Aide wrote:
> The issue is that the request to the db needs to filter based on a
> parameter that is posted on the controller method I protected with
> @require.
> At the moment the check_auth function takes only "predicate" and
> "environ" and I'd like to add some *args, **kwargs to pass in the
> params that would then go to the decorated controller.

You can do something like this (not tested but should work):

    from paste.request import parse_formvars, parse_querystring
    from repoze.what.predicates import Predicate

    from yourcoolapplication.model import BlogPost, DBSession

    class can_edit_post(Predicate):
        message = 'Post %(post_id)s can only be edited by its author'

        def __init__(self, post_id_variable='post_id', variable_type='GET'
            self.post_id_variable = post_id_variable
            self.variable_type = variable_type
            super(can_edit_post, self).__init__(**kwargs)

        def evaluate(self, environ, credentials):
            # Extracting the post Id from the POST/GET variables
            include_get_vars = self.variable_type == 'GET'
            vars = parse_formvars(environ, include_get_vars)
            post_id = vars[self.post_id_variable]
            # Loading the post object
            post = DBSession.query(BlogPost).filter(post_id=post_id).one()
            # Checking if it's the author
            if post.author_userid != credentials.get('repoze.what.userid'):

Then you can use it in your TG2 actions like this:

    from repoze.what.predicates import All, has_permission
    from yourcoolapplication.lib.auth.predicates import can_edit_post

    # ...
        @require(All(has_permission('edit-post'), can_edit_post()))
        def edit_post(self, post_id, new_contents):

> If you know any other pattern that would help solve my issue, please
> don't hesitate to enlighten me... if you think this would be a worthy
> addition, then state so and I'll go ahead and propose a patch.

Hopefully in repoze.what v2 context-sensitive authorization will be easier and 
will also have an alternative to predicates. In the mean time, what I'm 
considering is make .evaluate() receive two more short-cuts to data already 
available in the environ: post_vars and get_vars, in addition to the short-cut 
to the repoze.what credentials dictionary. So its signature would be:
    evaluate(environ, credentials, post_vars, get_vars)

But I doubt this will be available for v1 because it would break 
compatibility. I'm open to other solutions that won't break compatibility for 
repoze.what v1, though.

Gustavo Narea <http://gustavonarea.net/>.

Get rid of unethical constraints! Get freedomware:
Repoze-dev mailing list

Reply via email to