repoze.what helpers functions

0 views
Skip to first unread message

Jorge Vargas

unread,
Nov 24, 2008, 12:28:47 PM11/24/08
to turbogea...@googlegroups.com
hello Gustavo,all.

I'll like to propose a bit of api, I'm not 100% sure if this isn't
really there but it will be nice.

I suggest it will be added to repoze.what.authorize.py although with
the move of require to tgcore maybe it should be there.

The methods are the following:

current_user
current_groups
current_permissions

they are all wrappers against the environ and identity dict but I
believe they are common enough to be there.

What do you think?

Gustavo Narea

unread,
Nov 24, 2008, 3:04:38 PM11/24/08
to turbogea...@googlegroups.com
Hello, Jorge.

I think it's a good idea.

However, it's better to implement it in TurboGears itself because of the same
reason why @require has been moved from repoze.what to TG: The only safe way
to deal with the environment is by passing it around (instead of storing it in
a global variable, for example).

If it's implemented in repoze.what, then the three functions below will need
to be passed the WSGI environment as an argument. On the contrary, if they are
implemented in TurboGears, they could be defined so that the environment isn't
passed as argument.

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

Get rid of unethical constraints! Get freedomware:
http://www.getgnulinux.org/

Diez B. Roggisch

unread,
Nov 24, 2008, 4:57:09 PM11/24/08
to turbogea...@googlegroups.com
Gustavo Narea schrieb:

> Hello, Jorge.
>
> I think it's a good idea.
>
> However, it's better to implement it in TurboGears itself because of the same
> reason why @require has been moved from repoze.what to TG: The only safe way
> to deal with the environment is by passing it around (instead of storing it in
> a global variable, for example).
>
> If it's implemented in repoze.what, then the three functions below will need
> to be passed the WSGI environment as an argument. On the contrary, if they are
> implemented in TurboGears, they could be defined so that the environment isn't
> passed as argument.

I don't follow that argument. It would be a very easy endeavour (and
AFAIK is already undertaken by other middlewares) to keep a thread-local
reference to the environmemnt, for such purposes.

See the request/response variables for example.

Now there might be other reasons not to put these functions into
repoze.what, but out of my head I don't see any. Having a
metadata-provider pluggable in repoze.who makes it worthwhile to add
convenience-functions to access that metadata. And given that repoze.who
isn't concerned with things such as groups, repoze.what appears to be
the logical place.

Diez

Gustavo Narea

unread,
Nov 25, 2008, 10:31:09 AM11/25/08
to turbogea...@googlegroups.com
Hello, Diez.

I know that's another option, but Chris McDonough has already explained to me
why that should be avoided. This is a part of the conversation:

> > So, before implementing such a functionality with a thread-local, I
> > wanted to ask: Why did you prefer passing the environ around instead of
> > using a thread-local?
>
> The reason the Pylons folks need the StackedObjectProxy (which is a bug and
> confusion magnet) is because they use thread locals like this to represent
> request-local state.  For instance, when one Pylons application calls into
> another via WSGI, this thing stacks the environment in such a way that one
> application doesn't stomp on another's thread-locals.
>
> SOP is nasty, and I suspect using a "bare" thread local will become
> problematic in oddball environment configurations like the above, so were
> it me, I'd write it in such a way that the "raw" repoze.what stuff expects
> the environ to be passed in.  In any case, if you do end up using thread
> locals, I'd put the thread local stuff in the *calling* app, and not in
> repoze.what itself.

That's why I prefer repoze.what to be passed the environ every time it needs
the environ.

Cheers!

Diez B. Roggisch

unread,
Nov 25, 2008, 10:50:08 AM11/25/08
to turbogea...@googlegroups.com
On Tuesday 25 November 2008 16:31:09 Gustavo Narea wrote:
> Hello, Diez.
>
> I know that's another option, but Chris McDonough has already explained to
> me
>
> why that should be avoided. This is a part of the conversation:
> > > So, before implementing such a functionality with a thread-local, I
> > > wanted to ask: Why did you prefer passing the environ around instead of
> > > using a thread-local?
> >
> > The reason the Pylons folks need the StackedObjectProxy (which is a bug
> > and confusion magnet) is because they use thread locals like this to
> > represent request-local state.  For instance, when one Pylons application
> > calls into another via WSGI, this thing stacks the environment in such a
> > way that one application doesn't stomp on another's thread-locals.
> >
> > SOP is nasty, and I suspect using a "bare" thread local will become
> > problematic in oddball environment configurations like the above, so were
> > it me, I'd write it in such a way that the "raw" repoze.what stuff
> > expects the environ to be passed in.  In any case, if you do end up using
> > thread locals, I'd put the thread local stuff in the *calling* app, and
> > not in repoze.what itself.
>
> That's why I prefer repoze.what to be passed the environ every time it
> needs the environ.

I understand that sentiment, and if repoze.wha and what are supposed to be
independent middlewares - so mote it be.

From and end-user POV however this is a moot point. I don't have the environ
available in TG2. Django makes these things explicit - TG doesn't.

So not putting them into repoze.what will introduce the need to wrap them
again, passing the explicit environment which is fetched from some
thread-local storage (or even the SOP, to keep mulit-apps possible I presume,
yet I don't know when such a stack is pushed/pop'd).

Diez

Jorge Vargas

unread,
Nov 25, 2008, 11:11:24 AM11/25/08
to turbogea...@googlegroups.com
I agree with Diez here.
if repoze.what's goal is to be framework agnostic then this type of
thing should be inside repoze.what. That way if you are using pylons
or TG or whatever you will have one true way across frameworks. if we
start adding small things at the framework level it's going to be a
problem.

For example with pylons there is no auth in the core so where is this
supposed to land? where will the require and the current_* methods be
in pylons? I'm thinking they will end up on a wiki and/or doc page
where you will be required to copy into your project.

SOP is at the core of pylons but it allows you to do a lot of
interesting stuff, so I say it's a necessary evil.

Gustavo Narea

unread,
Nov 25, 2008, 11:15:10 AM11/25/08
to turbogea...@googlegroups.com
Hi, Diez.

On Tuesday November 25, 2008 16:50:08 Diez B. Roggisch wrote:
> I understand that sentiment, and if repoze.wha and what are supposed to be
> independent middlewares - so mote it be.
>
> From and end-user POV however this is a moot point. I don't have the
> environ available in TG2. Django makes these things explicit - TG doesn't.
>
> So not putting them into repoze.what will introduce the need to wrap them
> again, passing the explicit environment which is fetched from some
> thread-local storage (or even the SOP, to keep mulit-apps possible I
> presume, yet I don't know when such a stack is pushed/pop'd).

I don't think it's a big problem for two reasons:
1.- Implementing such functionality is trivial both in the application and
in the framework:
> def get_username():
> from tg import request
> identity = request.environ.get('repoze.who.identity')
> return identity and identity.get('repoze.who.userid')
2.- I think most applications won't use get_groups() or get_permissions()
helpers. Why would you need them if repoze.what already deals with them to
grant/deny access?

*However*, I think it's absolutely necessary a function that returns the
identity dict itself.

Cheers.

Gustavo Narea

unread,
Nov 25, 2008, 11:33:00 AM11/25/08
to turbogea...@googlegroups.com
Hello, Jorge.

On Tuesday November 25, 2008 17:11:24 Jorge Vargas wrote:
> I agree with Diez here.
> if repoze.what's goal is to be framework agnostic then this type of
> thing should be inside repoze.what. That way if you are using pylons
> or TG or whatever you will have one true way across frameworks. if we
> start adding small things at the framework level it's going to be a
> problem.

I don't think so. As I explained in the previous email, it's such a trivial
functionality (if implemented at the application/framework level; this is, if
you have the environ at hand) that I think there will be no difference from
one implementation to another.

> For example with pylons there is no auth in the core so where is this
> supposed to land? where will the require and the current_* methods be
> in pylons? I'm thinking they will end up on a wiki and/or doc page
> where you will be required to copy into your project.

The other issue is that I'm not sure it fits in repoze.what; we're talking
about identity stuff. Keep in mind that repoze.who deals with identification
and authentication (who are you?), while repoze.what deals with authorization
(what can you do?).

repoze.what provides a simple repoze.who metadata provider which is the one
that loads the groups and permissions into repoze.who's identity dict. I think
that providing information about the current user is out of the scope of an
authorization framework, even if such data was loaded by the authorization
framework itself.

But again, I think we definitely need a function that returns the whole
identity.

chrism

unread,
Nov 26, 2008, 5:46:09 AM11/26/08
to TurboGears Trunk

> I agree with Diez here.
> if repoze.what's goal is to be framework agnostic then this type of
> thing should be inside repoze.what. That way if you are using pylons
> or TG or whatever you will have one true way across frameworks. if we
> start adding small things at the framework level it's going to be a
> problem.
>
> For example with pylons there is no auth in the core so where is this
> supposed to land? where will the require and the current_* methods be
> in pylons? I'm thinking they will end up on a wiki and/or doc page
> where you will be required to copy into your project.
>
> SOP is at the core of pylons but it allows you to do a lot of
> interesting stuff, so I say it's a necessary evil.

My $.02: SOP is a hack that works around the fact that the environ
(and other request-local vars) are not passed around but are instead
kept as thread-locals. If you pass them around, it's unnecessary.
Pylons is the only framework that elides this stuff, and is thus the
only framework that requires SOP. So while it's already a necessary
evil for Pylons, it shouldn't need to become a necessary evil for
every framework (or anti-framework, like Werkzeug) that uses
repoze.what.

Mark Ramm

unread,
Nov 26, 2008, 12:22:44 PM11/26/08
to turbogea...@googlegroups.com
>> SOP is at the core of pylons but it allows you to do a lot of
>> interesting stuff, so I say it's a necessary evil.
>
> My $.02: SOP is a hack that works around the fact that the environ
> (and other request-local vars) are not passed around but are instead
> kept as thread-locals.

>If you pass them around, it's unnecessary.

And frankly, I like Ian bicking's suggestion that we keep
request-specific information on the WebOb request object and if
necessary put some "framework hooks" in that populate the extra values
of request. Then there's just one thing that you have to pass around
inside your framework, and you can easily achieve the "stacked" part
just by keeping your request around even after you call some other
WSGI app/middleware.

--Mark Ramm

Reply all
Reply to author
Forward
0 new messages