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

« back to all changes in this revision

Viewing changes to www/dispatch/login.py

  • Committer: mattgiuca
  • Date: 2008-01-09 21:33:56 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:144
Trunk, and all subdirectories with Python files:
    Added to svn:ignore all *.pyc *.pyo, to avoid compiled files
    showing up in svn st / diff / commit lists.
    Added to svn:ignore trampoline/trampoline.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
# Date: 21/12/2007
21
21
 
22
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 conf
29
 
from common import (util, db, caps, forumutil)
30
 
from auth import authenticate, autherror
 
23
 
 
24
from mod_python import (util, Session)
 
25
 
 
26
from auth import authenticate
31
27
 
32
28
def login(req):
33
29
    """Determines whether the user is logged in or not (looking at sessions),
34
 
    and if not, presents the login page. Returns a User object, or None
 
30
    and if not, presents the login page. Returns a String username, or None
35
31
    if not logged in.
36
32
 
37
33
    If the user was already logged in, nothing is written to req. Returns
38
 
    the User object for the logged in user.
 
34
    a string of the username.
39
35
 
40
36
    If the user was not logged in, but manages to authenticate due to
41
37
    included postdata with a valid username/password, throws a redirect
44
40
    If the user is not logged in, or fails to authenticate, a full page is
45
41
    written to req. Returns None. The caller should immediately terminate.
46
42
    """
47
 
    # Get the user details from the session, if already logged in
48
 
    # (None means not logged in yet)
49
 
    login_details = get_user_details(req)
 
43
    session = req.get_session()
50
44
 
51
45
    # Check the session to see if someone is logged in. If so, go with it.
52
46
    # No security is required here. You must have already been authenticated
53
47
    # in order to get a 'login_name' variable in the session.
54
 
    if login_details is not None and login_details.state == "enabled":
55
 
        # Only allow users to authenticate if their account is ENABLED
56
 
        return login_details
57
 
 
58
 
    badlogin = None
59
 
 
 
48
    try:
 
49
        return session['login_name']
 
50
    except KeyError:
 
51
        pass
 
52
 
 
53
    badlogin = False
60
54
    # Check if there is any postdata containing login information
61
 
    if login_details is None and req.method == 'POST':
 
55
    if req.method == 'POST':
62
56
        fields = req.get_fieldstorage()
63
 
        username = fields.getfirst('user')
64
 
        password = fields.getfirst('pass')
 
57
        username = fields.getfirst('user').value
 
58
        password = fields.getfirst('pass').value
65
59
        if username is not None:
66
60
            # From this point onwards, we will be showing an error message
67
61
            # if unsuccessful.
68
62
            # Authenticate
69
 
            if password is None:
70
 
                badlogin = "No password supplied."
 
63
            if (password is not None and
 
64
                authenticate.authenticate(username, password)):
 
65
                # Success - Set the session and redirect to avoid POSTDATA
 
66
                session['login_name'] = username
 
67
                session.save()
 
68
                req.throw_redirect(req.uri)
71
69
            else:
72
 
                try:
73
 
                    login_details = \
74
 
                        authenticate.authenticate(username.value, password.value)
75
 
                # NOTE: Can't catch AuthError, since each module throws a
76
 
                # different identity of AuthError.
77
 
                except Exception, msg:
78
 
                    badlogin = msg
79
 
                if login_details is None:
80
 
                    # Must have got an error. Do not authenticate.
81
 
                    pass
82
 
                elif login_details.pass_expired():
83
 
                    badlogin = "Your password has expired."
84
 
                elif login_details.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['user'] = login_details
90
 
                    session.save()
91
 
                    db.DB().update_user(username.value,
92
 
                                        last_login = time.localtime())
93
 
                    req.add_cookie(forumutil.make_forum_cookie(login_details))
94
 
                    req.throw_redirect(req.uri)
 
70
                badlogin = True
95
71
 
96
 
    # Present the HTML login page
 
72
    # User is not logged in. Present the login box.
 
73
    # Give a 403 Forbidden status, but present a full HTML login page
 
74
    # instead of the usual 403 error.
 
75
    req.status = req.HTTP_FORBIDDEN
97
76
    req.content_type = "text/html"
98
77
    req.title = "Login"
99
78
    req.write_html_head_foot = True
100
79
 
101
 
    # User is not logged in or their account is not enabled.
102
 
    if login_details is not None:
103
 
        # Only possible if no errors occured thus far
104
 
        if login_details.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 = login_details
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, login_details.fullname)
115
 
            return None
116
 
        elif login_details.state == "disabled":
117
 
            # User has authenticated but their account is disabled
118
 
            badlogin = "Your account has been disabled."
119
 
        elif login_details.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
 
            db.DB().update_user(login_details.login, state='no_agreement')
126
 
            req.throw_redirect(req.uri)
127
 
 
128
80
    # Write the HTML for the login page
129
81
    # If badlogin, display an error message indicating a failed login
130
 
    req.write("""<div id="ivle_padding">
131
 
<p>Welcome to the Informatics Virtual Learning Environment.
132
 
   Please log in to access your files and assessment.</p>
133
 
""")
134
 
    if badlogin is not None:
135
 
        req.write("""<p class="error">%s</p>
136
 
""" % badlogin)
 
82
    if badlogin:
 
83
        req.write("""<p class="error">Invalid username or password.</p>""")
137
84
    req.write("""<form action="" method="post">
138
85
  <table>
139
86
    <tr><td>Username:</td><td><input name="user" type="text" /></td></tr>
142
89
  </table>
143
90
</form>
144
91
""")
145
 
    # Write the "Message of the Day" document, if it exists.
146
 
    try:
147
 
        req.sendfile(conf.motd_path)
148
 
    except IOError:
149
 
        pass
150
 
    req.write('</div>\n')
151
92
 
152
93
    return None
153
94
 
154
 
def get_user_details(req):
 
95
def get_username(req):
155
96
    """Gets the name of the logged in user, without presenting a login box
156
97
    or attempting to authenticate.
157
98
    Returns None if there is no user logged in.
162
103
    # No security is required here. You must have already been authenticated
163
104
    # in order to get a 'login_name' variable in the session.
164
105
    try:
165
 
        return session['user']
 
106
        return session['login_name']
166
107
    except KeyError:
167
108
        return None
168
 
 
169
 
def present_tos(req, fullname):
170
 
    """Present the Terms of Service screen to the user (who has just logged in
171
 
    for the first time and needs to accept these before being admitted into
172
 
    the system).
173
 
    """
174
 
    req.title = "Terms of Service"
175
 
    # Include the JavaScript for the "makeuser" Ajax stuff
176
 
    req.scripts = [
177
 
        "media/common/json2.js",
178
 
        "media/common/util.js",
179
 
        "media/common/tos.js",
180
 
    ]
181
 
    req.write("""<div id="ivle_padding">
182
 
<p>Welcome, <b>%s</b>.</p>
183
 
<p>As this is the first time you have logged into IVLE, you are required to
184
 
accept these Terms of Service before using the system.</p>
185
 
<p>You will be allowed to re-read these terms at any time from the "Help"
186
 
menu.</p>
187
 
<hr />
188
 
""" % fullname)
189
 
    # Write out the text of the license
190
 
    util.send_terms_of_service(req)
191
 
    req.write("""<hr />
192
 
<div id="tos_acceptbuttons">
193
 
<p>Please click "I Accept" to indicate that you have read and understand these
194
 
terms, or click "I Decline" to log out of IVLE.</p>
195
 
<p>
196
 
  <input type="button" value="I Accept" onclick="accept_license()" />
197
 
  <input type="button" value="I Decline" onclick="decline_license()" />
198
 
</p>
199
 
</div>
200
 
""")
201