Skip to content
Snippets Groups Projects
Commit ec53ce8b authored by Sebastian Kehr's avatar Sebastian Kehr :rowboat_tone2: Committed by Dorian Merz
Browse files

refs #15777 [fid] username update feature

* API calls
* menu link
* translations
parent 91768faf
No related merge requests found
......@@ -21,6 +21,7 @@
use fid\Controller\UserController;
use fid\Controller\UserControllerFactory;
use fid\FormModel\UsernameChangeModel;
use fid\FormModel\PasswordChangeModel;
use fid\FormModel\PasswordResetModel;
use fid\FormModel\UserCreateModel;
......@@ -55,6 +56,7 @@ return [
UserUpdateModel::class => require_once 'user-update-form.php',
PasswordResetModel::class => require_once 'password-reset-form.php',
PasswordChangeModel::class => require_once 'password-change-form.php',
UsernameChangeModel::class => require_once 'username-change-form.php',
],
'controllers' => [
'factories' => [
......@@ -227,6 +229,26 @@ return [
'action' => 'changePassword',
],
],
],
'change-username' => [
'type' => 'literal',
'options' => [
'route' => '/change-username',
'defaults' => [
'controller' => UserController::class,
'action' => 'changeUsername',
],
],
],
'update-username' => [
'type' => 'literal',
'options' => [
'route' => '/update-username',
'defaults' => [
'controller' => UserController::class,
'action' => 'updateUsername',
],
],
]
],
],
......@@ -280,4 +302,4 @@ return [
]
],
],
];
\ No newline at end of file
];
<?php
/**
* Copyright (C) 2019 Leipzig University Library
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* @author Sebastian Kehr <kehr@ub.uni-leipzig.de>
* @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2
*/
use Zend\Filter\StringTrim;
use Zend\Form\Element\Email;
use Zend\Form\Element\Submit;
use Zend\Form\Element\Text;
use Zend\Hydrator\ClassMethods;
use Zend\Validator\EmailAddress;
use Zend\Validator\Identical;
use Zend\Validator\StringLength;
return [
'hydrator' => ClassMethods::class,
'elements' => [
'username' => [
'spec' => [
'name' => 'username',
'type' => Email::class,
'options' => [
'label' => 'label_newusername',
],
'attributes' => [
'required' => 'required',
],
],
],
'usernameConfirmation' => [
'spec' => [
'name' => 'usernameConfirmation',
'type' => Text::class,
'options' => [
'label' => 'label_newusername_confirmation',
],
'attributes' => [
'required' => 'required',
],
],
],
'submit' => [
'spec' => [
'name' => 'submit',
'type' => Submit::class,
'attributes' => [
'value' => 'label_submit',
],
],
],
],
'input_filter' => [
'username' => [
'name' => 'username',
'required' => true,
'filters' => [
StringTrim::class => [
'name' => StringTrim::class,
],
],
'validators' => [
StringLength::class => [
'name' => StringLength::class,
'options' => [
'max' => 255
],
],
EmailAddress::class => [
'name' => EmailAddress::class,
],
],
],
'usernameConfirmation' => [
'name' => 'usernameConfirmation',
'required' => true,
'validators' => [
Identical::class => [
'name' => Identical::class,
'options' => [
'strict' => false,
'token' => 'username',
'messages' => [
Identical::NOT_SAME => 'error_username_confirmation',
],
],
],
],
],
'submit' => [
'name' => 'submit',
'required' => true,
],
],
];
......@@ -27,6 +27,7 @@ use fid\FormModel\PasswordResetModel;
use fid\FormModel\UserCreateModel;
use fid\FormModel\UserInitModel;
use fid\FormModel\UserUpdateModel;
use fid\FormModel\UsernameChangeModel;
use fid\Service\Client;
use fid\Service\ClientException;
use fid\Service\DataTransferObject\Library;
......@@ -86,6 +87,7 @@ class UserController extends AbstractBase
}
/**
* @noinspection PhpUnused
* @return ViewModel
*/
public function initAction()
......@@ -110,6 +112,7 @@ class UserController extends AbstractBase
}
/**
* @noinspection PhpUnused
* @return Response|ViewModel
*/
public function createAction()
......@@ -177,6 +180,11 @@ class UserController extends AbstractBase
return $view;
}
/**
* @noinspection PhpUnused
* @return Response|ViewModel
*/
public function updateAction()
{
/** @var Request $request */
......@@ -217,6 +225,73 @@ class UserController extends AbstractBase
return $viewModel;
}
/**
* @noinspection PhpUnused
* @return ViewModel
*/
public function changeUsernameAction()
{
/** @var Request $request */
$request = $this->getRequest();
$form = $this->serviceLocator->get(UsernameChangeModel::class);
$forwarded = $this->params()->fromRoute('forwarded', false);
if ($submitted = $this->formWasSubmitted()) {
$form->setData($request->getPost());
if (!$forwarded && $form->isValid()) {
return $this->changeUsername($form);
}
}
$view = $this->createViewModel();
$view->setVariables(compact('form'));
$view->setTemplate('fid/user/username-change');
return $view;
}
/**
* @noinspection PhpUnused
* @return Response
*/
public function updateUsernameAction()
{
/** @var Request $request */
$request = $this->getRequest();
$query = $request->getQuery();
$messenger = $this->getMessenger();
if ($credentials = $query->get('logon')) {
try {
$this->client->logon($credentials);
} catch (ClientException $exception) {
$message = $exception->getCode() === 401
? 'fid::username_update_error_expired'
: 'fid::username_update_error';
$messenger->addErrorMessage($this->translate($message));
return $this->redirect()->toRoute('fid/user/change-username');
}
$query->offsetUnset('logon');
return $this->redirect()->toRoute('fid/user/update-username', [], [
'query' => $query->toArray()
]);
}
try {
$user = $this->client->requestUserDetails();
$user->setUsername($query->get('username'));
$this->client->requestUserUsernameUpdate($user);
$message = $this->translate('fid::username_update_success');
$this->getMessenger()->addSuccessMessage($message);
} catch (ClientException $exception) {
$message = $this->translate('fid::username_update_error');
$this->getMessenger()->addErrorMessage($message);
}
return $this->redirect()->toRoute('myresearch-home');
}
public function policyAction()
{
$viewModel = $this->createViewModel();
......@@ -498,6 +573,35 @@ class UserController extends AbstractBase
]);
}
protected function changeUsername(Form $form)
{
$messenger = $this->getMessenger();
$model = $form->getHydrator()->hydrate(
$form->getData(), new UsernameChangeModel());
/** @noinspection PhpUndefinedFieldInspection */
$query['lng'] = $this->layout()->userLang;
$username = $query['username'] = $model->getUsername();
$baseUrl = $this->url()->fromRoute('fid/user/update-username',
[], ['query' => $query, 'force_canonical' => true]);
try {
$this->client->requestUsernameLink($baseUrl, $username);
} catch (ClientException $exception) {
$message = $exception->getCode() === 400
? 'fid::username_change_error_username'
: 'fid::username_change_error';
$messenger->addErrorMessage($this->translate($message));
return $this->forward()->dispatch(self::class, [
'action' => 'changeUsername',
'forwarded' => true
]);
}
$message = $this->translate('fid::username_change_success');
$messenger->addSuccessMessage(sprintf($message, $username));
return $this->redirect()->toRoute('myresearch-home');
}
protected function getMessenger(): FlashMessenger
{
......@@ -662,4 +766,4 @@ class UserController extends AbstractBase
return $viewModel;
}
}
\ No newline at end of file
}
<?php
/**
* Copyright (C) 2019 Leipzig University Library
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* @author Gregor Gawol <gawol@ub.uni-leipzig.de>
* @author Sebastian Kehr <kehr@ub.uni-leipzig.de>
* @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2
*/
namespace fid\FormModel;
class UsernameChangeModel
{
/**
* @var string
*/
protected $username;
/**
* @var string
*/
protected $usernameConfirmation;
/**
* @var string
*/
protected $submit;
/**
* @return string
*/
public function getUsername(): string
{
return $this->username;
}
/**
* @param string $username
*/
public function setUsername(string $username): void
{
$this->username = $username;
}
/**
* @return string
*/
public function getUsernameConfirmation(): string
{
return $this->usernameConfirmation;
}
/**
* @param string $usernameConfirmation
*/
public function setUsernameConfirmation(string $usernameConfirmation): void
{
$this->usernameConfirmation = $usernameConfirmation;
}
/**
* @return string
*/
public function getSubmit(): string
{
return $this->submit;
}
/**
* @param string $submit
*/
public function setSubmit(string $submit): void
{
$this->submit = $submit;
}
}
......@@ -241,6 +241,22 @@ class Client
}
}
/**
* @param string $baseUrl
* @param string $username
*
* @throws ClientException
*/
public function requestUsernameLink(string $baseUrl, string $username): void
{
$body = json_encode(compact('baseUrl', 'username'));
$request = $this->buildRequest('post', 'mail/username', $body);
$response = $this->sendAuthenticatedRequest($request);
if ($response->getStatusCode() !== 204) {
$this->throwException($response);
}
}
/**
* @return User|null
......@@ -327,6 +343,19 @@ class Client
['user:update-password:request']);
}
/**
* @param User $user
*
* @return User
* @throws ClientException
*/
public function requestUserUsernameUpdate(User $user): User
{
return $this->doRequestUserUpdate($user, [
'user:update-username:request'
]);
}
/**
* @return User[]
* @throws ClientException
......
......@@ -41,7 +41,8 @@ class User
* "user:details:response",
* "user:creation:request",
* "user:creation:response",
* "user:update:response"
* "user:update:response",
* "user:update-username:request"
* })
*/
protected $username;
......
......@@ -6,9 +6,12 @@ user_create_form_title = "Registrierung abschließen"
user_update_form_title = "Profildaten editieren."
password_reset_form_title = "Passwort zurücksetzen"
password_change_form_title = "Neues Passwort speichern"
username_change_form_title = "E-Mail-Adresse ändern"
label_username = "E-Mail-Adresse"
label_newusername = "Neue E-Mail-Adresse"
label_username_confirmation = "E-Mail-Adresse wiederholen"
label_newusername_confirmation = "Neue E-Mail-Adresse wiederholen"
label_firstname = "Vorname"
label_lastname = "Nachname"
label_salutation = "Anrede"
......@@ -71,8 +74,18 @@ password_change_error_expired = "Der Link ist abgelaufen."
password_change_error_autologon = "Ihr Passwort wurde gespeichert. Jedoch ist ein unerwarteteter Fehler bei der automatischen Anmeldung aufgetreten."
password_change_success = "Passwort erfolgreich gespeichert."
username_change_link = "E-Mail-Adresse ändern"
username_change_error = "Es ist ein unerwarteter Fehler aufgetreten."
username_change_error_username = "Die von Ihnen gewählte E-Mail-Adresse ist schon vergeben."
username_change_success = "Ein Verifikationslink wurde soeben an Ihre neue E-Mail-Addresse %s gesendet. Die Zustellung kann einige Minuten in Anspruch nehmen. Bitte schauen Sie ggf. auch in Ihren Spamordner."
username_update_error = "Es ist ein unerwarteter Fehler beim Aktualisieren Ihrer E-Mail-Adresse aufgetreten."
username_update_error_expired = "Ihr Verifikationslink ist bereits abgelaufen. Bitte starten Sie den Vorgang erneut."
username_update_success = "Ihre E-Mail-Addresse wurde erfolgreich aktualisiert."
Edit Account = "Profildaten ändern"
access_level_requested = "Ihre Zugehörigkeit zur unten stehenden Gruppe wird derzeit noch überprüft."
; Admin section
......
......@@ -6,9 +6,12 @@ user_create_form_title = "Complete registration"
user_update_form_title = "Profile data"
password_reset_form_title = "Reset password"
password_change_form_title = "Save new password"
username_change_form_title = "Update email address"
label_username = "Email address"
label_newusername = "New email address"
label_username_confirmation = "Retype email address"
label_newusername_confirmation = "Retype new email address"
label_password = "Password"
label_password_confirmation = "Retype Password"
label_salutation = "Salutation"
......@@ -71,6 +74,15 @@ password_change_error = "An unexpected error has occurred."
password_change_error_expired = "The link has already expired."
password_change_error_autologon = "You password has been update. However, an unexpected error has occurred during the process of logging on."
username_change_link = "Update email address"
username_change_error = "An unexpected error has occurred."
username_change_error_username = "The specified email address is already taken."
username_change_success = "A confirmation link has just been sent to your new email address %s. This may take several minutes. Please check also the junk folder of your mailbox."
username_update_error = "An unexpected error has occurred when updating your email address."
username_update_error_expired = "Your configmration link has already expired."
username_update_success = "Your email address has successfully been updated."
Edit Account = "Edit Account"
access_level_requested = "Your membership status regarding the group below is currently being verified."
......
<?php
/**
* Copyright (C) 2019 Leipzig University Library
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* @author Gregor Gawol <gawol@ub.uni-leipzig.de>
* @author Sebastian Kehr <kehr@ub.uni-leipzig.de>
* @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2
*/
use Zend\Form\Element;
use Zend\Form\Form;
use Zend\Form\View\Helper\FormElementErrors;
use Zend\Form\View\Helper\FormLabel;
use Zend\Form\View\Helper\FormSubmit;
use Zend\I18n\Translator\TranslatorInterface;
/** @var FormLabel $formLabel */
$formLabel = $this->formLabel();
/**@var FormSubmit $formSubmit */
$formSubmit = $this->formSubmit();
/** @var FormElementErrors $formElementErrors */
$formElementErrors = $this->formElementErrors();
$formLabel->setTranslatorTextDomain('fid');
$formSubmit->setTranslatorTextDomain('fid');
$formElementErrors->setTranslatorTextDomain('fid');
/** @var TranslatorInterface $translator */
$translator = $this->getHelperPluginManager()->get('translate')
->getTranslator();
$formLabel->setTranslator($translator);
$formElementErrors->setTranslator($translator);
/** @var Form $form */
$form = $this->form;
$form->setAttribute('method', 'post');
$form->setAttribute('action', $this->url('fid/user/change-username'));
$form->setAttribute('class', 'registration');
$form->prepare();
$this->headTitle($this->translate("fid::username_change_form_title"));
?>
<h2><?= $this->translate("fid::username_change_form_title") ?></h2>
<div class="subito-pg">
* <?=$this->transEsc("This field is required")?>
</div>
<?= $this->flashmessages() ?>
<?= $this->form()->openTag($form) ?>
<br/>
<? /* username */ ?>
<?php
/** @var Element\Text $elemUsername */
$elemUsername = $form->get('username');
$elemUsername->setLabelAttributes(['class' => 'control-label']);
$elemUsername->setAttributes(['class' => 'form-control']);
?>
<div class="form-group">
<?= $this->formLabel($elemUsername) ?>
<?= $this->formElement($elemUsername) ?>
<?= $this->formElementErrors($elemUsername) ?>
</div>
<? /* username confirmation */ ?>
<?php
/** @var Element\Text $elemUsernameConfirmation */
$elemUsernameConfirmation = $form->get('usernameConfirmation');
$elemUsernameConfirmation->setLabelAttributes(['class' => 'control-label']);
$elemUsernameConfirmation->setAttributes(['class' => 'form-control']);
?>
<div class="form-group">
<?= $this->formLabel($elemUsernameConfirmation) ?>
<?= $this->formElement($elemUsernameConfirmation) ?>
<?= $this->formElementErrors($elemUsernameConfirmation) ?>
</div>
<? /* submit button */ ?>
<?php
/** @var Element\Submit $elemSubmit */
$elemSubmit = $form->get('submit');
$elemSubmit->setAttributes(['class' => 'btn btn-primary']);
?>
<div class="form-group">
<a class="back-to-login btn btn-link" href="<?=$this->url('myresearch-userlogin') ?>">
<i class="fa fa-chevron-left" aria-hidden="true"></i>
<?=$this->transEsc('Back')?>
</a>
<?= $this->formElement($elemSubmit) ?>
</div>
<?= $this->form()->closeTag($form) ?>
......@@ -69,6 +69,15 @@
</a>
<? endif; ?>
<?php if ($this->auth()->isLoggedIn()): ?>
<a href="<?=$this->url('fid/user/change-username')?>" data-lightbox>
<span class="no-padding">
<i class="fa fa-fw fa-envelope" aria-hidden="true"></i>
</span>
<?=$this->transEsc('fid::username_change_link')?>
</a>
<? endif; ?>
<?php if ($user = $this->auth()->isLoggedIn()): ?>
<span class="logout-button">
<a href="<?=$this->url('myresearch-logout')?>">
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment