18
18
# Author: Will Grant, Nick Chadwick
23
import mod_python.Cookie
25
# This needs to be importable from outside Apache.
29
import ivle.dispatch.login
30
from ivle.auth import authenticate, AuthError
20
31
from ivle.webapp.base.xhtml import XHTMLView
32
from ivle.webapp.base.plugins import CookiePlugin
33
from ivle.dispatch.login import get_user_details
35
class LoginView(XHTMLView):
36
'''A view to allow a user to log in.'''
37
template = 'login.html'
39
def authorize(self, req):
42
def populate(self, req, ctx):
43
fields = req.get_fieldstorage()
44
nexturl = fields.getfirst('url')
49
# We are already logged in. Don't bother logging in again.
50
# Note that req.user is None even if we are 'logged in', if the user is
52
if req.user is not None:
53
req.throw_redirect(nexturl)
55
ctx['path'] = ivle.util.make_path('+login') + \
56
'?' + urllib.urlencode([('url', nexturl)])
58
# If this succeeds, the user is invalid.
59
user = get_user_details(req)
61
if user.state == "no_agreement":
62
# Authenticated, but need to accept the ToS. Send them there.
63
# IMPORTANT NOTE FOR HACKERS: You can't simply disable this
64
# if you are not planning to display a ToS page - the ToS
65
# acceptance process actually calls usrmgt to create the user
66
# jails and related stuff.
67
req.throw_redirect(ivle.util.make_path('+tos') + \
68
'?' + urllib.urlencode([('url', nexturl)]))
69
elif user.state == "pending":
70
# FIXME: this isn't quite the right answer, but it
71
# should be more robust in the short term.
72
session = req.get_session()
75
user.state = u'no_agreement'
77
req.throw_redirect(nexturl)
79
if req.method == "POST":
80
# While req.user is normally set to get_user_details, it won't set
81
# it if the account isn't valid. So we get it ourselves.
82
user = get_user_details(req)
86
username = fields.getfirst('user')
87
password = fields.getfirst('pass')
88
if username is not None:
89
# From this point onwards, we will be showing an error message
93
badlogin = "No password supplied."
97
user = authenticate.authenticate(req.store,
98
username.value, password.value)
99
except AuthError, msg:
102
# Must have got an error. Do not authenticate.
103
# The except: above will have set a message.
106
# Success - Set the session and redirect to the URL.
107
session = req.get_session()
108
session['login'] = user.login
110
user.last_login = datetime.datetime.now()
113
# Create cookies for plugins that might request them.
114
for plugin in req.plugin_index[CookiePlugin]:
115
for cookie in plugin.cookies:
116
# The function can be None if they just need to be
118
if plugin.cookies[cookie] is not None:
119
req.add_cookie(mod_python.Cookie.Cookie(cookie,
120
plugin.cookies[cookie](user), path='/'))
122
req.throw_redirect(nexturl)
125
# Render the login form with the error message.
126
ctx['error'] = badlogin
23
129
class LogoutView(XHTMLView):
24
130
'''A view to log the current session out.'''
25
131
template = 'logout.html'
27
133
def authorize(self, req):
28
return req.user is not None
134
# This can be used by any authenticated user, even if they haven't
135
# accepted the ToS yet.
136
return ivle.dispatch.login.get_user_details(req) is not None
30
138
def populate(self, req, ctx):
31
139
if req.method == "POST":
34
ctx['path'] = ivle.util.make_path('logout')
142
ctx['path'] = ivle.util.make_path('+logout')