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

« back to all changes in this revision

Viewing changes to ivle/studpath.py

  • Committer: mattgiuca
  • Date: 2008-01-31 01:10:29 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:344
dispatch/ivle CSS foo.
The IVLE header is now a fixed height in em (previously was just intrinsic
    height).
This fixes the "tabs sometimes don't line up with the base line" display
problem, and also makes it much easier to add fixed or absolute content on the
rest of the page.

This was done by separating the tabs out into a separate div and making that
absolutely positioned. Now the header is exactly 5.3em.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# IVLE - Informatics Virtual Learning Environment
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
 
# Module: studpath
19
 
# Author: Matt Giuca
20
 
# Date:   14/12/2007
21
 
 
22
 
# Provides functions for translating URLs into physical locations in the
23
 
# student directories in the local file system.
24
 
# Also performs common authorization, disallowing students from visiting paths
25
 
# they dont own.
26
 
 
27
 
import os
28
 
import stat
29
 
 
30
 
from ivle import util
31
 
 
32
 
def url_to_local(config, urlpath):
33
 
    """Given a URL path (part of a URL query string, see below), returns a
34
 
    tuple of
35
 
        * the username of the student whose directory is being browsed
36
 
        * the absolute path in the file system where that file will be
37
 
            found within the student directories.
38
 
 
39
 
    urlpath: Part of the URL, but only the part *after* the application. For
40
 
    instance, given the URL "/ivle/browse/joe/mydir/myfile", urlpath will
41
 
    be just "joe/mydir/myfile". The expected result is something like
42
 
    ("joe", "/home/informatics/jails/joe/home/joe/mydir/myfile").
43
 
    Note that the actual location is not guaranteed by this interface (this
44
 
    function serves as a single point of control as to how URLs map onto
45
 
    student directories).
46
 
 
47
 
    Returns (None, None) if the path is empty.
48
 
 
49
 
    >>> stubconfig = {'paths': {'jails': {'mounts': '/jails'}}}
50
 
 
51
 
    >>> url_to_local(stubconfig, 'joe/foo/bar/baz')
52
 
    ('joe', '/jails/joe/home/joe/foo/bar/baz')
53
 
    >>> url_to_local(stubconfig, 'joe')
54
 
    ('joe', '/jails/joe/home/joe')
55
 
    >>> url_to_local(stubconfig, 'joe/')
56
 
    ('joe', '/jails/joe/home/joe')
57
 
 
58
 
    We have some protection from various potential attacks. An empty,
59
 
    absolute, or ..-prefixed path yields a special result.
60
 
 
61
 
    >>> url_to_local(stubconfig, '')
62
 
    (None, None)
63
 
    >>> url_to_local(stubconfig, '/foo')
64
 
    (None, None)
65
 
    >>> url_to_local(stubconfig, '../bar')
66
 
    (None, None)
67
 
    """
68
 
 
69
 
    # First normalise the path
70
 
    urlpath = os.path.normpath(urlpath)
71
 
    # Now if it begins with ".." or separator, then it's illegal
72
 
    if urlpath.startswith("..") or urlpath.startswith(os.sep):
73
 
        return (None, None)
74
 
    # Note: User can be a group name. There is absolutely no difference in our
75
 
    # current directory scheme.
76
 
    (user, subpath) = util.split_path(urlpath)
77
 
    if user is None: return (None, None)
78
 
 
79
 
    # Join the user onto 'home' then the full path specified.
80
 
    # This results in the user's name being repeated twice, which is in
81
 
    # accordance with our directory scheme.
82
 
    # (The first time is the name of the jail, the second is the user's home
83
 
    # directory within the jail).
84
 
    path = os.path.join(config['paths']['jails']['mounts'],
85
 
                        user, 'home', urlpath)
86
 
 
87
 
    return (user, path)
88
 
 
89
 
def url_to_jailpaths(config, urlpath):
90
 
    """Given a URL path (part of a URL query string), returns a tuple of
91
 
        * the username of the student whose directory is being browsed
92
 
        * the absolute path where the jail will be located.
93
 
        * the path of the file relative to the jail.
94
 
 
95
 
    urlpath: See urlpath in url_to_local.
96
 
 
97
 
    >>> stubconfig = {'paths': {'jails': {'mounts': '/jails'}}}
98
 
 
99
 
    >>> url_to_jailpaths(stubconfig, "joe/mydir//myfile/.././myfile")
100
 
    ('joe', '/jails/joe', '/home/joe/mydir/myfile')
101
 
    >>> url_to_jailpaths(stubconfig, "")
102
 
    (None, None, None)
103
 
    >>> url_to_jailpaths(stubconfig, "../foo")
104
 
    (None, None, None)
105
 
    >>> url_to_jailpaths(stubconfig, "/foo")
106
 
    (None, None, None)
107
 
    """
108
 
    # First normalise the path
109
 
    urlpath = os.path.normpath(urlpath)
110
 
    # Now if it begins with "..", or is absolute, then it's illegal
111
 
    if urlpath.startswith("..") or os.path.isabs(urlpath):
112
 
        return (None, None, None)
113
 
    # Note: User can be a group name. There is absolutely no difference in our
114
 
    # current directory scheme.
115
 
    (user, subpath) = util.split_path(urlpath)
116
 
    if user is None: return (None, None, None)
117
 
 
118
 
    jail = os.path.join(config['paths']['jails']['mounts'], user)
119
 
    path = to_home_path(urlpath)
120
 
 
121
 
    return (user, jail, path)
122
 
 
123
 
def to_home_path(urlpath):
124
 
    """Given a URL path (eg. joe/foo/bar/baz), returns a path within the home.
125
 
 
126
 
    >>> to_home_path('joe/foo/bar/baz')
127
 
    '/home/joe/foo/bar/baz'
128
 
    >>> to_home_path('joe/foo//bar/baz/../../')
129
 
    '/home/joe/foo'
130
 
    >>> to_home_path('joe/foo//bar/baz/../../../../../') is None
131
 
    True
132
 
    """
133
 
 
134
 
    urlpath = os.path.normpath(urlpath)
135
 
    # If it begins with '..', it's illegal.
136
 
    if urlpath.startswith(".."):
137
 
        return None
138
 
 
139
 
    return os.path.join('/home', urlpath)
140
 
 
141
 
def published(path):
142
 
    """Given a path on the LOCAL file system, determines whether the path has a 
143
 
    '.published' file.  Returns True or False."""
144
 
    publish_file_path = os.path.join(path,'.published')
145
 
    return os.access(publish_file_path,os.F_OK)
146
 
 
147
 
def worldreadable(path):
148
 
    """Given a path on the LOCAL file system, determines whether the path is 
149
 
    world readble. Returns True or False."""
150
 
    try:
151
 
        mode = os.stat(path).st_mode
152
 
        if mode & stat.S_IROTH:
153
 
            return True
154
 
        else:
155
 
            return False
156
 
    except OSError, e:
157
 
        return False
158
 
 
159
 
 
160
 
def authorize(req, user):
161
 
    """Given a request, checks whether req.user is allowed to
162
 
    access req.path. Returns None on authorization success. Raises
163
 
    HTTP_FORBIDDEN on failure.
164
 
 
165
 
    This is for general authorization (assuming not in public mode; this is
166
 
    the standard auth code for fileservice, download and serve).
167
 
    """
168
 
    # TODO: Groups
169
 
    # First normalise the path
170
 
    urlpath = os.path.normpath(req.path)
171
 
    # Now if it begins with ".." or separator, then it's illegal
172
 
    if urlpath.startswith("..") or urlpath.startswith(os.sep):
173
 
        return False
174
 
 
175
 
    (owner, _) = util.split_path(urlpath)
176
 
    if user.login != owner:
177
 
        return False
178
 
    return True
179
 
 
180
 
def authorize_public(req):
181
 
    """A different kind of authorization. Rather than making sure the
182
 
    logged-in user owns the file, this checks if the file is in a published
183
 
    directory.
184
 
 
185
 
    This is for the "public mode" of the serve app.
186
 
 
187
 
    Same interface as "authorize" - None on success, HTTP_FORBIDDEN exception
188
 
    raised on failure.
189
 
    """
190
 
    _, path = url_to_local(req.config, req.path)
191
 
 
192
 
    # Walk up the tree, and find the deepest directory.
193
 
    while not os.path.isdir(path):
194
 
        path = os.path.dirname(path)
195
 
 
196
 
    if not (worldreadable(path) and published(path)):
197
 
        return False
198
 
    return True