From 36ef4ec06b5108961f5ba0db8483c0a68c8aaa30 Mon Sep 17 00:00:00 2001
From: Dominik Frantisek Bucik <bucik@ics.muni.cz>
Date: Fri, 1 Sep 2023 16:43:22 +0200
Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Forgotten=20username=20f?=
 =?UTF-8?q?low?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 dictionaries/lsaai.definition.json            |   9 +
 dictionaries/pwd_reset.definition.json        |   3 +
 .../username_reminder.definition.json         |  32 +++
 lib/TemplateHelper.php                        |  42 ++++
 templates/pwd_reset-tpl.php                   |   4 +
 templates/username_reminder-tpl.php           | 196 ++++++++++++++++++
 themes/lsusernamelogin/core/loginuserpass.php |  16 +-
 www/username_reminder.php                     |  12 ++
 8 files changed, 310 insertions(+), 4 deletions(-)
 create mode 100644 dictionaries/username_reminder.definition.json
 create mode 100644 templates/username_reminder-tpl.php
 create mode 100644 www/username_reminder.php

diff --git a/dictionaries/lsaai.definition.json b/dictionaries/lsaai.definition.json
index f145830..b5c6bc6 100644
--- a/dictionaries/lsaai.definition.json
+++ b/dictionaries/lsaai.definition.json
@@ -11,12 +11,21 @@
   "login_button_register": {
     "en": "Sign up"
   },
+  "forgot_password": {
+    "en": "Forgotten password? Recover it here."
+  },
+  "forgot_username": {
+    "en": "Forgotten username? Recover it here."
+  },
   "email": {
     "en": "Email"
   },
   "login_button_forgotten_password": {
     "en": "Forgotten password"
   },
+  "login_button_forgotten_username": {
+    "en": "Forgotten username"
+  },
   "title_WRONGUSERPASS": {
     "en": "Incorrect username or password"
   },
diff --git a/dictionaries/pwd_reset.definition.json b/dictionaries/pwd_reset.definition.json
index 62c19fa..199e1e8 100644
--- a/dictionaries/pwd_reset.definition.json
+++ b/dictionaries/pwd_reset.definition.json
@@ -23,6 +23,9 @@
   "err_text_part2": {
     "en": "If you have problem with recovering your password, please contact "
   },
+  "button_forgotten_username": {
+    "en": "Forgot your username?"
+  },
   "support": {
     "en": "support"
   },
diff --git a/dictionaries/username_reminder.definition.json b/dictionaries/username_reminder.definition.json
new file mode 100644
index 0000000..badc99e
--- /dev/null
+++ b/dictionaries/username_reminder.definition.json
@@ -0,0 +1,32 @@
+{
+  "header": {
+    "en": "Forgot your username?"
+  },
+  "email": {
+    "en": "Email"
+  },
+  "text": {
+    "en": "Enter your email address. We'll send you the username if an account exists associated with the specified email."
+  },
+  "ok_header": {
+    "en": "Check the inbox."
+  },
+  "ok_text": {
+    "em": " If there is an account associated with the specified email, you will see your username."
+  },
+  "err_header": {
+    "en": "Something went wrong"
+  },
+  "err_text_part1": {
+    "en": "Oops, there has been a problem on our side. Please contact "
+  },
+  "err_text_part2": {
+    "en": "In the message, please specify that you have been trying to get an LS Username reminder and do not forget to include the email address you have used."
+  },
+  "support": {
+    "en": "support"
+  },
+  "submit": {
+    "en": "Submit"
+  }
+}
diff --git a/lib/TemplateHelper.php b/lib/TemplateHelper.php
index 71ce0df..93f4659 100644
--- a/lib/TemplateHelper.php
+++ b/lib/TemplateHelper.php
@@ -68,6 +68,48 @@ class TemplateHelper
         Logger::debug(print_r($response, true));
     }
 
+    public static function sendUsernameReminder($email)
+    {
+        $rpcAdapter = new AdapterRpc();
+
+        $conf = Configuration::getConfig(TemplateHelper::CONFIG_FILE_NAME);
+        $pwdConf = $conf->getConfigItem(TemplateHelper::PWD_RESET);
+        $voShortName = $pwdConf->getString(TemplateHelper::PWDRESET_VO_SHORT_NAME);
+        $perunNamespace = $pwdConf->getString(TemplateHelper::PWDRESET_PERUN_NAMESPACE);
+        $emailAttr = $pwdConf->getString(TemplateHelper::PWDRESET_PERUN_EMAIL_ATTR);
+
+        $userName = trim($email);
+        Logger::debug(print_r($email, true));
+
+        try {
+            $user = $rpcAdapter->getPerunUserByEmail($emailAttr, $email);
+            Logger::debug(print_r($user, true));
+        } catch (Exception $ex) {
+            throw new Exception($ex);
+        }
+        if (null === $user) {
+            throw new Exception('There is no Lifescience RI user with username: ' . $userName);
+        }
+
+        $vo = $rpcAdapter->getVoByShortName($voShortName);
+        $member = $rpcAdapter->getMemberByUser($user, $vo);
+
+        $connector = $rpcAdapter->getConnector();
+
+        $response = $connector->post(
+            'membersManager',
+            'sendUsernameReminderEmail',
+            [
+                'member' => $member->getId(),
+                'namespace' => $perunNamespace,
+                'emailAttributeURN' => $emailAttr,
+                'language' => TemplateHelper::LANG_EN,
+            ]
+        );
+
+        Logger::debug(print_r($response, true));
+    }
+
     /**
      * Recursive attribute array listing function.
      *
diff --git a/templates/pwd_reset-tpl.php b/templates/pwd_reset-tpl.php
index 4923f9a..37f2477 100644
--- a/templates/pwd_reset-tpl.php
+++ b/templates/pwd_reset-tpl.php
@@ -183,6 +183,10 @@ echo $onLoad; ?>>
                                 echo $this->t('{lsaai:pwd_reset:submit}'); ?>
                             </button>
                         </div>
+                      <a class="btn btn-link" href="<?php
+                          echo SimpleSAML\Module::getModuleURL("lsaai/username_reminder.php");?>">
+                          <?php echo $this->t('{lsaai:pwd_reset:button_forgotten_username}')?>
+                      </a>
                     </form>
 
                     <?php
diff --git a/templates/username_reminder-tpl.php b/templates/username_reminder-tpl.php
new file mode 100644
index 0000000..f0385be
--- /dev/null
+++ b/templates/username_reminder-tpl.php
@@ -0,0 +1,196 @@
+<?php
+
+declare(strict_types=1);
+
+use SimpleSAML\Configuration;
+use SimpleSAML\Logger;
+use SimpleSAML\Module\lsaai\TemplateHelper;
+
+$config = Configuration::getInstance();
+
+if (!isset($_POST['usernameReminderOk'])) {
+    $_POST['usernameReminderOk'] = false;
+}
+
+/*
+ * Support the htmlinject hook, which allows modules to change header, pre and post body on all pages.
+ */
+$this->data['htmlinject'] = [
+    'htmlContentPre' => [],
+    'htmlContentPost' => [],
+    'htmlContentHead' => [],
+];
+
+$jquery = [];
+if (array_key_exists('jquery', $this->data)) {
+    $jquery = $this->data['jquery'];
+}
+
+if (array_key_exists('pageid', $this->data)) {
+    $hookinfo = [
+        'pre' => &$this->data['htmlinject']['htmlContentPre'],
+        'post' => &$this->data['htmlinject']['htmlContentPost'],
+        'head' => &$this->data['htmlinject']['htmlContentHead'],
+        'jquery' => &$jquery,
+        'page' => $this->data['pageid'],
+    ];
+
+    SimpleSAML\Module::callHooks('htmlinject', $hookinfo);
+}
+
+header('X-Frame-Options: SAMEORIGIN');
+
+?><!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+    <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0"/>
+    <script type="text/javascript" src="/<?php
+    echo $this->data['baseurlpath']; ?>resources/script.js"></script>
+    <title>LS Username Login</title>
+
+    <link rel="stylesheet" type="text/css" href="/<?php
+    echo $this->data['baseurlpath']; ?>resources/default.css"/>
+    <link rel="icon" type="image/icon" href="/<?php
+    echo $this->data['baseurlpath']; ?>resources/icons/favicon.ico"/>
+
+    <?php
+
+    if (!empty($this->data['htmlinject']['htmlContentHead'])) {
+        foreach ($this->data['htmlinject']['htmlContentHead'] as $c) {
+            echo $c;
+        }
+    }
+
+    if ($this->isLanguageRTL()) {
+        ?>
+        <link rel="stylesheet" type="text/css" href="/<?php
+        echo $this->data['baseurlpath']; ?>resources/default-rtl.css"/>
+        <?php
+    }
+    ?>
+
+    <link rel="stylesheet" type="text/css" href="<?php
+    echo SimpleSAML\Module::getModuleUrl('lsaai/res/bootstrap/css/bootstrap.min.css'); ?>"/>
+    <link rel="stylesheet" type="text/css" href="<?php
+    echo SimpleSAML\Module::getModuleUrl('lsaai/res/css/lsaai.css'); ?>"/>
+
+    <meta name="robots" content="noindex, nofollow"/>
+
+
+    <?php
+    if (array_key_exists('head', $this->data)) {
+        echo '<!-- head -->' . $this->data['head'] . '<!-- /head -->';
+    }
+    ?>
+</head>
+<?php
+$onLoad = '';
+if (array_key_exists('autofocus', $this->data)) {
+    $onLoad .= 'SimpleSAML_focus(\'' . $this->data['autofocus'] . '\');';
+}
+if (isset($this->data['onLoad'])) {
+    $onLoad .= $this->data['onLoad'];
+}
+
+if ('' !== $onLoad) {
+    $onLoad = ' onload="' . $onLoad . '"';
+}
+?>
+<body<?php
+echo $onLoad; ?>>
+
+
+<div id="wrap">
+
+    <div id="content" class="content">
+        <div class="row pl-0 pr-0">
+            <div class="col-md-6 col-md-offset-3 logo-wrap col-align--center">
+                <img src="<?php
+                echo SimpleSAML\Module::getModuleUrl('lsaai/res/img/ls_logo.png'); ?>" alt="LS Username Login Logo">
+            </div>
+            <div class="col-md-6 col-md-offset-3">
+                <?php
+                echo '<h1> ' . $this->t('{lsaai:username_reminder:header}') . '</h1>';
+                $userEmail = '';
+                if (isset($_POST['email'])) {
+                    $userEmail = $_POST['email'];
+                    try {
+                        if (!$_POST['usernameReminderOk']) {
+                            TemplateHelper::sendUsernameReminder($userEmail);
+                            $_POST['usernameReminderOk'] = true;
+                            unset($_POST['email']);
+                        } ?>
+                        <div class="alert alert-success">
+                            <p>
+                                <span class="glyphicon glyphicon-exclamation-sign"
+                                      style="float:left; font-size: 38px; margin-right: 10px;"></span>
+                                <strong><?php
+                                    echo $this->t('{lsaai:username_reminder:ok_header}'); ?></strong>
+                            </p>
+                            <p><?php
+                                echo $this->t('{lsaai:username_reminder:ok_text}'); ?></p>
+                        </div>
+
+                        <?php
+                    } catch (\Exception $exception) {
+                        Logger::error('username_reminder-tpl.php - ' . $exception->getMessage());
+                        $emailAddress = $config->getString('technicalcontact_email');
+                        if (!str_starts_with('mailto:', $emailAddress)) {
+                            $emailAddress = 'mailto:' . $emailAddress;
+                        } ?>
+                        <div class="alert alert-danger">
+                            <span class="glyphicon glyphicon-exclamation-sign"
+                                  style="float:left; font-size: 38px; margin-right: 10px;"></span>
+                            <strong><?php
+                                echo $this->t('{lsaai:username_reminder:err_header}'); ?></strong>
+                            <p><?php
+                                echo $this->t('{lsaai:username_reminder:err_text_part1}'); ?>
+                                <a href="<?php
+                                  echo $emailAddress; ?>">
+                                  <?php echo $this->t('{lsaai:username_reminder:support}'); ?></a>.
+                                  <?php echo $this->t('{lsaai:username_reminder:err_text_part2}'); ?>
+                            </p>
+                        </div>
+
+                        <?php
+                    }
+                }
+
+                if (!$_POST['usernameReminderOk']) {
+                    ?>
+
+                    <p><?php
+                        echo $this->t('{lsaai:username_reminder:text}'); ?></p>
+
+                    <br>
+
+                    <form action="" method="post" name="username_reminder" class="form-horizontal">
+                        <div class="form-group">
+                            <label class="sr-only" for="inlineFormInputGroup"><?php
+                                echo $this->t('{lsaai:username_reminder:email}'); ?></label>
+                            <div class="input-group mb-2">
+                            <span class="input-group-addon">
+                                    <span class=" glyphicon glyphicon-envelope" id="basic-addon1"></span>
+                            </span>
+                                <input id="email" name="email" class="form-control" value="<?php
+                                echo $userEmail; ?>" placeholder="Email address" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+
+                        <div class="form-group">
+                            <button class="btn btn-success btn-block" type="submit">
+                                <?php
+                                echo $this->t('{lsaai:username_reminder:submit}'); ?>
+                            </button>
+                        </div>
+                    </form>
+
+                    <?php
+                }
+                ?>
+            </div>
+
+<?php
+
+$this->includeAtTemplateBase('includes/footer.php');
diff --git a/themes/lsusernamelogin/core/loginuserpass.php b/themes/lsusernamelogin/core/loginuserpass.php
index 6776ec7..2aa7e91 100644
--- a/themes/lsusernamelogin/core/loginuserpass.php
+++ b/themes/lsusernamelogin/core/loginuserpass.php
@@ -183,11 +183,15 @@ echo $onLoad; ?>>
                             </p>
                                 <?php
                             } ?>
-                        <a class="btn btn-link" href="<?php
+                      <a class="btn btn-link" href="<?php
                         echo SimpleSAML\Module::getModuleURL('lsaai/pwd_reset.php'); ?>">
-                            <?php
-                            echo $this->t('{lsaai:lsaai:forgot_password}'); ?>
-                        </a>
+                          <?php echo $this->t('{lsaai:lsaai:forgot_password}'); ?>
+                      </a>
+                      <br/>
+                      <a class="btn btn-link" href="<?php
+                          echo SimpleSAML\Module::getModuleURL('lsaai/username_reminder.php'); ?>">
+                            <?php echo $this->t('{lsaai:lsaai:forgot_username}'); ?>
+                      </a>
                     </div>
                     <?php
                 }
@@ -235,6 +239,10 @@ echo $onLoad; ?>>
                             <?php
                             echo $this->t('{lsaai:lsaai:login_button_forgotten_password}')?>
                         </a>
+                        <a class="btn btn-link" href="<?php
+                        echo SimpleSAML\Module::getModuleURL("lsaai/username_reminder.php");?>">
+                          <?php echo $this->t('{lsaai:lsaai:login_button_forgotten_username}')?>
+                        </a>
                     </div>
                     <?php
                     foreach ($this->data['stateparams'] as $name => $value) {
diff --git a/www/username_reminder.php b/www/username_reminder.php
new file mode 100644
index 0000000..6e77f6e
--- /dev/null
+++ b/www/username_reminder.php
@@ -0,0 +1,12 @@
+<?php
+
+declare(strict_types=1);
+
+use SimpleSAML\Configuration;
+use SimpleSAML\Module\perun\AdapterRpc;
+use SimpleSAML\XHTML\Template;
+
+$config = Configuration::getInstance();
+
+$t = new Template($config, 'lsaai:username_reminder-tpl.php');
+$t->show();
-- 
GitLab