56
65
Return Value: the uid associated with the user. INT
59
# FIXME: the IVLE server must check that an admin is doing this!
61
if 'uid' not in props or props['uid'] is None:
62
raise NotImplementedError, "No algorithm for creating uids yet!"
66
username = props['username']
69
password = props['password']
73
email = props['email']
77
fullname = props['fullname']
78
rolenm = props['rolenm']
80
studentid = props['studentid']
83
common.makeuser.make_user_db(username, uid, password, email, nick,
84
fullname, rolenm, studentid)
68
if 'unixid' not in props or props['unixid'] is None:
69
# For the time being, just choose a random unixid.
70
# This may result in duplicates, but the unixid is essentially
71
# a monitoring/logging convenience only. Oh, and dups could kill
73
props['unixid'] = random.randrange(5000,10000)
74
# raise NotImplementedError, "No algorithm for creating uids yet!"
76
# props['unixid'] = unixid
78
common.makeuser.make_user_db(**props)
80
return int(props['unixid'])
82
def update_user(props):
83
"""Create the database record for the given user.
85
login - user who is making the change (not necessarily the one
87
update - dict of fields to be updated. The fields are all those
88
in the login table of the db.
90
Omitted fields will not be set.
92
update = props['update']
93
# Note: "login" is special - it is not part of the kwargs to
94
# db.update_user, but the first arg - used to find the user to update.
95
# However it doesn't need any special treatment here.
98
db.update_user(**update)
101
def get_login(login, passwd, _realm, _login, _may_save):
102
"""Callback function used by pysvn for authentication.
104
logging.debug("Getting password for %s (realm %s)" % (login, _realm))
105
return (True, login, passwd, False)
88
107
def activate_user(props):
89
108
"""Create the on-disk stuff for the given user.
105
124
details = db.get_user(login)
107
# FIXME: make svn config/auth
111
common.makeuser.make_jail(login, details['unixid'])
126
# make svn config/auth
128
logging.debug("Creating repo")
129
common.makeuser.make_svn_repo(login, throw_on_error=False)
130
logging.debug("Creating svn config")
131
common.makeuser.make_svn_config(login, throw_on_error=False)
132
logging.debug("Creating svn auth")
133
passwd = common.makeuser.make_svn_auth(login, throw_on_error=False)
134
logging.debug("passwd: %s" % passwd)
137
svn.callback_get_login = partial(get_login, login, passwd)
139
if conf.svn_addr[-1] != '/':
140
conf.svn_addr = conf.svn_addr + "/"
142
# FIXME: This should be a loop over enrolements.
143
# We're not going to fix this now because it requires
144
# a large amount of admin console work to manage subject
146
# Instead, we're just going to use a single offering with
147
# a "short" name of "info1".
148
logging.debug("Creating /info1")
150
svn.mkdir(conf.svn_addr + login + "/info1",
151
"Initial creation of work directory for Informatics 1")
152
except Exception, exc:
153
logging.warning("While mkdiring info1: %s" % str(exc))
155
logging.debug("Creating /stuff")
157
svn.mkdir(conf.svn_addr + login + "/stuff",
158
"Initial creation of directory for miscellania")
159
except Exception, exc:
160
logging.warning("While mkdiring stuff: %s" % str(exc))
163
logging.debug("Creating jail")
164
common.makeuser.make_jail(login, details.unixid)
168
tcf_path = os.path.join(conf.jail_base, 'template/opt/ivle/lib/conf/conf.py')
169
cf_path = os.path.join(conf.jail_base, login, 'opt/ivle/lib/conf/conf.py')
172
cf = open(cf_path, "w")
173
cf.write(open(tcf_path, "r").read())
174
cf.write("# The login name for the owner of the jail\n")
175
cf.write("login = %s\n" % repr(login))
177
cf.write("# The subversion-only password for the owner of the jail\n")
178
cf.write("svn_pass = %s\n" % repr(passwd))
181
# Check out the repositories into the student's home dir
182
# FIXME: Call do_checkout instead of replicating this code.
183
# (do_checkout currently doesn't work)
188
logging.debug("Checking out directories in the jail")
190
svn.checkout(conf.svn_addr + login + "/stuff",
191
common.studpath.url_to_local(login + "/stuff")[1])
192
os.system("chown -R %d:%d %s" \
193
% (details.unixid, details.unixid,
194
common.studpath.url_to_local(login + "/stuff")[1]))
195
except Exception, exc:
196
logging.warning("While mkdiring stuff: %s" % str(exc))
199
svn.checkout(conf.svn_addr + login + "/info1",
200
common.studpath.url_to_local(login + "/info1")[1])
201
os.system("chown -R %d:%d %s" \
202
% (details.unixid, details.unixid,
203
common.studpath.url_to_local(login + "/info1")[1]))
204
except Exception, exc:
205
logging.warning("While mkdiring info1: %s" % str(exc))
208
# FIXME: should this be nicer?
209
os.system("chown -R %d:%d %s" \
210
% (details.unixid, details.unixid,
211
common.studpath.url_to_local(login)[1]))
214
logging.info("Enabling user")
113
215
db.update_user(login, state='enabled')
115
217
return {"response": "okay"}
222
def do_checkout(props):
223
"""Create the default contents of a user's jail by checking out from the
225
If any directory already exists, just fail silently (so this is not a
226
"wipe-and-checkout", merely a checkout if it failed or something).
228
login - the user name for the jail
232
# XXX / FIXME: This doesn't work - cannot get passwd
233
# (activate_me creates passwd, other svn stuff gets it from jailconf - we
234
# can't access either at this point).
236
login = props['login']
238
svn.callback_get_login = partial(get_login, login, passwd)
240
if conf.svn_addr[-1] != '/':
241
conf.svn_addr = conf.svn_addr + "/"
245
logging.debug("Checking out directories in the jail")
247
svn.checkout(conf.svn_addr + login + "/stuff",
248
common.studpath.url_to_local(login + "/stuff")[1])
249
os.system("chown -R %d:%d %s" \
250
% (details.unixid, details.unixid,
251
common.studpath.url_to_local(login + "/stuff")[1]))
252
except Exception, exc:
253
logging.warning("While mkdiring stuff: %s" % str(exc))
256
svn.checkout(conf.svn_addr + login + "/info1",
257
common.studpath.url_to_local(login + "/info1")[1])
258
os.system("chown -R %d:%d %s" \
259
% (details.unixid, details.unixid,
260
common.studpath.url_to_local(login + "/info1")[1]))
261
except Exception, exc:
262
logging.warning("While mkdiring info1: %s" % str(exc))
265
return {"response": "okay"}
121
268
'create_user':create_user,
122
'activate_user':activate_user
269
'update_user':update_user,
270
'activate_user':activate_user,
271
'do_checkout':do_checkout,
276
pidfile = open('/var/run/usrmgt-server.pid', 'w')
277
pidfile.write('%d\n' % os.getpid())
279
except IOError, (errno, strerror):
280
print "Couldn't write PID file. IO error(%s): %s" % (errno, strerror)
125
283
def dispatch(props):
284
logging.debug(repr(props))
126
285
action = props.keys()[0]
127
286
return actions[action](props[action])
129
288
if __name__ == "__main__":
290
print >>sys.stderr, "Usage: usrmgt-server <port> <magic>"
130
292
port = int(sys.argv[1])
131
293
magic = sys.argv[2]
133
common.chat.start_server(port, magic, False, dispatch)
297
logging.basicConfig(filename="/var/log/usrmgt.log", level=logging.INFO)
298
logging.info("Starting usrmgt server on port %d (pid = %d)" % (port, pid))
300
common.chat.start_server(port, magic, True, dispatch, initializer)