-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Gustavo Narea wrote:
> Hello, everybody.
> 
> Florent and I have been discussing about context-sensitivity in 
> repoze.what-1.0 predicates and there's a good enhancement that may be applied 
> but will break backwards compatibility, and I won't break backwards 
> incompatibility unless you want it. 
> 
> If you have repoze.what predicates this would affect you, so please read on.
> 
> Right now repoze.what predicates are context-sensitive because they are 
> evaluated with the WSGI environment. *But* if you have predicates that depend 
> on POST/GET variables, then you have to use Paste to extract the variables 
> you 
> need from the WSGI environment. This is, GET/POST variables are used a lot in 
> context-sensitivity authorization but they're not at hand (you need to write 
> a 
> little more code to get them).
> 
> So, there's a proposed solution which would make the 
> Predicate.evaluate(environ, credentials) method receive one more argument: 
> The 
> GET and POST variables. So its signature would end up as:
>>    evaluate(environ, credentials, variables)
> (where ``variables`` is a dict, and ``variables['post']`` and 
> ``variables['get']`` contain the POST and GET variables respectively)
> 
> But if I implement it, then your custom predicates (if any) will break. I 
> think it's a good compromise because:
>  1.- If your predicates still use the ._eval_with_environ() method then 
> you'll 
> have to switch to .evaluate() the sooner or later anyway because it's 
> deprecated (but still supported).
>  2.- Upgrading is easy: Just add the "variables" argument to your .evaluate() 
> method.
> 
> In case you don't find the big advantage of this change, think how you'd deal 
> with predicates that depend on GET/POST variables:
>>     from paste.request import parse_formvars
>>     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', **kwargs):
>>             self.post_id_variable = post_id_variable
>>             super(can_edit_post, self).__init__(**kwargs)
>>
>>         def evaluate(self, environ, credentials):
>>             # Extracting the post Id from the POST/GET variables
>>             vars = parse_formvars(environ)
>>             post_id = vars.get(self.post_id_variable)
>>            if not post_id:
>>                self.unmet('Post Id is not available')
>>             # 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'):
>>                 self.unmet(post_id=post_id)
> 
> While you could write:
>>     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', **kwargs):
>>             self.post_id_variable = post_id_variable
>>             super(can_edit_post, self).__init__(**kwargs)
>>
>>         def evaluate(self, environ, credentials, variables):
>>             post_id = variables['post'].get(self.post_id_variable)
>>            if not post_id:
>>                self.unmet('Post Id is not available')
>>             # 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'):
>>                 self.unmet(post_id=post_id)
> 
> Regarding variables available before the query string (if any; e.g., 
> "/blog/post/post_id"), as supported in TG, they could be passed by the 
> framework to the check_authorization() function so that it inserts them into 
> ``variables['extra']``. This would be optional, of course.
> 
> Finally, do you think this backwards incompatible change worths it? The poll 
> ends by tomorrow evening here in western Europe. :)

I would make 'check_authorization' call a new method
'evaluate_with_variables', which just passes through to 'evaluate' in
the base class (Predicate):  people could override it to do the extra
checking.  The cost is one extra function call for those not using the
indirection, but preserves backward compatibility.


Tres.
- --
===================================================================
Tres Seaver          +1 540-429-0999          tsea...@palladion.com
Palladion Software   "Excellence by Design"    http://palladion.com
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFJfgj4+gerLs4ltQ4RAomMAJ9BMNAEkd6msnGq2YINaGe4w5tnDQCglSEx
Cd60dqxfYgp7QO9fDngZ5B8=
=gQdH
-----END PGP SIGNATURE-----
_______________________________________________
Repoze-dev mailing list
Repoze-dev@lists.repoze.org
http://lists.repoze.org/listinfo/repoze-dev

Reply via email to