99
103
os.rename(ivle.conf.svn_conf + ".new", ivle.conf.svn_conf)
100
104
chown_to_webserver(ivle.conf.svn_conf)
102
def rebuild_svn_group_config(store):
106
def rebuild_svn_group_config():
103
107
"""Build the complete SVN configuration file for groups
110
groups = conn.get_all('project_group',
111
['groupid', 'groupnm', 'projectsetid'])
105
112
f = open(ivle.conf.svn_group_conf + ".new", "w")
106
113
f.write("# IVLE SVN Group Repositories Configuration\n")
107
114
f.write("# Auto-generated on %s\n" % time.asctime())
109
for group in store.find(ProjectGroup):
110
offering = group.project_set.offering
111
reponame = "_".join([offering.subject.short_name,
112
offering.semester.year,
113
offering.semester.semester,
117
projectsetid = g['projectsetid']
118
offeringinfo = conn.get_offering_info(projectsetid)
119
subj_short_name = offeringinfo['subj_short_name']
120
year = offeringinfo['year']
121
semester = offeringinfo['semester']
122
reponame = "_".join([subj_short_name, year, semester, g['groupnm']])
115
123
f.write("[%s:/]\n"%reponame)
116
for user in group.members:
117
f.write("%s = rw\n" % user.login)
124
users = conn.get_projectgroup_members(g['groupid'])
126
f.write("%s = rw\n"%u['login'])
120
129
os.rename(ivle.conf.svn_group_conf + ".new", ivle.conf.svn_group_conf)
186
195
Chowns the user's directory within the jail to the given UID.
197
Note: This takes separate username and uid arguments. The UID need not
198
*necessarily* correspond to a Unix username at all, if all you are
199
planning to do is setuid to it. This allows the caller the freedom of
200
deciding the binding between username and uid, if any.
188
202
force: If false, exception if jail already exists for this user.
189
203
If true (default), overwrites it, but preserves home directory.
205
svn_pass: If provided this will be a string, the randomly-generated
206
Subversion password for this user (if you happen to already have it).
207
If not provided, it will be read from the database.
191
209
# MUST run as root or some of this may fail
192
210
if os.getuid() != 0:
193
211
raise Exception("Must run make_jail as root")
195
213
# tempdir is for putting backup homes in
196
tempdir = os.path.join(ivle.conf.jail_src_base, '__temp__')
214
tempdir = os.path.join(ivle.conf.jail_base, '__temp__')
197
215
if not os.path.exists(tempdir):
198
216
os.makedirs(tempdir)
199
217
elif not os.path.isdir(tempdir):
200
218
os.unlink(tempdir)
201
219
os.mkdir(tempdir)
202
userdir = os.path.join(ivle.conf.jail_src_base, user.login)
220
userdir = os.path.join(ivle.conf.jail_src_base, username)
203
221
homedir = os.path.join(userdir, 'home')
204
userhomedir = os.path.join(homedir, user.login) # Return value
222
userhomedir = os.path.join(homedir, username) # Return value
206
224
if os.path.exists(userdir):
222
240
shutil.move(homebackup, homedir)
223
241
# Change the ownership of all the files to the right unixid
224
242
logging.debug("chown %s's home directory files to uid %d"
225
%(user.login, user.unixid))
226
os.spawnvp(os.P_WAIT, 'chown', ['chown', '-R', '%d:%d' % (user.unixid,
227
user.unixid), userhomedir])
244
os.chown(userhomedir, uid, uid)
245
for root, dirs, files in os.walk(userhomedir):
246
for fsobj in dirs + files:
247
os.chown(os.path.join(root, fsobj), uid, uid)
229
249
# No user jail exists
230
250
# Set up the user's home directory
231
251
os.makedirs(userhomedir)
232
252
# Chown (and set the GID to the same as the UID).
233
os.chown(userhomedir, user.unixid, user.unixid)
253
os.chown(userhomedir, uid, uid)
234
254
# Chmod to rwxr-xr-x (755)
235
255
os.chmod(userhomedir, 0755)
237
make_conf_py(user.login, userdir, user.svn_pass)
238
make_etc_passwd(user.login, userdir, ivle.conf.jail_system, user.unixid)
257
# There are 2 special files which need to be generated specific to this
258
# user: ${python_site_packages}/lib/conf/conf.py and /etc/passwd.
259
# "__" username "__" users are exempt (special)
260
if not (username.startswith("__") and username.endswith("__")):
261
make_conf_py(username, userdir, ivle.conf.jail_system, svn_pass)
262
make_etc_passwd(username, userdir, ivle.conf.jail_system, uid)
240
264
return userhomedir
242
def make_conf_py(username, user_jail_dir, svn_pass):
266
def make_conf_py(username, user_jail_dir, staging_dir, svn_pass=None):
244
268
Creates (overwriting any existing file, and creating directories) a
245
269
file ${python_site_packages}/ivle/conf/conf.py in a given user's jail.
246
270
username: Username.
247
271
user_jail_dir: User's jail dir, ie. ivle.conf.jail_base + username
248
svn_pass: User's SVN password.
272
staging_dir: The dir with the staging copy of the jail. (With the
273
template conf.py file).
274
svn_pass: As with make_jail. User's SVN password, but if not supplied,
275
will look up in the DB.
277
template_conf_path = os.path.join(staging_dir,
278
ivle.conf.python_site_packages[1:], "ivle/conf/conf.py")
250
279
conf_path = os.path.join(user_jail_dir,
251
280
ivle.conf.python_site_packages[1:], "ivle/conf/conf.py")
252
281
os.makedirs(os.path.dirname(conf_path))
254
# In the "in-jail" version of conf, we don't need MOST of the details
255
# (it would be a security risk to have them here).
256
# So we just write root_dir, and jail_base is "/".
257
# (jail_base being "/" means "jail-relative" paths are relative to "/"
258
# when inside the jail.)
260
# XXX: jail_base is wrong and shouldn't be here. Unfortunately, jail code
261
# uses ivle.studpath.url_to_{local,jailpaths}, both of which use
262
# jail_base. Note that they don't use the bits of the return value
263
# that depend on jail_base, so it can be any string.
283
# If svn_pass isn't supplied, grab it from the DB
285
dbconn = ivle.db.DB()
286
svn_pass = dbconn.get_user(username).svn_pass
289
# Read the contents of the template conf file
291
template_conf_file = open(template_conf_path, "r")
292
template_conf_data = template_conf_file.read()
293
template_conf_file.close()
295
# Couldn't open template conf.py for some reason
296
# Just treat it as empty file
297
template_conf_data = ("# Warning: Problem building config script.\n"
298
"# Could not find template conf.py file.\n")
264
300
conf_file = open(conf_path, "w")
265
conf_file.write("""# IVLE jail configuration
267
# In URL space, where in the site is IVLE located. (All URLs will be prefixed
269
# eg. "/" or "/ivle".
270
root_dir = %(root_dir)r
272
# This value is not relevant inside the jail, but must remain for now. See
273
# the XXX in ivle.makeuser.make_conf_py.
276
# The hostname for serving publicly accessible pages
277
public_host = %(public_host)r
279
# The URL under which the Subversion repositories are located.
280
svn_addr = %(svn_addr)r
282
# The login name for the owner of the jail
285
# The subversion-only password for the owner of the jail
286
svn_pass = %(svn_pass)r
287
""" % {'root_dir': ivle.conf.root_dir,
288
'public_host': ivle.conf.public_host,
289
'svn_addr': ivle.conf.svn_addr,
290
'username': username,
291
'svn_pass': svn_pass,
301
conf_file.write(template_conf_data)
302
conf_file.write("\n# The login name for the owner of the jail\n")
303
conf_file.write("login = %s\n" % repr(username))
304
conf_file.write("\n")
305
conf_file.write("# The subversion-only password for the owner of "
307
conf_file.write("svn_pass = %s\n" % repr(svn_pass))
293
308
conf_file.close()
295
310
# Make this file world-readable
313
328
% (username, unixid, unixid, username))
314
329
passwd_file.close()
331
def make_user_db(throw_on_error = True, **kwargs):
332
"""Creates a user's entry in the database, filling in all the fields.
333
All arguments must be keyword args. They are the fields in the table.
334
However, instead of supplying a "passhash", you must supply a
335
"password" argument, which will be hashed internally.
336
Also do not supply a state. All users are created in the "no_agreement"
338
Also pulls the user's subjects using the configured subject pulldown
339
module, and adds enrolments to the DB.
340
Throws an exception if the user already exists.
342
dbconn = ivle.db.DB()
343
dbconn.create_user(**kwargs)
346
# Pulldown subjects and add enrolments
347
ivle.pulldown_subj.enrol_user(kwargs['login'])
316
349
def mount_jail(login):
317
350
# This is where we'll mount to...
318
351
destdir = os.path.join(ivle.conf.jail_base, login)