Merge branch 'main' into avm99963-monorail

Merged commit 34d8229ae2b51fb1a15bd208e6fe6185c94f6266

GitOrigin-RevId: 7ee0917f93a577e475f8e09526dd144d245593f4
diff --git a/services/user_svc.py b/services/user_svc.py
index 28ad465..3307cfd 100644
--- a/services/user_svc.py
+++ b/services/user_svc.py
@@ -1,7 +1,6 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file or at
-# https://developers.google.com/open-source/licenses/bsd
+# Copyright 2016 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
 
 """A set of functions that provide persistence for users.
 
@@ -21,7 +20,7 @@
 from framework import framework_helpers
 from framework import sql
 from framework import validate
-from proto import user_pb2
+from mrproto import user_pb2
 from services import caches
 
 
@@ -204,9 +203,23 @@
     """Create many users in the database."""
     emails = [email.lower() for email in emails]
     ids = [framework_helpers.MurmurHash3_x86_32(email) for email in emails]
+
+    rows = self.user_tbl.Select(cnxn, cols=('user_id',), user_id=ids)
+    existing_ids = set(row[0] for row in rows)
+    if existing_ids:
+      existing_users = sorted(
+          (user_id, email)
+          for (user_id, email) in zip(ids, emails)
+          if user_id in existing_ids)
+      logging.error(
+          'Unable to create users because IDs are already taken: %.100000s',
+          existing_users)
+
     row_values = [
-      (user_id, email, not framework_bizobj.IsPriviledgedDomainUser(email))
-      for (user_id, email) in zip(ids, emails)]
+        (user_id, email, not framework_bizobj.IsPriviledgedDomainUser(email))
+        for (user_id, email) in zip(ids, emails)
+        if user_id not in existing_ids
+    ]
     self.user_tbl.InsertRows(
         cnxn, ['user_id', 'email', 'obscure_email'], row_values)
     self.user_2lc.InvalidateKeys(cnxn, ids)