first commit
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/user/form/APIProfileForm.php
|
||||
*
|
||||
* Copyright (c) 2014-2021 Simon Fraser University
|
||||
* Copyright (c) 2003-2021 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class APIProfileForm
|
||||
*
|
||||
* @ingroup user_form
|
||||
*
|
||||
* @brief Form to edit user's API key settings.
|
||||
*/
|
||||
|
||||
namespace PKP\user\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\notification\NotificationManager;
|
||||
use APP\template\TemplateManager;
|
||||
use Firebase\JWT\JWT;
|
||||
use PKP\config\Config;
|
||||
use PKP\notification\PKPNotification;
|
||||
use PKP\user\User;
|
||||
|
||||
class APIProfileForm extends BaseProfileForm
|
||||
{
|
||||
public const API_KEY_NEW = 1;
|
||||
public const API_KEY_DELETE = 0;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function __construct($user)
|
||||
{
|
||||
parent::__construct('user/apiProfileForm.tpl', $user);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::initData()
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
$user = $this->getUser();
|
||||
$this->setData('apiKeyEnabled', (bool) $user->getData('apiKeyEnabled'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
parent::readInputData();
|
||||
|
||||
$this->readUserVars([
|
||||
'apiKeyEnabled',
|
||||
'generateApiKey',
|
||||
'apiKeyAction',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the form to edit user's API key settings.
|
||||
*
|
||||
* @see BaseProfileForm::fetch
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*
|
||||
* @return string JSON-encoded form contents.
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$user = $request->getUser();
|
||||
$secret = Config::getVar('security', 'api_key_secret', '');
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
|
||||
if ($secret === '') {
|
||||
$this->handleOnMissingAPISecret($templateMgr, $user);
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
$templateMgr->assign(
|
||||
$user->getData('apiKey') ? [
|
||||
'apiKey' => JWT::encode($user->getData('apiKey'), $secret, 'HS256'),
|
||||
'apiKeyAction' => self::API_KEY_DELETE,
|
||||
'apiKeyActionTextKey' => 'user.apiKey.remove',
|
||||
] : [
|
||||
'apiKeyAction' => self::API_KEY_NEW,
|
||||
'apiKeyActionTextKey' => 'user.apiKey.generate',
|
||||
]
|
||||
);
|
||||
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$request = Application::get()->getRequest();
|
||||
$user = $request->getUser();
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
|
||||
if (Config::getVar('security', 'api_key_secret', '') === '') {
|
||||
$this->handleOnMissingAPISecret($templateMgr, $user);
|
||||
parent::execute(...$functionArgs);
|
||||
}
|
||||
|
||||
$apiKeyAction = (int)$this->getData('apiKeyAction');
|
||||
|
||||
$user->setData('apiKeyEnabled', $apiKeyAction === self::API_KEY_NEW ? 1 : null);
|
||||
$user->setData('apiKey', $apiKeyAction === self::API_KEY_NEW ? sha1(time()) : null);
|
||||
|
||||
$this->setData('apiKeyAction', (int)!$apiKeyAction);
|
||||
|
||||
parent::execute(...$functionArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle on missing API secret
|
||||
*
|
||||
*
|
||||
*/
|
||||
protected function handleOnMissingAPISecret(TemplateManager $templateMgr, User $user): void
|
||||
{
|
||||
$notificationManager = new NotificationManager();
|
||||
$notificationManager->createTrivialNotification(
|
||||
$user->getId(),
|
||||
PKPNotification::NOTIFICATION_TYPE_WARNING,
|
||||
[
|
||||
'contents' => __('user.apiKey.secretRequired'),
|
||||
]
|
||||
);
|
||||
$templateMgr->assign([
|
||||
'apiSecretMissing' => true,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\user\form\APIProfileForm', '\APIProfileForm');
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/user/form/BaseProfileForm.php
|
||||
*
|
||||
* Copyright (c) 2014-2021 Simon Fraser University
|
||||
* Copyright (c) 2003-2021 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class BaseProfileForm
|
||||
*
|
||||
* @ingroup user_form
|
||||
*
|
||||
* @brief Base form to edit an aspect of user profile.
|
||||
*/
|
||||
|
||||
namespace PKP\user\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use PKP\form\Form;
|
||||
use PKP\session\SessionManager;
|
||||
use PKP\user\User;
|
||||
|
||||
abstract class BaseProfileForm extends Form
|
||||
{
|
||||
/** @var User */
|
||||
public $_user;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $template
|
||||
* @param User $user
|
||||
*/
|
||||
public function __construct($template, $user)
|
||||
{
|
||||
parent::__construct($template);
|
||||
|
||||
$this->_user = $user;
|
||||
assert(isset($user));
|
||||
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorPost($this));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCSRF($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user associated with this profile
|
||||
*/
|
||||
public function getUser()
|
||||
{
|
||||
return $this->_user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
parent::execute(...$functionArgs);
|
||||
|
||||
$request = Application::get()->getRequest();
|
||||
$user = $request->getUser();
|
||||
Repo::user()->edit($user);
|
||||
|
||||
if ($functionArgs['emailUpdated'] ?? false) {
|
||||
$sessionManager = SessionManager::getManager();
|
||||
$session = $sessionManager->getUserSession();
|
||||
|
||||
if ($session->getSessionVar('email')) {
|
||||
$session->setSessionVar('email', $user->getEmail());
|
||||
}
|
||||
|
||||
$sessionManager->invalidateSessions($user->getId(), $sessionManager->getUserSession()->getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\user\form\BaseProfileForm', '\BaseProfileForm');
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/user/form/ChangePasswordForm.php
|
||||
*
|
||||
* Copyright (c) 2014-2021 Simon Fraser University
|
||||
* Copyright (c) 2003-2021 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class ChangePasswordForm
|
||||
*
|
||||
* @ingroup user_form
|
||||
*
|
||||
* @brief Form to change a user's password.
|
||||
*/
|
||||
|
||||
namespace PKP\user\form;
|
||||
|
||||
use APP\facades\Repo;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\form\Form;
|
||||
use PKP\security\Validation;
|
||||
use PKP\site\Site;
|
||||
use PKP\user\User;
|
||||
|
||||
class ChangePasswordForm extends Form
|
||||
{
|
||||
/** @var User */
|
||||
public $_user;
|
||||
|
||||
/** @var Site */
|
||||
public $_site;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param User $user
|
||||
* @param Site $site
|
||||
*/
|
||||
public function __construct($user, $site)
|
||||
{
|
||||
parent::__construct('user/changePassword.tpl');
|
||||
|
||||
$this->_user = $user;
|
||||
$this->_site = $site;
|
||||
|
||||
// Validation checks for this form
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'oldPassword', 'required', 'user.profile.form.oldPasswordInvalid', function ($password) use ($user) {
|
||||
return Validation::checkCredentials($user->getUsername(), $password);
|
||||
}));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorLength($this, 'password', 'required', 'user.register.form.passwordLengthRestriction', '>=', $site->getMinPasswordLength()));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidator($this, 'password', 'required', 'user.profile.form.newPasswordRequired'));
|
||||
$form = $this;
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'password', 'required', 'user.register.form.passwordsDoNotMatch', function ($password) use ($form) {
|
||||
return $password == $form->getData('password2');
|
||||
}));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'password', 'required', 'user.profile.form.passwordSameAsOld', function ($password) use ($form) {
|
||||
return $password != $form->getData('oldPassword');
|
||||
}));
|
||||
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorPost($this));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCSRF($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user associated with this password
|
||||
*/
|
||||
public function getUser()
|
||||
{
|
||||
return $this->_user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the site
|
||||
*/
|
||||
public function getSite()
|
||||
{
|
||||
return $this->_site;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::fetch
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager();
|
||||
$templateMgr->assign([
|
||||
'minPasswordLength' => $this->getSite()->getMinPasswordLength(),
|
||||
'username' => $this->getUser()->getUsername(),
|
||||
]);
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
$this->readUserVars(['oldPassword', 'password', 'password2']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$user = $this->getUser();
|
||||
$user->setPassword(Validation::encryptCredentials($user->getUsername(), $this->getData('password')));
|
||||
parent::execute(...$functionArgs);
|
||||
Repo::user()->edit($user);
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\user\form\ChangePasswordForm', '\ChangePasswordForm');
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/user/form/ContactForm.php
|
||||
*
|
||||
* Copyright (c) 2014-2021 Simon Fraser University
|
||||
* Copyright (c) 2003-2021 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class ContactForm
|
||||
*
|
||||
* @ingroup user_form
|
||||
*
|
||||
* @brief Form to edit user's contact information.
|
||||
*/
|
||||
|
||||
namespace PKP\user\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\facades\Locale;
|
||||
use PKP\user\User;
|
||||
|
||||
class ContactForm extends BaseProfileForm
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function __construct($user)
|
||||
{
|
||||
parent::__construct('user/contactForm.tpl', $user);
|
||||
|
||||
// Validation checks for this form
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorEmail($this, 'email', 'required', 'user.profile.form.emailRequired'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidator($this, 'country', 'required', 'user.profile.form.countryRequired'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom(
|
||||
$this,
|
||||
'email',
|
||||
'required',
|
||||
'user.register.form.emailExists',
|
||||
function (string $email, int $userId) {
|
||||
if ($user = Repo::user()->getByEmail($email, true)) {
|
||||
return (int)$user->getId() === $userId;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
[(int)$user->getId()]
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc BaseProfileForm::fetch
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$site = $request->getSite();
|
||||
$countries = [];
|
||||
foreach (Locale::getCountries() as $country) {
|
||||
$countries[$country->getAlpha2()] = $country->getLocalName();
|
||||
}
|
||||
asort($countries);
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign([
|
||||
'countries' => $countries,
|
||||
'availableLocales' => $site->getSupportedLocaleNames(),
|
||||
]);
|
||||
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc BaseProfileForm::initData()
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
$user = $this->getUser();
|
||||
|
||||
$this->_data = [
|
||||
'country' => $user->getCountry(),
|
||||
'email' => $user->getEmail(),
|
||||
'phone' => $user->getPhone(),
|
||||
'signature' => $user->getSignature(null), // Localized
|
||||
'mailingAddress' => $user->getMailingAddress(),
|
||||
'affiliation' => $user->getAffiliation(null), // Localized
|
||||
'locales' => $user->getLocales(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
parent::readInputData();
|
||||
|
||||
$this->readUserVars([
|
||||
'country', 'email', 'signature', 'phone', 'mailingAddress', 'affiliation', 'locales',
|
||||
]);
|
||||
|
||||
if ($this->getData('locales') == null || !is_array($this->getData('locales'))) {
|
||||
$this->setData('locales', []);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$user = $this->getUser();
|
||||
$functionArgs['emailUpdated'] = $user->getEmail() !== $this->getData('email');
|
||||
|
||||
$user->setCountry($this->getData('country'));
|
||||
$user->setEmail($this->getData('email'));
|
||||
$user->setSignature($this->getData('signature'), null); // Localized
|
||||
$user->setPhone($this->getData('phone'));
|
||||
$user->setMailingAddress($this->getData('mailingAddress'));
|
||||
$user->setAffiliation($this->getData('affiliation'), null); // Localized
|
||||
|
||||
$request = Application::get()->getRequest();
|
||||
$site = $request->getSite();
|
||||
$availableLocales = $site->getSupportedLocales();
|
||||
$locales = [];
|
||||
foreach ($this->getData('locales') as $locale) {
|
||||
if (Locale::isLocaleValid($locale) && in_array($locale, $availableLocales)) {
|
||||
array_push($locales, $locale);
|
||||
}
|
||||
}
|
||||
$user->setLocales($locales);
|
||||
|
||||
parent::execute(...$functionArgs);
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\user\form\ContactForm', '\ContactForm');
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/user/form/IdentityForm.php
|
||||
*
|
||||
* Copyright (c) 2014-2021 Simon Fraser University
|
||||
* Copyright (c) 2003-2021 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class IdentityForm
|
||||
*
|
||||
* @ingroup user_form
|
||||
*
|
||||
* @brief Form to edit user's identity information.
|
||||
*/
|
||||
|
||||
namespace PKP\user\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\user\User;
|
||||
|
||||
class IdentityForm extends BaseProfileForm
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function __construct($user)
|
||||
{
|
||||
parent::__construct('user/identityForm.tpl', $user);
|
||||
|
||||
// the users register for the site, thus
|
||||
// the site primary locale is the required default locale
|
||||
$site = Application::get()->getRequest()->getSite();
|
||||
$this->addSupportedFormLocale($site->getPrimaryLocale());
|
||||
|
||||
// Validation checks for this form
|
||||
$form = $this;
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorLocale($this, 'givenName', 'required', 'user.profile.form.givenNameRequired', $site->getPrimaryLocale()));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'familyName', 'optional', 'user.profile.form.givenNameRequired.locale', function ($familyName) use ($form) {
|
||||
$givenNames = $form->getData('givenName');
|
||||
foreach ($familyName as $locale => $value) {
|
||||
if (!empty($value) && empty($givenNames[$locale])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc BaseProfileForm::fetch
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
|
||||
$user = $this->getUser();
|
||||
$templateMgr->assign([
|
||||
'username' => $user->getUsername(),
|
||||
]);
|
||||
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc BaseProfileForm::initData()
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
$user = $this->getUser();
|
||||
|
||||
$this->_data = [
|
||||
'givenName' => $user->getGivenName(null),
|
||||
'familyName' => $user->getFamilyName(null),
|
||||
'preferredPublicName' => $user->getPreferredPublicName(null),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
parent::readInputData();
|
||||
|
||||
$this->readUserVars([
|
||||
'givenName', 'familyName', 'preferredPublicName',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$request = Application::get()->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
||||
$user->setGivenName($this->getData('givenName'), null);
|
||||
$user->setFamilyName($this->getData('familyName'), null);
|
||||
$user->setPreferredPublicName($this->getData('preferredPublicName'), null);
|
||||
|
||||
parent::execute(...$functionArgs);
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\user\form\IdentityForm', '\IdentityForm');
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/user/form/LoginChangePasswordForm.php
|
||||
*
|
||||
* Copyright (c) 2014-2021 Simon Fraser University
|
||||
* Copyright (c) 2003-2021 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class LoginChangePasswordForm
|
||||
*
|
||||
* @ingroup user_form
|
||||
*
|
||||
* @brief Form to change a user's password in order to login.
|
||||
*/
|
||||
|
||||
namespace PKP\user\form;
|
||||
|
||||
use APP\facades\Repo;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\form\Form;
|
||||
use PKP\security\Validation;
|
||||
use PKP\site\Site;
|
||||
|
||||
class LoginChangePasswordForm extends Form
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Site $site
|
||||
*/
|
||||
public function __construct($site)
|
||||
{
|
||||
parent::__construct('user/loginChangePassword.tpl');
|
||||
|
||||
// Validation checks for this form
|
||||
$form = $this;
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'oldPassword', 'required', 'user.profile.form.oldPasswordInvalid', function ($password) use ($form) {
|
||||
return Validation::checkCredentials($form->getData('username'), $password);
|
||||
}));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorLength($this, 'password', 'required', 'user.register.form.passwordLengthRestriction', '>=', $site->getMinPasswordLength()));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidator($this, 'password', 'required', 'user.profile.form.newPasswordRequired'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'password', 'required', 'user.register.form.passwordsDoNotMatch', function ($password) use ($form) {
|
||||
return $password == $form->getData('password2');
|
||||
}));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorPost($this));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCSRF($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::display
|
||||
*
|
||||
* @param null|mixed $request
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function display($request = null, $template = null)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$site = $request->getSite();
|
||||
$templateMgr->assign('minPasswordLength', $site->getMinPasswordLength());
|
||||
parent::display($request, $template);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
$this->readUserVars(['username', 'oldPassword', 'password', 'password2']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*
|
||||
* @return bool success
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$user = Repo::user()->getByUsername($this->getData('username'), false);
|
||||
parent::execute(...$functionArgs);
|
||||
if ($user != null) {
|
||||
$user->setPassword(Validation::encryptCredentials($user->getUsername(), $this->getData('password')));
|
||||
$user->setMustChangePassword(0);
|
||||
Repo::user()->edit($user);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\user\form\LoginChangePasswordForm', '\LoginChangePasswordForm');
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/user/form/PublicProfileForm.php
|
||||
*
|
||||
* Copyright (c) 2014-2021 Simon Fraser University
|
||||
* Copyright (c) 2003-2021 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class PublicProfileForm
|
||||
*
|
||||
* @ingroup user_form
|
||||
*
|
||||
* @brief Form to edit user's public profile.
|
||||
*/
|
||||
|
||||
namespace PKP\user\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use APP\file\PublicFileManager;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\core\Core;
|
||||
use PKP\user\User;
|
||||
|
||||
class PublicProfileForm extends BaseProfileForm
|
||||
{
|
||||
public const PROFILE_IMAGE_MAX_WIDTH = 150;
|
||||
public const PROFILE_IMAGE_MAX_HEIGHT = 150;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function __construct($user)
|
||||
{
|
||||
parent::__construct('user/publicProfileForm.tpl', $user);
|
||||
|
||||
// Validation checks for this form
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorORCID($this, 'orcid', 'optional', 'user.orcid.orcidInvalid'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorUrl($this, 'userUrl', 'optional', 'user.profile.form.urlInvalid'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc BaseProfileForm::initData()
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
$user = $this->getUser();
|
||||
|
||||
$this->_data = [
|
||||
'orcid' => $user->getOrcid(),
|
||||
'userUrl' => $user->getUrl(),
|
||||
'biography' => $user->getBiography(null), // Localized
|
||||
];
|
||||
|
||||
parent::initData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
parent::readInputData();
|
||||
|
||||
$this->readUserVars([
|
||||
'orcid', 'userUrl', 'biography',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload a profile image.
|
||||
*
|
||||
* @return bool True iff success.
|
||||
*/
|
||||
public function uploadProfileImage()
|
||||
{
|
||||
if (!Application::get()->getRequest()->checkCSRF()) {
|
||||
throw new \Exception('CSRF mismatch!');
|
||||
}
|
||||
|
||||
$publicFileManager = new PublicFileManager();
|
||||
|
||||
$user = $this->getUser();
|
||||
$type = $publicFileManager->getUploadedFileType('uploadedFile');
|
||||
$extension = $publicFileManager->getImageExtension($type);
|
||||
if (!$extension) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$uploadName = 'profileImage-' . (int) $user->getId() . $extension;
|
||||
if (!$publicFileManager->uploadSiteFile('uploadedFile', $uploadName)) {
|
||||
return false;
|
||||
}
|
||||
$filePath = $publicFileManager->getSiteFilesPath();
|
||||
[$width, $height] = getimagesize($filePath . '/' . $uploadName);
|
||||
|
||||
if ($width > self::PROFILE_IMAGE_MAX_WIDTH || $height > self::PROFILE_IMAGE_MAX_HEIGHT || $width <= 0 || $height <= 0) {
|
||||
$userSetting = null;
|
||||
$user->setData('profileImage', $userSetting);
|
||||
Repo::user()->edit($user, ['profileImage']);
|
||||
$publicFileManager->removeSiteFile($filePath);
|
||||
return false;
|
||||
}
|
||||
|
||||
$user->setData('profileImage', [
|
||||
'name' => $publicFileManager->getUploadedFileName('uploadedFile'),
|
||||
'uploadName' => $uploadName,
|
||||
'width' => $width,
|
||||
'height' => $height,
|
||||
'dateUploaded' => Core::getCurrentDate(),
|
||||
]);
|
||||
Repo::user()->edit($user, ['profileImage']);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a profile image.
|
||||
*
|
||||
* @return bool True iff success.
|
||||
*/
|
||||
public function deleteProfileImage()
|
||||
{
|
||||
if (!Application::get()->getRequest()->checkCSRF()) {
|
||||
throw new \Exception('CSRF mismatch!');
|
||||
}
|
||||
|
||||
$user = $this->getUser();
|
||||
$profileImage = $user->getData('profileImage');
|
||||
if (!$profileImage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$publicFileManager = new PublicFileManager();
|
||||
if ($publicFileManager->removeSiteFile($profileImage['uploadName'])) {
|
||||
$user->setData('profileImage', null);
|
||||
Repo::user()->edit($user, ['profileImage']);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc BaseProfileForm::fetch
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
|
||||
$publicFileManager = new PublicFileManager();
|
||||
$templateMgr->assign([
|
||||
'profileImage' => $request->getUser()->getData('profileImage'),
|
||||
'profileImageMaxWidth' => self::PROFILE_IMAGE_MAX_WIDTH,
|
||||
'profileImageMaxHeight' => self::PROFILE_IMAGE_MAX_HEIGHT,
|
||||
'publicSiteFilesPath' => $publicFileManager->getSiteFilesPath(),
|
||||
]);
|
||||
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$request = Application::get()->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
||||
$user->setOrcid($this->getData('orcid'));
|
||||
$user->setUrl($this->getData('userUrl'));
|
||||
$user->setBiography($this->getData('biography'), null); // Localized
|
||||
|
||||
parent::execute(...$functionArgs);
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\user\form\PublicProfileForm', '\PublicProfileForm');
|
||||
}
|
||||
@@ -0,0 +1,313 @@
|
||||
<?php
|
||||
/**
|
||||
* @defgroup user_form User Forms
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file classes/user/form/RegistrationForm.php
|
||||
*
|
||||
* Copyright (c) 2014-2021 Simon Fraser University
|
||||
* Copyright (c) 2003-2021 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class RegistrationForm
|
||||
*
|
||||
* @ingroup user_form
|
||||
*
|
||||
* @brief Form for user registration.
|
||||
*/
|
||||
|
||||
namespace PKP\user\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use APP\notification\form\NotificationSettingsForm;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\config\Config;
|
||||
use PKP\core\Core;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\facades\Locale;
|
||||
use PKP\form\Form;
|
||||
use PKP\security\Role;
|
||||
use PKP\security\Validation;
|
||||
use PKP\session\SessionManager;
|
||||
use PKP\site\Site;
|
||||
use PKP\user\InterestManager;
|
||||
use PKP\user\User;
|
||||
|
||||
class RegistrationForm extends Form
|
||||
{
|
||||
/** @var User The user object being created (available to hooks during registrationform::execute hook) */
|
||||
public $user;
|
||||
|
||||
/** @var bool user is already registered with another context */
|
||||
public $existingUser;
|
||||
|
||||
/** @var bool whether or not captcha is enabled for this form */
|
||||
public $captchaEnabled;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Site $site
|
||||
*/
|
||||
public function __construct($site)
|
||||
{
|
||||
parent::__construct('frontend/pages/userRegister.tpl');
|
||||
|
||||
// Validation checks for this form
|
||||
$form = $this;
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'username', 'required', 'user.register.form.usernameExists', [Repo::user(), 'getByUsername'], [true], true));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidator($this, 'username', 'required', 'user.profile.form.usernameRequired'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidator($this, 'password', 'required', 'user.profile.form.passwordRequired'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorUsername($this, 'username', 'required', 'user.register.form.usernameAlphaNumeric'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorLength($this, 'password', 'required', 'user.register.form.passwordLengthRestriction', '>=', $site->getMinPasswordLength()));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'password', 'required', 'user.register.form.passwordsDoNotMatch', fn ($password) => $password == $form->getData('password2')));
|
||||
|
||||
$this->addCheck(new \PKP\form\validation\FormValidator($this, 'givenName', 'required', 'user.profile.form.givenNameRequired'));
|
||||
|
||||
$this->addCheck(new \PKP\form\validation\FormValidator($this, 'country', 'required', 'user.profile.form.countryRequired'));
|
||||
|
||||
// Email checks
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorEmail($this, 'email', 'required', 'user.profile.form.emailRequired'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'email', 'required', 'user.register.form.emailExists', [Repo::user(), 'getByEmail'], [true], true));
|
||||
|
||||
$this->captchaEnabled = Config::getVar('captcha', 'captcha_on_register') && Config::getVar('captcha', 'recaptcha');
|
||||
if ($this->captchaEnabled) {
|
||||
$request = Application::get()->getRequest();
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorReCaptcha($this, $request->getRemoteAddr(), 'common.captcha.error.invalid-input-response', $request->getServerHost()));
|
||||
}
|
||||
|
||||
$context = Application::get()->getRequest()->getContext();
|
||||
if ($context && $context->getData('privacyStatement')) {
|
||||
$this->addCheck(new \PKP\form\validation\FormValidator($this, 'privacyConsent', 'required', 'user.profile.form.privacyConsentRequired'));
|
||||
}
|
||||
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorPost($this));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCSRF($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::fetch()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$site = $request->getSite();
|
||||
|
||||
if ($this->captchaEnabled) {
|
||||
$templateMgr->assign('recaptchaPublicKey', Config::getVar('captcha', 'recaptcha_public_key'));
|
||||
}
|
||||
|
||||
$countries = [];
|
||||
foreach (Locale::getCountries() as $country) {
|
||||
$countries[$country->getAlpha2()] = $country->getLocalName();
|
||||
}
|
||||
asort($countries);
|
||||
$templateMgr->assign('countries', $countries);
|
||||
|
||||
$userFormHelper = new UserFormHelper();
|
||||
$userFormHelper->assignRoleContent($templateMgr, $request);
|
||||
|
||||
$templateMgr->assign([
|
||||
'source' => $request->getUserVar('source'),
|
||||
'minPasswordLength' => $site->getMinPasswordLength(),
|
||||
'enableSiteWidePrivacyStatement' => Config::getVar('general', 'sitewide_privacy_statement'),
|
||||
'siteWidePrivacyStatement' => $site->getData('privacyStatement'),
|
||||
]);
|
||||
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::initData()
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
$this->_data = [
|
||||
'locales' => [],
|
||||
'userGroupIds' => [],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
parent::readInputData();
|
||||
|
||||
$this->readUserVars([
|
||||
'username',
|
||||
'password',
|
||||
'password2',
|
||||
'givenName',
|
||||
'familyName',
|
||||
'affiliation',
|
||||
'email',
|
||||
'country',
|
||||
'interests',
|
||||
'emailConsent',
|
||||
'privacyConsent',
|
||||
'readerGroup',
|
||||
'reviewerGroup',
|
||||
]);
|
||||
|
||||
if ($this->captchaEnabled) {
|
||||
$this->readUserVars([
|
||||
'g-recaptcha-response',
|
||||
]);
|
||||
}
|
||||
|
||||
// Collect the specified user group IDs into a single piece of data
|
||||
$this->setData('userGroupIds', array_merge(
|
||||
array_keys((array) $this->getData('readerGroup')),
|
||||
array_keys((array) $this->getData('reviewerGroup'))
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::validate()
|
||||
*/
|
||||
public function validate($callHooks = true)
|
||||
{
|
||||
$request = Application::get()->getRequest();
|
||||
|
||||
// Ensure the consent checkbox has been completed for the site and any user
|
||||
// group sign-ups if we're in the site-wide registration form
|
||||
if (!$request->getContext()) {
|
||||
if ($request->getSite()->getData('privacyStatement')) {
|
||||
$privacyConsent = $this->getData('privacyConsent');
|
||||
if (!is_array($privacyConsent) || !array_key_exists(Application::CONTEXT_ID_NONE, $privacyConsent)) {
|
||||
$this->addError('privacyConsent[' . Application::CONTEXT_ID_NONE . ']', __('user.register.form.missingSiteConsent'));
|
||||
}
|
||||
}
|
||||
|
||||
if (!Config::getVar('general', 'sitewide_privacy_statement')) {
|
||||
$contextIds = [];
|
||||
foreach ($this->getData('userGroupIds') as $userGroupId) {
|
||||
$userGroup = Repo::userGroup()->get($userGroupId);
|
||||
$contextIds[] = $userGroup->getContextId();
|
||||
}
|
||||
|
||||
$contextIds = array_unique($contextIds);
|
||||
if (!empty($contextIds)) {
|
||||
$contextDao = Application::getContextDao();
|
||||
$privacyConsent = (array) $this->getData('privacyConsent');
|
||||
foreach ($contextIds as $contextId) {
|
||||
$context = $contextDao->getById($contextId);
|
||||
if ($context->getData('privacyStatement') && !array_key_exists($contextId, $privacyConsent)) {
|
||||
$this->addError('privacyConsent[' . $contextId . ']', __('user.register.form.missingContextConsent'));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return parent::validate($callHooks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new user.
|
||||
*
|
||||
* @return int|null User ID, or false on failure
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$requireValidation = Config::getVar('email', 'require_validation');
|
||||
|
||||
// New user
|
||||
$this->user = $user = Repo::user()->newDataObject();
|
||||
|
||||
$user->setUsername($this->getData('username'));
|
||||
|
||||
// The multilingual user data (givenName, familyName and affiliation) will be saved
|
||||
// in the current UI locale and copied in the site's primary locale too
|
||||
$request = Application::get()->getRequest();
|
||||
$site = $request->getSite();
|
||||
$sitePrimaryLocale = $site->getPrimaryLocale();
|
||||
$currentLocale = Locale::getLocale();
|
||||
|
||||
// Set the base user fields (name, etc.)
|
||||
$user->setGivenName($this->getData('givenName'), $currentLocale);
|
||||
$user->setFamilyName($this->getData('familyName'), $currentLocale);
|
||||
$user->setEmail($this->getData('email'));
|
||||
$user->setCountry($this->getData('country'));
|
||||
$user->setAffiliation($this->getData('affiliation'), $currentLocale);
|
||||
|
||||
if ($sitePrimaryLocale != $currentLocale) {
|
||||
$user->setGivenName($this->getData('givenName'), $sitePrimaryLocale);
|
||||
$user->setFamilyName($this->getData('familyName'), $sitePrimaryLocale);
|
||||
$user->setAffiliation($this->getData('affiliation'), $sitePrimaryLocale);
|
||||
}
|
||||
|
||||
$user->setDateRegistered(Core::getCurrentDate());
|
||||
$user->setInlineHelp(1); // default new users to having inline help visible.
|
||||
$user->setPassword(Validation::encryptCredentials($this->getData('username'), $this->getData('password')));
|
||||
|
||||
if ($requireValidation) {
|
||||
// The account should be created in a disabled
|
||||
// state.
|
||||
$user->setDisabled(true);
|
||||
$user->setDisabledReason(__('user.login.accountNotValidated', ['email' => $this->getData('email')]));
|
||||
}
|
||||
|
||||
parent::execute(...$functionArgs);
|
||||
|
||||
Repo::user()->add($user);
|
||||
$userId = $user->getId();
|
||||
if (!$userId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Associate the new user with the existing session
|
||||
$sessionManager = SessionManager::getManager();
|
||||
$session = $sessionManager->getUserSession();
|
||||
$session->setSessionVar('username', $user->getUsername());
|
||||
|
||||
// Save the selected roles or assign the Reader role if none selected
|
||||
if ($request->getContext() && !$this->getData('reviewerGroup')) {
|
||||
$defaultReaderGroup = Repo::userGroup()->getByRoleIds([Role::ROLE_ID_READER], $request->getContext()->getId(), true)->first();
|
||||
if ($defaultReaderGroup) {
|
||||
Repo::userGroup()->assignUserToGroup($user->getId(), $defaultReaderGroup->getId(), $request->getContext()->getId());
|
||||
}
|
||||
} else {
|
||||
$userFormHelper = new UserFormHelper();
|
||||
$userFormHelper->saveRoleContent($this, $user);
|
||||
}
|
||||
|
||||
// Save the email notification preference
|
||||
if ($request->getContext() && !$this->getData('emailConsent')) {
|
||||
// Get the public notification types
|
||||
$notificationSettingsForm = new NotificationSettingsForm();
|
||||
$notificationCategories = $notificationSettingsForm->getNotificationSettingCategories($request->getContext());
|
||||
foreach ($notificationCategories as $notificationCategory) {
|
||||
if ($notificationCategory['categoryKey'] === 'notification.type.public') {
|
||||
$publicNotifications = $notificationCategory['settings'];
|
||||
}
|
||||
}
|
||||
if (isset($publicNotifications)) {
|
||||
$notificationSubscriptionSettingsDao = DAORegistry::getDAO('NotificationSubscriptionSettingsDAO'); /** @var NotificationSubscriptionSettingsDAO $notificationSubscriptionSettingsDao */
|
||||
$notificationSubscriptionSettingsDao->updateNotificationSubscriptionSettings(
|
||||
'blocked_emailed_notification',
|
||||
$publicNotifications,
|
||||
$user->getId(),
|
||||
$request->getContext()->getId()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Insert the user interests
|
||||
$interestManager = new InterestManager();
|
||||
$interestManager->setInterestsForUser($user, $this->getData('interests'));
|
||||
|
||||
return $userId;
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\user\form\RegistrationForm', '\RegistrationForm');
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/user/form/ResetPasswordForm.php
|
||||
*
|
||||
* Copyright (c) 2014-2021 Simon Fraser University
|
||||
* Copyright (c) 2003-2021 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class ResetPasswordForm
|
||||
*
|
||||
* @ingroup user_form
|
||||
*
|
||||
* @brief Form to reset a user's password.
|
||||
*/
|
||||
|
||||
namespace PKP\user\form;
|
||||
|
||||
use APP\facades\Repo;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\form\Form;
|
||||
use PKP\form\validation\FormValidator;
|
||||
use PKP\form\validation\FormValidatorCSRF;
|
||||
use PKP\form\validation\FormValidatorCustom;
|
||||
use PKP\form\validation\FormValidatorLength;
|
||||
use PKP\form\validation\FormValidatorPost;
|
||||
use PKP\security\Validation;
|
||||
use PKP\session\SessionManager;
|
||||
|
||||
class ResetPasswordForm extends Form
|
||||
{
|
||||
/** @var object */
|
||||
protected $_user;
|
||||
|
||||
/** @var object */
|
||||
protected $_site;
|
||||
|
||||
/** @var string */
|
||||
protected $_hash;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct($user, $site, $hash)
|
||||
{
|
||||
parent::__construct('user/userPasswordReset.tpl');
|
||||
|
||||
$this->_user = $user;
|
||||
$this->_site = $site;
|
||||
$this->_hash = $hash;
|
||||
|
||||
$this->addCheck(new FormValidatorLength($this, 'password', 'required', 'user.register.form.passwordLengthRestriction', '>=', $site->getMinPasswordLength()));
|
||||
$this->addCheck(new FormValidator($this, 'password', 'required', 'user.profile.form.newPasswordRequired'));
|
||||
$form = $this;
|
||||
$this->addCheck(new FormValidatorCustom($this, 'password', 'required', 'user.register.form.passwordsDoNotMatch', function ($password) use ($form) {
|
||||
return $password == $form->getData('password2');
|
||||
}));
|
||||
|
||||
$this->addCheck(new FormValidatorPost($this));
|
||||
$this->addCheck(new FormValidatorCSRF($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user associated with this password
|
||||
*/
|
||||
public function getUser()
|
||||
{
|
||||
return $this->_user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the site
|
||||
*/
|
||||
public function getSite()
|
||||
{
|
||||
return $this->_site;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the password reset hash
|
||||
*/
|
||||
public function getHash()
|
||||
{
|
||||
return $this->_hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::display
|
||||
*
|
||||
* @param null|mixed $request
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function display($request = null, $template = null)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign([
|
||||
'minPasswordLength' => $this->getSite()->getMinPasswordLength(),
|
||||
'username' => $this->getUser()->getUsername(),
|
||||
'hash' => $this->getHash(),
|
||||
]);
|
||||
parent::display($request, $template);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
$this->readUserVars(['username', 'hash', 'password', 'password2']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$user = $this->getUser();
|
||||
$user->setPassword(Validation::encryptCredentials($user->getUsername(), $this->getData('password')));
|
||||
$user->setMustChangePassword(0);
|
||||
|
||||
SessionManager::getManager()->invalidateSessions($user->getId());
|
||||
Repo::user()->edit($user);
|
||||
|
||||
parent::execute(...$functionArgs);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the password reset hash
|
||||
*/
|
||||
public function validatePasswordResetHash()
|
||||
{
|
||||
if (Validation::verifyPasswordResetHash($this->getUser()->getId(), $this->getHash())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the error page when passed invalid password reset hash
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function displayInvalidHashErrorMessage($request, $template = null)
|
||||
{
|
||||
$this->setTemplate('frontend/pages/error.tpl');
|
||||
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
|
||||
$templateMgr->assign([
|
||||
'errorMsg' => 'user.login.lostPassword.invalidHash',
|
||||
'backLink' => $request->url(null, null, 'lostPassword'),
|
||||
'backLinkLabel' => 'user.login.resetPassword',
|
||||
]);
|
||||
|
||||
parent::display($request, $template);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/user/form/RolesForm.php
|
||||
*
|
||||
* Copyright (c) 2014-2021 Simon Fraser University
|
||||
* Copyright (c) 2003-2021 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class RolesForm
|
||||
*
|
||||
* @ingroup user_form
|
||||
*
|
||||
* @brief Form to edit the roles area of the user profile.
|
||||
*/
|
||||
|
||||
namespace PKP\user\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\user\InterestManager;
|
||||
use PKP\user\User;
|
||||
|
||||
class RolesForm extends BaseProfileForm
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function __construct($user)
|
||||
{
|
||||
parent::__construct('user/rolesForm.tpl', $user);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc BaseProfileForm::fetch
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
|
||||
$userGroupIds = Repo::userGroup()->getCollector()
|
||||
->filterByUserIds([$request->getUser()->getId()])
|
||||
->getIds()
|
||||
->toArray();
|
||||
|
||||
$templateMgr->assign('userGroupIds', $userGroupIds);
|
||||
|
||||
$userFormHelper = new UserFormHelper();
|
||||
$userFormHelper->assignRoleContent($templateMgr, $request);
|
||||
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc BaseProfileForm::initData()
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
$interestManager = new InterestManager();
|
||||
|
||||
$user = $this->getUser();
|
||||
|
||||
$this->_data = [
|
||||
'interests' => $interestManager->getInterestsForUser($user),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
parent::readInputData();
|
||||
|
||||
$this->readUserVars([
|
||||
'authorGroup',
|
||||
'reviewerGroup',
|
||||
'readerGroup',
|
||||
'interests',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$request = Application::get()->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
||||
// Save the roles
|
||||
$userFormHelper = new UserFormHelper();
|
||||
$userFormHelper->saveRoleContent($this, $user);
|
||||
|
||||
// Insert the user interests
|
||||
$interestManager = new InterestManager();
|
||||
$interestManager->setInterestsForUser($user, $this->getData('interests'));
|
||||
|
||||
parent::execute(...$functionArgs);
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\user\form\RolesForm', '\RolesForm');
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/user/form/UserFormHelper.php
|
||||
*
|
||||
* Copyright (c) 2014-2021 Simon Fraser University
|
||||
* Copyright (c) 2003-2021 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class UserFormHelper
|
||||
*
|
||||
* @ingroup user_form
|
||||
*
|
||||
* @brief Helper functions for shared user form concerns.
|
||||
*/
|
||||
|
||||
namespace PKP\user\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\form\Form;
|
||||
use PKP\security\Role;
|
||||
use PKP\template\PKPTemplateManager;
|
||||
use PKP\user\User;
|
||||
|
||||
class UserFormHelper
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign role selection content to the template manager.
|
||||
*
|
||||
* @param PKPTemplateManager $templateMgr
|
||||
* @param PKPRequest $request
|
||||
*/
|
||||
public function assignRoleContent($templateMgr, $request)
|
||||
{
|
||||
// Need the count in order to determine whether to display
|
||||
// extras-on-demand for role selection in other contexts.
|
||||
$contextDao = Application::getContextDAO();
|
||||
$contexts = $contextDao->getAll(true)->toArray();
|
||||
$contextsWithUserRegistration = [];
|
||||
foreach ($contexts as $context) {
|
||||
if (!$context->getData('disableUserReg')) {
|
||||
$contextsWithUserRegistration[] = $context;
|
||||
}
|
||||
}
|
||||
$templateMgr->assign([
|
||||
'contexts' => $contexts,
|
||||
'showOtherContexts' => !$request->getContext() || count($contextsWithUserRegistration) > 1,
|
||||
]);
|
||||
|
||||
// Expose potential self-registration user groups to template
|
||||
$authorUserGroups = $reviewerUserGroups = $readerUserGroups = [];
|
||||
|
||||
foreach ($contexts as $context) {
|
||||
if ($context->getData('disableUserReg')) {
|
||||
continue;
|
||||
}
|
||||
$reviewerUserGroups[$context->getId()] = Repo::userGroup()->getByRoleIds([Role::ROLE_ID_REVIEWER], $context->getId())->toArray();
|
||||
$authorUserGroups[$context->getId()] = Repo::userGroup()->getByRoleIds([Role::ROLE_ID_AUTHOR], $context->getId())->toArray();
|
||||
$readerUserGroups[$context->getId()] = Repo::userGroup()->getByRoleIds([Role::ROLE_ID_READER], $context->getId())->toArray();
|
||||
}
|
||||
$templateMgr->assign([
|
||||
'reviewerUserGroups' => $reviewerUserGroups,
|
||||
'authorUserGroups' => $authorUserGroups,
|
||||
'readerUserGroups' => $readerUserGroups,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save role elements of an executed user form.
|
||||
*
|
||||
* @param Form $form The form from which to fetch elements
|
||||
* @param User $user The current user
|
||||
*/
|
||||
public function saveRoleContent($form, $user)
|
||||
{
|
||||
$contextDao = Application::getContextDAO();
|
||||
$contexts = $contextDao->getAll(true);
|
||||
while ($context = $contexts->next()) {
|
||||
if ($context->getData('disableUserReg')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ([
|
||||
[
|
||||
'roleId' => Role::ROLE_ID_REVIEWER,
|
||||
'formElement' => 'reviewerGroup'
|
||||
],
|
||||
[
|
||||
'roleId' => Role::ROLE_ID_AUTHOR,
|
||||
'formElement' => 'authorGroup'
|
||||
],
|
||||
[
|
||||
'roleId' => Role::ROLE_ID_READER,
|
||||
'formElement' => 'readerGroup'
|
||||
],
|
||||
] as $groupData) {
|
||||
$groupFormData = (array) $form->getData($groupData['formElement']);
|
||||
$userGroups = Repo::userGroup()->getByRoleIds([$groupData['roleId']], $context->getId());
|
||||
foreach ($userGroups as $userGroup) {
|
||||
if (!$userGroup->getPermitSelfRegistration()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$groupId = $userGroup->getId();
|
||||
$inGroup = Repo::userGroup()->userInGroup($user->getId(), $groupId);
|
||||
if (!$inGroup && array_key_exists($groupId, $groupFormData)) {
|
||||
Repo::userGroup()->assignUserToGroup($user->getId(), $groupId);
|
||||
} elseif ($inGroup && !array_key_exists($groupId, $groupFormData)) {
|
||||
Repo::userGroup()->removeUserFromGroup($user->getId(), $groupId, $context->getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\user\form\UserFormHelper', '\UserFormHelper');
|
||||
}
|
||||
Reference in New Issue
Block a user