login decorator on view classes

24 views
Skip to first unread message

someone1

unread,
Aug 25, 2011, 6:03:42 PM8/25/11
to kay-users
Hello all! I'm new to Kay and hope to use it on my next application.

I have modeled my views around a custom handler class I borrowed off a
Google example project (http://code.google.com/apis/friendconnect/
articles/serverside_integration.html#controller) that does a lot of
prep work I'd need in every call. I tried to use the @login_required
decorator on the <<def get(self):>> functions, but it errors due to an
incorrect number of arguments.

Am I missing something or doing this incorrectly? I just need Google
User authentication for Google App users only (going to deploy my app
to the Google App Store). If any guidance can be give on how to make
this work, I'd greatly appreciate it! If I have to make my own
"middleware" class for this to work, I don't mind, I just don't want
to end up recreating functionality that already exists!

Thanks,
Prateek

Ian Lewis

unread,
Aug 25, 2011, 8:13:02 PM8/25/11
to kay-...@googlegroups.com
Hi,

I'm guessing you have something like this. However, kay's
login_required should adapt to methods
on classes as well so the following should work.

class MyHandler(RequestHandler):

@login_required
def get(self, request, ...):
...


Can you provide a traceback of the error that occurred?

Ian

> --
> You received this message because you are subscribed to the Google Groups "kay-users" group.
> To post to this group, send email to kay-...@googlegroups.com.
> To unsubscribe from this group, send email to kay-users+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/kay-users?hl=en.
>
>

--
Ian

http://www.ianlewis.org/

someone1

unread,
Aug 25, 2011, 9:33:51 PM8/25/11
to kay-users
Hey,

Thanks for the quick reply. Here is the Traceback:

Traceback (most recent call last)
File "....\src\kay\lib\werkzeug\wsgi.py", line 466, in __call__
return app(environ, start_response)
File "....\src\kay\app.py", line 475, in __call__
response = self.get_response(request)
File "....\src\kay\app.py", line 406, in get_response
return self.handle_uncaught_exception(request, exc_info)
File "....\src\kay\app.py", line 372, in get_response
response = view_func(request, **values)
File "....\src\kay\handlers\__init__.py", line 34, in __call__
return func(**kwargs)
TypeError: inner() takes at least 1 argument (0 given)

Here is the code:

import controller
from kay.auth.decorators import *

class ManageAccount(controller.TemplateRenderer):
def get_template(self):
return 'crm/account/account_overview.html'

@login_required
def get(self):
return self.render()

@login_required
def post(self):
return self.render({})

manage_account = ManageAccount()

I don't need to pass in the request parameter since the BaseHandler
class handles this (sets a class attribute).

Thanks,
Prateek
> > For more options, visit this group athttp://groups.google.com/group/kay-users?hl=en.
>
> --
> Ian
>
> http://www.ianlewis.org/

Ian Lewis

unread,
Aug 26, 2011, 3:43:01 AM8/26/11
to kay-...@googlegroups.com
Hi,

On Fri, Aug 26, 2011 at 10:33 AM, someone1 <some...@gmail.com> wrote:
> I don't need to pass in the request parameter since the BaseHandler
> class handles this (sets a class attribute).

Well then, that's your reason right there. login_required expects that
a request is being
passed to your view. You'll either need to pass the request to the get() post()
views, or wrap the handler itself.

handler = login_required(MyHandler())

--
Ian

http://www.ianlewis.org/

someone1

unread,
Aug 26, 2011, 12:39:48 PM8/26/11
to kay-users
Thanks for the reply, however, your suggestion did not work.

I got it to work by adding a second decorator:

def login_required2(func):
def inner(self, *args, **kwargs):
if self.request.user.is_anonymous():
if self.request.is_xhr:
raise Forbidden
else:
return redirect(create_login_url(self.request.url))
return func(self, *args, **kwargs)
update_wrapper(inner, func)
return inner

This seems to have done the trick, though since I'm not very familiar
with decorators or the framework, I'm not sure if this is "best
practice" or will break anything. Could anybody please confirm that
this method will work correctly?

I also did not need to use the "adapt_to_methods" function on this
since its meant for methods. Not sure if there's a way to update the
login_required to detect a method call versus a function call and use
the appropriate request variable.

Thanks,
Prateek

On Aug 26, 3:43 am, Ian Lewis <ianmle...@gmail.com> wrote:
> Hi,
>

Ian Lewis

unread,
Aug 26, 2011, 6:50:35 PM8/26/11
to kay-...@googlegroups.com, kay-users
Hi,

On 2011/08/27, at 1:39, someone1 <some...@gmail.com> wrote:
> Thanks for the reply, however, your suggestion did not work.

Yes I didn't test my code but it should have worked if the class is being called the normal way using the __call__() method. I was assuming you had made your own handler class and was calling it in the normal way with a request argument. i.e. The way kay's generic CRUD class based views work.

> I got it to work by adding a second decorator:
>
> def login_required2(func):
> def inner(self, *args, **kwargs):
> if self.request.user.is_anonymous():
> if self.request.is_xhr:
> raise Forbidden
> else:
> return redirect(create_login_url(self.request.url))
> return func(self, *args, **kwargs)
> update_wrapper(inner, func)
> return inner
>
> This seems to have done the trick, though since I'm not very familiar
> with decorators or the framework, I'm not sure if this is "best
> practice" or will break anything. Could anybody please confirm that
> this method will work correctly?

This looks like it will work correctly by placing it on the methods in your class.

> I also did not need to use the "adapt_to_methods" function on this
> since its meant for methods. Not sure if there's a way to update the
> login_required to detect a method call versus a function call and use
> the appropriate request variable.

The way you are calling holding the request object on the class is more like how webapp does things rather than how Kay does it. That's the reason why login required isn't working. I can't provide working code unless I know how your handler works.

someone1

unread,
Aug 26, 2011, 7:11:40 PM8/26/11
to kay-users
All I did was extend the kay.handlers.BaseHandler and added a few
functions (render, getTemplate, getData). I followed the example of
how to use the class using the Kay DOCS (http://kay-docs.shehas.net/
views.html#class-based-views).

How is my usage different than Kay's? The BaseHandler is the class
that holds the request object in the class, I just followed along.

Thank you for your input, I am trying my best to familiarize myself
with Kay and its model.

-Prateek

On Aug 26, 6:50 pm, Ian Lewis <ianmle...@gmail.com> wrote:
> Hi,
>
Reply all
Reply to author
Forward
0 new messages