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

440 by drtomc
usrmgt: move the usrmgt sever to a better place.
1
#!/usr/bin/python
2
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
3
import os
4
import pysvn
5
import subprocess
440 by drtomc
usrmgt: move the usrmgt sever to a better place.
6
import sys
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
7
import urllib
8
from functools import partial
548 by mattgiuca
www/apps/userservice: Allows unixid as an argument to create_user.
9
import traceback
567 by drtomc
usrmgt: use proper logging.
10
import logging
684 by apeel
Added an initialisor to usrmgt-server which creates a PID file in /var/run. Needed for the /etc/init.d/ script.
11
import errno
440 by drtomc
usrmgt: move the usrmgt sever to a better place.
12
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
13
import conf
473 by drtomc
usrmgt: progress the skeleton a bit further.
14
import common.db
440 by drtomc
usrmgt: move the usrmgt sever to a better place.
15
import common.chat
16
import common.makeuser
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
17
import common.studpath
440 by drtomc
usrmgt: move the usrmgt sever to a better place.
18
19
# usage:
20
#   usrmgt-server <port> <magic>
21
452 by drtomc
usrmgt: checkpoint work on the usrmgt server.
22
# User management operations:
23
#   - Create local user
24
#   - [Re]Create jail for a user
25
#       - Create a svn repository for a user
26
#           - create repository
27
#           - svn config
28
#           - svn auth
29
#       - Checkout repository as home directory
30
#       - /etc/passwd entry
31
#   - Disable a user's account
32
#   - Enable a user's account
33
#   - Remove a user
34
#   - Rebuild svn config
35
#   - Rebuild svn auth file
36
#   - Rebuild passwd + push to nodes.
37
440 by drtomc
usrmgt: move the usrmgt sever to a better place.
38
def create_user(props):
452 by drtomc
usrmgt: checkpoint work on the usrmgt server.
39
    """Create the database record for the given user.
40
       Expected properties:
548 by mattgiuca
www/apps/userservice: Allows unixid as an argument to create_user.
41
        login       - used as a unix login name and svn repository name.
452 by drtomc
usrmgt: checkpoint work on the usrmgt server.
42
                      STRING REQUIRED 
548 by mattgiuca
www/apps/userservice: Allows unixid as an argument to create_user.
43
        unixid      - the unix uid under which execution will take place
454 by drtomc
usrmgt-server: more work.
44
                      on the behalf of the user. Don't use 0! If not specified
45
                      or None, one will be allocated from the configured
46
                      numeric range.
47
                      INT OPTIONAL
48
        password    - the clear-text password for the user. If this property is
49
                      absent or None, this is an indication that external
50
                      authentication should be used (i.e. LDAP).
452 by drtomc
usrmgt: checkpoint work on the usrmgt server.
51
                      STRING OPTIONAL
464 by mattgiuca
usermgt-server: Added email.
52
        email       - the user's email address.
53
                      STRING OPTIONAL
452 by drtomc
usrmgt: checkpoint work on the usrmgt server.
54
        nick        - the display name to use.
55
                      STRING REQUIRED
56
        fullname    - The name of the user for results and/or other official
57
                      purposes.
58
                      STRING REQUIRED
59
        rolenm      - The user's role. Must be one of "anyone", "student",
60
                      "tutor", "lecturer", "admin".
61
                      STRING/ENUM REQUIRED
454 by drtomc
usrmgt-server: more work.
62
        studentid   - If supplied and not None, the student id of the user for
452 by drtomc
usrmgt: checkpoint work on the usrmgt server.
63
                      results and/or other official purposes.
64
                      STRING OPTIONAL
454 by drtomc
usrmgt-server: more work.
65
       Return Value: the uid associated with the user. INT
452 by drtomc
usrmgt: checkpoint work on the usrmgt server.
66
    """
440 by drtomc
usrmgt: move the usrmgt sever to a better place.
67
548 by mattgiuca
www/apps/userservice: Allows unixid as an argument to create_user.
68
    if 'unixid' not in props or props['unixid'] is None:
541 by drtomc
Implement a vege algorithm for allocating unix uids: rnd.
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
72
        # each other. <sigh>
548 by mattgiuca
www/apps/userservice: Allows unixid as an argument to create_user.
73
        props['unixid'] = random.randrange(5000,10000)
541 by drtomc
Implement a vege algorithm for allocating unix uids: rnd.
74
        # raise NotImplementedError, "No algorithm for creating uids yet!"
548 by mattgiuca
www/apps/userservice: Allows unixid as an argument to create_user.
75
        # unixid = invent-uid
76
        # props['unixid'] = unixid
77
78
    common.makeuser.make_user_db(**props)
79
80
    return int(props['unixid'])
454 by drtomc
usrmgt-server: more work.
81
551 by mattgiuca
userservice/usrmgt-server: Added update_user action to both.
82
def update_user(props):
83
    """Create the database record for the given user.
84
       Expected properties:
85
        login       - user who is making the change (not necessarily the one
86
                      being updated).
87
        update      - dict of fields to be updated. The fields are all those
88
                      in the login table of the db.
89
                      'login' required.
90
                      Omitted fields will not be set.
91
    """
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.
96
97
    db = common.db.DB()
98
    db.update_user(**update)
99
    db.close()
100
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
101
def get_login(login, passwd, _realm, _login, _may_save):
102
    """Callback function used by pysvn for authentication.
103
    """
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
104
    logging.debug("Getting password for %s (realm %s)" % (login, _realm))
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
105
    return (True, login, passwd, False)
106
473 by drtomc
usrmgt: progress the skeleton a bit further.
107
def activate_user(props):
108
    """Create the on-disk stuff for the given user.
109
       Sets the state of the user in the db from pending to enabled.
454 by drtomc
usrmgt-server: more work.
110
       Expected properties:
473 by drtomc
usrmgt: progress the skeleton a bit further.
111
        login       - the user name for the jail
454 by drtomc
usrmgt-server: more work.
112
                      STRING REQUIRED
456 by drtomc
usrmgt-server: a bit more work.
113
       Return Value: None
454 by drtomc
usrmgt-server: more work.
114
    """
456 by drtomc
usrmgt-server: a bit more work.
115
473 by drtomc
usrmgt: progress the skeleton a bit further.
116
    login = props['login']
117
118
    db = common.db.DB()
119
120
    try:
121
122
        # FIXME: check we're pending
123
124
        details = db.get_user(login)
125
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
126
        # make svn config/auth
127
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
128
        logging.debug("Creating repo")
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
129
        common.makeuser.make_svn_repo(login, throw_on_error=False)
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
130
        logging.debug("Creating svn config")
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
131
        common.makeuser.make_svn_config(login, throw_on_error=False)
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
132
        logging.debug("Creating svn auth")
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
133
        passwd = common.makeuser.make_svn_auth(login, throw_on_error=False)
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
134
        logging.debug("passwd: %s" % passwd)
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
135
136
        svn = pysvn.Client()
137
        svn.callback_get_login = partial(get_login, login, passwd)
528 by drtomc
usrmgt-server: robustify svn url handling a bit.
138
139
        if conf.svn_addr[-1] != '/':
140
            conf.svn_addr = conf.svn_addr + "/"
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
141
    
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
145
        #        offerings.
146
        #        Instead, we're just going to use a single offering with
147
        #        a "short" name of "info1".
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
148
        logging.debug("Creating /info1")
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
149
        try:
150
            svn.mkdir(conf.svn_addr + login + "/info1",
151
                      "Initial creation of work directory for Informatics 1")
152
        except Exception, exc:
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
153
            logging.warning("While mkdiring info1: %s" % str(exc))
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
154
            pass
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
155
        logging.debug("Creating /stuff")
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
156
        try:
157
            svn.mkdir(conf.svn_addr + login + "/stuff",
158
                      "Initial creation of directory for miscellania")
159
        except Exception, exc:
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
160
            logging.warning("While mkdiring stuff: %s" % str(exc))
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
161
            pass
162
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
163
        logging.debug("Creating jail")
767 by mattgiuca
Moved code to create user's jail version of conf.py from usrmgt server
164
        common.makeuser.make_jail(login, details.unixid, svn_pass=passwd)
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
165
768 by mattgiuca
usrmgt-server: Made do_checkout work!
166
        do_checkout(props, svn_pass=passwd)
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
167
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]))
172
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
173
        logging.info("Enabling user")
473 by drtomc
usrmgt: progress the skeleton a bit further.
174
        db.update_user(login, state='enabled')
175
478 by mattgiuca
scripts/usrmgr-server: Renamed actions from dashes to underscores.
176
        return {"response": "okay"}
473 by drtomc
usrmgt: progress the skeleton a bit further.
177
178
    finally:
179
        db.close()
440 by drtomc
usrmgt: move the usrmgt sever to a better place.
180
768 by mattgiuca
usrmgt-server: Made do_checkout work!
181
def do_checkout(props, svn_pass=None):
676 by mattgiuca
usrmgt-server: Moved SVN checkout code from activate_me into a separate
182
    """Create the default contents of a user's jail by checking out from the
183
    repositories.
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).
186
       Expected properties:
187
        login       - the user name for the jail
188
                      STRING REQUIRED
189
       Return Value: None
190
    """
191
    login = props['login']
768 by mattgiuca
usrmgt-server: Made do_checkout work!
192
193
    # If svn_pass isn't supplied, grab it from the DB
194
    if svn_pass is None:
195
        db = common.db.DB()
196
        user = db.get_user(login)
197
        svn_pass = user.svn_pass
198
        db.close()
199
677 by mattgiuca
userservice: Fix error message text.
200
    svn = pysvn.Client()
768 by mattgiuca
usrmgt-server: Made do_checkout work!
201
    svn.callback_get_login = partial(get_login, login, svn_pass)
202
203
    if conf.svn_addr[-1] != os.sep:
204
        conf.svn_addr += os.sep
205
206
    # FIXME: <hack>
676 by mattgiuca
usrmgt-server: Moved SVN checkout code from activate_me into a separate
207
208
    logging.debug("Checking out directories in the jail")
209
    try:
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" \
768 by mattgiuca
usrmgt-server: Made do_checkout work!
213
                % (user.unixid, user.unixid,
676 by mattgiuca
usrmgt-server: Moved SVN checkout code from activate_me into a separate
214
                   common.studpath.url_to_local(login + "/stuff")[1]))
215
    except Exception, exc:
216
        logging.warning("While mkdiring stuff: %s" % str(exc))
217
        pass
218
    try:
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" \
768 by mattgiuca
usrmgt-server: Made do_checkout work!
222
                % (user.unixid, user.unixid,
676 by mattgiuca
usrmgt-server: Moved SVN checkout code from activate_me into a separate
223
                   common.studpath.url_to_local(login + "/info1")[1]))
224
    except Exception, exc:
225
        logging.warning("While mkdiring info1: %s" % str(exc))
226
        pass
227
768 by mattgiuca
usrmgt-server: Made do_checkout work!
228
    # FIXME: </hack>
229
676 by mattgiuca
usrmgt-server: Moved SVN checkout code from activate_me into a separate
230
    return {"response": "okay"}
231
452 by drtomc
usrmgt: checkpoint work on the usrmgt server.
232
actions = {
478 by mattgiuca
scripts/usrmgr-server: Renamed actions from dashes to underscores.
233
        'create_user':create_user,
551 by mattgiuca
userservice/usrmgt-server: Added update_user action to both.
234
        'update_user':update_user,
235
        'activate_user':activate_user,
676 by mattgiuca
usrmgt-server: Moved SVN checkout code from activate_me into a separate
236
        'do_checkout':do_checkout,
452 by drtomc
usrmgt: checkpoint work on the usrmgt server.
237
    }
238
684 by apeel
Added an initialisor to usrmgt-server which creates a PID file in /var/run. Needed for the /etc/init.d/ script.
239
def initializer():
240
    try:
241
        pidfile = open('/var/run/usrmgt-server.pid', 'w')
242
        pidfile.write('%d\n' % os.getpid())
243
        pidfile.close()
244
    except IOError, (errno, strerror):
245
        print "Couldn't write PID file. IO error(%s): %s" % (errno, strerror)
246
        sys.exit(1)
247
452 by drtomc
usrmgt: checkpoint work on the usrmgt server.
248
def dispatch(props):
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
249
    logging.debug(repr(props))
452 by drtomc
usrmgt: checkpoint work on the usrmgt server.
250
    action = props.keys()[0]
251
    return actions[action](props[action])
252
440 by drtomc
usrmgt: move the usrmgt sever to a better place.
253
if __name__ == "__main__":
612 by mattgiuca
scripts/usrmgt-server: Now checks the length of its arguments and gives a
254
    if len(sys.argv) <3:
255
        print >>sys.stderr, "Usage: usrmgt-server <port> <magic>"
256
        sys.exit(1)
440 by drtomc
usrmgt: move the usrmgt sever to a better place.
257
    port = int(sys.argv[1])
258
    magic = sys.argv[2]
259
567 by drtomc
usrmgt: use proper logging.
260
    pid = os.getpid()
261
764 by mattgiuca
usrmgt-server: Revert accidental change in previous commit: Logging level set
262
    logging.basicConfig(filename="/var/log/usrmgt.log", level=logging.INFO)
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
263
    logging.info("Starting usrmgt server on port %d (pid = %d)" % (port, pid))
567 by drtomc
usrmgt: use proper logging.
264
684 by apeel
Added an initialisor to usrmgt-server which creates a PID file in /var/run. Needed for the /etc/init.d/ script.
265
    common.chat.start_server(port, magic, True, dispatch, initializer)