35
25
# - Rebuild svn auth file
36
26
# - Rebuild passwd + push to nodes.
38
29
def create_user(props):
39
30
"""Create the database record for the given user.
40
31
Expected properties:
41
login - used as a unix login name and svn repository name.
32
username - used as a unix login name and svn repository name.
43
unixid - the unix uid under which execution will take place
34
uid - the unix uid under which execution will take place
44
35
on the behalf of the user. Don't use 0! If not specified
45
36
or None, one will be allocated from the configured
65
56
Return Value: the uid associated with the user. INT
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)
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)
107
88
def activate_user(props):
108
89
"""Create the on-disk stuff for the given user.
124
105
details = db.get_user(login)
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, svn_pass=passwd)
166
do_checkout(props, svn_pass=passwd)
168
# FIXME: should this be nicer?
169
os.system("chown -R %d:%d %s" \
170
% (details.unixid, details.unixid,
171
common.studpath.url_to_local(login)[1]))
173
logging.info("Enabling user")
107
# FIXME: make svn config/auth
111
common.makeuser.make_jail(login, details['unixid'])
174
113
db.update_user(login, state='enabled')
176
115
return {"response": "okay"}
181
def do_checkout(props, svn_pass=None):
182
"""Create the default contents of a user's jail by checking out from the
184
If any directory already exists, just fail silently (so this is not a
185
"wipe-and-checkout", merely a checkout if it failed or something).
187
login - the user name for the jail
191
login = props['login']
193
# If svn_pass isn't supplied, grab it from the DB
196
user = db.get_user(login)
197
svn_pass = user.svn_pass
201
svn.callback_get_login = partial(get_login, login, svn_pass)
203
if conf.svn_addr[-1] != os.sep:
204
conf.svn_addr += os.sep
208
logging.debug("Checking out directories in the jail")
210
svn.checkout(conf.svn_addr + login + "/stuff",
211
common.studpath.url_to_local(login + "/stuff")[1])
212
os.system("chown -R %d:%d %s" \
213
% (user.unixid, user.unixid,
214
common.studpath.url_to_local(login + "/stuff")[1]))
215
except Exception, exc:
216
logging.warning("While mkdiring stuff: %s" % str(exc))
219
svn.checkout(conf.svn_addr + login + "/info1",
220
common.studpath.url_to_local(login + "/info1")[1])
221
os.system("chown -R %d:%d %s" \
222
% (user.unixid, user.unixid,
223
common.studpath.url_to_local(login + "/info1")[1]))
224
except Exception, exc:
225
logging.warning("While mkdiring info1: %s" % str(exc))
230
return {"response": "okay"}
233
121
'create_user':create_user,
234
'update_user':update_user,
235
'activate_user':activate_user,
236
'do_checkout':do_checkout,
122
'activate_user':activate_user
241
pidfile = open('/var/run/usrmgt-server.pid', 'w')
242
pidfile.write('%d\n' % os.getpid())
244
except IOError, (errno, strerror):
245
print "Couldn't write PID file. IO error(%s): %s" % (errno, strerror)
248
125
def dispatch(props):
249
logging.debug(repr(props))
250
126
action = props.keys()[0]
251
127
return actions[action](props[action])
253
129
if __name__ == "__main__":
255
print >>sys.stderr, "Usage: usrmgt-server <port> <magic>"
257
130
port = int(sys.argv[1])
258
131
magic = sys.argv[2]
262
logging.basicConfig(filename="/var/log/usrmgt.log", level=logging.INFO)
263
logging.info("Starting usrmgt server on port %d (pid = %d)" % (port, pid))
265
common.chat.start_server(port, magic, True, dispatch, initializer)
133
common.chat.start_server(port, magic, False, dispatch)