~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)
1079 by William Grant
Merge setup-refactor branch. This completely breaks existing installations;
32
import ivle.conf
1080.1.65 by William Grant
www/apps/server: Don't use ivle.interpret.get_uid() just to check that a user
33
from ivle.database import User
1099.3.6 by William Grant
Move serve over to the new framework. It sort of works, except not.
34
from ivle.webapp.base.views import BaseView
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.
1099.3.7 by William Grant
Fix ServeView to use the new serveservice protocol.
49
        (login, jail, path) = studpath.url_to_jailpaths(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
102
        (out, err) = ivle.interpret.execute_raw(owner, jail, '/home',
103
                    os.path.join(ivle.conf.share_path, 'services/serveservice'),
104
                    args)
105
        assert not err
106
107
        # Remove the JSON from the front of the response, and decode it.
108
        json = out.split('\n', 1)[0]
109
        out = out[len(json) + 1:]
110
        response = cjson.decode(json)
111
112
        if 'error' in response:
113
            if response['error'] == 'not-found':
114
                raise NotFound()
115
            elif response['error'] in ('is-directory', 'forbidden'):
116
                raise Forbidden()
117
            elif response['error'] == 'is-executable':
118
                # We need to execute it. Just run it with Python in the jail.
119
                interp_object = interpret.interpreter_objects["cgi-python"]
120
                interpret.interpret_file(req, owner, jail, response['path'],
121
                                         interp_object, gentle=True)
122
                return
123
            else:
124
                raise AssertionError('Unknown error from serveservice: %s' %
125
                                     response['error'])
126
127
        if download:
128
            req.headers_out["Content-Disposition"] = \
129
                         "attachment; filename=%s" % response['name']
130
        req.content_type = response['type']
131
        req.write(out)
93 by mattgiuca
New directory hierarchy.
132
1099.3.11 by William Grant
Implement a DownloadView. It mostly works.
133
class DownloadView(ServeView):
1099.3.12 by William Grant
Support downloading of a selection of files as a zip.
134
    def __init__(self, req, path):
135
        super(DownloadView, self).__init__(req, path)
136
        filelist = req.get_fieldstorage().getlist('path')
137
        if filelist:
138
            self.files = [f.value for f in filelist]
139
        else:
140
            self.files = None
141
1099.3.11 by William Grant
Implement a DownloadView. It mostly works.
142
    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.
143
        self.serve_file(req, owner, jail, path, download=True,files=self.files)
144
145
class PublicServeView(ServeView):
146
    def __init__(self, req, path):
1099.1.148 by William Grant
Fix public mode serve authorization to traverse to the deepest directory,
147
        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.
148
        super(PublicServeView, self).__init__(req, path)
149
150
    def authorize(self, req):
262 by mattgiuca
studpath: Added "authorize" function which checks the logged in user against
151
        # 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.
152
        # files, BUT the accessed file needs to have a file named '.published'
153
        # in its parent directory.
154
        return studpath.authorize_public(req)
155
156
class Plugin(ViewPlugin, PublicViewPlugin):
1099.3.6 by William Grant
Move serve over to the new framework. It sort of works, except not.
157
    urls = [
1099.3.11 by William Grant
Implement a DownloadView. It mostly works.
158
        ('serve/*path', ServeView),
159
        ('download/*path', DownloadView),
1099.3.6 by William Grant
Move serve over to the new framework. It sort of works, except not.
160
    ]
1099.1.147 by William Grant
Provide a public serve view. Under /~user/path/to/script. How shiny.
161
162
    public_urls = [
163
        ('~*path', PublicServeView),
164
    ]