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

« back to all changes in this revision

Viewing changes to scripts/usrmgt-server

  • Committer: wagrant
  • Date: 2008-07-22 01:12:38 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:929
CodePress: Use the text cursor over the entire <pre>.

Show diffs side-by-side

added added

removed removed

Lines of Context:
8
8
from functools import partial
9
9
import traceback
10
10
import logging
 
11
import errno
11
12
 
12
13
import conf
13
14
import common.db
64
65
       Return Value: the uid associated with the user. INT
65
66
    """
66
67
 
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
68
    common.makeuser.make_user_db(**props)
78
 
 
79
 
    return int(props['unixid'])
 
69
    user = common.db.get_user(props["login"])
 
70
    return user["unixid"]
80
71
 
81
72
def update_user(props):
82
73
    """Create the database record for the given user.
97
88
    db.update_user(**update)
98
89
    db.close()
99
90
 
100
 
def get_login(login, passwd, _realm, _login, _may_save):
 
91
def get_login(login, passwd, realm, existing_login, _may_save):
101
92
    """Callback function used by pysvn for authentication.
 
93
    login, passwd: Credentials of the user attempting to log in.
 
94
        passwd in clear (this should be the user's svn_pass, a
 
95
        randomly-generated permanent password for this user, not their main
 
96
        IVLE password).
 
97
    realm, existing_login, _may_save: The 3 arguments passed by pysvn to
 
98
        callback_get_login.
 
99
        The following has been determined empirically, not from docs:
 
100
        existing_login will be the name of the user who owns the process on
 
101
        the first attempt, "" on subsequent attempts. We use this fact.
102
102
    """
103
 
    logging.debug("Getting password for %s (realm %s)" % (login, _realm))
104
 
    return (True, login, passwd, False)
 
103
    logging.debug("Getting password for %s (realm %s)" % (login, realm))
 
104
    # Only provide credentials on the _first_ attempt.
 
105
    # If we're being asked again, then it means the credentials failed for
 
106
    # some reason and we should just fail. (This is not desirable, but it's
 
107
    # better than being asked an infinite number of times).
 
108
    if existing_login == "":
 
109
        logging.warning("Could not authenticate SVN for %s" % login)
 
110
        return (False, login, passwd, False)
 
111
    else:
 
112
        return (True, login, passwd, False)
105
113
 
106
114
def activate_user(props):
107
115
    """Create the on-disk stuff for the given user.
112
120
       Return Value: None
113
121
    """
114
122
 
 
123
    os.umask(0022) # Bad, but start_server sets it worse.
 
124
 
115
125
    login = props['login']
116
126
 
117
127
    db = common.db.DB()
160
170
            pass
161
171
 
162
172
        logging.debug("Creating jail")
163
 
        common.makeuser.make_jail(login, details.unixid)
164
 
 
165
 
        # FIXME: <hack>
166
 
 
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')
169
 
 
170
 
        os.remove(cf_path)
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))
175
 
        cf.write("\n")
176
 
        cf.write("# The subversion-only password for the owner of the jail\n")
177
 
        cf.write("svn_pass = %s\n" % repr(passwd))
178
 
        cf.close()
179
 
 
180
 
        # FIXME: </hack>
181
 
 
182
 
        logging.debug("Checking out directories in the jail")
183
 
        try:
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))
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
 
            logging.warning("While mkdiring info1: %s" % str(exc))
194
 
            pass
 
173
        common.makeuser.make_jail(login, details.unixid, svn_pass=passwd)
 
174
 
 
175
        common.makeuser.mount_jail(login)
 
176
 
 
177
        do_checkout(props, svn_pass=passwd)
195
178
 
196
179
        # FIXME: should this be nicer?
197
180
        os.system("chown -R %d:%d %s" \
198
181
                % (details.unixid, details.unixid,
199
182
                   common.studpath.url_to_local(login)[1]))
200
183
 
201
 
 
202
184
        logging.info("Enabling user")
203
185
        db.update_user(login, state='enabled')
204
186
 
207
189
    finally:
208
190
        db.close()
209
191
 
 
192
def do_checkout(props, svn_pass=None):
 
193
    """Create the default contents of a user's jail by checking out from the
 
194
    repositories.
 
195
    If any directory already exists, just fail silently (so this is not a
 
196
    "wipe-and-checkout", merely a checkout if it failed or something).
 
197
       Expected properties:
 
198
        login       - the user name for the jail
 
199
                      STRING REQUIRED
 
200
       Return Value: None
 
201
    """
 
202
    login = props['login']
 
203
 
 
204
    db = common.db.DB()
 
205
    user = db.get_user(login)
 
206
    # If svn_pass isn't supplied, grab it from the DB
 
207
    if svn_pass is None:
 
208
        svn_pass = user.svn_pass
 
209
    db.close()
 
210
 
 
211
    svn = pysvn.Client()
 
212
    svn.callback_get_login = partial(get_login, login, svn_pass)
 
213
 
 
214
    if conf.svn_addr[-1] != os.sep:
 
215
        conf.svn_addr += os.sep
 
216
 
 
217
    # FIXME: <hack>
 
218
 
 
219
    logging.debug("Checking out directories in the jail")
 
220
    try:
 
221
        svn.checkout(conf.svn_addr + login + "/stuff",
 
222
                     common.studpath.url_to_local(login + "/stuff")[1])
 
223
        os.system("chown -R %d:%d %s" \
 
224
                % (user.unixid, user.unixid,
 
225
                   common.studpath.url_to_local(login + "/stuff")[1]))
 
226
    except Exception, exc:
 
227
        logging.warning("While mkdiring stuff: %s" % str(exc))
 
228
        pass
 
229
    try:
 
230
        svn.checkout(conf.svn_addr + login + "/info1",
 
231
                     common.studpath.url_to_local(login + "/info1")[1])
 
232
        os.system("chown -R %d:%d %s" \
 
233
                % (user.unixid, user.unixid,
 
234
                   common.studpath.url_to_local(login + "/info1")[1]))
 
235
    except Exception, exc:
 
236
        logging.warning("While mkdiring info1: %s" % str(exc))
 
237
        pass
 
238
 
 
239
    # FIXME: </hack>
 
240
 
 
241
    return {"response": "okay"}
 
242
 
210
243
actions = {
211
244
        'create_user':create_user,
212
245
        'update_user':update_user,
213
246
        'activate_user':activate_user,
 
247
        'do_checkout':do_checkout,
214
248
    }
215
249
 
 
250
def initializer():
 
251
    try:
 
252
        pidfile = open('/var/run/usrmgt-server.pid', 'w')
 
253
        pidfile.write('%d\n' % os.getpid())
 
254
        pidfile.close()
 
255
    except IOError, (errno, strerror):
 
256
        print "Couldn't write PID file. IO error(%s): %s" % (errno, strerror)
 
257
        sys.exit(1)
 
258
 
216
259
def dispatch(props):
217
260
    logging.debug(repr(props))
218
261
    action = props.keys()[0]
230
273
    logging.basicConfig(filename="/var/log/usrmgt.log", level=logging.INFO)
231
274
    logging.info("Starting usrmgt server on port %d (pid = %d)" % (port, pid))
232
275
 
233
 
    common.chat.start_server(port, magic, True, dispatch)
 
276
    common.chat.start_server(port, magic, True, dispatch, initializer)