~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
440 by drtomc
usrmgt: move the usrmgt sever to a better place.
11
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
12
import conf
473 by drtomc
usrmgt: progress the skeleton a bit further.
13
import common.db
440 by drtomc
usrmgt: move the usrmgt sever to a better place.
14
import common.chat
15
import common.makeuser
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
16
import common.studpath
440 by drtomc
usrmgt: move the usrmgt sever to a better place.
17
18
# usage:
19
#   usrmgt-server <port> <magic>
20
452 by drtomc
usrmgt: checkpoint work on the usrmgt server.
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
440 by drtomc
usrmgt: move the usrmgt sever to a better place.
37
def create_user(props):
452 by drtomc
usrmgt: checkpoint work on the usrmgt server.
38
    """Create the database record for the given user.
39
       Expected properties:
548 by mattgiuca
www/apps/userservice: Allows unixid as an argument to create_user.
40
        login       - used as a unix login name and svn repository name.
452 by drtomc
usrmgt: checkpoint work on the usrmgt server.
41
                      STRING REQUIRED 
548 by mattgiuca
www/apps/userservice: Allows unixid as an argument to create_user.
42
        unixid      - the unix uid under which execution will take place
454 by drtomc
usrmgt-server: more work.
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).
452 by drtomc
usrmgt: checkpoint work on the usrmgt server.
50
                      STRING OPTIONAL
464 by mattgiuca
usermgt-server: Added email.
51
        email       - the user's email address.
52
                      STRING OPTIONAL
452 by drtomc
usrmgt: checkpoint work on the usrmgt server.
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
454 by drtomc
usrmgt-server: more work.
61
        studentid   - If supplied and not None, the student id of the user for
452 by drtomc
usrmgt: checkpoint work on the usrmgt server.
62
                      results and/or other official purposes.
63
                      STRING OPTIONAL
454 by drtomc
usrmgt-server: more work.
64
       Return Value: the uid associated with the user. INT
452 by drtomc
usrmgt: checkpoint work on the usrmgt server.
65
    """
440 by drtomc
usrmgt: move the usrmgt sever to a better place.
66
548 by mattgiuca
www/apps/userservice: Allows unixid as an argument to create_user.
67
    if 'unixid' not in props or props['unixid'] is None:
541 by drtomc
Implement a vege algorithm for allocating unix uids: rnd.
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>
548 by mattgiuca
www/apps/userservice: Allows unixid as an argument to create_user.
72
        props['unixid'] = random.randrange(5000,10000)
541 by drtomc
Implement a vege algorithm for allocating unix uids: rnd.
73
        # raise NotImplementedError, "No algorithm for creating uids yet!"
548 by mattgiuca
www/apps/userservice: Allows unixid as an argument to create_user.
74
        # unixid = invent-uid
75
        # props['unixid'] = unixid
76
77
    common.makeuser.make_user_db(**props)
78
79
    return int(props['unixid'])
454 by drtomc
usrmgt-server: more work.
80
551 by mattgiuca
userservice/usrmgt-server: Added update_user action to both.
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
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
100
def get_login(login, passwd, _realm, _login, _may_save):
101
    """Callback function used by pysvn for authentication.
102
    """
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
103
    logging.debug("Getting password for %s (realm %s)" % (login, _realm))
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
104
    return (True, login, passwd, False)
105
473 by drtomc
usrmgt: progress the skeleton a bit further.
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.
454 by drtomc
usrmgt-server: more work.
109
       Expected properties:
473 by drtomc
usrmgt: progress the skeleton a bit further.
110
        login       - the user name for the jail
454 by drtomc
usrmgt-server: more work.
111
                      STRING REQUIRED
456 by drtomc
usrmgt-server: a bit more work.
112
       Return Value: None
454 by drtomc
usrmgt-server: more work.
113
    """
456 by drtomc
usrmgt-server: a bit more work.
114
473 by drtomc
usrmgt: progress the skeleton a bit further.
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
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
125
        # make svn config/auth
126
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
127
        logging.debug("Creating repo")
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
128
        common.makeuser.make_svn_repo(login, throw_on_error=False)
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
129
        logging.debug("Creating svn config")
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
130
        common.makeuser.make_svn_config(login, throw_on_error=False)
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
131
        logging.debug("Creating svn auth")
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
132
        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
133
        logging.debug("passwd: %s" % passwd)
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
134
135
        svn = pysvn.Client()
136
        svn.callback_get_login = partial(get_login, login, passwd)
528 by drtomc
usrmgt-server: robustify svn url handling a bit.
137
138
        if conf.svn_addr[-1] != '/':
139
            conf.svn_addr = conf.svn_addr + "/"
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
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".
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
147
        logging.debug("Creating /info1")
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
148
        try:
149
            svn.mkdir(conf.svn_addr + login + "/info1",
150
                      "Initial creation of work directory for Informatics 1")
151
        except Exception, exc:
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
152
            logging.warning("While mkdiring info1: %s" % str(exc))
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
153
            pass
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
154
        logging.debug("Creating /submissions")
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
155
        try:
156
            svn.mkdir(conf.svn_addr + login + "/submissions",
157
                      "Initial creation of submissions directory")
158
        except Exception, exc:
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
159
            logging.warning("While mkdiring submissions: %s" % str(exc))
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
160
            pass
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
161
        logging.debug("Creating /stuff")
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
162
        try:
163
            svn.mkdir(conf.svn_addr + login + "/stuff",
164
                      "Initial creation of directory for miscellania")
165
        except Exception, exc:
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
166
            logging.warning("While mkdiring stuff: %s" % str(exc))
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
167
            pass
168
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
169
        logging.debug("Creating jail")
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
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
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
189
        logging.debug("Checking out directories in the jail")
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
190
        try:
528 by drtomc
usrmgt-server: robustify svn url handling a bit.
191
            svn.checkout(conf.svn_addr + login + "/stuff",
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
192
                         common.studpath.url_to_local(login + "/stuff")[1])
193
        except Exception, exc:
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
194
            logging.warning("While mkdiring stuff: %s" % str(exc))
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
195
            pass
196
        try:
528 by drtomc
usrmgt-server: robustify svn url handling a bit.
197
            svn.checkout(conf.svn_addr + login + "/submissions",
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
198
                         common.studpath.url_to_local(login + "/submissions")[1])
199
        except Exception, exc:
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
200
            logging.warning("While mkdiring submissions: %s" % str(exc))
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
201
            pass
202
        try:
528 by drtomc
usrmgt-server: robustify svn url handling a bit.
203
            svn.checkout(conf.svn_addr + login + "/info1",
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
204
                         common.studpath.url_to_local(login + "/info1")[1])
205
        except Exception, exc:
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
206
            logging.warning("While mkdiring info1: %s" % str(exc))
522 by drtomc
Add quite a lot of stuff to get usrmgt happening.
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
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
215
        logging.info("Enabling user")
473 by drtomc
usrmgt: progress the skeleton a bit further.
216
        db.update_user(login, state='enabled')
217
478 by mattgiuca
scripts/usrmgr-server: Renamed actions from dashes to underscores.
218
        return {"response": "okay"}
473 by drtomc
usrmgt: progress the skeleton a bit further.
219
220
    finally:
221
        db.close()
440 by drtomc
usrmgt: move the usrmgt sever to a better place.
222
452 by drtomc
usrmgt: checkpoint work on the usrmgt server.
223
actions = {
478 by mattgiuca
scripts/usrmgr-server: Renamed actions from dashes to underscores.
224
        'create_user':create_user,
551 by mattgiuca
userservice/usrmgt-server: Added update_user action to both.
225
        'update_user':update_user,
226
        'activate_user':activate_user,
452 by drtomc
usrmgt: checkpoint work on the usrmgt server.
227
    }
228
229
def dispatch(props):
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
230
    logging.debug(repr(props))
452 by drtomc
usrmgt: checkpoint work on the usrmgt server.
231
    action = props.keys()[0]
232
    return actions[action](props[action])
233
440 by drtomc
usrmgt: move the usrmgt sever to a better place.
234
if __name__ == "__main__":
235
    port = int(sys.argv[1])
236
    magic = sys.argv[2]
237
567 by drtomc
usrmgt: use proper logging.
238
    pid = os.getpid()
239
571 by drtomc
usrmgt: improve the logging. Amazing what happens when you actually read
240
    logging.basicConfig(filename="/var/log/usrmgt.log", level=logging.INFO)
241
    logging.info("Starting usrmgt server on port %d (pid = %d)" % (port, pid))
567 by drtomc
usrmgt: use proper logging.
242
243
    common.chat.start_server(port, magic, True, dispatch)