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

« back to all changes in this revision

Viewing changes to lib/common/db.py

  • Committer: mattgiuca
  • Date: 2008-03-09 21:37:04 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:677
userservice: Fix error message text.
usrmgt-server: Major fix - missing create svn object.

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
import conf
36
36
import md5
37
37
import copy
 
38
import time
38
39
 
39
40
from common import (caps, user)
40
41
 
 
42
TIMESTAMP_FORMAT = '%Y-%m-%d %H:%M:%S'
 
43
 
41
44
def _escape(val):
42
45
    """Wrapper around pg.escape_string. Prepares the Python value for use in
43
46
    SQL. Returns a string, which may be safely placed verbatim into an SQL
67
70
        return str(val)
68
71
    elif isinstance(val, caps.Role):
69
72
        return _escape(str(val))
 
73
    elif isinstance(val, time.struct_time):
 
74
        return _escape(time.strftime(TIMESTAMP_FORMAT, val))
70
75
    else:
71
76
        raise DBException("Attempt to insert an unsupported type "
72
77
            "into the database")
140
145
        Raises a DBException if the dictionary contains invalid fields.
141
146
        """
142
147
        if not DB.check_dict(dict, tablefields, disallowed):
143
 
            raise DBException("Supplied dictionary contains invalid fields.")
 
148
            extras = set(dict.keys()) - tablefields
 
149
            raise DBException("Supplied dictionary contains invalid fields. (%s)" % (repr(extras)))
144
150
        # Build two lists concurrently: field names and values, as SQL strings
145
151
        fieldnames = []
146
152
        values = []
172
178
        """
173
179
        if (not (DB.check_dict(primarydict, primary_keys, must=True)
174
180
            and DB.check_dict(updatedict, tablefields, disallowed_update))):
175
 
            raise DBException("Supplied dictionary contains invalid or "
176
 
                " missing fields.")
 
181
            raise DBException("Supplied dictionary contains invalid or missing fields (1).")
177
182
        # Make a list of SQL fragments of the form "field = 'new value'"
178
183
        # These fragments are ALREADY-ESCAPED
179
184
        setlist = []
199
204
        primarydict, tablename, primary_keys: See update.
200
205
        """
201
206
        if not DB.check_dict(primarydict, primary_keys, must=True):
202
 
            raise DBException("Supplied dictionary contains invalid or "
203
 
                " missing fields.")
 
207
            raise DBException("Supplied dictionary contains invalid or missing fields (2).")
204
208
        wherelist = []
205
209
        for k,v in primarydict.items():
206
210
            wherelist.append("%s = %s" % (k, _escape(v)))
225
229
            primary_keys is indeed the primary key).
226
230
        """
227
231
        if not DB.check_dict(primarydict, primary_keys, must=True):
228
 
            raise DBException("Supplied dictionary contains invalid or "
229
 
                " missing fields.")
 
232
            raise DBException("Supplied dictionary contains invalid or missing fields (3).")
230
233
        wherelist = []
231
234
        for k,v in primarydict.items():
232
235
            wherelist.append("%s = %s" % (k, _escape(v)))
289
292
    login_primary = frozenset(["login"])
290
293
    login_fields_list = [
291
294
        "login", "passhash", "state", "unixid", "email", "nick", "fullname",
292
 
        "rolenm", "studentid", "acct_exp", "pass_exp", "last_login"
 
295
        "rolenm", "studentid", "acct_exp", "pass_exp", "last_login", "svn_pass"
293
296
    ]
294
297
    login_fields = frozenset(login_fields_list)
295
 
    # Do not return passhash when reading from the DB
296
 
    login_getfields = login_fields - frozenset(["passhash"])
297
298
 
298
 
    def create_user(self, dry=False, **kwargs):
 
299
    def create_user(self, user_obj=None, dry=False, **kwargs):
299
300
        """Creates a user login entry in the database.
 
301
        Two ways to call this - passing a user object, or passing
 
302
        all fields as separate arguments.
 
303
 
 
304
        Either pass a "user_obj" as the first argument (in which case other
 
305
        fields will be ignored), or pass all fields as arguments.
 
306
 
300
307
        All user fields are to be passed as args. The argument names
301
308
        are the field names of the "login" table of the DB schema.
302
309
        However, instead of supplying a "passhash", you must supply a
307
314
        invalid keys or is missing required keys.
308
315
        """
309
316
        if 'passhash' in kwargs:
310
 
            raise DBException("Supplied arguments include passhash (invalid).")
 
317
            raise DBException("Supplied arguments include passhash (invalid) (1).")
311
318
        # Make a copy of the dict. Change password to passhash (hashing it),
312
319
        # and set 'state' to "no_agreement".
313
 
        kwargs = copy.copy(kwargs)
314
 
        if 'password' in kwargs:
315
 
            kwargs['passhash'] = _passhash(kwargs['password'])
316
 
            del kwargs['password']
317
 
        kwargs['state'] = "no_agreement"
 
320
        if user_obj is None:
 
321
            # Use the kwargs
 
322
            fields = copy.copy(kwargs)
 
323
        else:
 
324
            # Use the user object
 
325
            fields = dict(user_obj)
 
326
        if 'password' in fields:
 
327
            fields['passhash'] = _passhash(fields['password'])
 
328
            del fields['password']
 
329
        if 'role' in fields:
 
330
            # Convert role to rolenm
 
331
            fields['rolenm'] = str(user_obj.role)
 
332
            del fields['role']
 
333
        if user_obj is None:
 
334
            fields['state'] = "no_agreement"
 
335
            # else, we'll trust the user, but it SHOULD be "no_agreement"
 
336
            # (We can't change it because then the user object would not
 
337
            # reflect the DB).
 
338
        if 'local_password' in fields:
 
339
            del fields['local_password']
318
340
        # Execute the query.
319
 
        return self.insert(kwargs, "login", self.login_fields, dry=dry)
 
341
        return self.insert(fields, "login", self.login_fields, dry=dry)
320
342
 
321
343
    def update_user(self, login, dry=False, **kwargs):
322
344
        """Updates fields of a particular user. login is the name of the user
333
355
        with a new one.
334
356
        """
335
357
        if 'passhash' in kwargs:
336
 
            raise DBException("Supplied arguments include passhash (invalid).")
 
358
            raise DBException("Supplied arguments include passhash (invalid) (2).")
337
359
        if "password" in kwargs:
338
360
            kwargs = copy.copy(kwargs)
339
361
            kwargs['passhash'] = _passhash(kwargs['password'])
349
371
        Raises a DBException if the login is not found in the DB.
350
372
        """
351
373
        userdict = self.get_single({"login": login}, "login",
352
 
            self.login_getfields, self.login_primary,
 
374
            self.login_fields, self.login_primary,
353
375
            error_notfound="get_user: No user with that login name", dry=dry)
354
376
        if dry:
355
377
            return userdict     # Query string
359
381
    def get_users(self, dry=False):
360
382
        """Returns a list of all users in the DB, as User objects.
361
383
        """
362
 
        userdicts = self.get_all("login", self.login_getfields, dry=dry)
 
384
        userdicts = self.get_all("login", self.login_fields, dry=dry)
363
385
        if dry:
364
386
            return userdicts    # Query string
365
387
        # Package into User objects
368
390
    def user_authenticate(self, login, password, dry=False):
369
391
        """Performs a password authentication on a user. Returns True if
370
392
        "passhash" is the correct passhash for the given login, False
371
 
        otherwise.
 
393
        if the passhash does not match the password in the DB,
 
394
        and None if the passhash in the DB is NULL.
372
395
        Also returns False if the login does not exist (so if you want to
373
396
        differentiate these cases, use get_user and catch an exception).
374
397
        """
375
 
        query = ("SELECT login FROM login "
376
 
            "WHERE login = '%s' AND passhash = %s;"
377
 
            % (login, _escape(_passhash(password))))
 
398
        query = "SELECT passhash FROM login WHERE login = '%s';" % login
378
399
        if dry: return query
379
400
        result = self.db.query(query)
380
 
        # If one row was returned, succeed.
381
 
        # Otherwise, fail to authenticate.
382
 
        return result.ntuples() == 1
 
401
        if result.ntuples() == 1:
 
402
            # Valid username. Check password.
 
403
            passhash = result.getresult()[0][0]
 
404
            if passhash is None:
 
405
                return None
 
406
            return _passhash(password) == passhash
 
407
        else:
 
408
            return False
383
409
 
384
410
    def close(self):
385
411
        """Close the DB connection. Do not call any other functions after