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

93 by mattgiuca
New directory hierarchy.
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: common.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.
262 by mattgiuca
studpath: Added "authorize" function which checks the logged in user against
24
# Also performs common authorization, disallowing students from visiting paths
25
# they dont own.
93 by mattgiuca
New directory hierarchy.
26
27
import os
28
266 by mattgiuca
Added Publishing feature. This feature is complete except it currently isn't
29
import pysvn
30
93 by mattgiuca
New directory hierarchy.
31
import conf
32
from common import util
33
266 by mattgiuca
Added Publishing feature. This feature is complete except it currently isn't
34
# Make a Subversion client object (for published)
35
svnclient = pysvn.Client()
36
93 by mattgiuca
New directory hierarchy.
37
def url_to_local(urlpath):
38
    """Given a URL path (part of a URL query string, see below), returns a
39
    tuple of
40
        * the username of the student whose directory is being browsed
41
        * the absolute path in the file system where that file will be
42
            found within the student directories.
43
44
    urlpath: Part of the URL, but only the part *after* the application. For
45
    instance, given the URL "/ivle/browse/joe/home/mydir/myfile", urlpath will
46
    be just "joe/home/mydir/myfile". The expected result is something like
47
    ("joe", "/home/informatics/jails/joe/home/joe/home/mydir/myfile").
48
    Note that the actual location is not guaranteed by this interface (this
49
    function serves as a single point of control as to how URLs map onto
50
    student directories).
51
52
    Returns (None, None) if the path is empty.
53
106 by mattgiuca
Renamed "student_dir" to "jail_base" across the suite.
54
    See also: conf.jail_base
93 by mattgiuca
New directory hierarchy.
55
    """
125 by mattgiuca
common/studpath.py: Normalise and check path for ".." to disallow
56
    # First normalise the path
57
    urlpath = os.path.normpath(urlpath)
151 by mattgiuca
studpath: Security fix: Disallows paths beginning with os.sep.
58
    # Now if it begins with ".." or separator, then it's illegal
59
    if urlpath.startswith("..") or urlpath.startswith(os.sep):
125 by mattgiuca
common/studpath.py: Normalise and check path for ".." to disallow
60
        return (None, None)
93 by mattgiuca
New directory hierarchy.
61
    # Note: User can be a group name. There is absolutely no difference in our
62
    # current directory scheme.
63
    (user, subpath) = util.split_path(urlpath)
64
    if user is None: return (None, None)
65
66
    # Join the user onto 'home' then the full path specified.
67
    # This results in the user's name being repeated twice, which is in
68
    # accordance with our directory scheme.
69
    # (The first time is the name of the jail, the second is the user's home
70
    # directory within the jail).
106 by mattgiuca
Renamed "student_dir" to "jail_base" across the suite.
71
    path = os.path.join(conf.jail_base, user, 'home', urlpath)
93 by mattgiuca
New directory hierarchy.
72
73
    return (user, path)
74
75
def url_to_jailpaths(urlpath):
76
    """Given a URL path (part of a URL query string), returns a tuple of
77
        * the username of the student whose directory is being browsed
78
        * the absolute path where the jail will be located.
79
        * the path of the file relative to the jail.
80
81
    urlpath: See urlpath in url_to_local.
82
83
    >>> url_to_jailpaths("joe/home/mydir/myfile")
84
    ("joe", "/home/informatics/jails/joe", "home/joe/home/mydir/myfile")
85
86
    >>> url_to_jailpaths("")
87
    (None, None, None)
88
    """
125 by mattgiuca
common/studpath.py: Normalise and check path for ".." to disallow
89
    # First normalise the path
90
    urlpath = os.path.normpath(urlpath)
91
    # Now if it begins with ".." then it's illegal
92
    if urlpath.startswith(".."):
93
        return (None, None, None)
93 by mattgiuca
New directory hierarchy.
94
    # Note: User can be a group name. There is absolutely no difference in our
95
    # current directory scheme.
96
    (user, subpath) = util.split_path(urlpath)
97
    if user is None: return (None, None, None)
98
106 by mattgiuca
Renamed "student_dir" to "jail_base" across the suite.
99
    jail = os.path.join(conf.jail_base, user)
93 by mattgiuca
New directory hierarchy.
100
    path = os.path.join('home', urlpath)
101
102
    return (user, jail, path)
262 by mattgiuca
studpath: Added "authorize" function which checks the logged in user against
103
266 by mattgiuca
Added Publishing feature. This feature is complete except it currently isn't
104
def published(path):
105
    """Given a path on the LOCAL file system, determines whether the path has
106
    its "ivle:published" property active (in subversion). Returns True
107
    or False."""
108
    # Read SVN properties for this path
109
    try:
110
        props = svnclient.propget("ivle:published", path, recurse=False)
111
    except pysvn.ClientError:
112
        # Not under version control? Then it isn't published.
113
        return False
114
    return len(props) > 0
115
262 by mattgiuca
studpath: Added "authorize" function which checks the logged in user against
116
def authorize(req):
117
    """Given a request, checks whether req.username is allowed to
118
    access req.path. Returns None on authorization success. Raises
119
    HTTP_FORBIDDEN on failure.
120
121
    This is for general authorization (assuming not in public mode; this is
122
    the standard auth code for fileservice, download and serve).
123
    """
124
    # TODO: Groups
125
    # First normalise the path
126
    urlpath = os.path.normpath(req.path)
127
    # Now if it begins with ".." or separator, then it's illegal
128
    if urlpath.startswith("..") or urlpath.startswith(os.sep):
129
        req.throw_error(req.HTTP_FORBIDDEN)
130
131
    (owner, _) = util.split_path(urlpath)
132
    if req.username != owner:
133
        req.throw_error(req.HTTP_FORBIDDEN)
266 by mattgiuca
Added Publishing feature. This feature is complete except it currently isn't
134
135
def authorize_public(req):
136
    """A different kind of authorization. Rather than making sure the
267 by mattgiuca
Changed semantics of "published" property: Now applies to directories, not
137
    logged-in user owns the file, this checks if the file is in a published
138
    directory.
139
140
    This is for the "public mode" of the serve app.
266 by mattgiuca
Added Publishing feature. This feature is complete except it currently isn't
141
142
    Same interface as "authorize" - None on success, HTTP_FORBIDDEN exception
143
    raised on failure.
144
    """
145
    _, path = url_to_local(req.path)
267 by mattgiuca
Changed semantics of "published" property: Now applies to directories, not
146
    dirpath, _ = os.path.split(path)
147
    if not published(dirpath):
266 by mattgiuca
Added Publishing feature. This feature is complete except it currently isn't
148
        req.throw_error(req.HTTP_FORBIDDEN)