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

« back to all changes in this revision

Viewing changes to www/dispatch/__init__.py

  • Committer: chadnickbok
  • Date: 2009-01-13 05:33:58 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:1108
Updated the settings page to require the old password
when updating the password. Note that this field
is not shown when using ldap authentication

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
# Then passes the request along to the appropriate ivle app.
28
28
 
29
29
import mod_python
30
 
from mod_python import apache
 
30
from mod_python import apache, Cookie
31
31
 
 
32
import sys
32
33
import os
33
34
import os.path
 
35
import urllib
 
36
 
34
37
import conf
35
38
import conf.apps
 
39
import conf.conf
36
40
import apps
37
41
 
38
42
from request import Request
39
43
import html
 
44
import cgi
40
45
import login
41
 
from common import util
 
46
from common import (util, forumutil)
 
47
import traceback
 
48
import plugins.console
 
49
import logging
 
50
import socket
 
51
import time
42
52
 
43
53
def handler(req):
44
54
    """Handles a request which may be to anywhere in the site except media.
48
58
    """
49
59
    # Make the request object into an IVLE request which can be passed to apps
50
60
    apachereq = req
51
 
    req = Request(req, html.write_html_head)
 
61
    try:
 
62
        req = Request(req, html.write_html_head)
 
63
    except Exception:
 
64
        # Pass the apachereq to error reporter, since ivle req isn't created
 
65
        # yet.
 
66
        handle_unknown_exception(apachereq, *sys.exc_info())
 
67
        # Tell Apache not to generate its own errors as well
 
68
        return apache.OK
 
69
 
 
70
    # Run the main handler, and catch all exceptions
 
71
    try:
 
72
        return handler_(req, apachereq)
 
73
    except mod_python.apache.SERVER_RETURN:
 
74
        # An apache error. We discourage these, but they might still happen.
 
75
        # Just raise up.
 
76
        raise
 
77
    except Exception:
 
78
        handle_unknown_exception(req, *sys.exc_info())
 
79
        # Tell Apache not to generate its own errors as well
 
80
        return apache.OK
 
81
 
 
82
def handler_(req, apachereq):
 
83
    """
 
84
    Nested handler function. May raise exceptions. The top-level handler is
 
85
    just used to catch exceptions.
 
86
    Takes both an IVLE request and an Apache req.
 
87
    """
 
88
    # Hack? Try and get the user login early just in case we throw an error
 
89
    # (most likely 404) to stop us seeing not logged in even when we are.
 
90
    if not req.publicmode:
 
91
        req.user = login.get_user_details(req)
52
92
 
53
93
    # Check req.app to see if it is valid. 404 if not.
54
94
    if req.app is not None and req.app not in conf.apps.app_url:
55
 
        # Maybe it is a special app!
56
 
        if req.app == 'logout':
57
 
            logout(req)
58
 
        else:
59
 
            # TODO: Nicer 404 message?
60
 
            req.throw_error(Request.HTTP_NOT_FOUND)
 
95
        req.throw_error(Request.HTTP_NOT_FOUND,
 
96
            "There is no application called %s." % repr(req.app))
 
97
 
 
98
    # Special handling for public mode - only allow the public app, call it
 
99
    # and get out.
 
100
    # NOTE: This will not behave correctly if the public app uses
 
101
    # write_html_head_foot, but "serve" does not.
 
102
    if req.publicmode:
 
103
        if req.app != conf.apps.public_app:
 
104
            req.throw_error(Request.HTTP_FORBIDDEN,
 
105
                "This application is not available on the public site.")
 
106
        app = conf.apps.app_url[conf.apps.public_app]
 
107
        apps.call_app(app.dir, req)
 
108
        return req.OK
61
109
 
62
110
    # app is the App object for the chosen app
63
111
    if req.app is None:
64
 
        app = conf.apps.app_url[conf.default_app]
 
112
        app = conf.apps.app_url[conf.apps.default_app]
65
113
    else:
66
114
        app = conf.apps.app_url[req.app]
67
115
 
68
116
    # Check if app requires auth. If so, perform authentication and login.
 
117
    # This will either return a User object, None, or perform a redirect
 
118
    # which we will not catch here.
69
119
    if app.requireauth:
70
 
        req.username = login.login(req)
71
 
        logged_in = req.username is not None
 
120
        req.user = login.login(req)
 
121
        logged_in = req.user is not None
72
122
    else:
73
 
        req.username = login.get_username(req)
 
123
        req.user = login.get_user_details(req)
74
124
        logged_in = True
75
125
 
76
126
    if logged_in:
 
127
        # Keep the user's session alive by writing to the session object.
 
128
        # req.get_session().save()
 
129
        # Well, it's a fine idea, but it creates considerable grief in the
 
130
        # concurrent update department, so instead, we'll just make the
 
131
        # sessions not time out.
 
132
        req.get_session().unlock()
 
133
 
77
134
        # If user did not specify an app, HTTP redirect to default app and
78
135
        # exit.
79
136
        if req.app is None:
80
 
            req.throw_redirect(util.make_path(conf.default_app))
 
137
            req.throw_redirect(util.make_path(conf.apps.default_app))
81
138
 
82
139
        # Set the default title to the app's tab name, if any. Otherwise URL
83
140
        # name.
88
145
 
89
146
        # Call the specified app with the request object
90
147
        apps.call_app(app.dir, req)
 
148
 
91
149
    # if not logged in, login.login will have written the login box.
92
150
    # Just clean up and exit.
93
151
 
98
156
 
99
157
    # When done, write out the HTML footer if the app has requested it
100
158
    if req.write_html_head_foot:
 
159
        # Show the console if required
 
160
        if logged_in and app.useconsole:
 
161
            plugins.console.present(req, windowpane=True)
101
162
        html.write_html_foot(req)
102
163
 
103
164
    # Note: Apache will not write custom HTML error messages here.
104
165
    # Use req.throw_error to do that.
105
166
    return req.OK
106
167
 
107
 
def logout(req):
108
 
    """Log out the current user (if any) by destroying the session state.
109
 
    Then redirect to the top-level IVLE page."""
110
 
    session = req.get_session()
111
 
    session.invalidate()
112
 
    session.delete()
113
 
    req.throw_redirect(util.make_path(''))
 
168
def handle_unknown_exception(req, exc_type, exc_value, exc_traceback):
 
169
    """
 
170
    Given an exception that has just been thrown from IVLE, print its details
 
171
    to the request.
 
172
    This is a full handler. It assumes nothing has been written, and writes a
 
173
    complete HTML page.
 
174
    req: May be EITHER an IVLE req or an Apache req.
 
175
    IVLE reqs may have the HTML head/foot written (on a 400 error), but
 
176
    the handler code may pass an apache req if an exception occurs before
 
177
    the IVLE request is created.
 
178
    """
 
179
    req.content_type = "text/html"
 
180
    logfile = os.path.join(conf.conf.log_path, 'ivle_error.log')
 
181
    logfail = False
 
182
    # For some reason, some versions of mod_python have "_server" instead of
 
183
    # "main_server". So we check for both.
 
184
    try:
 
185
        admin_email = apache.main_server.server_admin
 
186
    except AttributeError:
 
187
        try:
 
188
            admin_email = apache._server.server_admin
 
189
        except AttributeError:
 
190
            admin_email = ""
 
191
    try:
 
192
        httpcode = exc_value.httpcode
 
193
        req.status = httpcode
 
194
    except AttributeError:
 
195
        httpcode = None
 
196
        req.status = apache.HTTP_INTERNAL_SERVER_ERROR
 
197
    try:
 
198
        login = req.user.login
 
199
    except AttributeError:
 
200
        login = None
 
201
 
 
202
    # Log File
 
203
    try:
 
204
        for h in logging.getLogger().handlers:
 
205
            logging.getLogger().removeHandler(h)
 
206
        logging.basicConfig(level=logging.INFO,
 
207
            format='%(asctime)s %(levelname)s: ' +
 
208
                '(HTTP: ' + str(req.status) +
 
209
                ', Ref: ' + str(login) + '@' +
 
210
                str(socket.gethostname()) + str(req.uri) +
 
211
                ') %(message)s',
 
212
            filename=logfile,
 
213
            filemode='a')
 
214
    except IOError:
 
215
        logfail = True
 
216
    logging.debug('Logging Unhandled Exception')
 
217
 
 
218
    # We handle 3 types of error.
 
219
    # IVLEErrors with 4xx response codes (client error).
 
220
    # IVLEErrors with 5xx response codes (handled server error).
 
221
    # Other exceptions (unhandled server error).
 
222
    # IVLEErrors should not have other response codes than 4xx or 5xx
 
223
    # (eg. throw_redirect should have been used for 3xx codes).
 
224
    # Therefore, that is treated as an unhandled error.
 
225
 
 
226
    if (exc_type == util.IVLEError and httpcode >= 400
 
227
        and httpcode <= 499):
 
228
        # IVLEErrors with 4xx response codes are client errors.
 
229
        # Therefore, these have a "nice" response (we even coat it in the IVLE
 
230
        # HTML wrappers).
 
231
        
 
232
        req.write_html_head_foot = True
 
233
        req.write_javascript_settings = False
 
234
        req.write('<div id="ivle_padding">\n')
 
235
        try:
 
236
            codename, msg = req.get_http_codename(httpcode)
 
237
        except AttributeError:
 
238
            codename, msg = None, None
 
239
        # Override the default message with the supplied one,
 
240
        # if available.
 
241
        if exc_value.message is not None:
 
242
            msg = exc_value.message
 
243
        if codename is not None:
 
244
            req.write("<h1>Error: %s</h1>\n" % cgi.escape(codename))
 
245
        else:
 
246
            req.write("<h1>Error</h1>\n")
 
247
        if msg is not None:
 
248
            req.write("<p>%s</p>\n" % cgi.escape(msg))
 
249
        else:
 
250
            req.write("<p>An unknown error occured.</p>\n")
 
251
        
 
252
        # Logging
 
253
        logging.info(str(msg))
 
254
        
 
255
        req.write("<p>(HTTP error code %d)</p>\n" % httpcode)
 
256
        if logfail:
 
257
            req.write("<p>Warning: Could not open Error Log: '%s'</p>\n"
 
258
                %cgi.escape(logfile))
 
259
        req.write('</div>\n')
 
260
        html.write_html_foot(req)
 
261
    else:
 
262
        # A "bad" error message. We shouldn't get here unless IVLE
 
263
        # misbehaves (which is currently very easy, if things aren't set up
 
264
        # correctly).
 
265
        # Write the traceback.
 
266
        # If this is a non-4xx IVLEError, get the message and httpcode and
 
267
        # make the error message a bit nicer (but still include the
 
268
        # traceback).
 
269
        # We also need to special-case IVLEJailError, as we can get another
 
270
        # almost-exception out of it.
 
271
 
 
272
        codename, msg = None, None
 
273
 
 
274
        if exc_type is util.IVLEJailError:
 
275
            msg = exc_value.type_str + ": " + exc_value.message
 
276
            tb = 'Exception information extracted from IVLEJailError:\n'
 
277
            tb += urllib.unquote(exc_value.info)
 
278
        else:
 
279
            try:
 
280
                codename, msg = req.get_http_codename(httpcode)
 
281
            except AttributeError:
 
282
                pass
 
283
            # Override the default message with the supplied one,
 
284
            # if available.
 
285
            if hasattr(exc_value, 'message') and exc_value.message is not None:
 
286
                msg = exc_value.message
 
287
                # Prepend the exception type
 
288
                if exc_type != util.IVLEError:
 
289
                    msg = exc_type.__name__ + ": " + msg
 
290
 
 
291
            tb = ''.join(traceback.format_exception(exc_type, exc_value,
 
292
                                                    exc_traceback))
 
293
 
 
294
        # Logging
 
295
        logging.error('%s\n%s'%(str(msg), tb))
 
296
 
 
297
        req.write("""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"                 
 
298
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">                                      
 
299
<html xmlns="http://www.w3.org/1999/xhtml">
 
300
<head><title>IVLE Internal Server Error</title></head>
 
301
<body>
 
302
<h1>IVLE Internal Server Error""")
 
303
        if (codename is not None
 
304
            and httpcode != apache.HTTP_INTERNAL_SERVER_ERROR):
 
305
            req.write(": %s" % cgi.escape(codename))
 
306
        req.write("""</h1>
 
307
<p>An error has occured which is the fault of the IVLE developers or
 
308
administration.</p>
 
309
""")
 
310
        if msg is not None:
 
311
            req.write("<p>%s</p>\n" % cgi.escape(msg))
 
312
        if httpcode is not None:
 
313
            req.write("<p>(HTTP error code %d)</p>\n" % httpcode)
 
314
        req.write("""
 
315
<p>Please report this to <a href="mailto:%s">%s</a> (the system
 
316
administrator). Include the following information:</p>
 
317
""" % (cgi.escape(admin_email), cgi.escape(admin_email)))
 
318
 
 
319
        req.write("<pre>\n%s\n</pre>\n"%cgi.escape(tb))
 
320
        if logfail:
 
321
            req.write("<p>Warning: Could not open Error Log: '%s'</p>\n"
 
322
                %cgi.escape(logfile))
 
323
        req.write("</body></html>")