display-accts: run user consistency checks

Make sure people don't accidentally add a group with a user that
doesn't actually exist.  This catches the "user" group which says
it wants a user named "games", but that user doesn't exist.

BUG=None
TEST=`./display-accts.py` passes
CQ-DEPEND=CL:273720

Change-Id: I96b1e582ce9aad9f06d6b8fdc72b9f1ee815a06b
Reviewed-on: https://chromium-review.googlesource.com/273112
Reviewed-by: Christopher Wiley <wiley@chromium.org>
Commit-Queue: Mike Frysinger <vapier@chromium.org>
Tested-by: Mike Frysinger <vapier@chromium.org>
diff --git a/profiles/base/accounts/display-accts.py b/profiles/base/accounts/display-accts.py
index e88fdf5..a5fb3c4 100755
--- a/profiles/base/accounts/display-accts.py
+++ b/profiles/base/accounts/display-accts.py
@@ -110,6 +110,30 @@
     p(a)
 
 
+def CheckConsistency(groups, users):
+  """Run various consistency/sanity checks on the lists of groups/users.
+
+  This does not check for syntax/etc... errors on a per-account basis as the
+  main _ParseAccount function above took care of that.
+  """
+  found_users = set(x.user for x in users)
+  want_users = set()
+  for group in groups:
+    if group.users:
+      want_users.update(group.users.split(','))
+
+  missing_users = want_users - found_users
+  if missing_users:
+    print('error: group lists unknown users', file=sys.stderr)
+    for group in groups:
+      for user in missing_users:
+        if user in group.users.split(','):
+          print('error: group "%s" wants missing user "%s"' %
+                (group.group, user), file=sys.stderr)
+
+  return not bool(missing_users)
+
+
 def GetParser():
   """Creates the argparse parser."""
   parser = argparse.ArgumentParser(description=__doc__)
@@ -123,10 +147,12 @@
   opts = parser.parse_args(argv)
 
   accounts = opts.account
+  consistency_check = False
   if not accounts:
     accounts_dir = os.path.dirname(os.path.realpath(__file__))
     accounts = (glob.glob(os.path.join(accounts_dir, 'group', '*')) +
                 glob.glob(os.path.join(accounts_dir, 'user', '*')))
+    consistency_check = True
 
   groups = []
   users = []
@@ -139,7 +165,7 @@
       else:
         users.append(ParseUser(name, content))
     except ValueError as e:
-      print('error: %s: %s' % (f, e))
+      print('error: %s: %s' % (f, e), file=sys.stderr)
       return os.EX_DATAERR
 
   if groups:
@@ -167,6 +193,9 @@
     )
     DisplayAccounts(users, order)
 
+  if consistency_check and not CheckConsistency(groups, users):
+    return os.EX_DATAERR
+
 
 if __name__ == '__main__':
   exit(main(sys.argv[1:]))
diff --git a/profiles/base/accounts/group/users b/profiles/base/accounts/group/users
index fd42ca1..307011c 100644
--- a/profiles/base/accounts/group/users
+++ b/profiles/base/accounts/group/users
@@ -1,3 +1,2 @@
 group:users
 gid:100
-users:games