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

93 by mattgiuca
New directory hierarchy.
1
# IVLE
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
# App: server
19
# Author: Tom Conway, Matt Giuca
20
# Date: 13/12/2007
21
22
# Serves content to the user (acting as a web server for students files).
23
# For most file types we just serve the static file, but
24
# for python files, we evaluate the python script inside
25
# our safe execution environment.
26
130 by mattgiuca
server: Imports os module correctly (needed by serve_file_directly).
27
import os
93 by mattgiuca
New directory hierarchy.
28
1099.3.7 by William Grant
Fix ServeView to use the new serveservice protocol.
29
import cjson
30
1099.3.15 by William Grant
Remove interpretservice, and clean up ivle.webapp.filesystem.serve.
31
from ivle import (studpath, interpret)
1080.1.65 by William Grant
www/apps/server: Don't use ivle.interpret.get_uid() just to check that a user
32
from ivle.database import User
1099.3.6 by William Grant
Move serve over to the new framework. It sort of works, except not.
33
from ivle.webapp.base.views import BaseView
1099.1.203 by William Grant
Fix PublicServeView authorisation.
34
from ivle.webapp.base.xhtml import XHTMLErrorView
1099.1.147 by William Grant
Provide a public serve view. Under /~user/path/to/script. How shiny.
35
from ivle.webapp.base.plugins import ViewPlugin, PublicViewPlugin
1099.3.6 by William Grant
Move serve over to the new framework. It sort of works, except not.
36
from ivle.webapp.errors import NotFound, Unauthorized, Forbidden
1079 by William Grant
Merge setup-refactor branch. This completely breaks existing installations;
37
1099.3.6 by William Grant
Move serve over to the new framework. It sort of works, except not.
38
class ServeView(BaseView):
39
    def __init__(self, req, path):
40
        self.path = path
41
42
    def authorize(self, req):
43
        return req.user is not None
44
45
    def render(self, req):
46
        """Handler for the Server application which serves pages."""
47
        # Get the username of the student whose work we are browsing, and the
48
        # path on the local machine where the file is stored.
1273 by William Grant
Remove ivle.conf usage from ivle.studpath.
49
        (login, jail, path) = studpath.url_to_jailpaths(req.config, self.path)
1099.3.6 by William Grant
Move serve over to the new framework. It sort of works, except not.
50
51
        owner = User.get_by_login(req.store, login)
52
        if not owner:
53
            # There is no user.
54
            raise NotFound()
55
1099.3.11 by William Grant
Implement a DownloadView. It mostly works.
56
        self.serve(req, owner, jail, path)
57
58
    def serve(self, req, owner, jail, path):
1099.1.147 by William Grant
Provide a public serve view. Under /~user/path/to/script. How shiny.
59
        self.serve_file(req, owner, jail, path)
60
1099.1.169 by William Grant
Don't shadow the dispatch-called authorize() in ServeView.
61
    def path_authorize(self, req):
1099.1.147 by William Grant
Provide a public serve view. Under /~user/path/to/script. How shiny.
62
        """Given a request, checks whether req.username is allowed to
63
        access req.path. Returns True on authz success, False on failure.
1099.1.169 by William Grant
Don't shadow the dispatch-called authorize() in ServeView.
64
65
        This can't be done in the usual authorize(), because we rely on the
66
        jail being mounted.
1099.1.147 by William Grant
Provide a public serve view. Under /~user/path/to/script. How shiny.
67
        """
68
        # Private mode authorization: standard (only logged in user can access
69
        # their own files, and can access all of them).
70
        return studpath.authorize(req, req.user)
71
72
    def serve_file(self, req, owner, jail, path, download=False, files=None):
73
        """Serves a file, using one of three possibilities: interpreting it,
74
        serving it directly, or denying it and returning a 403 Forbidden error.
75
        No return value. Writes to req (possibly throwing an HTTP error).
76
77
        req: An IVLE request object.
78
        owner: The user who owns the file being served.
79
        jail: The user's jail.
80
        path: Filename in the jail.
81
        download:  Should the file be viewed in browser or downloaded
82
        """
83
84
        # We need a no-op trampoline run to ensure that the jail is mounted.
85
        # Otherwise we won't be able to authorise for public mode!
86
        noop_object = interpret.interpreter_objects["noop"]
87
        interpret.interpret_file(req, owner, jail, '', noop_object)
88
89
        # Authorize access. If failure, this throws a HTTP_FORBIDDEN error.
1099.1.169 by William Grant
Don't shadow the dispatch-called authorize() in ServeView.
90
        if not self.path_authorize(req):
1099.1.147 by William Grant
Provide a public serve view. Under /~user/path/to/script. How shiny.
91
            raise Unauthorized()
92
93
        args = []
94
        if download:
95
            args.append('-d')
96
97
        if files and download:
98
            args += [os.path.join(path, f) for f in files]
99
        else:
100
            args.append(path)
101
1224 by William Grant
Remove ivle.conf dependency from ivle.webapp.filesystem.serve.
102
        (out, err) = interpret.execute_raw(owner, jail, '/home',
1250 by William Grant
Unbreak serve - it was depending on the old names of a module.
103
                    os.path.join(req.config['paths']['share'],
1224 by William Grant
Remove ivle.conf dependency from ivle.webapp.filesystem.serve.
104
                                 'services/serveservice'),
1099.1.147 by William Grant
Provide a public serve view. Under /~user/path/to/script. How shiny.
105
                    args)
106
        assert not err
107
108
        # Remove the JSON from the front of the response, and decode it.
109
        json = out.split('\n', 1)[0]
110
        out = out[len(json) + 1:]
111
        response = cjson.decode(json)
112
113
        if 'error' in response:
114
            if response['error'] == 'not-found':
115
                raise NotFound()
116
            elif response['error'] in ('is-directory', 'forbidden'):
117
                raise Forbidden()
118
            elif response['error'] == 'is-executable':
119
                # We need to execute it. Just run it with Python in the jail.
120
                interp_object = interpret.interpreter_objects["cgi-python"]
121
                interpret.interpret_file(req, owner, jail, response['path'],
122
                                         interp_object, gentle=True)
123
                return
124
            else:
125
                raise AssertionError('Unknown error from serveservice: %s' %
126
                                     response['error'])
127
128
        if download:
129
            req.headers_out["Content-Disposition"] = \
130
                         "attachment; filename=%s" % response['name']
131
        req.content_type = response['type']
132
        req.write(out)
93 by mattgiuca
New directory hierarchy.
133
1099.3.11 by William Grant
Implement a DownloadView. It mostly works.
134
class DownloadView(ServeView):
1099.3.12 by William Grant
Support downloading of a selection of files as a zip.
135
    def __init__(self, req, path):
136
        super(DownloadView, self).__init__(req, path)
137
        filelist = req.get_fieldstorage().getlist('path')
138
        if filelist:
139
            self.files = [f.value for f in filelist]
140
        else:
141
            self.files = None
142
1099.3.11 by William Grant
Implement a DownloadView. It mostly works.
143
    def serve(self, req, owner, jail, path):
1099.1.147 by William Grant
Provide a public serve view. Under /~user/path/to/script. How shiny.
144
        self.serve_file(req, owner, jail, path, download=True,files=self.files)
145
146
class PublicServeView(ServeView):
147
    def __init__(self, req, path):
1099.1.148 by William Grant
Fix public mode serve authorization to traverse to the deepest directory,
148
        req.path = path # XXX: Needed because we don't have an app prefix.
1099.1.147 by William Grant
Provide a public serve view. Under /~user/path/to/script. How shiny.
149
        super(PublicServeView, self).__init__(req, path)
150
151
    def authorize(self, req):
1099.1.203 by William Grant
Fix PublicServeView authorisation.
152
        # Only accessible in public mode.
153
        return req.user is None
154
155
    def path_authorize(self, req):
262 by mattgiuca
studpath: Added "authorize" function which checks the logged in user against
156
        # Public mode authorization: any user can access any other user's
1099.1.147 by William Grant
Provide a public serve view. Under /~user/path/to/script. How shiny.
157
        # files, BUT the accessed file needs to have a file named '.published'
158
        # in its parent directory.
159
        return studpath.authorize_public(req)
160
1099.1.203 by William Grant
Fix PublicServeView authorisation.
161
    # We don't want to redirect to a login page on Unauthorized.
162
    @classmethod
163
    def get_error_view(cls, e):
164
        return XHTMLErrorView
165
1099.1.147 by William Grant
Provide a public serve view. Under /~user/path/to/script. How shiny.
166
class Plugin(ViewPlugin, PublicViewPlugin):
1099.3.6 by William Grant
Move serve over to the new framework. It sort of works, except not.
167
    urls = [
1099.3.11 by William Grant
Implement a DownloadView. It mostly works.
168
        ('serve/*path', ServeView),
169
        ('download/*path', DownloadView),
1099.3.6 by William Grant
Move serve over to the new framework. It sort of works, except not.
170
    ]
1099.1.147 by William Grant
Provide a public serve view. Under /~user/path/to/script. How shiny.
171
172
    public_urls = [
173
        ('~*path', PublicServeView),
174
    ]