chiark / gitweb /
Found in crybaby's working tree.
[chopwood] / backend.py
index fda32e0b8e37d259090e71f4d6ac864bd407e069..2596306363e7c6171107bdbfa8d26b81de8f40c9 100644 (file)
@@ -44,7 +44,8 @@ CONF.DEFAULTS.update(
 ###--------------------------------------------------------------------------
 ### Utilities.
 
-def fill_in_fields(fno_user, fno_passwd, fno_map, user, passwd, args):
+def fill_in_fields(fno_user, fno_passwd, fno_map,
+                   user, passwd, args, defaults = None):
   """
   Return a vector of filled-in fields.
 
@@ -53,6 +54,10 @@ def fill_in_fields(fno_user, fno_passwd, fno_map, user, passwd, args):
   is a sequence of (NAME, POS) pairs.  The USER and PASSWD arguments give the
   actual user name and password values; ARGS are the remaining arguments,
   maybe in the form `NAME=VALUE'.
+
+  If DEFAULTS is given, it is a fully-filled-in sequence of records.  The
+  user name and password are taken from the DEFAULTS if USER and PASSWD are
+  `None' on entry; they cannot be set from ARGS.
   """
 
   ## Prepare the result vector, and set up some data structures.
@@ -63,7 +68,8 @@ def fill_in_fields(fno_user, fno_passwd, fno_map, user, passwd, args):
   if fno_user >= n or fno_passwd >= n: ok = False
   for k, i in fno_map:
     fmap[k] = i
-    rmap[i] = "`%s'" % k
+    if i in rmap: ok = False
+    else: rmap[i] = "`%s'" % k
     if i >= n: ok = False
   if not ok:
     raise U.ExpectedError, \
@@ -71,8 +77,12 @@ def fill_in_fields(fno_user, fno_passwd, fno_map, user, passwd, args):
 
   ## Prepare the new record's fields.
   f = [None]*n
-  f[fno_user] = user
-  f[fno_passwd] = passwd
+  if user is not None: f[fno_user] = user
+  elif defaults is not None: f[no_user] = defaults[no_user]
+  else: raise U.ExpectedError, (500, "No user name given")
+  if passwd is not None: f[fno_passwd] = passwd
+  elif defaults is not None: f[no_passwd] = defaults[no_passwd]
+  else: raise U.ExpectedError, (500, "No password given")
 
   for a in args:
     if '=' in a:
@@ -89,10 +99,12 @@ def fill_in_fields(fno_user, fno_passwd, fno_map, user, passwd, args):
       raise U.ExpectedError, (400, "Field %s is already set" % rmap[i])
     f[i] = v
 
-  ## Check that the vector of fields is properly set up.
+  ## Check that the vector of fields is properly set up.  Copy unset values
+  ## from the defaults if they're available.
   for i in xrange(n):
-    if f[i] is None:
-      raise U.ExpectedError, (500, "Field %s is unset" % rmap[i])
+    if f[i] is not None: pass
+    elif defaults is not None: f[i] = defaults[i]
+    else: raise U.ExpectedError, (500, "Field %s is unset" % rmap[i])
 
   ## Done.
   return f
@@ -165,7 +177,7 @@ class FlatFileRecord (BasicRecord):
   is careful to do this).
   """
 
-  def __init__(me, line, delim, fmap, *args, **kw):
+  def __init__(me, line, delim, fno_user, fno_passwd, fmap, *args, **kw):
     """
     Initialize the record, splitting the LINE into fields separated by DELIM,
     and setting attributes under control of FMAP.
@@ -174,6 +186,8 @@ class FlatFileRecord (BasicRecord):
     line = line.rstrip('\n')
     fields = line.split(delim)
     me._delim = delim
+    me._fno_user = fno_user
+    me._fno_passwd = fno_passwd
     me._fmap = fmap
     me._raw = fields
     for k, v in fmap.iteritems():
@@ -199,6 +213,14 @@ class FlatFileRecord (BasicRecord):
       fields[v] = val
     return me._delim.join(fields) + '\n'
 
+  def edit(me, args):
+    """
+    Modify the record as described by the ARGS.
+
+    Fields other than the user name and password can be modified.
+    """
+    ff = fill_in_fields(
+
 class FlatFileBackend (object):
   """
   Password storage in a flat passwd(5)-style file.