I did a quick test which seems to work :
class Essai(object):
def requires_login(self, next=None, message="login required" ):
"""
decorator that prevents access to action if not logged in
"""
> def decorator(action):
> def f(*a, **b):
*pnext = next*
self.flash = message
if not pnext:
pnext = "defaulturl"
print pnext, self.flash
return action(*a, **b)
f.__doc__ = action.__doc__
f.__name__ = action.__name__
f.__dict__.update(action.__dict__)
return f
> return decorator
>
> e=Essai()
> @e.requires_login()
def myfunc(x,y):
print "myfunc",x,y
> @e.requires_login(next="other_next", message = "failed")
def myfunc2(x,y):
print "myfunc2",x,y
> myfunc(0,"c")
myfunc2(1,"a")
Which output :
> defaulturl login required
myfunc 0 c
other_next failed
myfunc2 1 a
But you're right, we have to be careful with the variable scope. Without
copying the decorator parameter into the local scope (see pnext), I
get UnboundLocalError: local variable 'next' referenced before
assignment....
-Mathieu
On Sun, May 30, 2010 at 01:57, mdipierro <[email protected]> wrote:
> I need to try this. there is a potential issue wich scope of
> variables.
>
> On May 29, 11:09 am, Mathieu Clabaut <[email protected]>
> wrote:
> > Did i miss something ot the following would be ok ?
> >
> > def requires_login(self, next=None,
> message=self.message.access_denied
> > ):
> > """
> > decorator that prevents access to action if not logged in
> > """
> >
> > def decorator(action):
> >
> > def f(*a, **b):
> >
> > if not self.basic() and not self.is_logged_in():
> > request = self.environment.request
> > self.environment.session.flash = message
> > if not next:
> > next = self.settings.login_url + '?_next=' + \
> >
> > urllib.quote(URL(r=request,args=request.args,
> > vars=request.get_vars))
> > redirect(next)
> > return action(*a, **b)
> > f.__doc__ = action.__doc__
> > f.__name__ = action.__name__
> > f.__dict__.update(action.__dict__)
> > return f
> >
> > return decorator
> >
> > On Tue, May 25, 2010 at 01:07, Massimo Di Pierro <
> [email protected]>wrote:
> >
> > > It would be nice to be able to pass the following arguments to
> >
> > > @auth.requires_login(next=URL(...),message=T(...))
> >
> > > where next is the url to redirect to in case of no login. message is
> the
> > > message to be displayed.
> > > If somebody has time and wants to take a crack at it, let me know. It
> > > should be possible by modifying only the requires_login method.
> > > The problem is passing the arguments from the decorator to the function
> > > being returned.
> >
> > > Once the problem is solved we can add the feature to
> requires_membership
> > > and requires_permissions.
> >
> > > Massimo
>