25
34
# - Rebuild svn auth file
26
35
# - Rebuild passwd + push to nodes.
29
37
def create_user(props):
30
38
"""Create the database record for the given user.
31
39
Expected properties:
32
username - used as a unix login name and svn repository name.
40
login - used as a unix login name and svn repository name.
34
uid - the unix uid under which execution will take place
42
unixid - the unix uid under which execution will take place
35
43
on the behalf of the user. Don't use 0! If not specified
36
44
or None, one will be allocated from the configured
56
64
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)
67
if 'unixid' not in props or props['unixid'] is None:
68
# For the time being, just choose a random unixid.
69
# This may result in duplicates, but the unixid is essentially
70
# a monitoring/logging convenience only. Oh, and dups could kill
72
props['unixid'] = random.randrange(5000,10000)
73
# raise NotImplementedError, "No algorithm for creating uids yet!"
75
# props['unixid'] = unixid
77
common.makeuser.make_user_db(**props)
79
return int(props['unixid'])
81
def update_user(props):
82
"""Create the database record for the given user.
84
login - user who is making the change (not necessarily the one
86
update - dict of fields to be updated. The fields are all those
87
in the login table of the db.
89
Omitted fields will not be set.
91
update = props['update']
92
# Note: "login" is special - it is not part of the kwargs to
93
# db.update_user, but the first arg - used to find the user to update.
94
# However it doesn't need any special treatment here.
97
db.update_user(**update)
100
def get_login(login, passwd, _realm, _login, _may_save):
101
"""Callback function used by pysvn for authentication.
103
logging.debug("Getting password for %s (realm %s)" % (login, _realm))
104
return (True, login, passwd, False)
88
106
def activate_user(props):
89
107
"""Create the on-disk stuff for the given user.
105
123
details = db.get_user(login)
107
# FIXME: make svn config/auth
111
common.makeuser.make_jail(login, details['unixid'])
125
# make svn config/auth
127
logging.debug("Creating repo")
128
common.makeuser.make_svn_repo(login, throw_on_error=False)
129
logging.debug("Creating svn config")
130
common.makeuser.make_svn_config(login, throw_on_error=False)
131
logging.debug("Creating svn auth")
132
passwd = common.makeuser.make_svn_auth(login, throw_on_error=False)
133
logging.debug("passwd: %s" % passwd)
136
svn.callback_get_login = partial(get_login, login, passwd)
138
if conf.svn_addr[-1] != '/':
139
conf.svn_addr = conf.svn_addr + "/"
141
# FIXME: This should be a loop over enrolements.
142
# We're not going to fix this now because it requires
143
# a large amount of admin console work to manage subject
145
# Instead, we're just going to use a single offering with
146
# a "short" name of "info1".
147
logging.debug("Creating /info1")
149
svn.mkdir(conf.svn_addr + login + "/info1",
150
"Initial creation of work directory for Informatics 1")
151
except Exception, exc:
152
logging.warning("While mkdiring info1: %s" % str(exc))
154
logging.debug("Creating /stuff")
156
svn.mkdir(conf.svn_addr + login + "/stuff",
157
"Initial creation of directory for miscellania")
158
except Exception, exc:
159
logging.warning("While mkdiring stuff: %s" % str(exc))
162
logging.debug("Creating jail")
163
common.makeuser.make_jail(login, details.unixid)
167
tcf_path = os.path.join(conf.jail_base, 'template/opt/ivle/lib/conf/conf.py')
168
cf_path = os.path.join(conf.jail_base, login, 'opt/ivle/lib/conf/conf.py')
171
cf = open(cf_path, "w")
172
cf.write(open(tcf_path, "r").read())
173
cf.write("# The login name for the owner of the jail\n")
174
cf.write("login = %s\n" % repr(login))
176
cf.write("# The subversion-only password for the owner of the jail\n")
177
cf.write("svn_pass = %s\n" % repr(passwd))
182
logging.debug("Checking out directories in the jail")
184
svn.checkout(conf.svn_addr + login + "/stuff",
185
common.studpath.url_to_local(login + "/stuff")[1])
186
except Exception, exc:
187
logging.warning("While mkdiring stuff: %s" % str(exc))
190
svn.checkout(conf.svn_addr + login + "/info1",
191
common.studpath.url_to_local(login + "/info1")[1])
192
except Exception, exc:
193
logging.warning("While mkdiring info1: %s" % str(exc))
196
# FIXME: should this be nicer?
197
os.system("chown -R %d:%d %s" \
198
% (details.unixid, details.unixid,
199
common.studpath.url_to_local(login)[1]))
202
logging.info("Enabling user")
113
203
db.update_user(login, state='enabled')
115
205
return {"response": "okay"}
121
211
'create_user':create_user,
122
'activate_user':activate_user
212
'update_user':update_user,
213
'activate_user':activate_user,
125
216
def dispatch(props):
217
logging.debug(repr(props))
126
218
action = props.keys()[0]
127
219
return actions[action](props[action])
129
221
if __name__ == "__main__":
223
print >>sys.stderr, "Usage: usrmgt-server <port> <magic>"
130
225
port = int(sys.argv[1])
131
226
magic = sys.argv[2]
133
common.chat.start_server(port, magic, False, dispatch)
230
logging.basicConfig(filename="/var/log/usrmgt.log", level=logging.INFO)
231
logging.info("Starting usrmgt server on port %d (pid = %d)" % (port, pid))
233
common.chat.start_server(port, magic, True, dispatch)