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

« back to all changes in this revision

Viewing changes to ivle/studpath.py

  • Committer: William Grant
  • Date: 2009-01-20 00:23:54 UTC
  • mto: This revision was merged to the branch mainline in revision 1090.
  • Revision ID: grantw@unimelb.edu.au-20090120002354-a1i5mcaeqgq8fs2f
ivle.database.User: Add a write-only 'password' attribute. When set, it will
    hash the password and set the password hash on the object. If given None,
    it will set the password hash to None.

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
 
27
27
import os
28
28
import stat
 
29
import pysvn
29
30
 
 
31
import ivle.conf
30
32
from ivle import util
31
33
 
32
 
def url_to_local(config, urlpath):
 
34
# Make a Subversion client object (for published)
 
35
svnclient = pysvn.Client()
 
36
 
 
37
def url_to_local(urlpath):
33
38
    """Given a URL path (part of a URL query string, see below), returns a
34
39
    tuple of
35
40
        * the username of the student whose directory is being browsed
46
51
 
47
52
    Returns (None, None) if the path is empty.
48
53
 
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)
 
54
    See also: ivle.conf.jail_base
67
55
    """
68
 
 
69
56
    # First normalise the path
70
57
    urlpath = os.path.normpath(urlpath)
71
58
    # Now if it begins with ".." or separator, then it's illegal
81
68
    # accordance with our directory scheme.
82
69
    # (The first time is the name of the jail, the second is the user's home
83
70
    # directory within the jail).
84
 
    path = os.path.join(config['paths']['jails']['mounts'],
85
 
                        user, 'home', urlpath)
 
71
    path = os.path.join(ivle.conf.jail_base, user, 'home', urlpath)
86
72
 
87
73
    return (user, path)
88
74
 
89
 
def url_to_jailpaths(config, urlpath):
 
75
def url_to_jailpaths(urlpath):
90
76
    """Given a URL path (part of a URL query string), returns a tuple of
91
77
        * the username of the student whose directory is being browsed
92
78
        * the absolute path where the jail will be located.
94
80
 
95
81
    urlpath: See urlpath in url_to_local.
96
82
 
97
 
    >>> stubconfig = {'paths': {'jails': {'mounts': '/jails'}}}
 
83
    >>> url_to_jailpaths("joe/mydir/myfile")
 
84
    ("joe", "/home/informatics/jails/joe", "home/joe/mydir/myfile")
98
85
 
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")
 
86
    >>> url_to_jailpaths("")
106
87
    (None, None, None)
107
88
    """
108
89
    # First normalise the path
109
90
    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):
 
91
    # Now if it begins with ".." then it's illegal
 
92
    if urlpath.startswith(".."):
112
93
        return (None, None, None)
113
94
    # Note: User can be a group name. There is absolutely no difference in our
114
95
    # current directory scheme.
115
96
    (user, subpath) = util.split_path(urlpath)
116
97
    if user is None: return (None, None, None)
117
98
 
118
 
    jail = os.path.join(config['paths']['jails']['mounts'], user)
119
 
    path = to_home_path(urlpath)
 
99
    jail = os.path.join(ivle.conf.jail_base, user)
 
100
    path = os.path.join('/home', urlpath)
120
101
 
121
102
    return (user, jail, path)
122
103
 
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)
 
104
def svnpublished(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
140
115
 
141
116
def published(path):
142
117
    """Given a path on the LOCAL file system, determines whether the path has a 
157
132
        return False
158
133
 
159
134
 
160
 
def authorize(req, user):
 
135
def authorize(req):
161
136
    """Given a request, checks whether req.user is allowed to
162
137
    access req.path. Returns None on authorization success. Raises
163
138
    HTTP_FORBIDDEN on failure.
170
145
    urlpath = os.path.normpath(req.path)
171
146
    # Now if it begins with ".." or separator, then it's illegal
172
147
    if urlpath.startswith("..") or urlpath.startswith(os.sep):
173
 
        return False
 
148
        req.throw_error(req.HTTP_FORBIDDEN)
174
149
 
175
150
    (owner, _) = util.split_path(urlpath)
176
 
    if user.login != owner:
177
 
        return False
178
 
    return True
 
151
    if req.user.login != owner:
 
152
        req.throw_error(req.HTTP_FORBIDDEN)
179
153
 
180
154
def authorize_public(req):
181
155
    """A different kind of authorization. Rather than making sure the
187
161
    Same interface as "authorize" - None on success, HTTP_FORBIDDEN exception
188
162
    raised on failure.
189
163
    """
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
 
164
    _, path = url_to_local(req.path)
 
165
    dirpath, _ = os.path.split(path)
 
166
    if not (worldreadable(dirpath) and published(dirpath)):
 
167
        req.throw_error(req.HTTP_FORBIDDEN)