From ad200c89e2ff42ed7939f98ddc44a56c34bf7374 Mon Sep 17 00:00:00 2001
From: Kevin Paxman <kpaxman@uwaterloo.ca>
Date: Mon, 14 Nov 2022 18:33:28 -0500
Subject: [PATCH] EXPHR: Get bulk account creation basically working, minus
 WatIAM lookup and link on people page

---
 src/Form/UwAddUsersForm.php | 76 +++++++++++++++++++++++++++++++++----
 uw_cfg_common.routing.yml   |  2 +-
 2 files changed, 70 insertions(+), 8 deletions(-)

diff --git a/src/Form/UwAddUsersForm.php b/src/Form/UwAddUsersForm.php
index 023992ac..78770c1c 100644
--- a/src/Form/UwAddUsersForm.php
+++ b/src/Form/UwAddUsersForm.php
@@ -22,10 +22,10 @@ class UwAddUsersForm extends FormBase {
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
 
-    // The list of users this form.
+    // The list of users from this form.
     $form['users'] = [
-      '#title' => $this->t('WatIAM user ID(s) (maximum 8 characters per ID)'),
-      '#description' => $this->t('Enter a single WatIAM user ID, or multiple WatIAM user IDs, one per line.<br>You can use <a href="https://idm.uwaterloo.ca/search/" target="_blank">authenticated WatIAM search</a> if you don\'t know their user ID (will open a new window).'),
+      '#title' => $this->t('WatIAM user ID(s): (maximum 8 characters per ID)'),
+      '#description' => $this->t('Enter a single WatIAM user ID, or multiple WatIAM user IDs, one per line. All letters will be converted to lower case. Duplicates will be ignored.<br>You can use <a href="https://idm.uwaterloo.ca/search/" target="_blank">authenticated WatIAM search</a> if you don\'t know their user ID (will open a new window).'),
       '#type' => 'textarea',
       '#required' => TRUE,
     ];
@@ -46,16 +46,78 @@ class UwAddUsersForm extends FormBase {
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
 
-    // The permissions array that was submitted in the form.
+    // The user ID list that was submitted in the form.
     $submitted_users = explode(PHP_EOL, $form_state->getValue('users'));
 
+    // Be nice and remove whitespace.
+    $submitted_users = array_map('trim', $submitted_users);
+
+    // Remove any duplicates.
+    $submitted_users = array_unique($submitted_users);
+
     // Step through each of the submitted users to create if needed/possible,
     // or show a message if not.
     foreach ($submitted_users as $user) {
-      // Let's be nice and remove whitespace.
-      $user = trim($user);
-      $this->messenger()->addStatus($this->t('Normally something would happen here...'));
+      // Make sure the user ID is in lower case.
+      $user = strtolower($user);
+
+      // Ignore blank lines.
+      if (!strlen($user)) {
+        continue;
+      }
+
+      // Don't process long user IDs.
+      if (strlen($user) > 8) {
+        $this->messenger()->addError($this->t('The user ID <em>@user</em> is too long and was skipped.', array('@user' => $user)));
+        continue;
+      }
+
+      // Don't process user IDs with invalid characters.
+      if (!preg_match('/^[a-z0-9]+$/', $user)) {
+        $this->messenger()->addError($this->t('The user ID <em>@user</em> contains invalid characters and was skipped.', array('@user' => $user)));
+        continue;
+      }
+
+      $existing_user = user_load_by_name($user);
+      if ($existing_user) {
+        $this->messenger()->addError($this->t('The user ID <a href="@link"><em>@user</em></a> already exists and was skipped.', array('@link' => \Drupal::service('path_alias.manager')->getAliasByPath('/user/' . $existing_user->uid->value),'@user' => $user)));
+        continue;
+      }
+
+      // Seems OK.
+
+      // Create a strong random password.
+      $sets[] = 'abcdefghijklmnopqrstuvwxyz';
+      $sets[] = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
+      $sets[] = '0123456789';
+      $sets[] = '!@#$%^&*()-_=+[]{}?`~"';
+      $password = '';
+      $password_length = rand(16,32);
+      while(strlen($password) < $password_length) {
+        foreach ($sets as $set) {
+          $password .= $set[array_rand(str_split($set))];
+          if (strlen($password) == $password_length) {
+            break;
+          }
+        }
+      }
+      $password = str_shuffle($password);
+
+      // Add the user.
+      // TODO: look up info from WatIAM.
+      $new_user = \Drupal\user\Entity\User::create();
+      $new_user->setPassword($password);
+      $new_user->enforceIsNew();
+      $new_user->setEmail($user . '@uwaterloo.ca');
+      $new_user->setUsername($user);
+      $new_user->set('field_uw_first_name', 'Firstname');
+      $new_user->set('field_uw_last_name', 'Lastname');
+      $new_user->activate();
+      $new_user->save();
+
+      $this->messenger()->addStatus($this->t('Created a new user with the user ID <a href="@link"><em>@user</em></a>.', array('@link' => \Drupal::service('path_alias.manager')->getAliasByPath('/user/' . $new_user->uid->value),'@user' => $user)));
     }
+
     // Set the message that the users have been created.
     $this->messenger()->addStatus($this->t('Finished creating users.'));
   }
diff --git a/uw_cfg_common.routing.yml b/uw_cfg_common.routing.yml
index 033a9a5e..87ef7aaf 100644
--- a/uw_cfg_common.routing.yml
+++ b/uw_cfg_common.routing.yml
@@ -51,7 +51,7 @@ uw_cfg_common.uw_menu_report_csv:
 uw_add_users.form:
   path: '/admin/add-uwaterloo-users'
   defaults:
-    _title: 'Add UWaterloo User(s)'
+    _title: 'Add UWaterloo user(s)'
     _form: '\Drupal\uw_cfg_common\Form\UwAddUsersForm'
   requirements:
     _permission: 'administer users'
-- 
GitLab