~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to ivle/dispatch/login.py

  • Committer: William Grant
  • Date: 2009-04-28 04:50:39 UTC
  • Revision ID: grantw@unimelb.edu.au-20090428045039-ibb7gwtjrhe9osq3
Populate req.config in a cleaner manner.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# IVLE - Informatics Virtual Learning Environment
2
 
# Copyright (C) 2007-2008 The University of Melbourne
3
 
#
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.
8
 
#
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.
13
 
#
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
17
 
 
18
 
# Module: dispatch.login
19
 
# Author: Matt Giuca
20
 
# Date: 21/12/2007
21
 
 
22
 
# Provides services for checking logins and presenting the login page.
23
 
import os
24
 
import time
25
 
 
26
 
from mod_python import Session
27
 
 
28
 
import ivle.conf
29
 
from ivle import (util, caps, forumutil)
30
 
from ivle.auth import authenticate
31
 
import ivle.database
32
 
from ivle.auth import AuthError
33
 
 
34
 
def login(req):
35
 
    """Determines whether the user is logged in or not (looking at sessions),
36
 
    and if not, presents the login page. Returns a User object, or None
37
 
    if not logged in.
38
 
 
39
 
    If the user was already logged in, nothing is written to req. Returns
40
 
    the User object for the logged in user.
41
 
 
42
 
    If the user was not logged in, but manages to authenticate due to
43
 
    included postdata with a valid username/password, throws a redirect
44
 
    back to the same page (to avoid leaving POSTDATA in the browser).
45
 
 
46
 
    If the user is not logged in, or fails to authenticate, a full page is
47
 
    written to req. Returns None. The caller should immediately terminate.
48
 
    """
49
 
    # Get the user details from the session, if already logged in
50
 
    # (None means not logged in yet)
51
 
    user = get_user_details(req)
52
 
 
53
 
    # Check the session to see if someone is logged in. If so, go with it.
54
 
    # No security is required here. You must have already been authenticated
55
 
    # in order to get a 'login_name' variable in the session.
56
 
    if user is not None and user.state == "enabled":
57
 
        # Only allow users to authenticate if their account is ENABLED
58
 
        return user
59
 
 
60
 
    badlogin = None
61
 
 
62
 
    # Check if there is any postdata containing login information
63
 
    if user is None and req.method == 'POST':
64
 
        fields = req.get_fieldstorage()
65
 
        username = fields.getfirst('user')
66
 
        password = fields.getfirst('pass')
67
 
        if username is not None:
68
 
            # From this point onwards, we will be showing an error message
69
 
            # if unsuccessful.
70
 
            # Authenticate
71
 
            if password is None:
72
 
                badlogin = "No password supplied."
73
 
            else:
74
 
                try:
75
 
                    user = \
76
 
                        authenticate.authenticate(username.value, password.value)
77
 
                except AuthError, msg:
78
 
                    badlogin = msg
79
 
                if user is None:
80
 
                    # Must have got an error. Do not authenticate.
81
 
                    pass
82
 
                elif user.pass_expired():
83
 
                    badlogin = "Your password has expired."
84
 
                elif user.acct_expired():
85
 
                    badlogin = "Your account has expired."
86
 
                else:
87
 
                    # Success - Set the session and redirect to avoid POSTDATA
88
 
                    session = req.get_session()
89
 
                    session['login'] = user.login
90
 
                    session.save()
91
 
                    user.last_login = time.localtime()
92
 
                    req.store.commit()
93
 
                    req.add_cookie(forumutil.make_forum_cookie(user))
94
 
                    req.throw_redirect(req.uri)
95
 
 
96
 
    # Present the HTML login page
97
 
    req.content_type = "text/html"
98
 
    req.title = "Login"
99
 
    req.write_html_head_foot = True
100
 
 
101
 
    # User is not logged in or their account is not enabled.
102
 
    if user is not None:
103
 
        # Only possible if no errors occured thus far
104
 
        if user.state == "no_agreement":
105
 
            # User has authenticated but has not accepted the TOS.
106
 
            # Present them with the TOS page.
107
 
            # First set their username for display at the top, but make sure
108
 
            # the apps tabs are not displayed
109
 
            req.user = user
110
 
            # IMPORTANT NOTE FOR HACKERS: You can't simply disable this check
111
 
            # if you are not planning to display a TOS page - the TOS
112
 
            # acceptance process actually calls usermgt to create the user
113
 
            # jails and related stuff.
114
 
            present_tos(req, user.fullname)
115
 
            return None
116
 
        elif user.state == "disabled":
117
 
            # User has authenticated but their account is disabled
118
 
            badlogin = "Your account has been disabled."
119
 
        elif user.state == "pending":
120
 
            # FIXME: this isn't quite the right answer, but it
121
 
            # should be more robust in the short term.
122
 
            session = req.get_session()
123
 
            session.invalidate()
124
 
            session.delete()
125
 
            user.state = u'no_agreement'
126
 
            req.store.commit()
127
 
            req.throw_redirect(req.uri)
128
 
 
129
 
    # Write the HTML for the login page
130
 
    # If badlogin, display an error message indicating a failed login
131
 
    req.write("""<div id="ivle_padding">
132
 
<p>Welcome to the Informatics Virtual Learning Environment.
133
 
   Please log in to access your files and assessment.</p>
134
 
""")
135
 
    if badlogin is not None:
136
 
        req.write("""<p class="error">%s</p>
137
 
""" % badlogin)
138
 
    req.write("""<form action="" method="post">
139
 
  <table>
140
 
    <tr><td>Username:</td><td><input name="user" type="text" /></td></tr>
141
 
    <tr><td>Password:</td><td><input name="pass" type="password" /></td></tr>
142
 
    <tr><td colspan="2"><input type="submit" value="Login" /></td></tr>
143
 
  </table>
144
 
</form>
145
 
""")
146
 
    # Write the "Message of the Day" document, if it exists.
147
 
    try:
148
 
        req.sendfile(ivle.conf.motd_path)
149
 
    except IOError:
150
 
        pass
151
 
    req.write('</div>\n')
152
 
 
153
 
    return None
154
 
 
155
 
def get_user_details(req):
156
 
    """Gets the name of the logged in user, without presenting a login box
157
 
    or attempting to authenticate.
158
 
    Returns None if there is no user logged in.
159
 
    """
160
 
    session = req.get_session()
161
 
 
162
 
    # Check the session to see if someone is logged in. If so, go with it.
163
 
    try:
164
 
        login = session['login']
165
 
    except KeyError:
166
 
        return None
167
 
 
168
 
    # Get the full User object from the db associated with this login
169
 
    return ivle.database.User.get_by_login(req.store, login)
170
 
 
171
 
def present_tos(req, fullname):
172
 
    """Present the Terms of Service screen to the user (who has just logged in
173
 
    for the first time and needs to accept these before being admitted into
174
 
    the system).
175
 
    """
176
 
    req.title = "Terms of Service"
177
 
    # Include the JavaScript for the "makeuser" Ajax stuff
178
 
    req.scripts = [
179
 
        "media/common/json2.js",
180
 
        "media/common/util.js",
181
 
        "media/common/tos.js",
182
 
    ]
183
 
    req.write("""<div id="ivle_padding">
184
 
<p>Welcome, <b>%s</b>.</p>
185
 
<p>As this is the first time you have logged into IVLE, you are required to
186
 
accept these Terms of Service before using the system.</p>
187
 
<p>You will be allowed to re-read these terms at any time from the "Help"
188
 
menu.</p>
189
 
<hr />
190
 
""" % fullname)
191
 
    # Write out the text of the license
192
 
    util.send_terms_of_service(req)
193
 
    req.write("""<hr />
194
 
<div id="tos_acceptbuttons">
195
 
<p>Please click "I Accept" to indicate that you have read and understand these
196
 
terms, or click "I Decline" to log out of IVLE.</p>
197
 
<p>
198
 
  <input type="button" value="I Accept" onclick="accept_license()" />
199
 
  <input type="button" value="I Decline" onclick="decline_license()" />
200
 
</p>
201
 
</div>
202
 
""")
203