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

« back to all changes in this revision

Viewing changes to ivle/studpath.py

Modified the database so that exercises are now stored in the database, rather
than in flat files.

This also necessitated adding new tables and storm classes for test suites
and test cases.

Note that this commit merely changes the database and adds a script to
upload exercises. The code for actually reading exercises has yet
to be changed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
import stat
29
29
import pysvn
30
30
 
 
31
import ivle.conf
31
32
from ivle import util
32
33
 
33
34
# Make a Subversion client object (for published)
34
35
svnclient = pysvn.Client()
35
36
 
36
 
def url_to_local(config, urlpath):
 
37
def url_to_local(urlpath):
37
38
    """Given a URL path (part of a URL query string, see below), returns a
38
39
    tuple of
39
40
        * the username of the student whose directory is being browsed
50
51
 
51
52
    Returns (None, None) if the path is empty.
52
53
 
53
 
    >>> stubconfig = {'paths': {'jails': {'mounts': '/jails'}}}
54
 
 
55
 
    >>> url_to_local(stubconfig, 'joe/foo/bar/baz')
56
 
    ('joe', '/jails/joe/home/joe/foo/bar/baz')
57
 
    >>> url_to_local(stubconfig, 'joe')
58
 
    ('joe', '/jails/joe/home/joe')
59
 
    >>> url_to_local(stubconfig, 'joe/')
60
 
    ('joe', '/jails/joe/home/joe')
61
 
 
62
 
    We have some protection from various potential attacks. An empty,
63
 
    absolute, or ..-prefixed path yields a special result.
64
 
 
65
 
    >>> url_to_local(stubconfig, '')
66
 
    (None, None)
67
 
    >>> url_to_local(stubconfig, '/foo')
68
 
    (None, None)
69
 
    >>> url_to_local(stubconfig, '../bar')
70
 
    (None, None)
 
54
    See also: ivle.conf.jail_base
71
55
    """
72
 
 
73
56
    # First normalise the path
74
57
    urlpath = os.path.normpath(urlpath)
75
58
    # Now if it begins with ".." or separator, then it's illegal
85
68
    # accordance with our directory scheme.
86
69
    # (The first time is the name of the jail, the second is the user's home
87
70
    # directory within the jail).
88
 
    path = os.path.join(config['paths']['jails']['mounts'],
89
 
                        user, 'home', urlpath)
 
71
    path = os.path.join(ivle.conf.jail_base, user, 'home', urlpath)
90
72
 
91
73
    return (user, path)
92
74
 
93
 
def url_to_jailpaths(config, urlpath):
 
75
def url_to_jailpaths(urlpath):
94
76
    """Given a URL path (part of a URL query string), returns a tuple of
95
77
        * the username of the student whose directory is being browsed
96
78
        * the absolute path where the jail will be located.
98
80
 
99
81
    urlpath: See urlpath in url_to_local.
100
82
 
101
 
    >>> stubconfig = {'paths': {'jails': {'mounts': '/jails'}}}
 
83
    >>> url_to_jailpaths("joe/mydir/myfile")
 
84
    ('joe', '/var/lib/ivle/jailmounts/joe', '/home/joe/mydir/myfile')
102
85
 
103
 
    >>> url_to_jailpaths(stubconfig, "joe/mydir//myfile/.././myfile")
104
 
    ('joe', '/jails/joe', '/home/joe/mydir/myfile')
105
 
    >>> url_to_jailpaths(stubconfig, "")
106
 
    (None, None, None)
107
 
    >>> url_to_jailpaths(stubconfig, "../foo")
108
 
    (None, None, None)
109
 
    >>> url_to_jailpaths(stubconfig, "/foo")
 
86
    >>> url_to_jailpaths("")
110
87
    (None, None, None)
111
88
    """
112
89
    # First normalise the path
113
90
    urlpath = os.path.normpath(urlpath)
114
 
    # Now if it begins with "..", or is absolute, then it's illegal
115
 
    if urlpath.startswith("..") or os.path.isabs(urlpath):
 
91
    # Now if it begins with ".." then it's illegal
 
92
    if urlpath.startswith(".."):
116
93
        return (None, None, None)
117
94
    # Note: User can be a group name. There is absolutely no difference in our
118
95
    # current directory scheme.
119
96
    (user, subpath) = util.split_path(urlpath)
120
97
    if user is None: return (None, None, None)
121
98
 
122
 
    jail = os.path.join(config['paths']['jails']['mounts'], user)
123
 
    path = to_home_path(urlpath)
 
99
    jail = os.path.join(ivle.conf.jail_base, user)
 
100
    path = os.path.join('/home', urlpath)
124
101
 
125
102
    return (user, jail, path)
126
103
 
127
 
def to_home_path(urlpath):
128
 
    """Given a URL path (eg. joe/foo/bar/baz), returns a path within the home.
129
 
 
130
 
    >>> to_home_path('joe/foo/bar/baz')
131
 
    '/home/joe/foo/bar/baz'
132
 
    >>> to_home_path('joe/foo//bar/baz/../../')
133
 
    '/home/joe/foo'
134
 
    >>> to_home_path('joe/foo//bar/baz/../../../../../') is None
135
 
    True
136
 
    """
137
 
 
138
 
    urlpath = os.path.normpath(urlpath)
139
 
    # If it begins with '..', it's illegal.
140
 
    if urlpath.startswith(".."):
141
 
        return None
142
 
 
143
 
    return os.path.join('/home', urlpath)
144
 
 
145
104
def svnpublished(path):
146
105
    """Given a path on the LOCAL file system, determines whether the path has
147
106
    its "ivle:published" property active (in subversion). Returns True
173
132
        return False
174
133
 
175
134
 
176
 
def authorize(req, user):
 
135
def authorize(req):
177
136
    """Given a request, checks whether req.user is allowed to
178
137
    access req.path. Returns None on authorization success. Raises
179
138
    HTTP_FORBIDDEN on failure.
186
145
    urlpath = os.path.normpath(req.path)
187
146
    # Now if it begins with ".." or separator, then it's illegal
188
147
    if urlpath.startswith("..") or urlpath.startswith(os.sep):
189
 
        return False
 
148
        req.throw_error(req.HTTP_FORBIDDEN)
190
149
 
191
150
    (owner, _) = util.split_path(urlpath)
192
 
    if user.login != owner:
193
 
        return False
194
 
    return True
 
151
    if req.user.login != owner:
 
152
        req.throw_error(req.HTTP_FORBIDDEN)
195
153
 
196
154
def authorize_public(req):
197
155
    """A different kind of authorization. Rather than making sure the
203
161
    Same interface as "authorize" - None on success, HTTP_FORBIDDEN exception
204
162
    raised on failure.
205
163
    """
206
 
    _, path = url_to_local(req.config, req.path)
207
 
 
208
 
    # Walk up the tree, and find the deepest directory.
209
 
    while not os.path.isdir(path):
210
 
        path = os.path.dirname(path)
211
 
 
212
 
    if not (worldreadable(path) and published(path)):
213
 
        return False
214
 
    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)