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

« back to all changes in this revision

Viewing changes to ivle/makeuser.py

  • Committer: me at id
  • Date: 2009-01-15 01:29:07 UTC
  • mto: This revision was merged to the branch mainline in revision 1090.
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:branches%2Fstorm:1147
ivle.makeuser: Don't create a local.auth. It wasn't used anywhere, and seems
    to have only been there for historical reasons.
setup.configure: Remove svn_auth_local from the config.py boilerplate; it was
    used solely by ivle.makeuser.

Show diffs side-by-side

added added

removed removed

Lines of Context:
45
45
import filecmp
46
46
import logging
47
47
import ivle.conf
 
48
import ivle.db
48
49
import ivle.pulldown_subj
49
50
 
50
 
from ivle.database import ProjectGroup
51
 
 
52
51
def chown_to_webserver(filename):
53
52
    """
54
53
    Chowns a file so the web server user owns it.
74
73
 
75
74
    chown_to_webserver(path)
76
75
 
77
 
def rebuild_svn_config(store):
 
76
def rebuild_svn_config():
78
77
    """Build the complete SVN configuration file.
79
78
    """
80
 
    users = store.find(ivle.database.User)
 
79
    conn = ivle.db.DB()
 
80
    users = conn.get_users()
81
81
    groups = {}
82
 
    # TODO: Populate groups with per-offering tutors/lecturers/etc.
 
82
    for u in users:
 
83
        role = str(u.role)
 
84
        if role not in groups:
 
85
            groups[role] = []
 
86
        groups[role].append(u.login)
83
87
    f = open(ivle.conf.svn_conf + ".new", "w")
84
88
    f.write("# IVLE SVN Repositories Configuration\n")
85
89
    f.write("# Auto-generated on %s\n" % time.asctime())
99
103
    os.rename(ivle.conf.svn_conf + ".new", ivle.conf.svn_conf)
100
104
    chown_to_webserver(ivle.conf.svn_conf)
101
105
 
102
 
def rebuild_svn_group_config(store):
 
106
def rebuild_svn_group_config():
103
107
    """Build the complete SVN configuration file for groups
104
108
    """
 
109
    conn = ivle.db.DB()
 
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())
108
115
    f.write("\n")
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,
114
 
                             group.name])
 
116
    for g in groups:
 
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'])
 
125
        for u in users:
 
126
            f.write("%s = rw\n"%u['login'])
118
127
        f.write("\n")
119
128
    f.close()
120
129
    os.rename(ivle.conf.svn_group_conf + ".new", ivle.conf.svn_group_conf)
174
183
    return (to_add, to_remove)
175
184
 
176
185
 
177
 
def make_jail(user, force=True):
 
186
def make_jail(username, uid, force=True, svn_pass=None):
178
187
    """Creates a new user's jail space, in the jail directory as configured in
179
188
    conf.py.
180
189
 
185
194
 
186
195
    Chowns the user's directory within the jail to the given UID.
187
196
 
 
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.
 
201
 
188
202
    force: If false, exception if jail already exists for this user.
189
203
    If true (default), overwrites it, but preserves home directory.
 
204
 
 
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.
190
208
    """
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")
194
212
    
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
205
223
 
206
224
    if os.path.exists(userdir):
207
225
        if not force:
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])
 
243
            %(username, uid))
 
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)
228
248
    else:
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)
236
256
 
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)
239
263
 
240
264
    return userhomedir
241
265
 
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):
243
267
    """
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.
249
276
    """
 
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))
253
282
 
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.)
259
 
 
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
 
284
    if svn_pass is None:
 
285
        dbconn = ivle.db.DB()
 
286
        svn_pass = dbconn.get_user(username).svn_pass
 
287
        dbconn.close()
 
288
 
 
289
    # Read the contents of the template conf file
 
290
    try:
 
291
        template_conf_file = open(template_conf_path, "r")
 
292
        template_conf_data = template_conf_file.read()
 
293
        template_conf_file.close()
 
294
    except:
 
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")
 
299
 
264
300
    conf_file = open(conf_path, "w")
265
 
    conf_file.write("""# IVLE jail configuration
266
 
 
267
 
# In URL space, where in the site is IVLE located. (All URLs will be prefixed
268
 
# with this).
269
 
# eg. "/" or "/ivle".
270
 
root_dir = %(root_dir)r
271
 
 
272
 
# This value is not relevant inside the jail, but must remain for now. See
273
 
# the XXX in ivle.makeuser.make_conf_py.
274
 
jail_base = '/'
275
 
 
276
 
# The hostname for serving publicly accessible pages
277
 
public_host = %(public_host)r
278
 
 
279
 
# The URL under which the Subversion repositories are located.
280
 
svn_addr = %(svn_addr)r
281
 
 
282
 
# The login name for the owner of the jail
283
 
login = %(username)r
284
 
 
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,
292
 
      })
 
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 "
 
306
        "the jail\n")
 
307
    conf_file.write("svn_pass = %s\n" % repr(svn_pass))
293
308
    conf_file.close()
294
309
 
295
310
    # Make this file world-readable
313
328
                      % (username, unixid, unixid, username))
314
329
    passwd_file.close()
315
330
 
 
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"
 
337
    state.
 
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.
 
341
    """
 
342
    dbconn = ivle.db.DB()
 
343
    dbconn.create_user(**kwargs)
 
344
    dbconn.close()
 
345
 
 
346
    # Pulldown subjects and add enrolments
 
347
    ivle.pulldown_subj.enrol_user(kwargs['login'])
 
348
 
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)