75
75
# directory seen when fileservice has no arguments or path). Paths without a
76
76
# slash are taken relative to the specified path.
78
# action=rm: Delete a file or directory (recursively).
79
# path: The path to the file or directory to delete.
78
# action=remove: Delete a file(s) or directory(s) (recursively).
79
# path: The path to the file or directory to delete. Can be specified
80
81
# TODO: More actions.
99
100
# application/json is the "best" content type but is not good for
100
101
# debugging because Firefox just tries to download it
101
mime_dirlisting = "text/plain"
102
mime_dirlisting = "text/html"
102
103
#mime_dirlisting = "application/json"
105
class ActionError(Exception):
106
"""Represents an error processing an action. This can be
107
raised by any of the action functions, and will be caught
108
by the top-level handler, put into the HTTP response field,
111
Important Security Consideration: The message passed to this
112
exception will be relayed to the client.
105
117
"""Handler for the File Services application."""
112
124
# side-effects on the server.
115
if req.method == 'POST':
127
if True or req.method == 'POST':
116
128
fields = req.get_fieldstorage()
117
129
action = fields.getfirst('action')
119
131
if action is not None:
120
handle_action(req, action, fields)
133
handle_action(req, action, fields)
134
except ActionError, message:
135
req.headers_out['X-IVLE-Action-Error'] = str(message)
122
137
handle_return(req)
128
143
writes the X-IVLE-Action-Error header to the request object. Otherwise,
129
144
does not touch the request object. Does NOT write any bytes in response.
146
May throw an ActionError. The caller should put this string into the
147
X-IVLE-Action-Error header, and then continue normally.
131
149
action: String, the action requested. Not sanitised.
132
150
fields: FieldStorage object containing all arguments passed.
135
path = fields.getfirst('path')
136
# TODO: Delete the file
137
# Do an SVN rm if possible
152
if action == "remove":
153
path = fields.getlist('path')
154
action_remove(req, path)
156
# Default, just send an error but then continue
157
raise ActionError("Unknown action")
140
159
def handle_return(req):
141
160
"""Perform the "return" part of the response.
249
268
# Can't get any more information so just return d
251
270
return filename, d
274
def actionpath_to_local(req, path):
275
"""Determines the local path upon which an action is intended to act.
276
Note that fileservice actions accept two paths: the request path,
277
and the "path" argument given to the action.
278
According to the rules, if the "path" argument begins with a '/' it is
279
relative to the user's home; if it does not, it is relative to the
282
This resolves the path, given the request and path argument.
284
May raise an ActionError("Invalid path"). The caller is expected to
285
let this fall through to the top-level handler, where it will be
286
put into the HTTP response field. Never returns None.
290
elif len(path) > 0 and path[0] == os.sep:
291
# Relative to student home
294
# Relative to req.path
295
path = os.path.join(req.path, path)
297
_, r = studpath.url_to_local(path)
299
raise ActionError("Invalid path")
302
def action_remove(req, paths):
303
# TODO: Do an SVN rm if the file is versioned.
304
"""Removes a list of files or directories."""
307
path = actionpath_to_local(req, path)
314
raise ActionError("Could not delete the file specified")
317
"Could not delete one or more of the files specified")