25
25
# This needs to be importable from outside Apache.
29
import ivle.dispatch.login
28
import ivle.pulldown_subj
29
import ivle.webapp.security
30
30
from ivle.auth import authenticate, AuthError
31
31
from ivle.webapp.base.xhtml import XHTMLView
32
32
from ivle.webapp.base.plugins import CookiePlugin
33
from ivle.dispatch.login import get_user_details
35
34
class LoginView(XHTMLView):
36
35
'''A view to allow a user to log in.'''
44
43
fields = req.get_fieldstorage()
45
44
nexturl = fields.getfirst('url')
46
# XXX Warning that Internet Explorer is unsupported
47
# Test if the user is in Internet Explorer
49
useragent = req.headers_in['User-Agent']
50
# A bit of very basic UA string detection
51
ctx['msie'] = ('MSIE' in useragent
52
and 'AppleWebKit' not in useragent
53
and 'Gecko' not in useragent
54
and 'Opera' not in useragent)
47
58
if nexturl is None:
50
# We are already logged in. Don't bother logging in again.
61
# We are already logged in. If it is a POST, they might be trying to
62
# clobber their session with some new credentials. That's their own
63
# business, so we let them do it. Otherwise, we don't bother prompting
64
# and just redirect to the destination.
51
65
# Note that req.user is None even if we are 'logged in', if the user is
53
if req.user is not None:
66
# invalid (state != enabled, or expired).
67
if req.method != "POST" and req.user is not None:
54
68
req.throw_redirect(nexturl)
56
ctx['path'] = ivle.util.make_path('+login') + \
57
'?' + urllib.urlencode([('url', nexturl)])
70
# Don't give any URL if we want /.
74
query_string = '?url=' + urllib.quote(nexturl, safe="/~")
76
ctx['path'] = req.make_path('+login') + query_string
59
78
# If this succeeds, the user is invalid.
60
user = get_user_details(req)
79
user = ivle.webapp.security.get_user_details(req)
61
80
if user is not None:
62
81
if user.state == "no_agreement":
63
82
# Authenticated, but need to accept the ToS. Send them there.
65
84
# if you are not planning to display a ToS page - the ToS
66
85
# acceptance process actually calls usrmgt to create the user
67
86
# jails and related stuff.
68
req.throw_redirect(ivle.util.make_path('+tos') + \
69
'?' + urllib.urlencode([('url', nexturl)]))
87
req.throw_redirect(req.make_path('+tos') + query_string)
70
88
elif user.state == "pending":
71
89
# FIXME: this isn't quite the right answer, but it
72
90
# should be more robust in the short term.
80
98
if req.method == "POST":
81
99
# While req.user is normally set to get_user_details, it won't set
82
100
# it if the account isn't valid. So we get it ourselves.
83
user = get_user_details(req)
101
user = ivle.webapp.security.get_user_details(req)
98
user = authenticate.authenticate(req.store,
99
username.value, password.value)
116
# Username is case insensitive
117
user = authenticate.authenticate(req.config, req.store,
118
username.value.lower(), password.value)
100
119
except AuthError, msg:
108
127
session = req.get_session()
109
128
session['login'] = user.login
111
131
user.last_login = datetime.datetime.now()
114
133
# Create cookies for plugins that might request them.
115
134
for plugin in req.config.plugin_index[CookiePlugin]:
120
139
req.add_cookie(mod_python.Cookie.Cookie(cookie,
121
140
plugin.cookies[cookie](user), path='/'))
142
# Add any new enrolments.
143
ivle.pulldown_subj.enrol_user(req.config, req.store, user)
123
146
req.throw_redirect(nexturl)
125
148
# We didn't succeed.
135
158
def authorize(self, req):
136
159
# This can be used by any authenticated user, even if they haven't
137
160
# accepted the ToS yet.
138
return ivle.dispatch.login.get_user_details(req) is not None
161
return ivle.webapp.security.get_user_details(req) is not None
140
163
def populate(self, req, ctx):
141
164
if req.method == "POST":
144
ctx['path'] = ivle.util.make_path('+logout')
167
ctx['path'] = req.make_path('+logout')