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

« back to all changes in this revision

Viewing changes to scripts/usrmgt-server

  • Committer: dcoles
  • Date: 2008-08-07 06:46:32 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:989
Groups: Added userservice/assign_group call. This allows a user with the 
CAP_MANAGEGROUPS permission to assign a user into a group. This records the 
assignment in the database and then regenerates a svn-groups.conf file which 
specifies which users can access which repository.

This commit introduces the /groups repository (which means a groups directory 
will have to be created in repositories area and the apache config will have to 
be updated to allow the new dav repositories to work - see the changes to 
ivle-svn.conf/ivle-both.conf and install_proc for exact details). There is also 
a new parameter svn_group_conf in the config file so you need to run `setup.py 
config` too.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#!/usr/bin/python
2
2
 
3
3
import os
4
 
import pysvn
5
 
import subprocess
6
4
import sys
7
 
import urllib
8
 
from functools import partial
 
5
import logging
9
6
 
10
7
import conf
11
8
import common.db
23
20
#           - create repository
24
21
#           - svn config
25
22
#           - svn auth
26
 
#       - Checkout repository as home directory
27
23
#       - /etc/passwd entry
28
24
#   - Disable a user's account
29
25
#   - Enable a user's account
32
28
#   - Rebuild svn auth file
33
29
#   - Rebuild passwd + push to nodes.
34
30
 
35
 
 
36
 
def create_user(props):
37
 
    """Create the database record for the given user.
38
 
       Expected properties:
39
 
        username    - used as a unix login name and svn repository name.
40
 
                      STRING REQUIRED 
41
 
        uid         - the unix uid under which execution will take place
42
 
                      on the behalf of the user. Don't use 0! If not specified
43
 
                      or None, one will be allocated from the configured
44
 
                      numeric range.
45
 
                      INT OPTIONAL
46
 
        password    - the clear-text password for the user. If this property is
47
 
                      absent or None, this is an indication that external
48
 
                      authentication should be used (i.e. LDAP).
49
 
                      STRING OPTIONAL
50
 
        email       - the user's email address.
51
 
                      STRING OPTIONAL
52
 
        nick        - the display name to use.
53
 
                      STRING REQUIRED
54
 
        fullname    - The name of the user for results and/or other official
55
 
                      purposes.
56
 
                      STRING REQUIRED
57
 
        rolenm      - The user's role. Must be one of "anyone", "student",
58
 
                      "tutor", "lecturer", "admin".
59
 
                      STRING/ENUM REQUIRED
60
 
        studentid   - If supplied and not None, the student id of the user for
61
 
                      results and/or other official purposes.
62
 
                      STRING OPTIONAL
63
 
       Return Value: the uid associated with the user. INT
64
 
    """
65
 
 
66
 
    # FIXME: the IVLE server must check that an admin is doing this!
67
 
 
68
 
    if 'uid' not in props or props['uid'] is None:
69
 
        raise NotImplementedError, "No algorithm for creating uids yet!"
70
 
        # uid = invent-uid
71
 
        # props['uid'] = uid
72
 
 
73
 
    username = props['username']
74
 
    uid = props['uid']
75
 
    try:
76
 
        password = props['password']
77
 
    except KeyError:
78
 
        password = None
79
 
    try:
80
 
        email = props['email']
81
 
    except KeyError:
82
 
        email = None
83
 
    nick = props['nick']
84
 
    fullname = props['fullname']
85
 
    rolenm = props['rolenm']
86
 
    try:
87
 
        studentid = props['studentid']
88
 
    except KeyError:
89
 
        studentid = None
90
 
    common.makeuser.make_user_db(username, uid, password, email, nick,
91
 
                                 fullname, rolenm, studentid)
92
 
 
93
 
    return uid
94
 
 
95
 
def get_login(login, passwd, _realm, _login, _may_save):
96
 
    """Callback function used by pysvn for authentication.
97
 
    """
98
 
    # print >> sys.stderr, "Getting password for %s (realm %s)" % (login, _realm)
99
 
    return (True, login, passwd, False)
100
 
 
101
31
def activate_user(props):
102
32
    """Create the on-disk stuff for the given user.
103
33
       Sets the state of the user in the db from pending to enabled.
107
37
       Return Value: None
108
38
    """
109
39
 
 
40
    os.umask(0022) # Bad, but start_server sets it worse.
 
41
 
110
42
    login = props['login']
111
43
 
112
44
    db = common.db.DB()
119
51
 
120
52
        # make svn config/auth
121
53
 
122
 
        # print >> sys.stderr, "Creating repo"
123
 
        common.makeuser.make_svn_repo(login, throw_on_error=False)
124
 
        # print >> sys.stderr, "Creating svn config"
125
 
        common.makeuser.make_svn_config(login, throw_on_error=False)
126
 
        # print >> sys.stderr, "Creating svn auth"
 
54
        repopath = os.path.join(conf.svn_repo_path, 'users', login)
 
55
        logging.debug("Creating user's Subversion repository")
 
56
        common.makeuser.make_svn_repo(repopath, throw_on_error=False)
 
57
 
 
58
        rebuild_svn_config(props)
 
59
 
 
60
        logging.debug("Adding Subversion authentication")
127
61
        passwd = common.makeuser.make_svn_auth(login, throw_on_error=False)
128
 
        # print >> sys.stderr, "passwd: %s" % passwd
129
 
 
130
 
        svn = pysvn.Client()
131
 
        svn.callback_get_login = partial(get_login, login, passwd)
132
 
    
133
 
        # FIXME: This should be a loop over enrolements.
134
 
        #        We're not going to fix this now because it requires
135
 
        #        a large amount of admin console work to manage subject
136
 
        #        offerings.
137
 
        #        Instead, we're just going to use a single offering with
138
 
        #        a "short" name of "info1".
139
 
        # print >> sys.stderr, "Creating /info1"
140
 
        try:
141
 
            svn.mkdir(conf.svn_addr + login + "/info1",
142
 
                      "Initial creation of work directory for Informatics 1")
143
 
        except Exception, exc:
144
 
            pass
145
 
        # print >> sys.stderr, "Creating /submissions"
146
 
        try:
147
 
            svn.mkdir(conf.svn_addr + login + "/submissions",
148
 
                      "Initial creation of submissions directory")
149
 
        except Exception, exc:
150
 
            pass
151
 
        # print >> sys.stderr, "Creating /stuff"
152
 
        try:
153
 
            svn.mkdir(conf.svn_addr + login + "/stuff",
154
 
                      "Initial creation of directory for miscellania")
155
 
        except Exception, exc:
156
 
            pass
157
 
 
158
 
        # print >> sys.stderr, "Creating jail"
159
 
        common.makeuser.make_jail(login, details.unixid)
160
 
 
161
 
        # FIXME: <hack>
162
 
 
163
 
        tcf_path = os.path.join(conf.jail_base, 'template/opt/ivle/lib/conf/conf.py')
164
 
        cf_path = os.path.join(conf.jail_base, login, 'opt/ivle/lib/conf/conf.py')
165
 
 
166
 
        os.remove(cf_path)
167
 
        cf = open(cf_path, "w")
168
 
        cf.write(open(tcf_path, "r").read())
169
 
        cf.write("# The login name for the owner of the jail\n")
170
 
        cf.write("login = %s\n" % repr(login))
171
 
        cf.write("\n")
172
 
        cf.write("# The subversion-only password for the owner of the jail\n")
173
 
        cf.write("svn_pass = %s\n" % repr(passwd))
174
 
        cf.close()
175
 
 
176
 
        # FIXME: </hack>
177
 
 
178
 
        # print >> sys.stderr, "Checking out directories in the jail"
179
 
        try:
180
 
            svn.checkout(conf.svn_addr + "/" + login + "/stuff",
181
 
                         common.studpath.url_to_local(login + "/stuff")[1])
182
 
        except Exception, exc:
183
 
            pass
184
 
        try:
185
 
            svn.checkout(conf.svn_addr + "/" + login + "/submissions",
186
 
                         common.studpath.url_to_local(login + "/submissions")[1])
187
 
        except Exception, exc:
188
 
            pass
189
 
        try:
190
 
            svn.checkout(conf.svn_addr + "/" + login + "/info1",
191
 
                         common.studpath.url_to_local(login + "/info1")[1])
192
 
        except Exception, exc:
193
 
            pass
194
 
 
195
 
        # FIXME: should this be nicer?
196
 
        os.system("chown -R %d:%d %s" \
197
 
                % (details.unixid, details.unixid,
198
 
                   common.studpath.url_to_local(login)[1]))
199
 
 
200
 
 
201
 
        # print >> sys.stderr, "Enabling user"
 
62
        logging.debug("passwd: %s" % passwd)
 
63
 
 
64
        logging.debug("Creating jail")
 
65
        common.makeuser.make_jail(login, details.unixid, svn_pass=passwd)
 
66
 
 
67
        logging.info("Enabling user")
202
68
        db.update_user(login, state='enabled')
203
69
 
204
70
        return {"response": "okay"}
205
 
    
206
 
    except Exception, exc:
207
 
        print >> sys.stderr, exc
208
71
 
209
72
    finally:
210
73
        db.close()
211
74
 
 
75
def rebuild_svn_config(props):
 
76
    """Rebuilds the svn config file
 
77
    Return value:
 
78
        response (okay, failure)
 
79
    """
 
80
    try:
 
81
        common.makeuser.rebuild_svn_config()
 
82
    except Exception, e:
 
83
        logging.warning('Rebuild of Subversion authorization config failed!')
 
84
        return{'response': 'failure', 'msg': repr(e)}
 
85
 
 
86
    return {'response': 'okay'}
 
87
 
 
88
def rebuild_svn_group_config(props):
 
89
    """Rebuilds the svn group config file
 
90
    Return value:
 
91
        response (okay, failure)
 
92
    """
 
93
    try:
 
94
        common.makeuser.rebuild_svn_group_config()
 
95
    except Exception, e:
 
96
        logging.warning(
 
97
            'Rebuild of Subversion group authorization config failed!')
 
98
        return{'response': 'failure', 'msg': repr(e)}
 
99
 
 
100
    return {'response': 'okay'}
 
101
 
 
102
def create_group_repository(props):
 
103
    """Creates on disk repository for the given group
 
104
    Expected properties:
 
105
        subj_short_name, year, semester, groupnm
 
106
    Return value:
 
107
        response (okay, failure)
 
108
    """
 
109
 
 
110
    subj_short_name = props['subj_short_name']
 
111
    year = props['year']
 
112
    semester = props['semester']
 
113
    groupnm = props['groupnm']
 
114
 
 
115
    namespace = "_".join([subj_short_name, year, semester, groupnm])
 
116
    repopath = os.path.join(conf.svn_repo_path, 'groups', namespace)
 
117
    logging.debug("Creating Subversion repository %s"%repopath)
 
118
    try:
 
119
        common.makeuser.make_svn_repo(repopath)
 
120
    except Exception, e:
 
121
        logging.error("Failed to create Subversion repository %s: %s"%
 
122
            (repopath,repr(e)))
 
123
        return {'response': 'failure', 'msg': repr(e)}
 
124
 
 
125
    return {'response': 'okay'}
 
126
 
212
127
actions = {
213
 
        'create_user':create_user,
214
 
        'activate_user':activate_user
 
128
        'activate_user':activate_user,
 
129
        'create_group_repository':create_group_repository,
 
130
        'rebuild_svn_config':rebuild_svn_config,
 
131
        'rebuild_svn_group_config':rebuild_svn_group_config,
215
132
    }
216
133
 
 
134
def initializer():
 
135
    try:
 
136
        pidfile = open('/var/run/usrmgt-server.pid', 'w')
 
137
        pidfile.write('%d\n' % os.getpid())
 
138
        pidfile.close()
 
139
    except IOError, (errno, strerror):
 
140
        print "Couldn't write PID file. IO error(%s): %s" % (errno, strerror)
 
141
        sys.exit(1)
 
142
 
217
143
def dispatch(props):
218
 
    # print >> sys.stderr, repr(props)
 
144
    logging.debug(repr(props))
219
145
    action = props.keys()[0]
220
146
    return actions[action](props[action])
221
147
 
222
148
if __name__ == "__main__":
223
 
    port = int(sys.argv[1])
224
 
    magic = sys.argv[2]
225
 
 
226
 
    common.chat.start_server(port, magic, False, dispatch)
 
149
    pid = os.getpid()
 
150
 
 
151
    logging.basicConfig(filename="/var/log/usrmgt.log", level=logging.INFO)
 
152
    logging.info("Starting usrmgt server on port %d (pid = %d)" %
 
153
                 (conf.usrmgt_port, pid))
 
154
 
 
155
    common.chat.start_server(conf.usrmgt_port, conf.usrmgt_magic, True, dispatch, initializer)