44
45
import ivle.conf.apps
45
46
from ivle.dispatch.request import Request
46
47
from ivle.dispatch import login
48
from ivle.webapp.base.plugins import ViewPlugin
49
from ivle.webapp.errors import HTTPError, Unauthorized
49
import plugins.console # XXX: Relies on www/ being in the Python path.
51
53
# XXX List of plugins, which will eventually be read in from conf
55
'ivle.webapp.core#Plugin',
53
56
'ivle.webapp.admin.user#Plugin',
54
57
'ivle.webapp.tutorial#Plugin',
55
58
'ivle.webapp.admin.subject#Plugin',
56
'ivle.webapp.browser#Plugin',
59
'ivle.webapp.filesystem.browser#Plugin',
60
'ivle.webapp.filesystem.diff#Plugin',
61
'ivle.webapp.filesystem.svnlog#Plugin',
57
62
'ivle.webapp.groups#Plugin',
58
63
'ivle.webapp.console#Plugin',
59
64
'ivle.webapp.security#Plugin',
65
'ivle.webapp.media#Plugin',
66
'ivle.webapp.forum#Plugin',
67
'ivle.webapp.help#Plugin',
68
'ivle.webapp.tos#Plugin',
69
'ivle.webapp.userservice#Plugin',
62
def get_routes_mapper():
72
def generate_route_mapper(view_plugins):
64
74
Build a Mapper object for doing URL matching using 'routes', based on the
75
given plugin registry.
67
77
m = routes.Mapper(explicit=True)
68
for pluginstr in plugins_HACK:
69
plugin_path, classname = pluginstr.split('#')
70
# Load the plugin module from somewhere in the Python path
71
# (Note that plugin_path is a fully-qualified Python module name).
72
plugin = getattr(__import__(plugin_path, fromlist=[classname]),
78
for plugin in view_plugins:
74
79
# Establish a URL pattern for each element of plugin.urls
80
assert hasattr(plugin, 'urls'), "%r does not have any urls" % plugin
75
81
for url in plugin.urls:
77
83
view_class = url[1]
79
85
m.connect(routex, view=view_class, **kwargs_dict)
88
def get_plugin(pluginstr):
89
plugin_path, classname = pluginstr.split('#')
90
# Load the plugin module from somewhere in the Python path
91
# (Note that plugin_path is a fully-qualified Python module name).
93
getattr(__import__(plugin_path, fromlist=[classname]), classname))
83
96
"""Handles a request which may be to anywhere in the site except media.
84
97
Intended to be called by mod_python, as a handler.
117
130
# Hack? Try and get the user login early just in case we throw an error
118
131
# (most likely 404) to stop us seeing not logged in even when we are.
119
132
if not req.publicmode:
120
req.user = login.get_user_details(req)
133
user = login.get_user_details(req)
135
# Don't set the user if it is disabled or hasn't accepted the ToS.
136
if user and user.valid:
122
139
### BEGIN New plugins framework ###
123
140
# XXX This should be done ONCE per Python process, not per request.
124
141
# (Wait till WSGI)
125
# XXX No authentication is done here
126
req.mapper = get_routes_mapper()
142
req.plugins = dict([get_plugin(pluginstr) for pluginstr in plugins_HACK])
143
# Index the plugins by base class
144
req.plugin_index = {}
145
for plugin in req.plugins.values():
146
# Getmro returns a tuple of all the super-classes of the plugin
147
for base in inspect.getmro(plugin):
148
if base not in req.plugin_index:
149
req.plugin_index[base] = []
150
req.plugin_index[base].append(plugin)
151
req.reverse_plugins = dict([(v, k) for (k, v) in req.plugins.items()])
152
req.mapper = generate_route_mapper(req.plugin_index[ViewPlugin])
127
154
matchdict = req.mapper.match(req.uri)
128
155
if matchdict is not None:
129
156
viewcls = matchdict['view']
131
158
# (The latter two seem to be built-in, and we don't want them).
132
159
kwargs = matchdict.copy()
133
160
del kwargs['view']
134
# Instantiate the view, which should be a BaseView class
135
view = viewcls(req, **kwargs)
162
# Instantiate the view, which should be a BaseView class
163
view = viewcls(req, **kwargs)
165
# Check that the request (mainly the user) is permitted to access
167
if not view.authorize(req):
172
# A view explicitly raised an HTTP error. Respect it.
175
# Try to find a custom error view.
176
if hasattr(viewcls, 'get_error_view'):
177
errviewcls = viewcls.get_error_view(e)
182
errview = errviewcls(req, e)
191
# A non-HTTPError appeared. We have an unknown exception. Panic.
192
handle_unknown_exception(req, *sys.exc_info())
140
197
### END New plugins framework ###
142
199
# Check req.app to see if it is valid. 404 if not.
166
223
# This will either return a User object, None, or perform a redirect
167
224
# which we will not catch here.
168
225
if app.requireauth:
169
req.user = login.login(req)
170
226
logged_in = req.user is not None
172
req.user = login.get_user_details(req)
230
assert logged_in # XXX
176
233
# Keep the user's session alive by writing to the session object.
177
234
# req.get_session().save()
206
263
# When done, write out the HTML footer if the app has requested it
207
264
if req.write_html_head_foot:
208
# Show the console if required
209
if logged_in and app.useconsole:
210
plugins.console.present(req, windowpane=True)
211
265
html.write_html_foot(req)
213
267
# Note: Apache will not write custom HTML error messages here.