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

« back to all changes in this revision

Viewing changes to www/dispatch/login.py

  • Committer: stevenbird
  • Date: 2008-02-19 21:17:21 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:512
Renaming of problems to exercises (initial commit).
Fix up module naming (exercises sometimes called tutorials).

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
from common import (util, db, caps, forumutil)
 
29
from auth import authenticate
 
30
 
 
31
def login(req):
 
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
 
34
    if not logged in.
 
35
 
 
36
    If the user was already logged in, nothing is written to req. Returns
 
37
    the User object for the logged in user.
 
38
 
 
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).
 
42
 
 
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.
 
45
    """
 
46
    # Get the user details from the session, if already logged in
 
47
    # (None means not logged in yet)
 
48
    login_details = get_user_details(req)
 
49
 
 
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 login_details is not None and login_details.state == "enabled":
 
54
        # Only allow users to authenticate if their account is ENABLED
 
55
        return login_details
 
56
 
 
57
    badlogin = None
 
58
    login_details = None    # We'll re-auth you
 
59
    # Check if there is any postdata containing login information
 
60
    if 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
 
66
            # if unsuccessful.
 
67
            # Authenticate
 
68
            if password is None:
 
69
                badlogin = "No password supplied."
 
70
            else:
 
71
                try:
 
72
                    login_details = \
 
73
                        authenticate.authenticate(username.value, password.value)
 
74
                except authenticate.AuthError, msg:
 
75
                    badlogin = msg
 
76
                if login_details is None:
 
77
                    # Must have got an error. Do not authenticate.
 
78
                    pass
 
79
                elif login_details.pass_expired():
 
80
                    badlogin = "Your password has expired."
 
81
                elif login_details.acct_expired():
 
82
                    badlogin = "Your account has expired."
 
83
                else:
 
84
                    # Success - Set the session and redirect to avoid POSTDATA
 
85
                    # TODO: Store the User object in session instead of
 
86
                    # individual fields
 
87
                    session = req.get_session()
 
88
                    session['user'] = login_details
 
89
                    session.save()
 
90
                    # XXX time.localtime() (a tuple of ints) is not valid for
 
91
                    # inserting as a TIMESTAMP in the DB.
 
92
                    #db.DB().update_user(username.value,
 
93
                    #                    last_login=time.localtime())
 
94
                    req.add_cookie(forumutil.make_forum_cookie(login_details))
 
95
                    req.throw_redirect(req.uri)
 
96
 
 
97
    # Give a 403 Forbidden status, but present a full HTML login page
 
98
    # instead of the usual 403 error.
 
99
    req.status = req.HTTP_FORBIDDEN
 
100
    req.content_type = "text/html"
 
101
    req.title = "Login"
 
102
    req.write_html_head_foot = True
 
103
 
 
104
    # User is not logged in or their account is not enabled.
 
105
    if login_details is not None:
 
106
        # Only possible if no errors occured thus far
 
107
        if login_details.state == "no_agreement":
 
108
            # User has authenticated but has not accepted the TOS.
 
109
            # Present them with the TOS page.
 
110
            # First set their username for display at the top, but make sure
 
111
            # the apps tabs are not displayed
 
112
            req.user = login_details
 
113
            # IMPORTANT NOTE FOR HACKERS: You can't simply disable this check
 
114
            # if you are not planning to display a TOS page - the TOS
 
115
            # acceptance process actually calls usermgt to create the user
 
116
            # jails and related stuff.
 
117
            present_tos(req, login_details.fullname)
 
118
            return None
 
119
        elif login_details.state == "disabled":
 
120
            # User has authenticated but their account is disabled
 
121
            badlogin = "Your account has been disabled."
 
122
    # Else, just fall through (failed to authenticate)
 
123
 
 
124
    # Write the HTML for the login page
 
125
    # If badlogin, display an error message indicating a failed login
 
126
    req.write("""<div id="ivle_padding">
 
127
<p>Welcome to the Informatics Virtual Learning Environment.
 
128
   Please log in to access your files and assessment.</p>
 
129
""")
 
130
    if badlogin is not None:
 
131
        req.write("""<p class="error">%s</p>
 
132
""" % badlogin)
 
133
    req.write("""<form action="" method="post">
 
134
  <table>
 
135
    <tr><td>Username:</td><td><input name="user" type="text" /></td></tr>
 
136
    <tr><td>Password:</td><td><input name="pass" type="password" /></td></tr>
 
137
    <tr><td colspan="2"><input type="submit" value="Login" /></td></tr>
 
138
  </table>
 
139
</form>
 
140
</div>
 
141
""")
 
142
 
 
143
    return None
 
144
 
 
145
def get_user_details(req):
 
146
    """Gets the name of the logged in user, without presenting a login box
 
147
    or attempting to authenticate.
 
148
    Returns None if there is no user logged in.
 
149
    """
 
150
    session = req.get_session()
 
151
 
 
152
    # Check the session to see if someone is logged in. If so, go with it.
 
153
    # No security is required here. You must have already been authenticated
 
154
    # in order to get a 'login_name' variable in the session.
 
155
    try:
 
156
        return session['user']
 
157
    except KeyError:
 
158
        return None
 
159
 
 
160
def present_tos(req, fullname):
 
161
    """Present the Terms of Service screen to the user (who has just logged in
 
162
    for the first time and needs to accept these before being admitted into
 
163
    the system).
 
164
    """
 
165
    req.title = "Terms of Service"
 
166
    # Include the JavaScript for the "makeuser" Ajax stuff
 
167
    req.scripts = [
 
168
        "media/common/json2.js",
 
169
        "media/common/util.js",
 
170
        "media/common/tos.js",
 
171
    ]
 
172
    req.write("""<div id="ivle_padding">
 
173
<p>Welcome, <b>%s</b>.</p>
 
174
<p>As this is the first time you have logged into IVLE, you are required to
 
175
accept these Terms of Service before using the system.</p>
 
176
<p>You will be allowed to re-read these terms at any time from the "Help"
 
177
menu.</p>
 
178
<hr />
 
179
""" % fullname)
 
180
    # Write out the text of the license
 
181
    license_file = os.path.join(util.make_local_path("apps"),
 
182
                        "tos", "license.html")
 
183
    req.sendfile(license_file)
 
184
    req.write("""<hr />
 
185
<div id="tos_acceptbuttons">
 
186
<p>Please click "I Accept" to indicate that you have read and understand these
 
187
terms, or click "I Decline" to log out of IVLE.</p>
 
188
<p>
 
189
  <input type="button" value="I Accept" onclick="accept_license()" />
 
190
  <input type="button" value="I Decline" onclick="decline_license()" />
 
191
</p>
 
192
</div>
 
193
""")
 
194