Just for everyone else's benefit here is how I solved this:
config.add_view('somename.handlers.auth:forbidden',
context='pyramid.exceptions.Forbidden', renderer='somename:templates/
auth/login.mako')
def
forbidden(request):
if not isinstance(request.account,
Account):
return {'error_count': 0, 'came_from':
request.url}
# if an user exists, it means we are not authorized to view this
page
else:
return HTTPForbidden('You are not authorized to view this
page.')
class AuthHandler(BaseHandler):
"""Handles authentication."""
@action(renderer='auth/login.mako')
def login(self):
"""Log the user in based on request."""
request = self.request
login_url = self.path_for('login') # self.path_for() is a
shortcut for self.request.route_path()
goto = request.params.get('came_from', self.referrer) #
self.referrer set in BaseHandler
if goto == login_url:
# never use the login form itself as came_from
goto = self.path_for('home')
login = request.params['login']
password = request.params['password']
account = Account().get_by(**{'email': login})
print 'goto' + goto
if account and account.check_password(password):
headers = remember(self.request, login)
return HTTPFound(location=goto, headers=headers)
else:
self.flash('Invalid email or password.', status='error')
error_count = int(request.params.get('error_count', 0)) +
1
return {'error_count': error_count, 'came_from': goto}
Cheers,
Walden
On Aug 6, 11:48 pm, walden <[email protected]> wrote:
> Thanks for the quick reply. I've already implemented the "user object
> as a request attribute" pattern.
>
> I noticed what you pasted above is a view, is there no good way to do
> this with a handler? I've been sticking with handlers thus far
> because I'm migrating a pylons application.
>
> Would I be better served by just using a view in this case?
>
> Thanks,
> Walden
>
> On Aug 6, 4:09 pm, Mariano Mara <[email protected]> wrote:
>
>
>
>
>
>
>
> > On 06.08.11 12:50, walden wrote:
>
> > > Hello,
>
> > > I've tried searching all over the documentation and the web, but
> > > please pardon me if I missed the answer.
>
> > > I'm in the process of migrating from Pylons 1.0 to Pyramid and I'm
> > > wondering how I should present a login form when using pyramid's
> > > handlers? I only want this login form to display if the user is not
> > > logged in. If they are logged in and don't have access to the page
> > > the forbidden page should be displayed.
>
> > > Ideally I'd like an action to be called to set up some variables in
> > > the template; for example:
>
> > > config.add_handler('display_login', '/login',
> > > 'appname.handlers.auth:AuthHandler', action='display_login',
> > > request_method='GET')
>
> > > @action(renderer='login.mako')
> > > def
> > > display_login(self):
> > > """Display the login
> > > form."""
> > > return {'error_count': 0, 'came_from': self.request.url}
>
> > > I tried using config.add_view() ala:
>
> > > config.add_view(renderer='appname:templates/login.mako',
> > > context='pyramid.exceptions.Forbidden')
>
> > > and it sort of works but it simply renders the template (as expected)
> > > rather than "redirecting" to /login. My guess is that would also
> > > display the login page in the second case where the user is logged in
> > > but does not have access.
>
> > > So how to do this properly? Thanks for your replies and let me know
> > > if you need any other code from my app to help diagnose.
>
> > > Cheers
> > > Walden
>
> > I found the Wiki Flow of Authentication recipe[1] most useful when I was
> > implementing login handlers in my first pyramid project.
> > Basically what I do is:
> > 1- implement the "user object as a request attribute" pattern[2]
> > 2- protect every view that's not for public use and redirect to the
> > Forbidden
> > view
> > 3- In my forbidden view I evaluate is a valid "user" exists as a request
> > attribute. If it does, they are forbidden the access, if it does not
> > exist, I
> > show the login page.
> > e.g.:
>
> > def forbidden(request):
> >
> > _ = request.translate
> >
> > title = _(u'my site')
> > # if no user instance exists in request, we need to log in
> >
> > if not isinstance(request.user, User):
> >
> > login_url = route_url('login', request)
> >
> > referrer = request.url
> >
> > if referrer == login_url:
> >
> > referrer = '/' # never use the login form itself as came_from
> >
> > came_from = request.params.get('came_from', referrer)
> >
> > message = ''
> >
> > login = ''
> >
> > password = ''
> >
> > if 'form.submitted' in request.params:
> >
> > login = request.params['login']
> >
> > password = request.params['password']
> >
> > try:
> >
> > # I check the provided password here
> > if User.login(login, password):
> >
> > headers = remember(request, login)
> >
> > # and check other stuff, such as temporary password, etc
> > usr=DBSession.query(User).get(login)
> >
> > if usr.temporarypass == False:
> >
> > return HTTPFound(location = came_from,
> >
> > headers = headers)
> >
> > else:
> >
> > return HTTPFound(location = request.application_url
> > + '/users/change_pass',
> > headers = headers)
> >
> > except Exception, errmsg:
> >
> > message = errmsg.args[0]
> >
> > return dict(
> >
> > message = message,
> >
> > url = request.application_url + '/login',
> >
> > came_from = came_from,
> >
> > login = login,
> >
> > password = password,
> >
> > title = title
> >
> > )
> >
> > # if an user exists, it means we are not authorized to view this page
> >
> > else:
> >
> > return dict(
> >
> > message = _(u'You are not authorized to view this page'),
> >
> > title = title
> > )
>
> > [1]http://docs.pylonsproject.org/projects/pyramid_cookbook/dev/wiki2_aut...
> > [2]http://docs.pylonsproject.org/projects/pyramid_cookbook/dev/authentic...
--
You received this message because you are subscribed to the Google Groups
"pylons-discuss" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/pylons-discuss?hl=en.