1
# IVLE - Informatics Virtual Learning Environment
2
# Copyright (C) 2007-2008 The University of Melbourne
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
# GNU General Public License for more details.
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
# Module: dispatch.login
22
# Provides services for checking logins and presenting the login page.
27
from ivle import (util, caps, forumutil)
28
from ivle.auth import authenticate, AuthError
32
"""Determines whether the user is logged in or not (looking at sessions),
33
and if not, presents the login page. Returns a User object, or None
36
If the user was already logged in, nothing is written to req. Returns
37
the User object for the logged in user.
39
If the user was not logged in, but manages to authenticate due to
40
included postdata with a valid username/password, throws a redirect
41
back to the same page (to avoid leaving POSTDATA in the browser).
43
If the user is not logged in, or fails to authenticate, a full page is
44
written to req. Returns None. The caller should immediately terminate.
46
# Get the user details from the session, if already logged in
47
# (None means not logged in yet)
48
user = get_user_details(req)
50
# Check the session to see if someone is logged in. If so, go with it.
51
# No security is required here. You must have already been authenticated
52
# in order to get a 'login_name' variable in the session.
53
if user is not None and user.state == "enabled":
54
# Only allow users to authenticate if their account is ENABLED
59
# Check if there is any postdata containing login information
60
if user is None and req.method == 'POST':
61
fields = req.get_fieldstorage()
62
username = fields.getfirst('user')
63
password = fields.getfirst('pass')
64
if username is not None:
65
# From this point onwards, we will be showing an error message
69
badlogin = "No password supplied."
72
user = authenticate.authenticate(req.store,
73
username.value, password.value)
74
except AuthError, msg:
77
# Must have got an error. Do not authenticate.
79
elif user.password_expired:
80
badlogin = "Your password has expired."
81
elif user.account_expired:
82
badlogin = "Your account has expired."
84
# Success - Set the session and redirect to avoid POSTDATA
85
session = req.get_session()
86
session['login'] = user.login
88
user.last_login = datetime.datetime.now()
90
req.add_cookie(forumutil.make_forum_cookie(user))
91
req.throw_redirect(req.uri)
93
# Present the HTML login page
94
req.content_type = "text/html"
96
req.write_html_head_foot = True
98
# User is not logged in or their account is not enabled.
100
# Only possible if no errors occured thus far
101
if user.state == "no_agreement":
102
# User has authenticated but has not accepted the TOS.
103
# Present them with the TOS page.
104
# First set their username for display at the top, but make sure
105
# the apps tabs are not displayed
107
# IMPORTANT NOTE FOR HACKERS: You can't simply disable this check
108
# if you are not planning to display a TOS page - the TOS
109
# acceptance process actually calls usermgt to create the user
110
# jails and related stuff.
111
present_tos(req, user.fullname)
113
elif user.state == "disabled":
114
# User has authenticated but their account is disabled
115
badlogin = "Your account has been disabled."
116
elif user.state == "pending":
117
# FIXME: this isn't quite the right answer, but it
118
# should be more robust in the short term.
119
session = req.get_session()
122
user.state = u'no_agreement'
124
req.throw_redirect(req.uri)
126
# Write the HTML for the login page
127
# If badlogin, display an error message indicating a failed login
128
req.write("""<div id="ivle_padding">
129
<p>Welcome to the Informatics Virtual Learning Environment.
130
Please log in to access your files and assessment.</p>
132
if badlogin is not None:
133
req.write("""<p class="error">%s</p>
135
req.write("""<form action="" method="post">
137
<tr><td>Username:</td><td><input name="user" type="text" /></td></tr>
138
<tr><td>Password:</td><td><input name="pass" type="password" /></td></tr>
139
<tr><td colspan="2"><input type="submit" value="Login" /></td></tr>
143
# Write the "Message of the Day" document, if it exists.
145
req.sendfile(ivle.conf.motd_path)
148
req.write('</div>\n')
152
def get_user_details(req):
153
"""Gets the name of the logged in user, without presenting a login box
154
or attempting to authenticate.
155
Returns None if there is no user logged in.
157
session = req.get_session()
159
# Check the session to see if someone is logged in. If so, go with it.
161
login = session['login']
165
# Get the full User object from the db associated with this login
166
return ivle.database.User.get_by_login(req.store, login)
168
def present_tos(req, fullname):
169
"""Present the Terms of Service screen to the user (who has just logged in
170
for the first time and needs to accept these before being admitted into
173
req.title = "Terms of Service"
174
# Include the JavaScript for the "makeuser" Ajax stuff
176
"media/common/json2.js",
177
"media/common/util.js",
178
"media/common/tos.js",
180
req.write("""<div id="ivle_padding">
181
<p>Welcome, <b>%s</b>.</p>
182
<p>As this is the first time you have logged into IVLE, you are required to
183
accept these Terms of Service before using the system.</p>
184
<p>You will be allowed to re-read these terms at any time from the "Help"
188
# Write out the text of the license
189
util.send_terms_of_service(req)
191
<div id="tos_acceptbuttons">
192
<p>Please click "I Accept" to indicate that you have read and understand these
193
terms, or click "I Decline" to log out of IVLE.</p>
195
<input type="button" value="I Accept" onclick="accept_license()" />
196
<input type="button" value="I Decline" onclick="decline_license()" />