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

« back to all changes in this revision

Viewing changes to scripts/usrmgt-server

  • Committer: dcoles
  • Date: 2008-02-29 02:11:58 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:624
forum: Removed the subsilver2 style and phpBB installer
Modified prosilver theme to be more IVLE integrated
Added db dumps for setup

setup.py: Added config.php generator code

doc/setup/install_proc.txt: New setup/install details

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
 
 
3
import os
 
4
import pysvn
 
5
import subprocess
 
6
import sys
 
7
import urllib
 
8
from functools import partial
 
9
import traceback
 
10
import logging
 
11
 
 
12
import conf
 
13
import common.db
 
14
import common.chat
 
15
import common.makeuser
 
16
import common.studpath
 
17
 
 
18
# usage:
 
19
#   usrmgt-server <port> <magic>
 
20
 
 
21
# User management operations:
 
22
#   - Create local user
 
23
#   - [Re]Create jail for a user
 
24
#       - Create a svn repository for a user
 
25
#           - create repository
 
26
#           - svn config
 
27
#           - svn auth
 
28
#       - Checkout repository as home directory
 
29
#       - /etc/passwd entry
 
30
#   - Disable a user's account
 
31
#   - Enable a user's account
 
32
#   - Remove a user
 
33
#   - Rebuild svn config
 
34
#   - Rebuild svn auth file
 
35
#   - Rebuild passwd + push to nodes.
 
36
 
 
37
def create_user(props):
 
38
    """Create the database record for the given user.
 
39
       Expected properties:
 
40
        login       - used as a unix login name and svn repository name.
 
41
                      STRING REQUIRED 
 
42
        unixid      - the unix uid under which execution will take place
 
43
                      on the behalf of the user. Don't use 0! If not specified
 
44
                      or None, one will be allocated from the configured
 
45
                      numeric range.
 
46
                      INT OPTIONAL
 
47
        password    - the clear-text password for the user. If this property is
 
48
                      absent or None, this is an indication that external
 
49
                      authentication should be used (i.e. LDAP).
 
50
                      STRING OPTIONAL
 
51
        email       - the user's email address.
 
52
                      STRING OPTIONAL
 
53
        nick        - the display name to use.
 
54
                      STRING REQUIRED
 
55
        fullname    - The name of the user for results and/or other official
 
56
                      purposes.
 
57
                      STRING REQUIRED
 
58
        rolenm      - The user's role. Must be one of "anyone", "student",
 
59
                      "tutor", "lecturer", "admin".
 
60
                      STRING/ENUM REQUIRED
 
61
        studentid   - If supplied and not None, the student id of the user for
 
62
                      results and/or other official purposes.
 
63
                      STRING OPTIONAL
 
64
       Return Value: the uid associated with the user. INT
 
65
    """
 
66
 
 
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
 
71
        # each other. <sigh>
 
72
        props['unixid'] = random.randrange(5000,10000)
 
73
        # raise NotImplementedError, "No algorithm for creating uids yet!"
 
74
        # unixid = invent-uid
 
75
        # props['unixid'] = unixid
 
76
 
 
77
    common.makeuser.make_user_db(**props)
 
78
 
 
79
    return int(props['unixid'])
 
80
 
 
81
def update_user(props):
 
82
    """Create the database record for the given user.
 
83
       Expected properties:
 
84
        login       - user who is making the change (not necessarily the one
 
85
                      being updated).
 
86
        update      - dict of fields to be updated. The fields are all those
 
87
                      in the login table of the db.
 
88
                      'login' required.
 
89
                      Omitted fields will not be set.
 
90
    """
 
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.
 
95
 
 
96
    db = common.db.DB()
 
97
    db.update_user(**update)
 
98
    db.close()
 
99
 
 
100
def get_login(login, passwd, _realm, _login, _may_save):
 
101
    """Callback function used by pysvn for authentication.
 
102
    """
 
103
    logging.debug("Getting password for %s (realm %s)" % (login, _realm))
 
104
    return (True, login, passwd, False)
 
105
 
 
106
def activate_user(props):
 
107
    """Create the on-disk stuff for the given user.
 
108
       Sets the state of the user in the db from pending to enabled.
 
109
       Expected properties:
 
110
        login       - the user name for the jail
 
111
                      STRING REQUIRED
 
112
       Return Value: None
 
113
    """
 
114
 
 
115
    login = props['login']
 
116
 
 
117
    db = common.db.DB()
 
118
 
 
119
    try:
 
120
 
 
121
        # FIXME: check we're pending
 
122
 
 
123
        details = db.get_user(login)
 
124
 
 
125
        # make svn config/auth
 
126
 
 
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)
 
134
 
 
135
        svn = pysvn.Client()
 
136
        svn.callback_get_login = partial(get_login, login, passwd)
 
137
 
 
138
        if conf.svn_addr[-1] != '/':
 
139
            conf.svn_addr = conf.svn_addr + "/"
 
140
    
 
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
 
144
        #        offerings.
 
145
        #        Instead, we're just going to use a single offering with
 
146
        #        a "short" name of "info1".
 
147
        logging.debug("Creating /info1")
 
148
        try:
 
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))
 
153
            pass
 
154
        logging.debug("Creating /submissions")
 
155
        try:
 
156
            svn.mkdir(conf.svn_addr + login + "/submissions",
 
157
                      "Initial creation of submissions directory")
 
158
        except Exception, exc:
 
159
            logging.warning("While mkdiring submissions: %s" % str(exc))
 
160
            pass
 
161
        logging.debug("Creating /stuff")
 
162
        try:
 
163
            svn.mkdir(conf.svn_addr + login + "/stuff",
 
164
                      "Initial creation of directory for miscellania")
 
165
        except Exception, exc:
 
166
            logging.warning("While mkdiring stuff: %s" % str(exc))
 
167
            pass
 
168
 
 
169
        logging.debug("Creating jail")
 
170
        common.makeuser.make_jail(login, details.unixid)
 
171
 
 
172
        # FIXME: <hack>
 
173
 
 
174
        tcf_path = os.path.join(conf.jail_base, 'template/opt/ivle/lib/conf/conf.py')
 
175
        cf_path = os.path.join(conf.jail_base, login, 'opt/ivle/lib/conf/conf.py')
 
176
 
 
177
        os.remove(cf_path)
 
178
        cf = open(cf_path, "w")
 
179
        cf.write(open(tcf_path, "r").read())
 
180
        cf.write("# The login name for the owner of the jail\n")
 
181
        cf.write("login = %s\n" % repr(login))
 
182
        cf.write("\n")
 
183
        cf.write("# The subversion-only password for the owner of the jail\n")
 
184
        cf.write("svn_pass = %s\n" % repr(passwd))
 
185
        cf.close()
 
186
 
 
187
        # FIXME: </hack>
 
188
 
 
189
        logging.debug("Checking out directories in the jail")
 
190
        try:
 
191
            svn.checkout(conf.svn_addr + login + "/stuff",
 
192
                         common.studpath.url_to_local(login + "/stuff")[1])
 
193
        except Exception, exc:
 
194
            logging.warning("While mkdiring stuff: %s" % str(exc))
 
195
            pass
 
196
        try:
 
197
            svn.checkout(conf.svn_addr + login + "/submissions",
 
198
                         common.studpath.url_to_local(login + "/submissions")[1])
 
199
        except Exception, exc:
 
200
            logging.warning("While mkdiring submissions: %s" % str(exc))
 
201
            pass
 
202
        try:
 
203
            svn.checkout(conf.svn_addr + login + "/info1",
 
204
                         common.studpath.url_to_local(login + "/info1")[1])
 
205
        except Exception, exc:
 
206
            logging.warning("While mkdiring info1: %s" % str(exc))
 
207
            pass
 
208
 
 
209
        # FIXME: should this be nicer?
 
210
        os.system("chown -R %d:%d %s" \
 
211
                % (details.unixid, details.unixid,
 
212
                   common.studpath.url_to_local(login)[1]))
 
213
 
 
214
 
 
215
        logging.info("Enabling user")
 
216
        db.update_user(login, state='enabled')
 
217
 
 
218
        return {"response": "okay"}
 
219
 
 
220
    finally:
 
221
        db.close()
 
222
 
 
223
actions = {
 
224
        'create_user':create_user,
 
225
        'update_user':update_user,
 
226
        'activate_user':activate_user,
 
227
    }
 
228
 
 
229
def dispatch(props):
 
230
    logging.debug(repr(props))
 
231
    action = props.keys()[0]
 
232
    return actions[action](props[action])
 
233
 
 
234
if __name__ == "__main__":
 
235
    if len(sys.argv) <3:
 
236
        print >>sys.stderr, "Usage: usrmgt-server <port> <magic>"
 
237
        sys.exit(1)
 
238
    port = int(sys.argv[1])
 
239
    magic = sys.argv[2]
 
240
 
 
241
    pid = os.getpid()
 
242
 
 
243
    logging.basicConfig(filename="/var/log/usrmgt.log", level=logging.INFO)
 
244
    logging.info("Starting usrmgt server on port %d (pid = %d)" % (port, pid))
 
245
 
 
246
    common.chat.start_server(port, magic, True, dispatch)