summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/Http/Controllers/AccountController.php4
-rw-r--r--app/Http/Controllers/Auth/LoginController.php4
-rw-r--r--app/Http/Controllers/UserController.php126
-rw-r--r--app/Http/Middleware/UseLocale.php2
-rw-r--r--app/Http/Middleware/UseTheme.php4
-rw-r--r--app/Http/RequestHandlers/DeleteUser.php71
-rw-r--r--app/Http/RequestHandlers/MasqueradeAsUser.php76
-rw-r--r--app/Http/RequestHandlers/ModuleAction.php (renamed from app/Http/Controllers/ModuleController.php)32
-rw-r--r--app/Http/RequestHandlers/SelectLanguage.php59
-rw-r--r--app/Http/RequestHandlers/SelectTheme.php59
-rw-r--r--app/I18N.php4
-rw-r--r--routes/web.php27
-rw-r--r--tests/app/Http/Controllers/ModuleControllerTest.php108
-rw-r--r--tests/app/Http/RequestHandlers/DeleteUserTest.php76
-rw-r--r--tests/app/Http/RequestHandlers/MasqueradeAsUserTest.php81
-rw-r--r--tests/app/Http/RequestHandlers/ModuleActionTest.php93
-rw-r--r--tests/app/Http/RequestHandlers/SelectLanguageTest.php57
-rw-r--r--tests/app/Http/RequestHandlers/SelectThemeTest.php59
18 files changed, 672 insertions, 270 deletions
diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php
index 70c12e1048..9bc34ba282 100644
--- a/app/Http/Controllers/AccountController.php
+++ b/app/Http/Controllers/AccountController.php
@@ -145,10 +145,10 @@ class AccountController extends AbstractBaseController
$tree->setUserPreference($user, 'rootid', $rootid);
// Switch to the new theme now
- Session::put('theme_id', $theme);
+ Session::put('theme', $theme);
// Switch to the new language now
- Session::put('locale', $language);
+ Session::put('language', $language);
return redirect(route('my-account', ['ged' => $tree->name()]));
}
diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php
index f6e15dbcca..221fd77aef 100644
--- a/app/Http/Controllers/Auth/LoginController.php
+++ b/app/Http/Controllers/Auth/LoginController.php
@@ -194,8 +194,8 @@ class LoginController extends AbstractBaseController
Log::addAuthenticationLog('Login: ' . Auth::user()->userName() . '/' . Auth::user()->realName());
Auth::user()->setPreference('sessiontime', (string) Carbon::now()->unix());
- Session::put('locale', Auth::user()->getPreference('language'));
- Session::put('theme_id', Auth::user()->getPreference('theme'));
+ Session::put('language', Auth::user()->getPreference('language'));
+ Session::put('theme', Auth::user()->getPreference('theme'));
I18N::init(Auth::user()->getPreference('language'));
}
diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php
deleted file mode 100644
index 884c5ecd3e..0000000000
--- a/app/Http/Controllers/UserController.php
+++ /dev/null
@@ -1,126 +0,0 @@
-<?php
-/**
- * webtrees: online genealogy
- * Copyright (C) 2019 webtrees development team
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-declare(strict_types=1);
-
-namespace Fisharebest\Webtrees\Http\Controllers;
-
-use Fig\Http\Message\StatusCodeInterface;
-use Fisharebest\Webtrees\Auth;
-use Fisharebest\Webtrees\I18N;
-use Fisharebest\Webtrees\Log;
-use Fisharebest\Webtrees\Services\UserService;
-use Fisharebest\Webtrees\Session;
-use Psr\Http\Message\ResponseInterface;
-use Psr\Http\Message\ServerRequestInterface;
-use function response;
-
-/**
- * User actions
- */
-class UserController extends AbstractBaseController
-{
- /**
- * @var UserService
- */
- private $user_service;
-
- /**
- * UserController constructor.
- *
- * @param UserService $user_service
- */
- public function __construct(UserService $user_service)
- {
- $this->user_service = $user_service;
- }
-
- /**
- * Delete a user.
- *
- * @param ServerRequestInterface $request
- *
- * @return ResponseInterface
- */
- public function delete(ServerRequestInterface $request): ResponseInterface
- {
- $user_id = (int) $request->getParsedBody()['user_id'];
-
- $user = $this->user_service->find($user_id);
-
- if ($user && Auth::isAdmin() && Auth::user() !== $user) {
- Log::addAuthenticationLog('Deleted user: ' . $user->userName());
- $this->user_service->delete($user);
- }
-
- return response('', StatusCodeInterface::STATUS_NO_CONTENT);
- }
-
- /**
- * Select a language.
- *
- * @param ServerRequestInterface $request
- *
- * @return ResponseInterface
- */
- public function language(ServerRequestInterface $request): ResponseInterface
- {
- $language = $request->getParsedBody()['language'];
-
- I18N::init($language);
- Session::put('locale', $language);
- Auth::user()->setPreference('language', $language);
-
- return response('', StatusCodeInterface::STATUS_NO_CONTENT);
- }
-
- /**
- * Masquerade as another user.
- *
- * @param ServerRequestInterface $request
- *
- * @return ResponseInterface
- */
- public function masquerade(ServerRequestInterface $request): ResponseInterface
- {
- $user_id = (int) $request->get('user_id');
-
- $user = $this->user_service->find($user_id);
-
- if ($user !== null && Auth::isAdmin() && Auth::user() !== $user) {
- Log::addAuthenticationLog('Masquerade as user: ' . $user->userName());
- Auth::login($user);
- Session::put('masquerade', '1');
- }
-
- return response('', StatusCodeInterface::STATUS_NO_CONTENT);
- }
-
- /**
- * Select a theme.
- *
- * @param ServerRequestInterface $request
- *
- * @return ResponseInterface
- */
- public function theme(ServerRequestInterface $request): ResponseInterface
- {
- $theme = $request->getParsedBody()['theme'];
- Session::put('theme_id', $theme);
- Auth::user()->setPreference('theme', $theme);
-
- return response('', StatusCodeInterface::STATUS_NO_CONTENT);
- }
-}
diff --git a/app/Http/Middleware/UseLocale.php b/app/Http/Middleware/UseLocale.php
index 4ab53f5985..5267ab8544 100644
--- a/app/Http/Middleware/UseLocale.php
+++ b/app/Http/Middleware/UseLocale.php
@@ -44,7 +44,7 @@ class UseLocale implements MiddlewareInterface
// Select a locale
define('WT_LOCALE', I18N::init('', $tree));
- Session::put('locale', WT_LOCALE);
+ Session::put('language', WT_LOCALE);
app()->instance(LocaleInterface::class, WebtreesLocale::create(WT_LOCALE));
diff --git a/app/Http/Middleware/UseTheme.php b/app/Http/Middleware/UseTheme.php
index db6cf6a296..48550cab49 100644
--- a/app/Http/Middleware/UseTheme.php
+++ b/app/Http/Middleware/UseTheme.php
@@ -61,7 +61,7 @@ class UseTheme implements MiddlewareInterface
app()->instance(ModuleThemeInterface::class, $theme);
// Remember this setting
- Session::put('theme_id', $theme->name());
+ Session::put('theme', $theme->name());
break;
}
@@ -80,7 +80,7 @@ class UseTheme implements MiddlewareInterface
$themes = $this->module_service->findByInterface(ModuleThemeInterface::class);
// Last theme used
- yield $themes->get(Session::get('theme_id', ''));
+ yield $themes->get(Session::get('theme', ''));
// Default for tree
$tree = app(Tree::class);
diff --git a/app/Http/RequestHandlers/DeleteUser.php b/app/Http/RequestHandlers/DeleteUser.php
new file mode 100644
index 0000000000..b548da8f1d
--- /dev/null
+++ b/app/Http/RequestHandlers/DeleteUser.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * webtrees: online genealogy
+ * Copyright (C) 2019 webtrees development team
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+declare(strict_types=1);
+
+namespace Fisharebest\Webtrees\Http\RequestHandlers;
+
+use Fig\Http\Message\StatusCodeInterface;
+use Fisharebest\Webtrees\Auth;
+use Fisharebest\Webtrees\Log;
+use Fisharebest\Webtrees\Services\UserService;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+use function response;
+
+/**
+ * Delete a user.
+ */
+class DeleteUser implements RequestHandlerInterface, StatusCodeInterface
+{
+ /** @var UserService */
+ private $user_service;
+
+ /**
+ * @param UserService $user_service
+ */
+ public function __construct(UserService $user_service)
+ {
+ $this->user_service = $user_service;
+ }
+
+ /**
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $user_id = (int) $request->getParsedBody()['user_id'];
+
+ $user = $this->user_service->find($user_id);
+
+ if ($user === null) {
+ throw new NotFoundHttpException('User ID ' . $user_id . ' not found');
+ }
+
+ if (Auth::isAdmin($user)) {
+ throw new AccessDeniedHttpException('Cannot delete an administrator');
+ }
+
+ Log::addAuthenticationLog('Deleted user: ' . $user->userName());
+ $this->user_service->delete($user);
+
+ return response('', StatusCodeInterface::STATUS_NO_CONTENT);
+ }
+}
diff --git a/app/Http/RequestHandlers/MasqueradeAsUser.php b/app/Http/RequestHandlers/MasqueradeAsUser.php
new file mode 100644
index 0000000000..959cf06170
--- /dev/null
+++ b/app/Http/RequestHandlers/MasqueradeAsUser.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * webtrees: online genealogy
+ * Copyright (C) 2019 webtrees development team
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+declare(strict_types=1);
+
+namespace Fisharebest\Webtrees\Http\RequestHandlers;
+
+use Fig\Http\Message\StatusCodeInterface;
+use Fisharebest\Webtrees\Auth;
+use Fisharebest\Webtrees\Contracts\UserInterface;
+use Fisharebest\Webtrees\Log;
+use Fisharebest\Webtrees\Services\UserService;
+use Fisharebest\Webtrees\Session;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+use function response;
+
+/**
+ * Masquerade as another user, for testing and administration.
+ */
+class MasqueradeAsUser implements RequestHandlerInterface, StatusCodeInterface
+{
+ /** @var UserInterface */
+ private $user;
+
+ /** @var UserService */
+ private $user_service;
+
+ /**
+ * @param UserInterface $user
+ * @param UserService $user_service
+ */
+ public function __construct(UserInterface $user, UserService $user_service)
+ {
+ $this->user = $user;
+ $this->user_service = $user_service;
+ }
+
+ /**
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $user_id = (int) $request->getParsedBody()['user_id'];
+
+ $user = $this->user_service->find($user_id);
+
+ if ($user === null) {
+ throw new NotFoundHttpException('User ID ' . $user_id . ' not found');
+ }
+
+ if ($this->user->id() !== $user_id) {
+ Log::addAuthenticationLog('Masquerade as user: ' . $user->userName());
+ Auth::login($user);
+ Session::put('masquerade', '1');
+ }
+
+ return response('', StatusCodeInterface::STATUS_NO_CONTENT);
+ }
+}
diff --git a/app/Http/Controllers/ModuleController.php b/app/Http/RequestHandlers/ModuleAction.php
index 04f41fc0b2..3022d84fbc 100644
--- a/app/Http/Controllers/ModuleController.php
+++ b/app/Http/RequestHandlers/ModuleAction.php
@@ -15,15 +15,17 @@
*/
declare(strict_types=1);
-namespace Fisharebest\Webtrees\Http\Controllers;
+namespace Fisharebest\Webtrees\Http\RequestHandlers;
use Fisharebest\Webtrees\Auth;
use Fisharebest\Webtrees\Contracts\UserInterface;
use Fisharebest\Webtrees\Services\ModuleService;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+use function app;
use function method_exists;
use function strpos;
use function strtolower;
@@ -31,48 +33,54 @@ use function strtolower;
/**
* Controller for module actions.
*/
-class ModuleController extends AbstractBaseController
+class ModuleAction implements RequestHandlerInterface
{
- /**
- * @var ModuleService
- */
+ /** @var ModuleService */
private $module_service;
+ /** @var UserInterface */
+ private $user;
+
/**
* ModuleController constructor.
*
* @param ModuleService $module_service
+ * @param UserInterface $user
*/
- public function __construct(ModuleService $module_service)
+ public function __construct(ModuleService $module_service, UserInterface $user)
{
$this->module_service = $module_service;
+ $this->user = $user;
}
/**
* Perform an HTTP action for one of the modules.
*
* @param ServerRequestInterface $request
- * @param UserInterface $user
*
* @return ResponseInterface
*/
- public function action(ServerRequestInterface $request, UserInterface $user): ResponseInterface
+ public function handle(ServerRequestInterface $request): ResponseInterface
{
- $module_name = $request->get('module', '');
+ $module_name = $request->getQueryParams()['module'] ?? $request->getParsedBody()['module'] ?? '';
+ $action = $request->getQueryParams()['action'] ?? $request->getParsedBody()['action'] ?? '';
// Check that the module is enabled.
// The module itself will need to check any tree-level access,
// which may be different for each component (tab, menu, etc.) of the module.
$module = $this->module_service->findByName($module_name);
+ if ($module === null) {
+ throw new NotFoundHttpException('Module ' . $module_name . ' does not exist');
+ }
+
// We'll call a function such as Module::getFooBarAction()
$verb = strtolower($request->getMethod());
- $action = $request->get('action', '');
$method = $verb . $action . 'Action';
// Actions with "Admin" in the name are for administrators only.
- if (strpos($action, 'Admin') !== false && !Auth::isAdmin($user)) {
- throw new AccessDeniedHttpException();
+ if (strpos($action, 'Admin') !== false && !Auth::isAdmin($this->user)) {
+ throw new AccessDeniedHttpException('Admin only action');
}
if (!method_exists($module, $method)) {
diff --git a/app/Http/RequestHandlers/SelectLanguage.php b/app/Http/RequestHandlers/SelectLanguage.php
new file mode 100644
index 0000000000..f75613cd43
--- /dev/null
+++ b/app/Http/RequestHandlers/SelectLanguage.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * webtrees: online genealogy
+ * Copyright (C) 2019 webtrees development team
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+declare(strict_types=1);
+
+namespace Fisharebest\Webtrees\Http\RequestHandlers;
+
+use Fig\Http\Message\StatusCodeInterface;
+use Fisharebest\Webtrees\Contracts\UserInterface;
+use Fisharebest\Webtrees\Session;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+use function response;
+
+/**
+ * Select a new language for the current session.
+ */
+class SelectLanguage implements RequestHandlerInterface, StatusCodeInterface
+{
+ /** @var UserInterface */
+ private $user;
+
+ /**
+ * @param UserInterface $user
+ */
+ public function __construct(UserInterface $user)
+ {
+ $this->user = $user;
+ }
+
+ /**
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $language = $request->getParsedBody()['language'];
+
+ Session::put('language', $language);
+
+ $this->user->setPreference('language', $language);
+
+ return response('', self::STATUS_NO_CONTENT);
+ }
+}
diff --git a/app/Http/RequestHandlers/SelectTheme.php b/app/Http/RequestHandlers/SelectTheme.php
new file mode 100644
index 0000000000..fe9deb960b
--- /dev/null
+++ b/app/Http/RequestHandlers/SelectTheme.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * webtrees: online genealogy
+ * Copyright (C) 2019 webtrees development team
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+declare(strict_types=1);
+
+namespace Fisharebest\Webtrees\Http\RequestHandlers;
+
+use Fig\Http\Message\StatusCodeInterface;
+use Fisharebest\Webtrees\Contracts\UserInterface;
+use Fisharebest\Webtrees\Session;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+use function response;
+
+/**
+ * Select a new theme for the current session.
+ */
+class SelectTheme implements RequestHandlerInterface, StatusCodeInterface
+{
+ /** @var UserInterface */
+ private $user;
+
+ /**
+ * @param UserInterface $user
+ */
+ public function __construct(UserInterface $user)
+ {
+ $this->user = $user;
+ }
+
+ /**
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $theme = $request->getParsedBody()['theme'];
+
+ Session::put('theme', $theme);
+
+ $this->user->setPreference('theme', $theme);
+
+ return response('', self::STATUS_NO_CONTENT);
+ }
+}
diff --git a/app/I18N.php b/app/I18N.php
index bb5ac40c91..48a5129868 100644
--- a/app/I18N.php
+++ b/app/I18N.php
@@ -316,9 +316,9 @@ class I18N
if ($code !== '') {
// Create the specified locale
self::$locale = Locale::create($code);
- } elseif (Session::has('locale') && file_exists(WT_ROOT . 'resources/lang/' . Session::get('locale') . '/messages.mo')) {
+ } elseif (Session::has('language') && file_exists(WT_ROOT . 'resources/lang/' . Session::get('language') . '/messages.mo')) {
// Select a previously used locale
- self::$locale = Locale::create(Session::get('locale'));
+ self::$locale = Locale::create(Session::get('language'));
} else {
if ($tree instanceof Tree) {
$default_locale = Locale::create($tree->getPreference('LANGUAGE', 'en-US'));
diff --git a/routes/web.php b/routes/web.php
index 9e8b49a315..595a89a755 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -17,6 +17,12 @@ declare(strict_types=1);
namespace Fisharebest\Webtrees;
+use Fisharebest\Webtrees\Http\RequestHandlers\DeleteUser;
+use Fisharebest\Webtrees\Http\RequestHandlers\MasqueradeAsUser;
+use Fisharebest\Webtrees\Http\RequestHandlers\ModuleAction;
+use Fisharebest\Webtrees\Http\RequestHandlers\SelectLanguage;
+use Fisharebest\Webtrees\Http\RequestHandlers\SelectTheme;
+
/** @var Tree|null $tree */
$tree = app(Tree::class);
@@ -129,6 +135,8 @@ if (Auth::isAdmin()) {
'GET:unused-media-thumbnail' => 'MediaFileController@unusedMediaThumbnail',
'GET:broadcast' => 'MessageController@broadcastPage',
'POST:broadcast' => 'MessageController@broadcastAction',
+ 'POST:delete-user' => DeleteUser::class,
+ 'POST:masquerade' => MasqueradeAsUser::class,
];
}
@@ -255,8 +263,6 @@ if ($tree instanceof Tree && $tree->getPreference('imported') === '1') {
'GET:autocomplete-folder' => 'AutocompleteController@folder',
'GET:autocomplete-page' => 'AutocompleteController@page',
'GET:autocomplete-place' => 'AutocompleteController@place',
- //'GET:branches' => 'BranchesController@page',
- //'GET:branches-list' => 'BranchesController@list',
'GET:calendar' => 'CalendarController@page',
'GET:calendar-events' => 'CalendarController@calendar',
'GET:help-text' => 'HelpTextController@helpText',
@@ -279,13 +285,6 @@ if ($tree instanceof Tree && $tree->getPreference('imported') === '1') {
'GET:report-list' => 'ReportEngineController@reportList',
'GET:report-setup' => 'ReportEngineController@reportSetup',
'GET:report-run' => 'ReportEngineController@reportRun',
- //'GET:family-list' => 'ListController@familyList',
- //'GET:individual-list' => 'ListController@individualList',
- //'GET:media-list' => 'ListController@mediaList',
- //'GET:note-list' => 'ListController@noteList',
- //'GET:place-hierarchy' => 'PlaceHierarchyController@show',
- //'GET:repository-list' => 'ListController@repositoryList',
- //'GET:source-list' => 'ListController@sourceList',
'POST:accept-changes' => 'PendingChangesController@acceptChanges',
'POST:reject-changes' => 'PendingChangesController@rejectChanges',
'POST:accept-all-changes' => 'PendingChangesController@acceptAllChanges',
@@ -315,13 +314,11 @@ $routes += [
'GET:verify' => 'Auth\\VerifyEmailController@verify',
'GET:forgot-password' => 'Auth\\ForgotPasswordController@forgotPasswordPage',
'POST:forgot-password' => 'Auth\\ForgotPasswordController@forgotPasswordAction',
- 'POST:delete-user' => 'UserController@delete',
- 'POST:language' => 'UserController@language',
- 'POST:masquerade' => 'UserController@masquerade',
- 'POST:theme' => 'UserController@theme',
+ 'POST:language' => SelectLanguage::class,
+ 'POST:theme' => SelectTheme::class,
'GET:privacy-policy' => 'StaticPageController@privacyPolicy',
- 'GET:module' => 'ModuleController@action',
- 'POST:module' => 'ModuleController@action',
+ 'GET:module' => ModuleAction::class,
+ 'POST:module' => ModuleAction::class,
];
return $routes;
diff --git a/tests/app/Http/Controllers/ModuleControllerTest.php b/tests/app/Http/Controllers/ModuleControllerTest.php
deleted file mode 100644
index a8b24b7aed..0000000000
--- a/tests/app/Http/Controllers/ModuleControllerTest.php
+++ /dev/null
@@ -1,108 +0,0 @@
-<?php
-/**
- * webtrees: online genealogy
- * Copyright (C) 2019 webtrees development team
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-declare(strict_types=1);
-
-namespace Fisharebest\Webtrees\Http\Controllers;
-
-use Fisharebest\Webtrees\Auth;
-use Fisharebest\Webtrees\Module\SiteMapModule;
-use Fisharebest\Webtrees\Services\ModuleService;
-use Fisharebest\Webtrees\Http\Request;
-
-/**
- * Test the module controller
- *
- * @covers \Fisharebest\Webtrees\Http\Controllers\AbstractBaseController
- * @covers \Fisharebest\Webtrees\Http\Controllers\ModuleController
- */
-class ModuleControllerTest extends \Fisharebest\Webtrees\TestCase
-{
- protected static $uses_database = true;
-
- /**
- * @expectedException \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
- * @return void
- */
- public function testMissingModule(): void
- {
- $request = new Request(['route' => 'module']);
- $controller = new ModuleController(new ModuleService());
- $controller->action($request, Auth::user());
- }
-
- /**
- * @expectedException \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
- * @return void
- */
- public function testInvalidModule(): void
- {
- $request = new Request(['route' => 'module', 'module' => 'no-such-module']);
- $controller = new ModuleController(new ModuleService());
- $controller->action($request, Auth::user());
- }
-
- /**
- * @expectedException \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
- * @return void
- */
- public function testMissingAction(): void
- {
- $request = new Request(['route' => 'module', 'module' => 'sitemap']);
- $controller = new ModuleController(new ModuleService());
- $controller->action($request, Auth::user());
- }
-
- /**
- * @expectedException \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
- * @return void
- */
- public function testInvalidAction(): void
- {
- $request = new Request(['route' => 'module', 'module' => 'sitemap', 'action' => 'no-such-action']);
- $controller = new ModuleController(new ModuleService());
- $controller->action($request, Auth::user());
- }
-
- /**
- * @expectedException \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
- * @return void
- */
- public function testVisitorCannotUseAdminAction(): void
- {
- $request = new Request(['route' => 'module', 'module' => 'sitemap', 'action' => 'DoAdminStuff']);
- $controller = new ModuleController(new ModuleService());
- $controller->action($request, Auth::user());
- }
-
- /**
- * @return void
- */
- public function testSucessfulAction(): void
- {
- // The sitemap module is disabled by defualt.
- $module_service = $this->createMock(ModuleService::class);
- $module_service
- ->method('findByName')
- ->with('sitemap')
- ->willReturn(new SiteMapModule());
-
- $request = new Request(['route' => 'module', 'module' => 'sitemap', 'action' => 'Index']);
- $controller = new ModuleController($module_service);
- $response = $controller->action($request, Auth::user());
-
- $this->assertSame(self::STATUS_OK, $response->getStatusCode());
- }
-}
diff --git a/tests/app/Http/RequestHandlers/DeleteUserTest.php b/tests/app/Http/RequestHandlers/DeleteUserTest.php
new file mode 100644
index 0000000000..5da843179e
--- /dev/null
+++ b/tests/app/Http/RequestHandlers/DeleteUserTest.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * webtrees: online genealogy
+ * Copyright (C) 2019 webtrees development team
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+declare(strict_types=1);
+
+use Fisharebest\Webtrees\Http\RequestHandlers\DeleteUser;
+use Fisharebest\Webtrees\Services\UserService;
+use Fisharebest\Webtrees\TestCase;
+
+/**
+ * @covers \Fisharebest\Webtrees\Http\RequestHandlers\DeleteUser
+ */
+class DeleteUserTest extends TestCase
+{
+ protected static $uses_database = true;
+
+ /**
+ * @return void
+ */
+ public function testDeleteUser(): void
+ {
+ $user_service = new UserService();
+ $user = $user_service->create('user1', 'real1', 'email1', 'pass1');
+ $handler = new DeleteUser($user_service);
+ $request = self::createRequest('POST', ['route' => 'delete-user'], ['user_id' => $user->id()]);
+ $response = $handler->handle($request);
+
+ // UserService caches user records
+ app('cache.array')->forget(UserService::class . $user->id());
+
+ self::assertSame(self::STATUS_NO_CONTENT, $response->getStatusCode());
+ self::assertNull($user_service->find($user->id()));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
+ * @expectedExceptionMessage User ID 98765 not found
+ * @return void
+ */
+ public function testDeleteNonExistingUser(): void
+ {
+ $user_service = new UserService();
+ $user_service->create('user1', 'real1', 'email1', 'pass1');
+ $handler = new DeleteUser($user_service);
+ $request = self::createRequest('POST', ['route' => 'delete-user'], ['user_id' => 98765]);
+ $handler->handle($request);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
+ * @expectedExceptionMessage Cannot delete an administrator
+ * @return void
+ */
+ public function testCannotDeleteAdministrator(): void
+ {
+ $user_service = new UserService();
+ $user = $user_service->create('user1', 'real1', 'email1', 'pass1');
+ $user->setPreference('canadmin', '1');
+ $handler = new DeleteUser($user_service);
+ $request = self::createRequest('POST', ['route' => 'delete-user'], ['user_id' => $user->id()]);
+ $handler->handle($request);
+ }
+}
+
diff --git a/tests/app/Http/RequestHandlers/MasqueradeAsUserTest.php b/tests/app/Http/RequestHandlers/MasqueradeAsUserTest.php
new file mode 100644
index 0000000000..90d1043975
--- /dev/null
+++ b/tests/app/Http/RequestHandlers/MasqueradeAsUserTest.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ * webtrees: online genealogy
+ * Copyright (C) 2019 webtrees development team
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+declare(strict_types=1);
+
+use Fisharebest\Webtrees\Auth;
+use Fisharebest\Webtrees\Http\RequestHandlers\MasqueradeAsUser;
+use Fisharebest\Webtrees\Services\UserService;
+use Fisharebest\Webtrees\Session;
+use Fisharebest\Webtrees\TestCase;
+
+/**
+ * @covers \Fisharebest\Webtrees\Http\RequestHandlers\MasqueradeAsUser
+ */
+class MasqueradeAsUserTest extends TestCase
+{
+ protected static $uses_database = true;
+
+ /**
+ * @return void
+ */
+ public function testMasqueradeAsUser(): void
+ {
+ $user_service = new UserService();
+ $user1 = $user_service->create('user1', 'real1', 'email1', 'pass1');
+ $user2 = $user_service->create('user2', 'real2', 'email2', 'pass2');
+ Auth::login($user1);
+ $handler = new MasqueradeAsUser($user1, $user_service);
+ $request = self::createRequest('POST', ['route' => 'masquerade'], ['user_id' => $user2->id()]);
+ $response = $handler->handle($request);
+
+ self::assertSame(self::STATUS_NO_CONTENT, $response->getStatusCode());
+ self::assertSame($user2->id(), Auth::id());
+ self::assertSame('1', Session::get('masquerade'));
+ }
+
+ /**
+ * @return void
+ */
+ public function testMasqueradeAsSelf(): void
+ {
+ $user_service = new UserService();
+ $user = $user_service->create('user', 'real', 'email', 'pass');
+ Auth::login($user);
+ $handler = new MasqueradeAsUser($user, $user_service);
+ $request = self::createRequest('POST', ['route' => 'masquerade'], ['user_id' => $user->id()]);
+ $response = $handler->handle($request);
+
+ self::assertSame(self::STATUS_NO_CONTENT, $response->getStatusCode());
+ self::assertSame($user->id(), Auth::id());
+ self::assertNull(Session::get('masquerade'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
+ * @expectedExceptionMessage User ID 98765 not found
+ * @return void
+ */
+ public function testMasqueradeAsNonExistingUser(): void
+ {
+ $user_service = new UserService();
+ $user = $user_service->create('user', 'real', 'email', 'pass');
+ Auth::login($user);
+ $handler = new MasqueradeAsUser($user, $user_service);
+ $request = self::createRequest('POST', ['route' => 'masquerade'], ['user_id' => 98765]);
+ $handler->handle($request);
+ }
+}
+
diff --git a/tests/app/Http/RequestHandlers/ModuleActionTest.php b/tests/app/Http/RequestHandlers/ModuleActionTest.php
new file mode 100644
index 0000000000..57d97a842f
--- /dev/null
+++ b/tests/app/Http/RequestHandlers/ModuleActionTest.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ * webtrees: online genealogy
+ * Copyright (C) 2019 webtrees development team
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+declare(strict_types=1);
+
+use Fisharebest\Webtrees\GuestUser;
+use Fisharebest\Webtrees\Http\RequestHandlers\ModuleAction;
+use Fisharebest\Webtrees\Services\ModuleService;
+use Fisharebest\Webtrees\TestCase;
+use Fisharebest\Webtrees\Tree;
+
+/**
+ * @covers \Fisharebest\Webtrees\Http\RequestHandlers\ModuleAction
+ */
+class ModuleActionTest extends TestCase
+{
+ protected static $uses_database = true;
+
+ /**
+ * @return void
+ */
+ public function testModuleAction(): void
+ {
+ $tree = Tree::create('tree', 'tree');
+ app()->instance(Tree::class, $tree);
+ $user = new GuestUser();
+ $module_service = new ModuleService();
+ $handler = new ModuleAction($module_service, $user);
+ $request = self::createRequest('GET', ['route' => 'module', 'module' => 'faq', 'action' => 'Show', 'ged' => $tree->name()]);
+ $response = $handler->handle($request);
+
+ $this->assertSame(self::STATUS_OK, $response->getStatusCode());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
+ * @expectedExceptionMessage Method getFishAction() not found in faq
+ * @return void
+ */
+ public function testNonExistingAction(): void
+ {
+ $user = new GuestUser();
+ $module_service = new ModuleService();
+ $handler = new ModuleAction($module_service, $user);
+ $request = self::createRequest('GET', ['route' => 'module', 'module' => 'faq', 'action' => 'Fish']);
+ $handler->handle($request);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
+ * @expectedExceptionMessage Module fish does not exist
+ * @return void
+ */
+ public function testNonExistingModule(): void
+ {
+ $user = new GuestUser();
+ $module_service = new ModuleService();
+ $handler = new ModuleAction($module_service, $user);
+ $request = self::createRequest('GET', ['route' => 'module', 'module' => 'fish', 'action' => 'Show']);
+ $response = $handler->handle($request);
+
+ $this->assertSame(self::STATUS_OK, $response->getStatusCode());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
+ * @expectedExceptionMessage Admin only action
+ * @return void
+ */
+ public function testAdminAction(): void
+ {
+ $tree = Tree::create('tree', 'tree');
+ app()->instance(Tree::class, $tree);
+ $user = new GuestUser();
+ $module_service = new ModuleService();
+ $handler = new ModuleAction($module_service, $user);
+ $request = self::createRequest('GET', ['route' => 'module', 'module' => 'faq', 'action' => 'Admin', 'ged' => $tree->name()]);
+ $handler->handle($request);
+ }
+}
+
diff --git a/tests/app/Http/RequestHandlers/SelectLanguageTest.php b/tests/app/Http/RequestHandlers/SelectLanguageTest.php
new file mode 100644
index 0000000000..22d0868df7
--- /dev/null
+++ b/tests/app/Http/RequestHandlers/SelectLanguageTest.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * webtrees: online genealogy
+ * Copyright (C) 2019 webtrees development team
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+declare(strict_types=1);
+
+use Fisharebest\Webtrees\GuestUser;
+use Fisharebest\Webtrees\Http\RequestHandlers\SelectLanguage;
+use Fisharebest\Webtrees\Services\UserService;
+use Fisharebest\Webtrees\TestCase;
+
+/**
+ * @covers \Fisharebest\Webtrees\Http\RequestHandlers\SelectLanguage
+ */
+class SelectLanguageTest extends TestCase
+{
+ protected static $uses_database = true;
+
+ /**
+ * @return void
+ */
+ public function testSelectLanguageForGuest(): void
+ {
+ $user = new GuestUser();
+ $handler = new SelectLanguage($user);
+ $request = self::createRequest('POST', ['route' => 'language'], ['language' => 'fr']);
+ $response = $handler->handle($request);
+
+ self::assertSame(self::STATUS_NO_CONTENT, $response->getStatusCode());
+ }
+
+ /**
+ * @return void
+ */
+ public function testSelectLanguageForUser(): void
+ {
+ $user_service = new UserService();
+ $user = $user_service->create('user', 'real', 'email', 'pass');
+ $handler = new SelectLanguage($user);
+ $request = self::createRequest('POST', ['route' => 'language'], ['language' => 'fr']);
+ $response = $handler->handle($request);
+
+ self::assertSame(self::STATUS_NO_CONTENT, $response->getStatusCode());
+ }
+}
+
diff --git a/tests/app/Http/RequestHandlers/SelectThemeTest.php b/tests/app/Http/RequestHandlers/SelectThemeTest.php
new file mode 100644
index 0000000000..f49e6b1f55
--- /dev/null
+++ b/tests/app/Http/RequestHandlers/SelectThemeTest.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * webtrees: online genealogy
+ * Copyright (C) 2019 webtrees development team
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+declare(strict_types=1);
+
+use Fisharebest\Webtrees\GuestUser;
+use Fisharebest\Webtrees\Http\RequestHandlers\SelectTheme;
+use Fisharebest\Webtrees\Services\UserService;
+use Fisharebest\Webtrees\TestCase;
+
+/**
+ * @covers \Fisharebest\Webtrees\Http\RequestHandlers\SelectTheme
+ */
+class SelectThemeTest extends TestCase
+{
+ protected static $uses_database = true;
+
+ /**
+ * @return void
+ */
+ public function testSelectThemeForGuest(): void
+ {
+ $user = new GuestUser();
+ $handler = new SelectTheme($user);
+ $request = self::createRequest('POST', ['route' => 'theme'], ['theme' => 'FOO']);
+ $response = $handler->handle($request);
+
+ self::assertSame(self::STATUS_NO_CONTENT, $response->getStatusCode());
+ self::assertSame('FOO', $user->getPreference('theme'));
+ }
+
+ /**
+ * @return void
+ */
+ public function testSelectThemeForUser(): void
+ {
+ $user_service = new UserService();
+ $user = $user_service->create('user', 'real', 'email', 'pass');
+ $handler = new SelectTheme($user);
+ $request = self::createRequest('POST', ['route' => 'theme'], ['theme' => 'FOO']);
+ $response = $handler->handle($request);
+
+ self::assertSame(self::STATUS_NO_CONTENT, $response->getStatusCode());
+ self::assertSame('FOO', $user->getPreference('theme'));
+ }
+}
+