first commit
This commit is contained in:
commit
e81864e683
2984 files changed
+267797
No files matched your search
@@ -0,0 +1,546 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Controller;
|
||||
|
||||
use In2code\Femanager\DataProcessor\DataProcessorRunner;
|
||||
use In2code\Femanager\Domain\Model\Log;
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use In2code\Femanager\Domain\Repository\UserGroupRepository;
|
||||
use In2code\Femanager\Domain\Repository\UserRepository;
|
||||
use In2code\Femanager\Domain\Service\SendMailService;
|
||||
use In2code\Femanager\Event\FinalCreateEvent;
|
||||
use In2code\Femanager\Event\FinalUpdateEvent;
|
||||
use In2code\Femanager\Finisher\FinisherRunner;
|
||||
use In2code\Femanager\Utility\BackendUtility;
|
||||
use In2code\Femanager\Utility\ConfigurationUtility;
|
||||
use In2code\Femanager\Utility\FrontendUtility;
|
||||
use In2code\Femanager\Utility\HashUtility;
|
||||
use In2code\Femanager\Utility\LocalizationUtility;
|
||||
use In2code\Femanager\Utility\LogUtility;
|
||||
use In2code\Femanager\Utility\StringUtility;
|
||||
use In2code\Femanager\Utility\UserUtility;
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility as BackendUtilityCore;
|
||||
use TYPO3\CMS\Core\Http\ApplicationType;
|
||||
use TYPO3\CMS\Core\Messaging\AbstractMessage;
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
|
||||
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
|
||||
use TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException;
|
||||
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
|
||||
/**
|
||||
* Class AbstractController
|
||||
*/
|
||||
abstract class AbstractController extends ActionController
|
||||
{
|
||||
/**
|
||||
* @var UserRepository
|
||||
*/
|
||||
protected $userRepository;
|
||||
|
||||
/**
|
||||
* @var UserGroupRepository
|
||||
*/
|
||||
protected $userGroupRepository;
|
||||
|
||||
/**
|
||||
* @var PersistenceManager
|
||||
*/
|
||||
protected $persistenceManager;
|
||||
|
||||
/**
|
||||
* @var SendMailService
|
||||
*/
|
||||
protected $sendMailService;
|
||||
|
||||
/**
|
||||
* @var FinisherRunner
|
||||
*/
|
||||
protected $finisherRunner;
|
||||
|
||||
/**
|
||||
* @var LogUtility
|
||||
*/
|
||||
protected $logUtility;
|
||||
|
||||
/**
|
||||
* Content Object
|
||||
*
|
||||
* @var ContentObjectRenderer
|
||||
*/
|
||||
public $contentObject;
|
||||
|
||||
/**
|
||||
* Former known as piVars
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $pluginVariables;
|
||||
|
||||
/**
|
||||
* TypoScript
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $config;
|
||||
|
||||
/**
|
||||
* Complete Configuration
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $allConfig;
|
||||
|
||||
/**
|
||||
* Module Configuration for Backend
|
||||
* this is a merge configuration -> TypoScript -> PageTSConfig -> UserTSConfig
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $moduleConfig;
|
||||
|
||||
/**
|
||||
* Current logged in user object
|
||||
*
|
||||
* @var User
|
||||
*/
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* All available usergroups
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
public $allUserGroups;
|
||||
|
||||
/**
|
||||
* AbstractController constructor.
|
||||
*
|
||||
* @param UserRepository $userRepository
|
||||
* @param UserGroupRepository $userGroupRepository
|
||||
* @param PersistenceManager $persistenceManager
|
||||
* @param SendMailService $sendMailService
|
||||
* @param FinisherRunner $finisherRunner
|
||||
* @param LogUtility $logUtility
|
||||
*/
|
||||
public function __construct(
|
||||
UserRepository $userRepository,
|
||||
UserGroupRepository $userGroupRepository,
|
||||
PersistenceManager $persistenceManager,
|
||||
SendMailService $sendMailService,
|
||||
FinisherRunner $finisherRunner,
|
||||
LogUtility $logUtility
|
||||
) {
|
||||
$this->userRepository = $userRepository;
|
||||
$this->userGroupRepository = $userGroupRepository;
|
||||
$this->persistenceManager = $persistenceManager;
|
||||
$this->sendMailService = $sendMailService;
|
||||
$this->finisherRunner = $finisherRunner;
|
||||
$this->logUtility = $logUtility;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefix method to createAction()
|
||||
* Create Confirmation from Admin is not necessary
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function createAllConfirmed(User $user)
|
||||
{
|
||||
$this->userRepository->add($user);
|
||||
$this->persistenceManager->persistAll();
|
||||
$this->logUtility->log(Log::STATUS_NEWREGISTRATION, $user);
|
||||
$this->finalCreate($user, 'new', 'createStatus');
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefix method to updateAction()
|
||||
* Update Confirmation from Admin is not necessary
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function updateAllConfirmed(User $user)
|
||||
{
|
||||
// send notify email to admin
|
||||
$existingUser = clone $this->userRepository->findByUid($user->getUid());
|
||||
|
||||
if (ConfigurationUtility::notifyAdminAboutEdits($this->settings) === true) {
|
||||
$this->sendMailService->send(
|
||||
'updateNotify',
|
||||
StringUtility::makeEmailArray(
|
||||
ConfigurationUtility::getValue('edit/email/notifyAdmin/receiver/email/value', $this->settings) ?:
|
||||
ConfigurationUtility::getValue('edit/notifyAdmin', $this->settings),
|
||||
$this->settings['edit']['email']['notifyAdmin']['receiver']['name']['value'] ?? null
|
||||
),
|
||||
StringUtility::makeEmailArray($user->getEmail(), $user->getUsername()),
|
||||
'Profile update',
|
||||
[
|
||||
'user' => $user,
|
||||
'changes' => UserUtility::getDirtyPropertiesFromUser($user),
|
||||
'settings' => $this->settings,
|
||||
],
|
||||
$this->config['edit.']['email.']['notifyAdmin.'] ?? []
|
||||
);
|
||||
}
|
||||
|
||||
$this->userRepository->update($user);
|
||||
$this->persistenceManager->persistAll();
|
||||
|
||||
$this->eventDispatcher->dispatch(new FinalUpdateEvent($user));
|
||||
$this->logUtility->log(Log::STATUS_PROFILEUPDATED, $user, ['existingUser' => $existingUser]);
|
||||
$this->redirectByAction('edit');
|
||||
$this->addFlashMessage(LocalizationUtility::translate('update'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefix method to updateAction(): Update must be confirmed by Admin
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function updateRequest($user)
|
||||
{
|
||||
if ($this->settings['edit']['confirmByAdmin'] ?? null) {
|
||||
$dirtyProperties = UserUtility::getDirtyPropertiesFromUser($user);
|
||||
$user = UserUtility::rollbackUserWithChangeRequest($user, $dirtyProperties);
|
||||
$this->sendMailService->send(
|
||||
'updateRequest',
|
||||
StringUtility::makeEmailArray(
|
||||
$this->settings['edit']['confirmByAdmin'] ?? '',
|
||||
$this->settings['edit']['email']['updateRequest']['sender']['name']['value'] ?? null
|
||||
),
|
||||
StringUtility::makeEmailArray($user->getEmail(), $user->getUsername()),
|
||||
'New Profile change request',
|
||||
[
|
||||
'user' => $user,
|
||||
'changes' => $dirtyProperties,
|
||||
'hash' => HashUtility::createHashForUser($user),
|
||||
],
|
||||
$this->config['edit.']['email.']['updateRequest.'] ?? []
|
||||
);
|
||||
$this->logUtility->log(
|
||||
Log::STATUS_PROFILEUPDATEREFUSEDADMIN,
|
||||
$user,
|
||||
['dirtyProperties' => $dirtyProperties]
|
||||
);
|
||||
$this->redirectByAction('edit', 'requestRedirect');
|
||||
$this->addFlashMessage(LocalizationUtility::translate('updateRequest'));
|
||||
} else {
|
||||
$this->logUtility->log(
|
||||
Log::STATUS_PROFILEUPDATEREFUSEDADMIN,
|
||||
$user,
|
||||
['message' => 'settings[edit][confirmByAdmin] is missing!']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Some additional actions after profile creation
|
||||
*
|
||||
* @param User $user
|
||||
* @param string $action
|
||||
* @param string $redirectByActionName Action to redirect
|
||||
* @param bool $login Login after creation
|
||||
* @param string $status
|
||||
* @param bool $backend Don't redirect if called from backend action
|
||||
*/
|
||||
public function finalCreate(
|
||||
$user,
|
||||
string $action,
|
||||
string $redirectByActionName,
|
||||
bool $login = true,
|
||||
string $status = '',
|
||||
bool $backend = false
|
||||
): void {
|
||||
$this->loginPreflight($user, $login);
|
||||
$variables = ['user' => $user, 'settings' => $this->settings, 'hash' => HashUtility::createHashForUser($user)];
|
||||
if (ConfigurationUtility::getValue(
|
||||
'new./email./createUserNotify./sender./email./value',
|
||||
$this->config
|
||||
) && ConfigurationUtility::getValue('new./email./createUserNotify./sender./name./value', $this->config)) {
|
||||
$this->sendMailService->send(
|
||||
'createUserNotify',
|
||||
StringUtility::makeEmailArray($user->getEmail(), $user->getFirstName() . ' ' . $user->getLastName()),
|
||||
StringUtility::makeEmailArray(
|
||||
ConfigurationUtility::getValue(
|
||||
'new./email./createUserNotify./sender./email./value',
|
||||
$this->config
|
||||
),
|
||||
ConfigurationUtility::getValue('new./email./createUserNotify./sender./name./value', $this->config)
|
||||
),
|
||||
$this->contentObject->cObjGetSingle(
|
||||
(string)ConfigurationUtility::getValue('new./email./createUserNotify./subject', $this->config),
|
||||
(array)ConfigurationUtility::getValue('new./email./createUserNotify./subject.', $this->config),
|
||||
),
|
||||
$variables,
|
||||
ConfigurationUtility::getValue('new./email./createUserNotify.', $this->config)
|
||||
);
|
||||
}
|
||||
|
||||
$createAdminNotify = ConfigurationUtility::getValue(
|
||||
'new./email./createAdminNotify./receiver./email./value',
|
||||
$this->config
|
||||
);
|
||||
if (!$createAdminNotify) {
|
||||
$createAdminNotify = $this->settings['new']['notifyAdmin'];
|
||||
}
|
||||
|
||||
// send notify email to admin
|
||||
if ($createAdminNotify) {
|
||||
$this->sendMailService->send(
|
||||
'createNotify',
|
||||
StringUtility::makeEmailArray(
|
||||
$createAdminNotify
|
||||
),
|
||||
StringUtility::makeEmailArray($user->getEmail(), $user->getUsername()),
|
||||
$this->contentObject->cObjGetSingle(
|
||||
(string)ConfigurationUtility::getValue('new./email./createAdminNotify./subject', $this->config),
|
||||
(array)ConfigurationUtility::getValue('new./email./createAdminNotify./subject.', $this->config)
|
||||
),
|
||||
$variables,
|
||||
ConfigurationUtility::getValue('new./email./createAdminNotify.', $this->config)
|
||||
);
|
||||
}
|
||||
|
||||
$this->eventDispatcher->dispatch(new FinalCreateEvent($user, $action));
|
||||
$this->finisherRunner->callFinishers($user, $this->actionMethodName, $this->settings, $this->contentObject);
|
||||
|
||||
if ($backend === false) {
|
||||
$this->redirectByAction($action, ($status ? $status . 'Redirect' : 'redirect'));
|
||||
$this->addFlashMessage(LocalizationUtility::translate('create'));
|
||||
$this->redirect($redirectByActionName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log user in
|
||||
*
|
||||
* @param User $user
|
||||
* @param $login
|
||||
* @throws IllegalObjectTypeException
|
||||
*/
|
||||
protected function loginPreflight(User $user, $login)
|
||||
{
|
||||
if ($login) {
|
||||
// persist user (otherwise login may not be possible)
|
||||
$this->userRepository->update($user);
|
||||
$this->persistenceManager->persistAll();
|
||||
if (ConfigurationUtility::getValue('new./login', $this->config) === '1') {
|
||||
UserUtility::login($user, ConfigurationUtility::getValue('persistence./storagePid', $this->allConfig));
|
||||
$this->addFlashMessage(LocalizationUtility::translate('login'), '', AbstractMessage::NOTICE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect by TypoScript setting
|
||||
* [userConfirmation|userConfirmationRefused|adminConfirmation|
|
||||
* adminConfirmationRefused|adminConfirmationRefusedSilent]Redirect
|
||||
*
|
||||
* @param string $action "new", "edit"
|
||||
* @param string $category "redirect", "requestRedirect" value from TypoScript
|
||||
*/
|
||||
protected function redirectByAction($action = 'new', $category = 'redirect')
|
||||
{
|
||||
$target = null;
|
||||
// redirect from TypoScript cObject
|
||||
if ($this->contentObject->cObjGetSingle(
|
||||
(string)ConfigurationUtility::getValue($action . './' . $category, $this->config),
|
||||
(array)ConfigurationUtility::getValue($action . './' . $category . '.', $this->config),
|
||||
)
|
||||
) {
|
||||
$target = $this->contentObject->cObjGetSingle(
|
||||
(string)ConfigurationUtility::getValue($action . './' . $category, $this->config),
|
||||
array_merge_recursive(
|
||||
(array)ConfigurationUtility::getValue($action . './' . $category . '.', $this->config),
|
||||
[
|
||||
'linkAccessRestrictedPages' => 1,
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// if redirect target
|
||||
if ($target) {
|
||||
$this->redirectToUri(StringUtility::removeDoubleSlashesFromUri($target));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if user is authenticated and params are valid
|
||||
*
|
||||
* @param User $user
|
||||
* @param int $uid Given fe_users uid
|
||||
* @param string $receivedToken Token
|
||||
*/
|
||||
protected function isSpoof($user, $uid, $receivedToken)
|
||||
{
|
||||
$errorOnProfileUpdate = false;
|
||||
$knownToken = GeneralUtility::hmac($user->getUid(), (string)$user->getCrdate()->getTimestamp());
|
||||
|
||||
//check if the params are valid
|
||||
if (!is_string($receivedToken) || !hash_equals($knownToken, $receivedToken)) {
|
||||
$errorOnProfileUpdate = true;
|
||||
}
|
||||
|
||||
//check if the logged user is allowed to edit / delete this record
|
||||
if ($user->getUid() !== (int)$uid && $uid > 0) {
|
||||
$errorOnProfileUpdate = true;
|
||||
}
|
||||
|
||||
if ($errorOnProfileUpdate === true) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns all values, which should be available in all views
|
||||
*/
|
||||
public function assignForAll()
|
||||
{
|
||||
$jsLabels = [
|
||||
'loading_states' => LocalizationUtility::translate('js.loading_states'),
|
||||
'please_choose' => LocalizationUtility::translate('pleaseChoose'),
|
||||
];
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'languageUid' => FrontendUtility::getFrontendLanguageUid(),
|
||||
'storagePid' => $this->allConfig['persistence']['storagePid'] ?? 0,
|
||||
'Pid' => FrontendUtility::getCurrentPid(),
|
||||
'data' => $this->contentObject->data,
|
||||
'useStaticInfoTables' => ExtensionManagementUtility::isLoaded('static_info_tables'),
|
||||
'jsLabels' => json_encode($jsLabels),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function initializeAction()
|
||||
{
|
||||
$this->controllerContext = $this->buildControllerContext();
|
||||
$this->user = UserUtility::getCurrentUser();
|
||||
$this->contentObject = $this->configurationManager->getContentObject();
|
||||
$this->pluginVariables = $this->request->getArguments();
|
||||
$this->moduleConfig = [];
|
||||
$this->allConfig = $this->configurationManager->getConfiguration(
|
||||
ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK
|
||||
);
|
||||
$this->config = $this->configurationManager->getConfiguration(
|
||||
ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT
|
||||
);
|
||||
|
||||
$this->config = $this->config[BackendUtility::getPluginOrModuleString() . '.']['tx_femanager.']['settings.'] ?? [];
|
||||
|
||||
if (ApplicationType::fromRequest($GLOBALS['TYPO3_REQUEST'])->isBackend()) {
|
||||
$config = BackendUtility::loadTS($this->allConfig['settings']['configPID'] ?? null);
|
||||
if (is_array($config['plugin.']['tx_femanager.']['settings.'] ?? null)) {
|
||||
$this->config = $config['plugin.']['tx_femanager.']['settings.'];
|
||||
$this->settings = $this->config;
|
||||
}
|
||||
|
||||
$this->moduleConfig = $config['module.']['tx_femanager.'] ?? '';
|
||||
|
||||
// Retrieve page TSconfig of the current page
|
||||
$pageTsConfig = BackendUtilityCore::getPagesTSconfig(BackendUtility::getPageIdentifier());
|
||||
if (is_array($pageTsConfig['module.']['tx_femanager.'] ?? null)) {
|
||||
$this->moduleConfig = array_merge($this->moduleConfig, $pageTsConfig['module.']['tx_femanager.'] ?? []);
|
||||
}
|
||||
|
||||
// Retrieve user TSconfig of currently logged in user
|
||||
$userTsConfig = $GLOBALS['BE_USER']->getTSConfig();
|
||||
|
||||
if ((is_array($userTsConfig['tx_femanager.']) ?? null) && (is_array($this->moduleConfig)?? null)) {
|
||||
$this->moduleConfig = array_merge_recursive($this->moduleConfig, $userTsConfig['tx_femanager.']);
|
||||
}
|
||||
}
|
||||
|
||||
$this->setAllUserGroups();
|
||||
$this->checkTypoScript();
|
||||
$this->checkStoragePid();
|
||||
|
||||
$dataProcessorRunner = $this->objectManager->get(DataProcessorRunner::class);
|
||||
$this->pluginVariables = $dataProcessorRunner->callClasses(
|
||||
$this->request->getArguments(),
|
||||
$this->settings,
|
||||
$this->contentObject,
|
||||
$this->arguments
|
||||
);
|
||||
$this->request->setArguments($this->pluginVariables);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate errormessages in flashmessages
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function getErrorFlashMessage()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function checkStoragePid()
|
||||
{
|
||||
if ((int)($this->allConfig['persistence']['storagePid'] ?? 0) === 0
|
||||
&& GeneralUtility::_GP('type') !== '1548935210'
|
||||
) {
|
||||
$this->addFlashMessage(LocalizationUtility::translate('error_no_storagepid'), '', AbstractMessage::ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
protected function checkTypoScript()
|
||||
{
|
||||
if (ApplicationType::fromRequest($GLOBALS['TYPO3_REQUEST'] ?? null)->isBackend()) {
|
||||
if (($this->config['_TypoScriptIncluded'] ?? '1') !== '1') {
|
||||
$this->addFlashMessage(
|
||||
(string)LocalizationUtility::translate('error_no_typoscript_be'),
|
||||
'',
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$typoscriptIncluded = ConfigurationUtility::getValue('_TypoScriptIncluded', $this->settings);
|
||||
if ($typoscriptIncluded !== '1' && !GeneralUtility::_GP('eID')) {
|
||||
$this->addFlashMessage(
|
||||
(string)LocalizationUtility::translate('error_no_typoscript'),
|
||||
'',
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function setAllUserGroups()
|
||||
{
|
||||
$controllerName = strtolower($this->controllerContext->getRequest()->getControllerName());
|
||||
$removeFromUserGroupSelection = $this->settings[$controllerName]['misc']['removeFromUserGroupSelection'] ?? '';
|
||||
$this->allUserGroups = $this->userGroupRepository->findAllForFrontendSelection($removeFromUserGroupSelection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send email to user for confirmation
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function sendCreateUserConfirmationMail(User $user)
|
||||
{
|
||||
$this->sendMailService->send(
|
||||
'createUserConfirmation',
|
||||
StringUtility::makeEmailArray($user->getEmail(), $user->getUsername()),
|
||||
[
|
||||
ConfigurationUtility::getValue('new./email./createUserConfirmation./sender./email./value', $this->config) =>
|
||||
ConfigurationUtility::getValue('new./email./createUserConfirmation./sender./name./value', $this->config),
|
||||
],
|
||||
$this->contentObject->cObjGetSingle(
|
||||
(string)ConfigurationUtility::getValue('new./email./createUserConfirmation./subject', $this->config),
|
||||
(array)ConfigurationUtility::getValue('new./email./createUserConfirmation./subject.', $this->config)
|
||||
),
|
||||
[
|
||||
'user' => $user,
|
||||
'hash' => HashUtility::createHashForUser($user),
|
||||
],
|
||||
ConfigurationUtility::getValue('new./email./createUserConfirmation.', $this->config)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace In2code\Femanager\Controller;
|
||||
|
||||
use In2code\Femanager\Domain\Service\RatelimiterService;
|
||||
|
||||
abstract class AbstractFrontendController extends AbstractController
|
||||
{
|
||||
/**
|
||||
* @var RatelimiterService
|
||||
*/
|
||||
protected $ratelimiterService;
|
||||
|
||||
public function injectRatelimiterService(RatelimiterService $ratelimiterService): void
|
||||
{
|
||||
$this->ratelimiterService = $ratelimiterService;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Controller;
|
||||
|
||||
use In2code\Femanager\DataProvider\CountryZonesDataProvider;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
|
||||
|
||||
class DataController extends ActionController
|
||||
{
|
||||
protected $countryZonesDataProvider;
|
||||
|
||||
public function __construct(CountryZonesDataProvider $countryZonesDataProvider)
|
||||
{
|
||||
$this->countryZonesDataProvider = $countryZonesDataProvider;
|
||||
}
|
||||
|
||||
public function getStatesForCountryAction(string $country): ResponseInterface
|
||||
{
|
||||
$countryZones = $this->countryZonesDataProvider->getCountryZonesForCountryIso3($country);
|
||||
$jsonData = [];
|
||||
foreach ($countryZones as $countryZone) {
|
||||
$jsonData[$countryZone->getIsoCode()] = $countryZone->getLocalName();
|
||||
}
|
||||
|
||||
return $this->jsonResponse(json_encode($jsonData));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Controller;
|
||||
|
||||
use In2code\Femanager\Domain\Model\Log;
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use In2code\Femanager\Domain\Model\UserGroup;
|
||||
use In2code\Femanager\Event\AfterUserUpdateEvent;
|
||||
use In2code\Femanager\Event\BeforeUpdateUserEvent;
|
||||
use In2code\Femanager\Event\DeleteUserEvent;
|
||||
use In2code\Femanager\Utility\ConfigurationUtility;
|
||||
use In2code\Femanager\Utility\FrontendUtility;
|
||||
use In2code\Femanager\Utility\HashUtility;
|
||||
use In2code\Femanager\Utility\LocalizationUtility;
|
||||
use In2code\Femanager\Utility\ObjectUtility;
|
||||
use In2code\Femanager\Utility\StringUtility;
|
||||
use In2code\Femanager\Utility\UserUtility;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use TYPO3\CMS\Core\Messaging\AbstractMessage;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Annotation\Validate;
|
||||
use TYPO3\CMS\Extbase\Http\ForwardResponse;
|
||||
|
||||
/**
|
||||
* Class EditController
|
||||
*/
|
||||
class EditController extends AbstractFrontendController
|
||||
{
|
||||
public function editAction(): ResponseInterface
|
||||
{
|
||||
$token = '';
|
||||
if ($this->user) {
|
||||
$token = GeneralUtility::hmac($this->user->getUid(), (string)$this->user->getCrdate()->getTimestamp());
|
||||
}
|
||||
$this->view->assignMultiple([
|
||||
'user' => $this->user,
|
||||
'allUserGroups' => $this->allUserGroups,
|
||||
'token' => $token
|
||||
]);
|
||||
$this->assignForAll();
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
public function initializeUpdateAction()
|
||||
{
|
||||
if ($this->keepPassword()) {
|
||||
unset($this->pluginVariables['user']['password']);
|
||||
unset($this->pluginVariables['password_repeat']);
|
||||
}
|
||||
$this->request->setArguments($this->pluginVariables);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @Validate("In2code\Femanager\Domain\Validator\ServersideValidator", param="user")
|
||||
* @Validate("In2code\Femanager\Domain\Validator\PasswordValidator", param="user")
|
||||
* @Validate("In2code\Femanager\Domain\Validator\CaptchaValidator", param="user")
|
||||
*/
|
||||
public function updateAction(User $user)
|
||||
{
|
||||
$currentUser = UserUtility::getCurrentUser();
|
||||
$userValues = $this->request->getArgument('user') ?? [];
|
||||
$token = $this->request->getArgument('token') ?? null;
|
||||
$identity = (int)($userValues['__identity'] ?? 0);
|
||||
$isSpoof = $this->isSpoof($currentUser, $identity, $token);
|
||||
|
||||
if (!$currentUser instanceof User || $identity === 0 || $token === null || $isSpoof) {
|
||||
$logStatus = $isSpoof ? Log::STATUS_PROFILEUPDATEATTEMPTEDSPOOF : Log::STATUS_PROFILEUPDATEREFUSEDSECURITY;
|
||||
$logContext = $isSpoof ? $currentUser : $user;
|
||||
$this->logUtility->log($logStatus, $logContext);
|
||||
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translateByState(Log::STATUS_PROFILEUPDATEREFUSEDSECURITY),
|
||||
'',
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
return new ForwardResponse('edit');
|
||||
}
|
||||
|
||||
$response = $this->redirectIfNoChangesOnObject($user);
|
||||
if ($response !== null) {
|
||||
return $response;
|
||||
}
|
||||
$user = FrontendUtility::forceValues(
|
||||
$user,
|
||||
ConfigurationUtility::getValue('edit./forceValues./beforeAnyConfirmation.', $this->config)
|
||||
);
|
||||
|
||||
$this->emailForUsername($user);
|
||||
UserUtility::convertPassword(
|
||||
$user,
|
||||
ConfigurationUtility::getValue('edit/misc/passwordSave', $this->settings)
|
||||
);
|
||||
|
||||
$this->eventDispatcher->dispatch(new BeforeUpdateUserEvent($user));
|
||||
if (!empty($this->settings['edit']['confirmByAdmin'])) {
|
||||
$this->updateRequest($user);
|
||||
} else {
|
||||
$this->updateAllConfirmed($user);
|
||||
}
|
||||
$this->redirect('edit');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user User object
|
||||
* @param string $hash
|
||||
* @param string $status could be "confirm", "refuse", "silentRefuse"
|
||||
*/
|
||||
public function confirmUpdateRequestAction(User $user, $hash, $status = 'confirm'): ResponseInterface
|
||||
{
|
||||
$this->view->assign('user', $user);
|
||||
if (!HashUtility::validHash($hash, $user) || !$user->getTxFemanagerChangerequest()) {
|
||||
$this->addFlashMessage(LocalizationUtility::translate('updateFailedProfile'), '', AbstractMessage::ERROR);
|
||||
return $this->htmlResponse(null);
|
||||
}
|
||||
switch ($status) {
|
||||
case 'confirm':
|
||||
$this->statusConfirm($user);
|
||||
break;
|
||||
case 'refuse':
|
||||
$this->statusRefuse($user);
|
||||
break;
|
||||
case 'silentRefuse':
|
||||
$this->logUtility->log(Log::STATUS_PROFILEUPDATEREFUSEDADMIN, $user);
|
||||
$this->addFlashMessage(LocalizationUtility::translateByState(Log::STATUS_PROFILEUPDATEREFUSEDADMIN));
|
||||
break;
|
||||
default:
|
||||
}
|
||||
$user->setTxFemanagerChangerequest('');
|
||||
$this->userRepository->update($user);
|
||||
|
||||
$this->eventDispatcher->dispatch(new AfterUserUpdateEvent($user, $hash, $status));
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Status update confirmation
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
protected function statusConfirm(User $user)
|
||||
{
|
||||
$values = GeneralUtility::xml2array($user->getTxFemanagerChangerequest());
|
||||
foreach ((array)$values as $field => $value) {
|
||||
if ($field !== 'usergroup' && method_exists($user, 'set' . ucfirst($field))) {
|
||||
$user->{'set' . ucfirst($field)}($value['new']);
|
||||
} else {
|
||||
$user->removeAllUsergroups();
|
||||
$usergroupUids = GeneralUtility::trimExplode(',', $value['new'], true);
|
||||
foreach ($usergroupUids as $usergroupUid) {
|
||||
/** @var UserGroup $usergroup */
|
||||
$usergroup = $this->userGroupRepository->findByUid($usergroupUid);
|
||||
$user->addUsergroup($usergroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
$user = FrontendUtility::forceValues($user, $this->config['edit.']['forceValues.']['onAdminConfirmation.']);
|
||||
$this->logUtility->log(Log::STATUS_PROFILEUPDATECONFIRMEDADMIN, $user);
|
||||
$this->addFlashMessage(LocalizationUtility::translate('updateProfile'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Status update refused
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
protected function statusRefuse(User $user)
|
||||
{
|
||||
$this->sendMailService->send(
|
||||
'updateRequestRefused',
|
||||
StringUtility::makeEmailArray($user->getEmail(), $user->getFirstName() . ' ' . $user->getLastName()),
|
||||
['sender@femanager.org' => 'Sender Name'],
|
||||
'Your change request was refused',
|
||||
[
|
||||
'user' => $user,
|
||||
'settings' => $this->settings
|
||||
],
|
||||
$this->config['edit.']['email.']['updateRequestRefused.']
|
||||
);
|
||||
$this->logUtility->log(Log::STATUS_PROFILEUPDATEREFUSEDADMIN, $user);
|
||||
$this->addFlashMessage(LocalizationUtility::translateByState(Log::STATUS_PROFILEUPDATEREFUSEDADMIN));
|
||||
}
|
||||
|
||||
/**
|
||||
* action delete
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function deleteAction(User $user)
|
||||
{
|
||||
$currentUser = UserUtility::getCurrentUser();
|
||||
$token = $this->request->hasArgument('token') ? $this->request->getArgument('token') : null;
|
||||
$uid = $this->request->hasArgument('user') ? $this->request->getArgument('user') : null;
|
||||
if ($currentUser === null ||
|
||||
$token === null ||
|
||||
$uid === null ||
|
||||
$this->isSpoof($currentUser, (int)$uid, $token)
|
||||
) {
|
||||
$this->logUtility->log(Log::STATUS_PROFILEUPDATEREFUSEDSECURITY, $user);
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translateByState(Log::STATUS_PROFILEUPDATEREFUSEDSECURITY),
|
||||
'',
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
return new ForwardResponse('edit');
|
||||
}
|
||||
|
||||
$this->eventDispatcher->dispatch(new DeleteUserEvent($user));
|
||||
$this->logUtility->log(Log::STATUS_PROFILEDELETE, $user);
|
||||
$this->addFlashMessage(LocalizationUtility::translateByState(Log::STATUS_PROFILEDELETE));
|
||||
$this->userRepository->remove($user);
|
||||
$this->redirectByAction('delete');
|
||||
$this->redirect('edit');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if password should be kept
|
||||
*
|
||||
* If password is empty
|
||||
* If password repeat is also empty
|
||||
* If keepPasswordIfEmpty configuration is turned on
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function keepPassword()
|
||||
{
|
||||
return !empty($this->settings['edit']['misc']['keepPasswordIfEmpty']) &&
|
||||
empty($this->pluginVariables['user']['password']) &&
|
||||
empty($this->pluginVariables['password_repeat']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check: If there are no changes, simple redirect back
|
||||
*/
|
||||
protected function redirectIfNoChangesOnObject(User $user)
|
||||
{
|
||||
if (!ObjectUtility::isDirtyObject($user)) {
|
||||
$this->addFlashMessage(LocalizationUtility::translate('noChanges'), '', AbstractMessage::NOTICE);
|
||||
return $this->redirect('edit');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
protected function emailForUsername(User $user)
|
||||
{
|
||||
$fillEmailWithUsername = ConfigurationUtility::getValue('edit/fillEmailWithUsername', $this->settings);
|
||||
if ($fillEmailWithUsername === '1') {
|
||||
$user->setEmail($user->getUsername());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,306 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Controller;
|
||||
|
||||
use In2code\Femanager\Domain\Model\Log;
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use In2code\Femanager\Event\InviteUserConfirmedEvent;
|
||||
use In2code\Femanager\Event\InviteUserCreateEvent;
|
||||
use In2code\Femanager\Event\InviteUserEditEvent;
|
||||
use In2code\Femanager\Event\InviteUserUpdateEvent;
|
||||
use In2code\Femanager\Utility\ConfigurationUtility;
|
||||
use In2code\Femanager\Utility\FrontendUtility;
|
||||
use In2code\Femanager\Utility\HashUtility;
|
||||
use In2code\Femanager\Utility\LocalizationUtility;
|
||||
use In2code\Femanager\Utility\StringUtility;
|
||||
use In2code\Femanager\Utility\UserUtility;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use TYPO3\CMS\Core\Messaging\AbstractMessage;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Annotation\Validate;
|
||||
use TYPO3\CMS\Extbase\Http\ForwardResponse;
|
||||
|
||||
/**
|
||||
* Class InvitationController
|
||||
*/
|
||||
class InvitationController extends AbstractFrontendController
|
||||
{
|
||||
/**
|
||||
* action new
|
||||
*/
|
||||
public function newAction(): ResponseInterface
|
||||
{
|
||||
$permissionCheck = $this->allowedUserForInvitationNewAndCreate();
|
||||
if ($permissionCheck instanceof ResponseInterface) {
|
||||
return $permissionCheck;
|
||||
}
|
||||
$this->view->assign('allUserGroups', $this->allUserGroups);
|
||||
$this->assignForAll();
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* action create
|
||||
*
|
||||
* @param User $user
|
||||
* @Validate("In2code\Femanager\Domain\Validator\ServersideValidator", param="user")
|
||||
* @Validate("In2code\Femanager\Domain\Validator\PasswordValidator", param="user")
|
||||
* @Validate("In2code\Femanager\Domain\Validator\CaptchaValidator", param="user")
|
||||
*/
|
||||
public function createAction(User $user)
|
||||
{
|
||||
if ($this->ratelimiterService->isLimited()) {
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translate('ratelimiter_too_many_attempts'),
|
||||
'',
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
$this->redirect('status');
|
||||
}
|
||||
|
||||
$permissionCheck = $this->allowedUserForInvitationNewAndCreate();
|
||||
if ($permissionCheck instanceof ResponseInterface) {
|
||||
return $permissionCheck;
|
||||
}
|
||||
$user->setDisable(true);
|
||||
$user = FrontendUtility::forceValues(
|
||||
$user,
|
||||
ConfigurationUtility::getValue('invitation./forceValues./beforeAnyConfirmation.', $this->config)
|
||||
);
|
||||
$user = UserUtility::fallbackUsernameAndPassword($user);
|
||||
if (ConfigurationUtility::getValue('invitation/fillEmailWithUsername', $this->settings) === '1') {
|
||||
$user->setEmail($user->getUsername());
|
||||
}
|
||||
UserUtility::hashPassword(
|
||||
$user,
|
||||
ConfigurationUtility::getValue('invitation/misc/passwordSave', $this->settings)
|
||||
);
|
||||
$this->eventDispatcher->dispatch(new InviteUserCreateEvent($user));
|
||||
$this->ratelimiterService->consumeSlot();
|
||||
$this->createAllConfirmed($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefix method to createAction()
|
||||
* Create Confirmation from Admin is not necessary
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function createAllConfirmed(User $user)
|
||||
{
|
||||
$this->userRepository->add($user);
|
||||
$this->persistenceManager->persistAll();
|
||||
$this->addFlashMessage(LocalizationUtility::translate('createAndInvited'));
|
||||
$this->logUtility->log(Log::STATUS_INVITATIONPROFILECREATED, $user);
|
||||
|
||||
// send confirmation mail to user
|
||||
$this->sendMailService->send(
|
||||
'invitation',
|
||||
StringUtility::makeEmailArray($user->getEmail(), $user->getUsername()),
|
||||
StringUtility::makeEmailArray($user->getEmail(), $user->getUsername()),
|
||||
'Profile creation with invitation',
|
||||
[
|
||||
'user' => $user,
|
||||
'settings' => $this->settings,
|
||||
'hash' => HashUtility::createHashForUser($user)
|
||||
],
|
||||
$this->config['invitation.']['email.']['invitation.']
|
||||
);
|
||||
|
||||
// send notify email to admin
|
||||
$notifyAdminStep1 = ConfigurationUtility::getValue('invitation/notifyAdminStep1', $this->settings);
|
||||
if ($notifyAdminStep1) {
|
||||
$this->sendMailService->send(
|
||||
'invitationNotifyStep1',
|
||||
StringUtility::makeEmailArray(
|
||||
$notifyAdminStep1,
|
||||
ConfigurationUtility::getValue('invitation/email/invitationAdminNotifyStep1/receiver/name/value', $this->settings)
|
||||
),
|
||||
StringUtility::makeEmailArray($user->getEmail(), $user->getUsername()),
|
||||
'Profile creation with invitation - Step 1',
|
||||
[
|
||||
'user' => $user,
|
||||
'settings' => $this->settings
|
||||
],
|
||||
ConfigurationUtility::getValue('invitation./email./invitationAdminNotifyStep1.', $this->config)
|
||||
);
|
||||
}
|
||||
|
||||
$this->eventDispatcher->dispatch(new InviteUserConfirmedEvent($user));
|
||||
|
||||
$this->redirectByAction('invitation', 'redirectStep1');
|
||||
$this->redirect('new');
|
||||
}
|
||||
|
||||
/**
|
||||
* action edit
|
||||
*
|
||||
* @param int $user User UID
|
||||
* @param string $hash
|
||||
*/
|
||||
public function editAction($user, $hash = null): ResponseInterface
|
||||
{
|
||||
$user = $this->userRepository->findByUid($user);
|
||||
|
||||
// User must exist and hash must be valid
|
||||
if ($user === null || !HashUtility::validHash($hash, $user)) {
|
||||
$this->addFlashMessage(LocalizationUtility::translate('createFailedProfile'), '', AbstractMessage::ERROR);
|
||||
$this->redirect('status');
|
||||
}
|
||||
|
||||
// User must not be deleted (deleted = 0) and not be activated (disable = 1)
|
||||
if ($user->getDisable() == 0) {
|
||||
$this->addFlashMessage(LocalizationUtility::translate('userAlreadyConfirmed'), '', AbstractMessage::ERROR);
|
||||
$this->redirect('status');
|
||||
}
|
||||
|
||||
$user->setDisable(false);
|
||||
$this->userRepository->update($user);
|
||||
$this->persistenceManager->persistAll();
|
||||
|
||||
$this->eventDispatcher->dispatch(new InviteUserEditEvent($user, $hash));
|
||||
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'user' => $user,
|
||||
'hash' => $hash
|
||||
]
|
||||
);
|
||||
|
||||
$this->assignForAll();
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* action update
|
||||
*
|
||||
* @param User $user
|
||||
* @param string $hash
|
||||
* @Validate("In2code\Femanager\Domain\Validator\ServersideValidator", param="user")
|
||||
* @Validate("In2code\Femanager\Domain\Validator\PasswordValidator", param="user")
|
||||
*/
|
||||
public function updateAction(User $user, $hash = null)
|
||||
{
|
||||
if (!HashUtility::validHash($hash, $user)) {
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translateByState(Log::STATUS_PROFILEUPDATEREFUSEDSECURITY),
|
||||
'',
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
$this->redirect('status');
|
||||
}
|
||||
$this->addFlashMessage(LocalizationUtility::translate('createAndInvitedFinished'));
|
||||
$this->logUtility->log(Log::STATUS_INVITATIONPROFILEENABLED, $user);
|
||||
$notifyAdmin = ConfigurationUtility::getValue('invitation/notifyAdmin', $this->settings);
|
||||
if ($notifyAdmin) {
|
||||
$this->sendMailService->send(
|
||||
'invitationNotify',
|
||||
StringUtility::makeEmailArray(
|
||||
$notifyAdmin,
|
||||
ConfigurationUtility::getValue('invitation/email/invitationAdminNotify/receiver/name/value', $this->settings)
|
||||
),
|
||||
StringUtility::makeEmailArray($user->getEmail(), $user->getUsername()),
|
||||
'Profile creation with invitation - Final',
|
||||
[
|
||||
'user' => $user,
|
||||
'settings' => $this->settings
|
||||
],
|
||||
ConfigurationUtility::getValue('invitation./email./invitationAdminNotify.', $this->config)
|
||||
);
|
||||
}
|
||||
$user = UserUtility::overrideUserGroup($user, $this->settings, 'invitation');
|
||||
UserUtility::hashPassword($user, ConfigurationUtility::getValue('invitation/misc/passwordSave', $this->settings));
|
||||
$this->userRepository->update($user);
|
||||
$this->persistenceManager->persistAll();
|
||||
$this->eventDispatcher->dispatch(new InviteUserUpdateEvent($user));
|
||||
$this->redirectByAction('invitation', 'redirectPasswordChanged');
|
||||
$this->redirect('status');
|
||||
}
|
||||
|
||||
/**
|
||||
* action delete
|
||||
*
|
||||
* @param int $user User UID
|
||||
* @param string $hash
|
||||
*/
|
||||
public function deleteAction($user, $hash = null)
|
||||
{
|
||||
$user = $this->userRepository->findByUid($user);
|
||||
|
||||
if ($user !== null && HashUtility::validHash($hash, $user)) {
|
||||
$this->logUtility->log(Log::STATUS_PROFILEDELETE, $user);
|
||||
$this->addFlashMessage(LocalizationUtility::translateByState(Log::STATUS_INVITATIONPROFILEDELETEDUSER));
|
||||
|
||||
// send notify email to admin
|
||||
$notifyAdmin = ConfigurationUtility::getValue('invitation/notifyAdmin', $this->settings);
|
||||
if ($notifyAdmin) {
|
||||
$this->sendMailService->send(
|
||||
'invitationRefused',
|
||||
StringUtility::makeEmailArray(
|
||||
$notifyAdmin,
|
||||
ConfigurationUtility::getValue('invitation/email/invitationRefused/receiver/name/value', $this->settings)
|
||||
),
|
||||
StringUtility::makeEmailArray($user->getEmail(), $user->getUsername()),
|
||||
'Profile deleted from User after invitation - Step 1',
|
||||
[
|
||||
'user' => $user,
|
||||
'settings' => $this->settings
|
||||
],
|
||||
$this->config['invitation.']['email.']['invitationRefused.']
|
||||
);
|
||||
}
|
||||
|
||||
$this->userRepository->remove($user);
|
||||
$this->redirectByAction('invitation', 'redirectDelete');
|
||||
$this->redirect('status');
|
||||
} else {
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translateByState(Log::STATUS_INVITATIONHASHERROR),
|
||||
'',
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
$this->redirect('status');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restricted Action to show messages
|
||||
*/
|
||||
public function statusAction(): ResponseInterface
|
||||
{
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if user is allowed to see this action
|
||||
*
|
||||
* @return true|ForwardResponse
|
||||
*/
|
||||
protected function allowedUserForInvitationNewAndCreate()
|
||||
{
|
||||
if (empty($this->settings['invitation']['allowedUserGroups'] ?? [])) {
|
||||
return true;
|
||||
}
|
||||
$allowedUsergroupUids = GeneralUtility::trimExplode(
|
||||
',',
|
||||
$this->settings['invitation']['allowedUserGroups'] ?? [],
|
||||
true
|
||||
);
|
||||
$currentUsergroupUids = UserUtility::getCurrentUsergroupUids();
|
||||
|
||||
// compare allowedUsergroups with currentUsergroups
|
||||
if (count(array_intersect($allowedUsergroupUids, $currentUsergroupUids))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// current user is not allowed
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translateByState(Log::STATUS_INVITATIONRESTRICTEDPAGE),
|
||||
'',
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
return new ForwardResponse('status');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,562 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Controller;
|
||||
|
||||
use In2code\Femanager\Domain\Model\Log;
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use In2code\Femanager\Domain\Service\AutoAdminConfirmationService;
|
||||
use In2code\Femanager\Event\BeforeUserConfirmEvent;
|
||||
use In2code\Femanager\Event\BeforeUserCreateEvent;
|
||||
use In2code\Femanager\Event\CreateConfirmationRequestEvent;
|
||||
use In2code\Femanager\Utility\ConfigurationUtility;
|
||||
use In2code\Femanager\Utility\FrontendUtility;
|
||||
use In2code\Femanager\Utility\HashUtility;
|
||||
use In2code\Femanager\Utility\LocalizationUtility;
|
||||
use In2code\Femanager\Utility\StringUtility;
|
||||
use In2code\Femanager\Utility\UserUtility;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use TYPO3\CMS\Core\Crypto\PasswordHashing\InvalidPasswordHashException;
|
||||
use TYPO3\CMS\Core\Http\ServerRequestFactory;
|
||||
use TYPO3\CMS\Core\Messaging\AbstractMessage;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Annotation\Validate;
|
||||
use TYPO3\CMS\Extbase\Event\Mvc\AfterRequestDispatchedEvent;
|
||||
use TYPO3\CMS\Extbase\Mvc\Exception\StopActionException;
|
||||
use TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException;
|
||||
use TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException;
|
||||
|
||||
/**
|
||||
* Class NewController
|
||||
*/
|
||||
class NewController extends AbstractFrontendController
|
||||
{
|
||||
/**
|
||||
* Render registration form
|
||||
*
|
||||
*/
|
||||
public function newAction(): ResponseInterface
|
||||
{
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'allUserGroups' => $this->allUserGroups
|
||||
]
|
||||
);
|
||||
$this->assignForAll();
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* action create
|
||||
*
|
||||
* @param User $user
|
||||
* @throws InvalidPasswordHashException
|
||||
* @throws StopActionException
|
||||
* @Validate("In2code\Femanager\Domain\Validator\ServersideValidator", param="user")
|
||||
* @Validate("In2code\Femanager\Domain\Validator\PasswordValidator", param="user")
|
||||
* @Validate("In2code\Femanager\Domain\Validator\CaptchaValidator", param="user")
|
||||
*/
|
||||
public function createAction(User $user)
|
||||
{
|
||||
if ($this->ratelimiterService->isLimited()) {
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translate('ratelimiter_too_many_attempts'),
|
||||
'',
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
$this->redirect('createStatus');
|
||||
}
|
||||
$user = UserUtility::overrideUserGroup($user, $this->settings);
|
||||
$configuration = ConfigurationUtility::getValue('new./forceValues./beforeAnyConfirmation.', $this->config);
|
||||
$user = FrontendUtility::forceValues($user, $configuration);
|
||||
$user = UserUtility::fallbackUsernameAndPassword($user);
|
||||
$user = UserUtility::takeEmailAsUsername($user, $this->settings);
|
||||
|
||||
UserUtility::hashPassword($user, ConfigurationUtility::getValue('new/misc/passwordSave', $this->settings));
|
||||
|
||||
$this->eventDispatcher->dispatch(new BeforeUserCreateEvent($user));
|
||||
$this->ratelimiterService->consumeSlot();
|
||||
|
||||
if ($this->isAllConfirmed()) {
|
||||
$this->createAllConfirmed($user);
|
||||
} else {
|
||||
$this->createRequest($user);
|
||||
}
|
||||
|
||||
$this->redirect('createStatus');
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatcher action for every confirmation request
|
||||
*
|
||||
* @param int $user User UID (user could be hidden)
|
||||
* @param string $hash Given hash
|
||||
* @param string $status
|
||||
* "userConfirmation", "userConfirmationRefused", "adminConfirmation",
|
||||
* "adminConfirmationRefused", "adminConfirmationRefusedSilent"
|
||||
* @param string $adminHash
|
||||
* @throws IllegalObjectTypeException
|
||||
* @throws StopActionException
|
||||
*/
|
||||
public function confirmCreateRequestAction(int $user, string $hash, string $status = 'adminConfirmation', string $adminHash = null)
|
||||
{
|
||||
$backend = false;
|
||||
$furtherFunctions = false;
|
||||
|
||||
$user = $this->userRepository->findByUid($user);
|
||||
|
||||
$this->eventDispatcher->dispatch(new BeforeUserConfirmEvent($user, $hash, $status));
|
||||
|
||||
if ($user === null) {
|
||||
$this->addFlashMessage(LocalizationUtility::translate('missingUserInDatabase'), '', AbstractMessage::ERROR);
|
||||
$this->redirect('new');
|
||||
}
|
||||
|
||||
$request = ServerRequestFactory::fromGlobals();
|
||||
// check if the the request was triggered via Backend
|
||||
if ($request->hasHeader('Accept')) {
|
||||
$accept = $request->getHeader('Accept')[0];
|
||||
if (false !== strpos($accept, 'application/json')) {
|
||||
$backend = true;
|
||||
}
|
||||
}
|
||||
|
||||
switch ($status) {
|
||||
case 'userConfirmation':
|
||||
if ($status === 'userConfirmation' && ConfigurationUtility::getValue(
|
||||
'new./email./createUserConfirmation./confirmUserConfirmation',
|
||||
$this->config
|
||||
) == '1') {
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'user' => $user,
|
||||
'status' => 'confirmUser',
|
||||
'hash' => $hash,
|
||||
]
|
||||
);
|
||||
$this->assignForAll();
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
$furtherFunctions = $this->statusUserConfirmation($user, $hash, $status);
|
||||
break;
|
||||
|
||||
case 'confirmDeletion':
|
||||
$furtherFunctions = $this->statusUserConfirmationRefused($user, $hash);
|
||||
break;
|
||||
|
||||
case 'confirmedByUser':
|
||||
$furtherFunctions = $this->statusUserConfirmation($user, $hash, $status);
|
||||
break;
|
||||
|
||||
case 'userConfirmationRefused':
|
||||
if (ConfigurationUtility::getValue('new./email./createUserConfirmation./confirmUserConfirmationRefused', $this->config) == '1') {
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'user' => $user,
|
||||
'status' => 'confirmDeletion',
|
||||
'hash' =>$hash
|
||||
]
|
||||
);
|
||||
$this->assignForAll();
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
$furtherFunctions = $this->statusUserConfirmationRefused($user, $hash);
|
||||
break;
|
||||
|
||||
case 'adminConfirmation':
|
||||
if ($status === 'adminConfirmation' && ConfigurationUtility::getValue(
|
||||
'new./email./createUserConfirmation./confirmAdminConfirmation',
|
||||
$this->config
|
||||
) == '1') {
|
||||
|
||||
if (!HashUtility::validHash($adminHash, $user, 'admin')) {
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translate('error_not_authorized'),
|
||||
'',
|
||||
ContextualFeedbackSeverity::ERROR
|
||||
);
|
||||
throw new PropagateResponseException($this->redirect('new'), 1743766811);
|
||||
}
|
||||
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'user' => $user,
|
||||
'status' => 'confirmAdmin',
|
||||
'hash' => $hash,
|
||||
]
|
||||
);
|
||||
$this->assignForAll();
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
if (($status === 'adminConfirmationRefused' || $status === 'adminConfirmationRefusedSilent') &&
|
||||
ConfigurationUtility::getValue(
|
||||
'new./email./createUserConfirmation./confirmAdminConfirmation',
|
||||
$this->config
|
||||
) == '1') {
|
||||
|
||||
if (!HashUtility::validHash($adminHash, $user, 'admin')) {
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translate('error_not_authorized'),
|
||||
'',
|
||||
ContextualFeedbackSeverity::ERROR
|
||||
);
|
||||
throw new PropagateResponseException($this->redirect('new'), 1743766811);
|
||||
}
|
||||
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'user' => $user,
|
||||
'status' => 'confirmAdminRefused',
|
||||
'silent' => $status === 'adminConfirmationRefusedSilent',
|
||||
'hash' => $hash,
|
||||
]
|
||||
);
|
||||
$this->assignForAll();
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
$furtherFunctions = $this->statusAdminConfirmation($user, $hash, $status, $backend);
|
||||
break;
|
||||
|
||||
case 'confirmedByAdmin':
|
||||
$furtherFunctions = $this->statusAdminConfirmation($user, $hash, $status, $backend);
|
||||
break;
|
||||
|
||||
case 'confirmedByAdminRefused':
|
||||
$furtherFunctions = $this->statusAdminConfirmationRefused($user, $hash, $status, $backend);
|
||||
break;
|
||||
|
||||
case 'adminConfirmationRefused':
|
||||
// Admin refuses profile
|
||||
if (ConfigurationUtility::getValue(
|
||||
'new./email./createUserConfirmation./confirmAdminConfirmation',
|
||||
$this->config
|
||||
) == '1') {
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'user' => $user,
|
||||
'status' => 'confirmAdminRefused',
|
||||
'hash' => $hash,
|
||||
]
|
||||
);
|
||||
$this->assignForAll();
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
break;
|
||||
|
||||
case 'adminConfirmationRefusedSilent':
|
||||
// Admin refuses profile
|
||||
if (ConfigurationUtility::getValue(
|
||||
'new./email./createUserConfirmation./confirmAdminConfirmation',
|
||||
$this->config
|
||||
) == '1') {
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'user' => $user,
|
||||
'status' => 'confirmAdminRefused',
|
||||
'hash' => $hash,
|
||||
]
|
||||
);
|
||||
$this->assignForAll();
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
$furtherFunctions = $this->statusAdminConfirmationRefused($user, $hash, $status);
|
||||
break;
|
||||
case 'confirmedByAdminRefusedSilent':
|
||||
$furtherFunctions = $this->statusAdminConfirmationRefused($user, $hash, $status);
|
||||
break;
|
||||
|
||||
default:
|
||||
$furtherFunctions = false;
|
||||
}
|
||||
|
||||
if ($backend) {
|
||||
$this->eventDispatcher->dispatch(new AfterRequestDispatchedEvent($this->request, $this->response));
|
||||
$this->persistenceManager->persistAll();
|
||||
// this request was triggered via Backend Module "Frontend users", so we stop here and provide a feedback to the BE
|
||||
echo json_encode(['status' => 'okay']) . PHP_EOL;
|
||||
die();
|
||||
}
|
||||
|
||||
if ($furtherFunctions) {
|
||||
$this->redirectByAction('new', $status . 'Redirect');
|
||||
}
|
||||
|
||||
$this->redirect('new');
|
||||
}
|
||||
|
||||
/**
|
||||
* Status action: User confirmation
|
||||
*
|
||||
* @param User $user
|
||||
* @param string $hash
|
||||
* @param string $status
|
||||
* @return bool allow further functions
|
||||
* @throws UnsupportedRequestTypeException
|
||||
* @throws IllegalObjectTypeException
|
||||
*/
|
||||
protected function statusUserConfirmation(User $user, string $hash, string $status)
|
||||
{
|
||||
if (HashUtility::validHash($hash, $user)) {
|
||||
if ($user->getTxFemanagerConfirmedbyuser()) {
|
||||
$this->addFlashMessage(LocalizationUtility::translate('userAlreadyConfirmed'), '', AbstractMessage::ERROR);
|
||||
$this->redirect('new');
|
||||
}
|
||||
|
||||
$user = FrontendUtility::forceValues($user, ConfigurationUtility::getValue('new./forceValues./onUserConfirmation.', $this->config));
|
||||
$user->setTxFemanagerConfirmedbyuser(true);
|
||||
$this->userRepository->update($user);
|
||||
$this->persistenceManager->persistAll();
|
||||
$this->logUtility->log(Log::STATUS_REGISTRATIONCONFIRMEDUSER, $user);
|
||||
|
||||
if ($this->isAdminConfirmationMissing($user)) {
|
||||
$this->createAdminConfirmationRequest($user);
|
||||
} else {
|
||||
$user->setDisable(false);
|
||||
$this->logUtility->log(Log::STATUS_NEWREGISTRATION, $user);
|
||||
$this->finalCreate($user, 'new', 'createStatus', true, $status);
|
||||
}
|
||||
} else {
|
||||
$this->addFlashMessage(LocalizationUtility::translate('createFailedProfile'), '', AbstractMessage::ERROR);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Status action: User confirmation refused
|
||||
*
|
||||
* @param User $user
|
||||
* @param string $hash
|
||||
* @return bool allow further functions
|
||||
* @throws IllegalObjectTypeException
|
||||
*/
|
||||
protected function statusUserConfirmationRefused(User $user, $hash)
|
||||
{
|
||||
if (HashUtility::validHash($hash, $user)) {
|
||||
$this->logUtility->log(Log::STATUS_REGISTRATIONREFUSEDUSER, $user);
|
||||
$this->addFlashMessage(LocalizationUtility::translate('createProfileDeleted'));
|
||||
$this->userRepository->remove($user);
|
||||
} else {
|
||||
$this->addFlashMessage(LocalizationUtility::translate('createFailedProfile'), '', AbstractMessage::ERROR);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Status action: Admin confirmation
|
||||
*
|
||||
* @param User $user
|
||||
* @param string $hash
|
||||
* @param string $status
|
||||
* @return bool allow further functions
|
||||
*/
|
||||
protected function statusAdminConfirmation(User $user, $hash, $status, $backend = false)
|
||||
{
|
||||
if (HashUtility::validHash($hash, $user)) {
|
||||
if ($user->getTxFemanagerConfirmedbyadmin()) {
|
||||
$this->addFlashMessage(LocalizationUtility::translate('userAlreadyConfirmed'), '', AbstractMessage::ERROR);
|
||||
$this->redirect('new');
|
||||
}
|
||||
|
||||
$user = FrontendUtility::forceValues($user, ConfigurationUtility::getValue('new./forceValues./onAdminConfirmation.', $this->config));
|
||||
$user->setTxFemanagerConfirmedbyadmin(true);
|
||||
$user->setDisable(false);
|
||||
$this->userRepository->update($user);
|
||||
$this->logUtility->log(Log::STATUS_REGISTRATIONCONFIRMEDADMIN, $user);
|
||||
$this->finalCreate($user, 'new', 'createStatus', false, $status, $backend);
|
||||
} else {
|
||||
$this->addFlashMessage(LocalizationUtility::translate('createFailedProfile'), '', AbstractMessage::ERROR);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Status action: Admin refused profile creation (normal or silent)
|
||||
*
|
||||
* @param User $user
|
||||
* @param $hash
|
||||
* @param $status
|
||||
* @return bool allow further functions
|
||||
* @throws IllegalObjectTypeException
|
||||
*/
|
||||
protected function statusAdminConfirmationRefused(User $user, $hash, $status)
|
||||
{
|
||||
if (HashUtility::validHash($hash, $user)) {
|
||||
$this->logUtility->log(Log::STATUS_REGISTRATIONREFUSEDADMIN, $user);
|
||||
$this->addFlashMessage(LocalizationUtility::translate('createProfileDeleted'));
|
||||
if ($status !== 'adminConfirmationRefusedSilent') {
|
||||
$this->sendMailService->send(
|
||||
'CreateUserNotifyRefused',
|
||||
StringUtility::makeEmailArray(
|
||||
$user->getEmail(),
|
||||
$user->getFirstName() . ' ' . $user->getLastName()
|
||||
),
|
||||
['sender@femanager.org' => 'Sender Name'],
|
||||
'Your profile was refused',
|
||||
['user' => $user],
|
||||
ConfigurationUtility::getValue('new./email./createUserNotifyRefused.', $this->config)
|
||||
);
|
||||
}
|
||||
$this->userRepository->remove($user);
|
||||
} else {
|
||||
$this->addFlashMessage(LocalizationUtility::translate('createFailedProfile'), '', AbstractMessage::ERROR);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Just for showing informations after user creation
|
||||
*/
|
||||
public function createStatusAction(): ResponseInterface
|
||||
{
|
||||
$this->assignForAll();
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Postfix method to createAction(): Create must be confirmed by Admin or User
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
protected function createRequest(User $user)
|
||||
{
|
||||
$user->setDisable(true);
|
||||
$this->userRepository->add($user);
|
||||
$this->persistenceManager->persistAll();
|
||||
$this->logUtility->log(Log::STATUS_PROFILECREATIONREQUEST, $user);
|
||||
if (!empty($this->settings['new']['confirmByUser'])) {
|
||||
$this->createUserConfirmationRequest($user);
|
||||
$this->redirectByAction('new', 'requestRedirect');
|
||||
} elseif (!empty($this->settings['new']['confirmByAdmin'])) {
|
||||
$this->createAdminConfirmationRequest($user);
|
||||
$this->redirectByAction('new', 'requestRedirect');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send email to user for confirmation
|
||||
*
|
||||
* @param User $user
|
||||
* @throws UnsupportedRequestTypeException
|
||||
*/
|
||||
protected function createUserConfirmationRequest(User $user)
|
||||
{
|
||||
$this->sendCreateUserConfirmationMail($user);
|
||||
$this->addFlashMessage(LocalizationUtility::translate('createRequestWaitingForUserConfirm'));
|
||||
$this->redirectByAction('new', 'requestRedirect');
|
||||
}
|
||||
|
||||
/**
|
||||
* Send email to admin for confirmation
|
||||
*
|
||||
* @param User $user
|
||||
* @throws UnsupportedRequestTypeException
|
||||
*/
|
||||
protected function createAdminConfirmationRequest(User $user)
|
||||
{
|
||||
$aacService = $this->objectManager->get(
|
||||
AutoAdminConfirmationService::class,
|
||||
$user,
|
||||
$this->settings,
|
||||
$this->contentObject
|
||||
);
|
||||
if ($aacService->isAutoAdminConfirmationFullfilled()) {
|
||||
$user->setDisable(false);
|
||||
$this->eventDispatcher->dispatch(
|
||||
new CreateConfirmationRequestEvent($user, CreateConfirmationRequestEvent::MODE_AUTOMATIC)
|
||||
);
|
||||
$this->createAllConfirmed($user);
|
||||
} else {
|
||||
$this->eventDispatcher->dispatch(
|
||||
new CreateConfirmationRequestEvent($user, CreateConfirmationRequestEvent::MODE_MANUAL)
|
||||
);
|
||||
$this->sendMailService->send(
|
||||
'createAdminConfirmation',
|
||||
StringUtility::makeEmailArray(
|
||||
$this->settings['new']['confirmByAdmin'] ?? '',
|
||||
$this->settings['new']['email']['createAdminConfirmation']['receiver']['name']['value'] ?? ''
|
||||
),
|
||||
StringUtility::makeEmailArray($user->getEmail(), $user->getUsername()),
|
||||
'New Registration request',
|
||||
[
|
||||
'user' => $user,
|
||||
'hash' => HashUtility::createHashForUser($user),
|
||||
'adminHash' => HashUtility::createHashForUser($user, 'admin'),
|
||||
],
|
||||
ConfigurationUtility::getValue('new./email./createAdminConfirmation.', $this->config)
|
||||
);
|
||||
$this->addFlashMessage(LocalizationUtility::translate('createRequestWaitingForAdminConfirm'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function isAllConfirmed()
|
||||
{
|
||||
return empty($this->settings['new']['confirmByUser']) && empty($this->settings['new']['confirmByAdmin']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @return bool
|
||||
*/
|
||||
protected function isAdminConfirmationMissing(User $user)
|
||||
{
|
||||
return !empty($this->settings['new']['confirmByAdmin']) && !$user->getTxFemanagerConfirmedbyadmin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Just for showing empty dialogue to resend confirmation mail
|
||||
*/
|
||||
public function resendConfirmationDialogueAction(): ResponseInterface
|
||||
{
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* re-sends a confirmation email if given mail is valid
|
||||
*
|
||||
* @throws UnsupportedRequestTypeException
|
||||
* @throws StopActionException
|
||||
*/
|
||||
public function resendConfirmationMailAction()
|
||||
{
|
||||
// @todo find a better way to fetch the data
|
||||
$result = GeneralUtility::_GP('tx_femanager_pi1');
|
||||
if (is_array($result)) {
|
||||
if (GeneralUtility::validEmail($result['user']['email'])) {
|
||||
$user = $this->userRepository->findFirstByEmail($result['user']['email']);
|
||||
if (is_a($user, User::class)) {
|
||||
$this->sendCreateUserConfirmationMail($user);
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translate('resendConfirmationMailSend'),
|
||||
'',
|
||||
AbstractMessage::INFO
|
||||
);
|
||||
$this->redirect('resendConfirmationDialogue');
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translate('resendConfirmationMailFail'),
|
||||
LocalizationUtility::translate('validationError'),
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
$this->redirect('resendConfirmationDialogue');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,276 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace In2code\Femanager\Controller;
|
||||
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use In2code\Femanager\Event\AdminConfirmationUserEvent;
|
||||
use In2code\Femanager\Event\RefuseUserEvent;
|
||||
use In2code\Femanager\Utility\ConfigurationUtility;
|
||||
use In2code\Femanager\Utility\HashUtility;
|
||||
use In2code\Femanager\Utility\LocalizationUtility;
|
||||
use In2code\Femanager\Utility\UserUtility;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use TYPO3\CMS\Backend\Routing\UriBuilder;
|
||||
use TYPO3\CMS\Core\Messaging\AbstractMessage;
|
||||
use TYPO3\CMS\Core\Site\SiteFinder;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Http\ForwardResponse;
|
||||
|
||||
/**
|
||||
* Class UserBackendController
|
||||
*/
|
||||
class UserBackendController extends AbstractController
|
||||
{
|
||||
protected $configPID;
|
||||
|
||||
/**
|
||||
* @param array $filter
|
||||
*/
|
||||
public function listAction(array $filter = []): ResponseInterface
|
||||
{
|
||||
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
|
||||
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'users' => $this->userRepository->findAllInBackend($filter),
|
||||
'moduleUri' => $uriBuilder->buildUriFromRoute('tce_db'),
|
||||
'action' => 'list',
|
||||
'loginAsEnabled' => $this->loginAsEnabled()
|
||||
]
|
||||
);
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $filter
|
||||
*/
|
||||
public function confirmationAction(array $filter = []): ResponseInterface
|
||||
{
|
||||
$this->configPID = $this->getConfigPID();
|
||||
|
||||
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
|
||||
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'users' => $this->userRepository->findAllInBackendForConfirmation(
|
||||
$filter,
|
||||
ConfigurationUtility::isBackendModuleFilterUserConfirmation()
|
||||
),
|
||||
'moduleUri' => $uriBuilder->buildUriFromRoute('tce_db'),
|
||||
'action' => 'confirmation'
|
||||
]
|
||||
);
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
public function userLogoutAction(User $user)
|
||||
{
|
||||
$queryParams = $this->request->getQueryParams();
|
||||
if (empty($queryParams['id']) || $queryParams['id'] !== (string)$user->getPid()) {
|
||||
return new ForwardResponse('list');
|
||||
}
|
||||
UserUtility::removeFrontendSessionToUser($user);
|
||||
$this->addFlashMessage('User successfully logged out');
|
||||
$this->redirect('list');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $userIdentifier
|
||||
*/
|
||||
public function confirmUserAction(int $userIdentifier)
|
||||
{
|
||||
$this->configPID = $this->getConfigPID();
|
||||
|
||||
$user = $this->userRepository->findByUid($userIdentifier);
|
||||
$queryParams = $this->request->getQueryParams();
|
||||
if (empty($queryParams['id']) || $user === null || $queryParams['id'] !== (string)$user->getPid()) {
|
||||
return new ForwardResponse('list');
|
||||
}
|
||||
$this->eventDispatcher->dispatch(new AdminConfirmationUserEvent($user));
|
||||
|
||||
$jsonResult = $this->getFrontendRequestResult('adminConfirmation', $userIdentifier, $user);
|
||||
|
||||
if ($jsonResult['status'] ?? false) {
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translate(
|
||||
'BackendConfirmationFlashMessageConfirmed',
|
||||
'femanager',
|
||||
[$user->getUsername()]
|
||||
),
|
||||
'User Confirmation'
|
||||
);
|
||||
} else {
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translate(
|
||||
'BackendConfirmationFlashMessageFailed',
|
||||
'femanager',
|
||||
[$user->getUsername()]
|
||||
),
|
||||
'User Confirmation',
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
}
|
||||
|
||||
$this->redirect('confirmation');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $userIdentifier
|
||||
*/
|
||||
public function refuseUserAction(int $userIdentifier)
|
||||
{
|
||||
$this->configPID = $this->getConfigPID();
|
||||
|
||||
$user = $this->userRepository->findByUid($userIdentifier);
|
||||
$queryParams = $this->request->getQueryParams();
|
||||
if (empty($queryParams['id']) || $user === null || $queryParams['id'] !== (string)$user->getPid()) {
|
||||
return new ForwardResponse('list');
|
||||
}
|
||||
$this->eventDispatcher->dispatch(new RefuseUserEvent($user));
|
||||
|
||||
$jsonResult = $this->getFrontendRequestResult('adminConfirmationRefused', $userIdentifier, $user);
|
||||
|
||||
if ($jsonResult['status'] ?? false) {
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translate(
|
||||
'BackendConfirmationFlashMessageRefused',
|
||||
'femanager',
|
||||
[$user->getUsername()]
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translate(
|
||||
'BackendConfirmationFlashMessageFailed',
|
||||
'femanager',
|
||||
[$user->getUsername()]
|
||||
),
|
||||
'User Confirmation',
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
}
|
||||
|
||||
$this->redirect('confirmation');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $filter
|
||||
*/
|
||||
public function listOpenUserConfirmationsAction(array $filter = []): ResponseInterface
|
||||
{
|
||||
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
|
||||
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'users' => $this->userRepository->findAllInBackendForConfirmation(
|
||||
$filter,
|
||||
false
|
||||
),
|
||||
'moduleUri' => $uriBuilder->buildUriFromRoute('tce_db'),
|
||||
'action' => 'listOpenUserConfirmations'
|
||||
]
|
||||
);
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $userIdentifier
|
||||
*/
|
||||
public function resendUserConfirmationRequestAction(int $userIdentifier)
|
||||
{
|
||||
$user = $this->userRepository->findByUid($userIdentifier);
|
||||
$queryParams = $this->request->getQueryParams();
|
||||
if (empty($queryParams['id']) || $user === null || $queryParams['id'] !== (string)$user->getPid()) {
|
||||
return new ForwardResponse('list');
|
||||
}
|
||||
$this->sendCreateUserConfirmationMail($user);
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translate(
|
||||
'BackendConfirmationFlashMessageReSend',
|
||||
'femanager',
|
||||
[$user->getUsername()]
|
||||
),
|
||||
'',
|
||||
AbstractMessage::OK
|
||||
);
|
||||
$this->redirect('listOpenUserConfirmations');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getConfigPID()
|
||||
{
|
||||
if (isset($this->moduleConfig['settings.']['configPID']) && $this->moduleConfig['settings.']['configPID'] > 0) {
|
||||
return (int)$this->moduleConfig['settings.']['configPID'];
|
||||
}
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translate(
|
||||
'BackendMissingConfigPID',
|
||||
'femanager'
|
||||
),
|
||||
'Backend Configuration',
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $status
|
||||
* @param $userIdentifier
|
||||
* @param $user
|
||||
*/
|
||||
public function getFrontendRequestResult($status, $userIdentifier, $user)
|
||||
{
|
||||
/** @var SiteFinder $siteFinder */
|
||||
$siteFinder = GeneralUtility::makeInstance(SiteFinder::class);
|
||||
|
||||
$site = $siteFinder->getSiteByPageId($this->configPID);
|
||||
$url = $site->getRouter()->generateUri(
|
||||
$this->configPID,
|
||||
[
|
||||
'tx_femanager_pi1' => [
|
||||
'user' => $userIdentifier,
|
||||
'hash' => HashUtility::createHashForUser($user),
|
||||
'status' => $status,
|
||||
'action' => 'confirmCreateRequest',
|
||||
'controller' => 'New'
|
||||
]
|
||||
]
|
||||
);
|
||||
|
||||
$response = GeneralUtility::makeInstance(RequestFactory::class)->request((string)$url, 'GET', ['headers' => ['accept' => 'application/json']]);
|
||||
if ($response->getStatusCode() >= 300) {
|
||||
$content = $response->getReasonPhrase();
|
||||
$GLOBALS['BE_USER']->writelog(4, 0, 1, 0, 'femanager: Frontend request failed.', $content);
|
||||
$this->addFlashMessage(
|
||||
LocalizationUtility::translate(
|
||||
'BackendConfirmationFlashMessageFailed',
|
||||
'femanager'
|
||||
),
|
||||
'User Confirmation',
|
||||
AbstractMessage::ERROR
|
||||
);
|
||||
} else {
|
||||
$content = $response->getBody()->getContents();
|
||||
return json_decode($content, true);
|
||||
}
|
||||
}
|
||||
|
||||
private function loginAsEnabled(): bool
|
||||
{
|
||||
if ($GLOBALS['BE_USER']->user['admin'] === 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$tsConfigEnableLoginAs = (int)($GLOBALS['BE_USER']->getTSConfig()['tx_femanager.']['UserBackend.']['enableLoginAs'] ?? 0);
|
||||
|
||||
return $tsConfigEnableLoginAs === 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace In2code\Femanager\Controller;
|
||||
|
||||
use In2code\Femanager\Domain\Model\Log;
|
||||
use In2code\Femanager\Domain\Model\User;
|
||||
use In2code\Femanager\Domain\Validator\ClientsideValidator;
|
||||
use In2code\Femanager\Event\ImpersonateEvent;
|
||||
use In2code\Femanager\Utility\BackendUserUtility;
|
||||
use In2code\Femanager\Utility\FrontendUtility;
|
||||
use In2code\Femanager\Utility\LocalizationUtility;
|
||||
use In2code\Femanager\Utility\UserUtility;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use TYPO3\CMS\Core\Error\Http\UnauthorizedException;
|
||||
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
|
||||
|
||||
/**
|
||||
* Class UserController
|
||||
*/
|
||||
class UserController extends AbstractFrontendController
|
||||
{
|
||||
/**
|
||||
* @param array $filter
|
||||
*/
|
||||
public function listAction(array $filter = []): ResponseInterface
|
||||
{
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'users' => $this->userRepository->findByUsergroups(
|
||||
$this->settings['list']['usergroup'] ?? '',
|
||||
$this->settings,
|
||||
$filter
|
||||
),
|
||||
'filter' => $filter
|
||||
]
|
||||
);
|
||||
$this->assignForAll();
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforce user setting from FlexForm and ignore &tx_femanager_pi1[user]=421
|
||||
*/
|
||||
public function initializeShowAction()
|
||||
{
|
||||
$arguments = $this->request->getArguments();
|
||||
if (!empty($this->settings['show']['user']) ?? '') {
|
||||
unset($arguments['user']);
|
||||
}
|
||||
$this->request->setArguments($arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
public function showAction(User $user = null): ResponseInterface
|
||||
{
|
||||
$this->view->assign('user', $this->getUser($user));
|
||||
$this->assignForAll();
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function imageDeleteAction(User $user)
|
||||
{
|
||||
if (UserUtility::getCurrentUser() !== $user) {
|
||||
throw new UnauthorizedException('You are not allowed to delete this image', 1516373759972);
|
||||
}
|
||||
$user->setImage($this->objectManager->get(ObjectStorage::class));
|
||||
$this->userRepository->update($user);
|
||||
$this->logUtility->log(Log::STATUS_PROFILEUPDATEIMAGEDELETE, $user);
|
||||
$this->addFlashMessage(LocalizationUtility::translateByState(Log::STATUS_PROFILEUPDATEIMAGEDELETE));
|
||||
$this->redirectToUri(FrontendUtility::getUriToCurrentPage());
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this Action from eID to validate field values
|
||||
*
|
||||
* @param string $validation Validation string like "required, email, min(10)"
|
||||
* @param string $value Given Field value
|
||||
* @param string $field Fieldname like "username" or "email"
|
||||
* @param User $user Existing User
|
||||
* @param string $additionalValue Additional Values
|
||||
* @param int $plugin tt_content.uid of the femanager plugin
|
||||
* @param string $referrerAction current action name
|
||||
*/
|
||||
public function validateAction(
|
||||
$validation = null,
|
||||
$value = null,
|
||||
$field = null,
|
||||
User $user = null,
|
||||
$additionalValue = '',
|
||||
int $plugin = 0,
|
||||
string $referrerAction = ''
|
||||
): ResponseInterface {
|
||||
$clientsideValidator = $this->objectManager->get(ClientsideValidator::class);
|
||||
$result = $clientsideValidator
|
||||
->setValidationSettingsString($validation)
|
||||
->setValue($value)
|
||||
->setFieldName($field)
|
||||
->setUser($user)
|
||||
->setAdditionalValue($additionalValue)
|
||||
->setPlugin($plugin)
|
||||
->setActionName($referrerAction)
|
||||
->validateField();
|
||||
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'isValid' => $result,
|
||||
'messages' => $clientsideValidator->getMessages(),
|
||||
'validation' => $validation,
|
||||
'value' => $value,
|
||||
'fieldname' => $field,
|
||||
'user' => $user
|
||||
]
|
||||
);
|
||||
return $this->htmlResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate frontenduser login for backend adminstrators only
|
||||
*
|
||||
* @param User $user
|
||||
* @throws UnauthorizedException
|
||||
*/
|
||||
public function loginAsAction(User $user)
|
||||
{
|
||||
$this->eventDispatcher->dispatch(new ImpersonateEvent($user));
|
||||
|
||||
if (!BackendUserUtility::isAdminAuthentication()) {
|
||||
throw new UnauthorizedException(LocalizationUtility::translate('error_not_authorized'), 1516373787864);
|
||||
}
|
||||
UserUtility::login($user);
|
||||
$this->redirectByAction('loginAs', 'redirect');
|
||||
$this->redirectToUri('/');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @return User
|
||||
*/
|
||||
protected function getUser(User $user = null)
|
||||
{
|
||||
if ($user === null) {
|
||||
if (is_numeric($this->settings['show']['user'])) {
|
||||
$user = $this->userRepository->findByUid($this->settings['show']['user']);
|
||||
} elseif ($this->settings['show']['user'] === '[this]') {
|
||||
$user = $this->user;
|
||||
}
|
||||
}
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user