[Repoze-dev] repoze.what custom predicate parameters

2009-01-26 Thread Florent Aide
Hi,

I'd like to write custom Predicates for an application using
repoze.what with TurboGears2. My predicate would perform some query on
the database and check the resulting object against predefined
criterion.

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.

This would permit my custom predicate to perfom its db query based on
the request params (as I would do in my controller's code) and thus
avoid code duplication inside each protected controller.

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.

Florent Aide.
___
Repoze-dev mailing list
Repoze-dev@lists.repoze.org
http://lists.repoze.org/listinfo/repoze-dev


Re: [Repoze-dev] repoze.what custom predicate parameters

2009-01-26 Thread Gustavo Narea
On Monday January 26, 2009 16:18:36 Florent Aide wrote:
 a here is the patch that would permit to write the kind of predicates
 I need... Gustavo, what do you think? Is that ok with you to apply
 this on the trunk. You broke compatibility anyway so why not break it
 a little more... :)

Well, I've not broken compatibility since the first stable release and I hope 
that won't ever be necessary. I've just deprecated some things for forward 
compatibility. :)

The problem is that people are not expected to evaluate predicates by 
themselves using Predicate.evaluate(); that's what check_authorization() is 
for:
http://static.repoze.org/whatdocs/Manual/Predicates.html#repoze.what.predicates.Predicate.evaluate

Therefore, unfortunately it'd be useless that .evaluate() was able to receive 
arbitrary arguments and keyword arguments because it will never receive them. 
It'll only receive what check_authorization() passes to it (unless you run 
.evaluate() by yourself, which is discouraged -- check_authorization() does 
some useful things for you unlike plain .evaluate()).

As I mentioned in the previous email, I agree that context-sensitive 
authorization should require less code (i.e., not using 
paste.request.parse_formvars by yourself). But my concern is how to do it 
without breaking compatibility. I'm open to any solution that won't break 
compatibility.

In repoze.what v2, the way I'll address this is by passing the POST and GET 
variables to .evaluate() too. At least that's the solution I have in mind 
right now.

Cheers!
-- 
Gustavo Narea http://gustavonarea.net/.

Get rid of unethical constraints! Get freedomware:
http://www.getgnulinux.org/
___
Repoze-dev mailing list
Repoze-dev@lists.repoze.org
http://lists.repoze.org/listinfo/repoze-dev


[Repoze-dev] repoze.bfg 0.6.5 released

2009-01-26 Thread Chris McDonough
repoze.bfg 0.6.5 was just put into the
http://dist.repoze.org/lemonade/dev/simple/ index.  This release has a couple of
new features, but it's mostly a speed micro-optimization release. As a result, a
repoze.bfg hello world application runs (for me) at somewhere between 900 and
1100 req/sec on a MacBook 2GHz machine, up from somewhere around 700 req/sec or
so in 0.6.3.

0.6.5 (2009-01-26)
==

Features


- You can now override the NotFound and Unauthorized responses that
  :mod:`repoze.bfg` generates when a view cannot be found or cannot be
  invoked due to lack of permission.  See the ZCML Hooks chapter in
  the docs for more information.

- Added Routes ZCML directive attribute explanations in documentation.

- Added a ``traversal_path`` API to the traversal module; see the
  traversal API chapter in the docs.  This was a function previously
  known as ``split_path`` that was not an API but people were using it
  anyway.  Unlike ``split_path``, it now returns a tuple instead of a
  list (as its values are cached).

Behavior Changes


- The ``repoze.bfg.view.render_view_to_response`` API will no longer
  raise a ValueError if an object returned by a view function it calls
  does not possess certain attributes (``headerlist``, ``app_iter``,
  ``status``).  This API used to attempt to perform a check using the
  ``is_response`` function in ``repoze.bfg.view``, and raised a
  ``ValueError`` if the ``is_response`` check failed.  The
  responsibility is now the caller's to ensure that the return value
  from a view function is a real response.

- WSGI environ dicts passed to ``repoze.bfg`` 's Router must now
  contain a REQUEST_METHOD key/value; if they do not, a KeyError will
  be raised (speed).

- It is no longer permissible to pass a nested list of principals to
  ``repoze.bfg.ACLAuthorizer.permits`` (e.g. ``['fred', ['larry',
  'bob']]``).  The principals list must be fully expanded.  This
  feature was never documented, and was never an API, so it's not a
  backwards incompatibility.

- It is no longer permissible for a security ACE to contain a nested
  list of permissions (e.g. ``(Allow, Everyone, ['read', ['view',
  ['write', 'manage']]])`)`.  The list must instead be fully expanded
  (e.g. ``(Allow, Everyone, ['read', 'view', 'write', 'manage])``).  This
  feature was never documented, and was never an API, so it's not a
  backwards incompatibility.

- The ``repoze.bfg.urldispatch.RoutesRootFactory`` now injects the
  ``wsgiorg.routing_args`` environment variable into the environ when
  a route matches.  This is a tuple of ((), routing_args) where
  routing_args is the value that comes back from the routes mapper
  match (the match dict).

- The ``repoze.bfg.traversal.RoutesModelTraverser`` class now wants to
  obtain the ``view_name`` and ``subpath`` from the
  ``wsgiorgs.routing_args`` environment variable.  It falls back to
  obtaining these from the context for backwards compatibility.

Implementation Changes
--

- Get rid of ``repoze.bfg.security.ACLAuthorizer``: the
  ``ACLSecurityPolicy`` now does what it did inline.

- Get rid of ``repoze.bfg.interfaces.NoAuthorizationInformation``
  exception: it was used only by ``ACLAuthorizer``.

- Use a homegrown NotFound error instead of ``webob.exc.HTTPNotFound``
  (the latter is slow).

- Use a homegrown Unauthorized error instead of
  ``webob.exc.Unauthorized`` (the latter is slow).

- the ``repoze.bfg.lru.lru_cached`` decorator now uses functools.wraps
  in order to make documentation of LRU-cached functions possible.

- Various speed micro-tweaks.

Bug Fixes
-

- ``repoze.bfg.testing.DummyModel`` did not have a ``get`` method;
  it now does.

___
Repoze-dev mailing list
Repoze-dev@lists.repoze.org
http://lists.repoze.org/listinfo/repoze-dev


Re: [Repoze-dev] repoze.what custom predicate parameters

2009-01-26 Thread Gustavo Narea
On Monday January 26, 2009 17:50:25 Florent Aide wrote:
 this won't work with urls of the form:

 /blog/post/post_id

 and thus we'll need to devise something more, like introspection of
 the decorated controller's method's args...

That's a good point. Fortunately I read this email before sending the other 
email/poll to the Repoze and TG mailing lists. Let's continue this over there 
:)

Cheers.
-- 
Gustavo Narea http://gustavonarea.net/.

Get rid of unethical constraints! Get freedomware:
http://www.getgnulinux.org/
___
Repoze-dev mailing list
Repoze-dev@lists.repoze.org
http://lists.repoze.org/listinfo/repoze-dev


Re: [Repoze-dev] [r.what] Backwards incompatibility in exchange for better context sensitivity?

2009-01-26 Thread Tres Seaver
-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 Designhttp://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

Re: [Repoze-dev] [tg-trunk] [r.what] Backwards incompatibility in exchange for better context sensitivity?

2009-01-26 Thread Jorge Vargas
On Mon, Jan 26, 2009 at 1:36 PM, Gustavo Narea m...@gustavonarea.net 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.


sounds interesting. Just a though can't we make it so that.

evaluate(environ, credentials, variables=None)
if variables:
new stuff
else:
warn.warning(...)
old behaviour

Won't this keep backward compatibility and still allow the specific
predicates to work?
___
Repoze-dev mailing list
Repoze-dev@lists.repoze.org
http://lists.repoze.org/listinfo/repoze-dev