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

« back to all changes in this revision

Viewing changes to ivle/makeuser.py

Fixed a broken link when adding a new project.

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
import logging
28
28
import subprocess
29
29
 
30
 
from storm.expr import Select, Max
31
 
 
32
30
import ivle.config
33
 
from ivle.database import (User, ProjectGroup, Assessed, ProjectSubmission,
34
 
        Project, ProjectSet, Offering, Enrolment, Subject, Semester)
 
31
from ivle.database import ProjectGroup, User
35
32
 
36
33
def chown_to_webserver(filename):
37
34
    """chown a directory and its contents to the web server.
72
69
        f.write("""
73
70
[%(login)s:/]
74
71
%(login)s = rw
75
 
""" % {'login': u.login.encode('utf-8')})
76
 
 
77
 
    # Now we need to grant offering tutors and lecturers access to the latest
78
 
    # submissions in their offerings. There are much prettier ways to do this,
79
 
    # but a lot of browser requests call this function, so it needs to be
80
 
    # fast. We can grab all of the paths needing authorisation directives with
81
 
    # a single query, and we cache the list of viewers for each offering.
82
 
    offering_viewers_cache = {}
83
 
    for (login, psid, pspath, offeringid) in store.find(
84
 
        (User.login, ProjectSubmission.id, ProjectSubmission.path,
85
 
         Offering.id),
86
 
            Assessed.id == ProjectSubmission.assessed_id,
87
 
            User.id == Assessed.user_id,
88
 
            Project.id == Assessed.project_id,
89
 
            ProjectSet.id == Project.project_set_id,
90
 
            Offering.id == ProjectSet.offering_id,
91
 
            ProjectSubmission.date_submitted == Select(
92
 
                    Max(ProjectSubmission.date_submitted),
93
 
                    ProjectSubmission.assessed_id == Assessed.id,
94
 
                    tables=ProjectSubmission
95
 
            )
96
 
        ):
97
 
 
98
 
        # Do we already have the list of logins authorised for this offering
99
 
        # cached? If not, get it.
100
 
        if offeringid not in offering_viewers_cache:
101
 
            offering_viewers_cache[offeringid] = list(store.find(
102
 
                    User.login,
103
 
                    User.id == Enrolment.user_id,
104
 
                    Enrolment.offering_id == offeringid,
105
 
                    Enrolment.role.is_in((u'tutor', u'lecturer')),
106
 
                    Enrolment.active == True,
107
 
                )
108
 
            )
109
 
 
110
 
        f.write("""
111
 
# Submission %(id)d
112
 
[%(login)s:%(path)s]
113
 
""" % {'login': login.encode('utf-8'), 'id': psid,
114
 
       'path': pspath.encode('utf-8')})
115
 
 
116
 
        for viewer_login in offering_viewers_cache[offeringid]:
117
 
            # We don't want to override the owner's write privilege,
118
 
            # so we don't add them to the read-only ACL.
119
 
            if login != viewer_login:
120
 
                f.write("%s = r\n" % viewer_login.encode('utf-8'))
 
72
""" % {'login': u.login})
121
73
 
122
74
    f.close()
123
75
    os.rename(temp_name, conf_name)
138
90
 
139
91
""" % {'time': time.asctime()})
140
92
 
141
 
    group_members_cache = {}
142
93
    for group in store.find(ProjectGroup):
143
94
        offering = group.project_set.offering
144
95
        reponame = "_".join([offering.subject.short_name,
146
97
                             offering.semester.semester,
147
98
                             group.name])
148
99
 
149
 
        f.write("[%s:/]\n" % reponame.encode('utf-8'))
150
 
        if group.id not in group_members_cache:
151
 
            group_members_cache[group.id] = set()
 
100
        f.write("[%s:/]\n" % reponame)
152
101
        for user in group.members:
153
 
            group_members_cache[group.id].add(user.login)
154
 
            f.write("%s = rw\n" % user.login.encode('utf-8'))
 
102
            f.write("%s = rw\n" % user.login)
155
103
        f.write("\n")
156
104
 
157
 
    # Now we need to grant offering tutors and lecturers access to the latest
158
 
    # submissions in their offerings. There are much prettier ways to do this,
159
 
    # but a lot of browser requests call this function, so it needs to be
160
 
    # fast. We can grab all of the paths needing authorisation directives with
161
 
    # a single query, and we cache the list of viewers for each offering.
162
 
    offering_viewers_cache = {}
163
 
    for (ssn, year, sem, name, psid, pspath, gid, offeringid) in store.find(
164
 
        (Subject.short_name, Semester.year, Semester.semester,
165
 
         ProjectGroup.name, ProjectSubmission.id, ProjectSubmission.path,
166
 
         ProjectGroup.id, Offering.id),
167
 
            Assessed.id == ProjectSubmission.assessed_id,
168
 
            ProjectGroup.id == Assessed.project_group_id,
169
 
            Project.id == Assessed.project_id,
170
 
            ProjectSet.id == Project.project_set_id,
171
 
            Offering.id == ProjectSet.offering_id,
172
 
            Subject.id == Offering.subject_id,
173
 
            Semester.id == Offering.semester_id,
174
 
            ProjectSubmission.date_submitted == Select(
175
 
                    Max(ProjectSubmission.date_submitted),
176
 
                    ProjectSubmission.assessed_id == Assessed.id,
177
 
                    tables=ProjectSubmission
178
 
            )
179
 
        ):
180
 
 
181
 
        reponame = "_".join([ssn, year, sem, name])
182
 
 
183
 
        # Do we already have the list of logins authorised for this offering
184
 
        # cached? If not, get it.
185
 
        if offeringid not in offering_viewers_cache:
186
 
            offering_viewers_cache[offeringid] = list(store.find(
187
 
                    User.login,
188
 
                    User.id == Enrolment.user_id,
189
 
                    Enrolment.offering_id == offeringid,
190
 
                    Enrolment.role.is_in((u'tutor', u'lecturer')),
191
 
                    Enrolment.active == True,
192
 
                )
193
 
            )
194
 
 
195
 
        f.write("""
196
 
# Submission %(id)d
197
 
[%(repo)s:%(path)s]
198
 
""" % {'repo': reponame.encode('utf-8'), 'id': psid,
199
 
       'path': pspath.encode('utf-8')})
200
 
 
201
 
        for viewer_login in offering_viewers_cache[offeringid]:
202
 
            # Skip existing group members, or they can't write to it any more.
203
 
            if viewer_login not in group_members_cache[gid]:
204
 
                f.write("%s = r\n" % viewer_login)
205
 
 
206
105
    f.close()
207
106
    os.rename(temp_name, conf_name)
208
107
    chown_to_webserver(conf_name)
215
114
    """
216
115
    # filename is, eg, /var/lib/ivle/svn/ivle.auth
217
116
    filename = config['paths']['svn']['auth_ivle']
 
117
    passwd = hashlib.md5(uuid.uuid4().bytes).hexdigest()
218
118
    if os.path.exists(filename):
219
119
        create = ""
220
120
    else:
221
121
        create = "c"
222
122
 
223
123
    user = User.get_by_login(store, login)
224
 
 
225
 
    if user.svn_pass is None:
226
 
        passwd = hashlib.md5(uuid.uuid4().bytes).hexdigest()
227
 
        user.svn_pass = unicode(passwd)
 
124
    user.svn_pass = unicode(passwd)
228
125
 
229
126
    res = subprocess.call(['htpasswd', '-%smb' % create,
230
 
                           filename, login, user.svn_pass])
 
127
                           filename, login, passwd])
231
128
    if res != 0 and throw_on_error:
232
129
        raise Exception("Unable to create ivle-auth for %s" % login)
233
130
 
235
132
    if create == "c":
236
133
        chown_to_webserver(filename)
237
134
 
238
 
    return user.svn_pass
 
135
    return passwd
239
136
 
240
137
def make_jail(user, config, force=True):
241
138
    """Create or update a user's jail.
264
161
        os.mkdir(tempdir)
265
162
    userdir = os.path.join(jail_src_base, user.login)
266
163
    homedir = os.path.join(userdir, 'home')
267
 
    tmpdir = os.path.join(userdir, 'tmp')
268
164
    userhomedir = os.path.join(homedir, user.login)   # Return value
269
165
 
270
166
    if os.path.exists(userdir):
273
169
        # User jail already exists. Blow it away but preserve their home
274
170
        # directory. It should be all that is there anyway, but you never
275
171
        # know!
276
 
        # Ignore warnings about the use of tempnam
 
172
        # Ignore warnings about the use of tmpnam
277
173
        warnings.simplefilter('ignore')
278
174
        homebackup = os.tempnam(tempdir)
279
175
        warnings.resetwarnings()
282
178
        # NOTE that shutil.move changed in Python 2.6, it now moves a
283
179
        # directory INTO the target (like `mv`), which it didn't use to do.
284
180
        # This code works regardless.
285
 
        shutil.move(userhomedir, homebackup)
 
181
        shutil.move(homedir, homebackup)
286
182
        shutil.rmtree(userdir)
287
 
        os.makedirs(homedir)
288
 
        shutil.move(homebackup, userhomedir)
 
183
        os.makedirs(userdir)
 
184
        shutil.move(homebackup, homedir)
289
185
        # Change the ownership of all the files to the right unixid
290
186
        logging.debug("chown %s's home directory files to uid %d"
291
187
            %(user.login, user.unixid))
303
199
    make_ivle_conf(user.login, userdir, user.svn_pass, config)
304
200
    make_etc_passwd(user.login, userdir, config['paths']['jails']['template'],
305
201
                    user.unixid)
306
 
    os.makedirs(tmpdir)
307
 
    os.chmod(tmpdir, 01777)
308
202
 
309
203
    return userhomedir
310
204
 
319
213
    @param svn_pass: User's SVN password.
320
214
    @param sys_config: An ivle.config.Config object (the system-wide config).
321
215
    """
322
 
    conf_path = os.path.join(user_jail_dir, "home/.ivle.conf")
323
 
    if not os.path.exists(os.path.dirname(conf_path)):
324
 
        os.makedirs(os.path.dirname(conf_path))
 
216
    conf_path = os.path.join(user_jail_dir, "etc/ivle/ivle.conf")
 
217
    os.makedirs(os.path.dirname(conf_path))
325
218
 
326
219
    # In the "in-jail" version of conf, we don't need MOST of the details
327
220
    # (it would be a security risk to have them here).
328
221
    # So we just write root_dir.
329
222
    conf_obj = ivle.config.Config(blank=True)
330
223
    conf_obj.filename = conf_path
331
 
    conf_obj['urls'] = {}
332
224
    conf_obj['urls']['root'] = sys_config['urls']['root']
333
225
    conf_obj['urls']['public_host'] = sys_config['urls']['public_host']
334
226
    conf_obj['urls']['svn_addr'] = sys_config['urls']['svn_addr']
335
 
    conf_obj['user_info'] = {}
336
227
    conf_obj['user_info']['login'] = username
337
228
    conf_obj['user_info']['svn_pass'] = svn_pass
338
229
    conf_obj.write()
348
239
    Creates /etc/passwd in the given user's jail. This will be identical to
349
240
    that in the template jail, except for the added entry for this user.
350
241
    """
351
 
    template_passwd_path = os.path.join(template_dir, "home/.passwd")
352
 
    passwd_path = os.path.join(user_jail_dir, "home/.passwd")
 
242
    template_passwd_path = os.path.join(template_dir, "etc/passwd")
 
243
    passwd_path = os.path.join(user_jail_dir, "etc/passwd")
353
244
    passwd_dir = os.path.dirname(passwd_path)
354
245
    if not os.path.exists(passwd_dir):
355
246
        os.makedirs(passwd_dir)