Handle admin redirects as RedirectResponse objects

This commit is contained in:
Giuseppe Criscione 2021-01-05 17:34:47 +01:00
parent 8088cb148f
commit 46f0671baa
8 changed files with 88 additions and 86 deletions

View File

@ -9,12 +9,12 @@ use Formwork\Assets;
use Formwork\Formwork;
use Formwork\Page;
use Formwork\Response\JSONResponse;
use Formwork\Response\RedirectResponse;
use Formwork\Response\Response;
use Formwork\Router\RouteParams;
use Formwork\Router\Router;
use Formwork\Translations\Translation;
use Formwork\Utils\FileSystem;
use Formwork\Utils\Header;
use Formwork\Utils\HTTPRequest;
use Formwork\Utils\Notification;
use Formwork\Utils\Session;
@ -115,12 +115,12 @@ final class Admin
}
if ($this->users->isEmpty()) {
$this->registerAdmin();
return $this->registerAdmin();
}
if (!$this->isLoggedIn() && $this->route() !== '/login/') {
Session::set('FORMWORK_REDIRECT_TO', $this->route());
$this->redirect('/login/');
return $this->redirect('/login/');
}
$response = $this->router->dispatch();
@ -202,9 +202,9 @@ final class Admin
*
* @param int $code HTTP redirect status code
*/
public function redirect(string $route, int $code = 302): void
public function redirect(string $route, int $code = 302): RedirectResponse
{
Header::redirect($this->uri($route), $code);
return new RedirectResponse($this->uri($route), $code);
}
/**
@ -212,9 +212,9 @@ final class Admin
*
* @param int $code HTTP redirect status code
*/
public function redirectToSite(int $code = 302): void
public function redirectToSite(int $code = 302): RedirectResponse
{
Header::redirect($this->siteUri(), $code);
return new RedirectResponse($this->siteUri(), $code);
}
/**
@ -222,9 +222,9 @@ final class Admin
*
* @param int $code HTTP redirect status code
*/
public function redirectToPanel(int $code = 302): void
public function redirectToPanel(int $code = 302): RedirectResponse
{
$this->redirect('/', $code);
return $this->redirect('/', $code);
}
/**
@ -233,13 +233,12 @@ final class Admin
* @param int $code HTTP redirect status code
* @param string $default Default route if HTTP referer is not available
*/
public function redirectToReferer(int $code = 302, string $default = '/'): void
public function redirectToReferer(int $code = 302, string $default = '/'): RedirectResponse
{
if (HTTPRequest::validateReferer($this->uri('/')) && HTTPRequest::referer() !== Uri::current()) {
Header::redirect(HTTPRequest::referer(), $code);
} else {
Header::redirect($this->uri($default), $code);
return new RedirectResponse(HTTPRequest::referer(), $code);
}
return new RedirectResponse($this->uri($default), $code);
}
/**
@ -319,7 +318,7 @@ final class Admin
$maxSize = FileSystem::shorthandToBytes(ini_get('post_max_size'));
if (HTTPRequest::contentLength() > $maxSize && $maxSize > 0) {
$this->notify($this->translate('admin.request.error.post-max-size'), 'error');
$this->redirectToReferer();
$this->redirectToReferer()->send(true);
}
}
}
@ -338,24 +337,23 @@ final class Admin
if (HTTPRequest::isXHR()) {
JSONResponse::error('Bad Request: the CSRF token is not valid', 400)->send();
}
$this->redirect('/login/');
$this->redirect('/login/')->send(true);
}
}
/**
* Register administration panel if no user exists
*/
protected function registerAdmin(): void
protected function registerAdmin(): Response
{
if (!HTTPRequest::isLocalhost()) {
$this->redirectToSite();
return $this->redirectToSite();
}
if ($this->router->request() !== '/') {
$this->redirectToPanel();
return $this->redirectToPanel();
}
$controller = new Controllers\RegisterController();
$controller->register();
exit;
return $controller->register();
}
/**
@ -366,8 +364,8 @@ final class Admin
// Default route
$this->router->add(
'/',
function (RouteParams $params): void {
$this->redirect('/dashboard/');
function (RouteParams $params): Response {
return $this->redirect('/dashboard/');
}
);

View File

@ -5,6 +5,7 @@ namespace Formwork\Admin\Controllers;
use Formwork\Admin\Security\AccessLimiter;
use Formwork\Admin\Security\CSRFToken;
use Formwork\Formwork;
use Formwork\Response\RedirectResponse;
use Formwork\Response\Response;
use Formwork\Utils\HTTPRequest;
use Formwork\Utils\Log;
@ -34,7 +35,7 @@ class AuthenticationController extends AbstractController
switch (HTTPRequest::method()) {
case 'GET':
if (Session::has('FORMWORK_USERNAME')) {
$this->admin()->redirectToPanel();
return $this->admin()->redirectToPanel();
}
// Always generate a new CSRF token
@ -78,10 +79,10 @@ class AuthenticationController extends AbstractController
if (($destination = Session::get('FORMWORK_REDIRECT_TO')) !== null) {
Session::remove('FORMWORK_REDIRECT_TO');
$this->admin()->redirect($destination);
return $this->admin()->redirect($destination);
}
$this->admin()->redirectToPanel();
return $this->admin()->redirectToPanel();
}
return $this->error($this->admin()->translate('admin.login.attempt.failed'), [
@ -96,18 +97,17 @@ class AuthenticationController extends AbstractController
/**
* Authentication@logout action
*/
public function logout(): void
public function logout(): RedirectResponse
{
CSRFToken::destroy();
Session::remove('FORMWORK_USERNAME');
Session::destroy();
if (Formwork::instance()->config()->get('admin.logout_redirect') === 'home') {
$this->admin()->redirectToSite();
} else {
$this->admin()->notify($this->admin()->translate('admin.login.logged-out'), 'info');
$this->admin()->redirectToPanel();
return $this->admin()->redirectToSite();
}
$this->admin()->notify($this->admin()->translate('admin.login.logged-out'), 'info');
return $this->admin()->redirectToPanel();
}
/**

View File

@ -7,6 +7,7 @@ use Formwork\Exceptions\TranslatedException;
use Formwork\Formwork;
use Formwork\Response\FileResponse;
use Formwork\Response\JSONResponse;
use Formwork\Response\Response;
use Formwork\Router\RouteParams;
use Formwork\Utils\FileSystem;
use RuntimeException;
@ -35,7 +36,7 @@ class BackupController extends AbstractController
/**
* Backup@download action
*/
public function download(RouteParams $params): FileResponse
public function download(RouteParams $params): Response
{
$this->ensurePermission('backup.download');
$file = Formwork::instance()->config()->get('backup.path') . base64_decode($params->get('backup'));
@ -46,7 +47,7 @@ class BackupController extends AbstractController
throw new RuntimeException($this->admin()->translate('admin.backup.error.cannot-download.invalid-filename'));
} catch (TranslatedException $e) {
$this->admin()->notify($this->admin()->translate('admin.backup.error.cannot-download', $e->getTranslatedMessage()), 'error');
$this->admin()->redirectToReferer(302, '/dashboard/');
return $this->admin()->redirectToReferer(302, '/dashboard/');
}
}
}

View File

@ -8,6 +8,7 @@ use Formwork\Fields\Validator;
use Formwork\Formwork;
use Formwork\Parsers\JSON;
use Formwork\Parsers\YAML;
use Formwork\Response\RedirectResponse;
use Formwork\Response\Response;
use Formwork\Utils\Arr;
use Formwork\Utils\FileSystem;
@ -26,10 +27,10 @@ class OptionsController extends AbstractController
/**
* Options@index action
*/
public function index(): void
public function index(): RedirectResponse
{
$this->ensurePermission('options.system');
$this->admin()->redirect('/options/system/');
return $this->admin()->redirect('/options/system/');
}
/**
@ -53,7 +54,7 @@ class OptionsController extends AbstractController
}
$this->admin()->notify($this->admin()->translate('admin.options.updated'), 'success');
$this->admin()->redirect('/options/system/');
return $this->admin()->redirect('/options/system/');
}
$fields->validate(Formwork::instance()->config());
@ -91,7 +92,7 @@ class OptionsController extends AbstractController
}
$this->admin()->notify($this->admin()->translate('admin.options.updated'), 'success');
$this->admin()->redirect('/options/site/');
return $this->admin()->redirect('/options/site/');
}
$fields->validate(new DataGetter($this->site()->data()));

View File

@ -12,6 +12,7 @@ use Formwork\Languages\LanguageCodes;
use Formwork\Page;
use Formwork\Parsers\YAML;
use Formwork\Response\JSONResponse;
use Formwork\Response\RedirectResponse;
use Formwork\Response\Response;
use Formwork\Router\RouteParams;
use Formwork\Site;
@ -69,7 +70,7 @@ class PagesController extends AbstractController
/**
* Pages@create action
*/
public function create(): void
public function create(): RedirectResponse
{
$this->ensurePermission('pages.create');
@ -82,10 +83,10 @@ class PagesController extends AbstractController
$this->admin()->notify($this->admin()->translate('admin.pages.page.created'), 'success');
} catch (TranslatedException $e) {
$this->admin()->notify($e->getTranslatedMessage(), 'error');
$this->admin()->redirectToReferer(302, '/pages/');
return $this->admin()->redirectToReferer(302, '/pages/');
}
$this->admin()->redirect('/pages/' . trim($page->route(), '/') . '/edit/');
return $this->admin()->redirect('/pages/' . trim($page->route(), '/') . '/edit/');
}
/**
@ -97,18 +98,21 @@ class PagesController extends AbstractController
$page = $this->site()->findPage($params->get('page'));
$this->ensurePageExists($page, 'pages.page.cannot-edit.page-not-found');
if ($page === null) {
$this->admin()->notify($this->admin()->translate('admin.pages.page.cannot-edit.page-not-found'), 'error');
return $this->admin()->redirectToReferer(302, '/pages/');
}
if ($params->has('language')) {
if (empty(Formwork::instance()->config()->get('languages.available'))) {
$this->admin()->redirect('/pages/' . trim($page->route(), '/') . '/edit/');
return $this->admin()->redirect('/pages/' . trim($page->route(), '/') . '/edit/');
}
$language = $params->get('language');
if (!in_array($language, Formwork::instance()->config()->get('languages.available'), true)) {
$this->admin()->notify($this->admin()->translate('admin.pages.page.cannot-edit.invalid-language', $language), 'error');
$this->admin()->redirect('/pages/' . trim($page->route(), '/') . '/edit/language/' . $this->site()->languages()->default() . '/');
return $this->admin()->redirect('/pages/' . trim($page->route(), '/') . '/edit/language/' . $this->site()->languages()->default() . '/');
}
if ($page->hasLanguage($language)) {
@ -116,7 +120,7 @@ class PagesController extends AbstractController
}
} elseif ($page->language() !== null) {
// Redirect to proper language
$this->admin()->redirect('/pages/' . trim($page->route(), '/') . '/edit/language/' . $page->language() . '/');
return $this->admin()->redirect('/pages/' . trim($page->route(), '/') . '/edit/language/' . $page->language() . '/');
}
// Check if page has to be published on next save
@ -165,7 +169,7 @@ class PagesController extends AbstractController
// Redirect if page route has changed
if ($params->get('page') !== ($route = trim($page->route(), '/'))) {
$this->admin()->redirect('/pages/' . $route . '/edit/');
return $this->admin()->redirect('/pages/' . $route . '/edit/');
}
break;
@ -243,13 +247,16 @@ class PagesController extends AbstractController
/**
* Pages@delete action
*/
public function delete(RouteParams $params): void
public function delete(RouteParams $params): RedirectResponse
{
$this->ensurePermission('pages.delete');
$page = $this->site()->findPage($params->get('page'));
$this->ensurePageExists($page, 'pages.page.cannot-delete.page-not-found');
if ($page === null) {
$this->admin()->notify($this->admin()->translate('admin.pages.page.cannot-delete.page-not-found'), 'error');
return $this->admin()->redirectToReferer(302, '/pages/');
}
if ($params->has('language')) {
$language = $params->get('language');
@ -257,13 +264,13 @@ class PagesController extends AbstractController
$page->setLanguage($language);
} else {
$this->admin()->notify($this->admin()->translate('admin.pages.page.cannot-delete.invalid-language', $language), 'error');
$this->admin()->redirectToReferer(302, '/pages/');
return $this->admin()->redirectToReferer(302, '/pages/');
}
}
if (!$page->isDeletable()) {
$this->admin()->notify($this->admin()->translate('admin.pages.page.cannot-delete.not-deletable'), 'error');
$this->admin()->redirectToReferer(302, '/pages/');
return $this->admin()->redirectToReferer(302, '/pages/');
}
// Delete just the content file only if there are more than one language
@ -277,56 +284,61 @@ class PagesController extends AbstractController
// Don't redirect to referer if it's to Pages@edit
if (!Str::startsWith(Uri::normalize(HTTPRequest::referer()), Uri::make(['path' => $this->admin()->uri('/pages/' . $params->get('page') . '/edit/')]))) {
$this->admin()->redirectToReferer(302, '/pages/');
} else {
$this->admin()->redirect('/pages/');
return $this->admin()->redirectToReferer(302, '/pages/');
}
return $this->admin()->redirect('/pages/');
}
/**
* Pages@uploadFile action
*/
public function uploadFile(RouteParams $params): void
public function uploadFile(RouteParams $params): RedirectResponse
{
$this->ensurePermission('pages.upload_files');
$page = $this->site()->findPage($params->get('page'));
$this->ensurePageExists($page, 'pages.page.cannot-upload-file.page-not-found');
if ($page === null) {
$this->admin()->notify($this->admin()->translate('admin.pages.page.cannot-upload-file.page-not-found'), 'error');
return $this->admin()->redirectToReferer(302, '/pages/');
}
if (HTTPRequest::hasFiles()) {
try {
$this->processPageUploads($page);
} catch (TranslatedException $e) {
$this->admin()->notify($this->admin()->translate('admin.uploader.error', $e->getTranslatedMessage()), 'error');
$this->admin()->redirect('/pages/' . $params->get('page') . '/edit/');
return $this->admin()->redirect('/pages/' . $params->get('page') . '/edit/');
}
}
$this->admin()->notify($this->admin()->translate('admin.uploader.uploaded'), 'success');
$this->admin()->redirect('/pages/' . $params->get('page') . '/edit/');
return $this->admin()->redirect('/pages/' . $params->get('page') . '/edit/');
}
/**
* Pages@deleteFile action
*/
public function deleteFile(RouteParams $params): void
public function deleteFile(RouteParams $params): RedirectResponse
{
$this->ensurePermission('pages.delete_files');
$page = $this->site()->findPage($params->get('page'));
$this->ensurePageExists($page, 'pages.page.cannot-delete-file.page-not-found');
if ($page === null) {
$this->admin()->notify($this->admin()->translate('admin.pages.page.cannot-delete-file.page-not-found'), 'error');
return $this->admin()->redirectToReferer(302, '/pages/');
}
if (!$page->files()->has($params->get('filename'))) {
$this->admin()->notify($this->admin()->translate('admin.pages.page.cannot-delete-file.file-not-found'), 'error');
$this->admin()->redirect('/pages/' . $params->get('page') . '/edit/');
return $this->admin()->redirect('/pages/' . $params->get('page') . '/edit/');
}
FileSystem::delete($page->path() . $params->get('filename'));
$this->admin()->notify($this->admin()->translate('admin.pages.page.file-deleted'), 'success');
$this->admin()->redirect('/pages/' . $params->get('page') . '/edit/');
return $this->admin()->redirect('/pages/' . $params->get('page') . '/edit/');
}
/**
@ -518,17 +530,6 @@ class PagesController extends AbstractController
}
}
/**
* Ensure a page exists
*/
protected function ensurePageExists(?Page $page, string $errorLanguageString): void
{
if ($page === null) {
$this->admin()->notify($this->admin()->translate($errorLanguageString), 'error');
$this->admin()->redirectToReferer(302, '/pages/');
}
}
/**
* Make a page num according to 'date' or default mode
*

View File

@ -34,7 +34,7 @@ class RegisterController extends AbstractController
if (!$data->hasMultiple(['username', 'fullname', 'password', 'language', 'email'])) {
$this->admin()->notify($this->admin()->translate('admin.users.user.cannot-create.var-missing'), 'error');
$this->admin()->redirectToPanel();
return $this->admin()->redirectToPanel();
}
$userData = [
@ -56,7 +56,7 @@ class RegisterController extends AbstractController
$time = $accessLog->log($data->get('username'));
$lastAccessRegistry->set($data->get('username'), $time);
$this->admin()->redirectToPanel();
return $this->admin()->redirectToPanel();
break;
}

View File

@ -12,6 +12,7 @@ use Formwork\Fields\Fields;
use Formwork\Files\Image;
use Formwork\Formwork;
use Formwork\Parsers\YAML;
use Formwork\Response\RedirectResponse;
use Formwork\Response\Response;
use Formwork\Router\RouteParams;
use Formwork\Utils\FileSystem;
@ -40,7 +41,7 @@ class UsersController extends AbstractController
/**
* Users@create action
*/
public function create(): void
public function create(): RedirectResponse
{
$this->ensurePermission('users.create');
@ -49,13 +50,13 @@ class UsersController extends AbstractController
// Ensure no required data is missing
if (!$data->hasMultiple(['username', 'fullname', 'password', 'email', 'language'])) {
$this->admin()->notify($this->admin()->translate('admin.users.user.cannot-create.var-missing'), 'error');
$this->admin()->redirect('/users/');
return $this->admin()->redirect('/users/');
}
// Ensure there isn't a user with the same username
if ($this->admin()->users()->has($data->get('username'))) {
$this->admin()->notify($this->admin()->translate('admin.users.user.cannot-create.already-exists'), 'error');
$this->admin()->redirect('/users/');
return $this->admin()->redirect('/users/');
}
$userData = [
@ -69,13 +70,13 @@ class UsersController extends AbstractController
YAML::encodeToFile($userData, Formwork::instance()->config()->get('admin.paths.accounts') . $data->get('username') . '.yml');
$this->admin()->notify($this->admin()->translate('admin.users.user.created'), 'success');
$this->admin()->redirect('/users/');
return $this->admin()->redirect('/users/');
}
/**
* Users@delete action
*/
public function delete(RouteParams $params): void
public function delete(RouteParams $params): RedirectResponse
{
$this->ensurePermission('users.delete');
@ -95,7 +96,7 @@ class UsersController extends AbstractController
$this->deleteAvatar($user);
} catch (TranslatedException $e) {
$this->admin()->notify($e->getTranslatedMessage(), 'error');
$this->admin()->redirectToReferer(302, '/users/');
return $this->admin()->redirectToReferer(302, '/users/');
}
$lastAccessRegistry = new Registry(Formwork::instance()->config()->get('admin.paths.logs') . 'lastAccess.json');
@ -104,7 +105,7 @@ class UsersController extends AbstractController
$lastAccessRegistry->remove($user->username());
$this->admin()->notify($this->admin()->translate('admin.users.user.deleted'), 'success');
$this->admin()->redirect('/users/');
return $this->admin()->redirect('/users/');
}
/**
@ -118,7 +119,7 @@ class UsersController extends AbstractController
if ($user === null) {
$this->admin()->notify($this->admin()->translate('admin.users.user.not-found'), 'error');
$this->admin()->redirect('/users/');
return $this->admin()->redirect('/users/');
}
// Disable password and/or role fields if they cannot be changed
@ -136,7 +137,7 @@ class UsersController extends AbstractController
$this->admin()->notify($this->admin()->translate('admin.users.user.cannot-edit', $user->username()), 'error');
}
$this->admin()->redirect('/users/' . $user->username() . '/profile/');
return $this->admin()->redirect('/users/' . $user->username() . '/profile/');
}
$fields->validate(new DataGetter($user->toArray()));
@ -164,7 +165,7 @@ class UsersController extends AbstractController
// Ensure that password can be changed
if (!$this->user()->canChangePasswordOf($user)) {
$this->admin()->notify($this->admin()->translate('admin.users.user.cannot-change-password'), 'error');
$this->admin()->redirect('/users/' . $user->username() . '/profile/');
$this->admin()->redirect('/users/' . $user->username() . '/profile/')->send(true);
}
// Hash the new password
@ -177,7 +178,7 @@ class UsersController extends AbstractController
// Ensure that user role can be changed
if ($data->get('role', $user->role()) !== $user->role() && !$this->user()->canChangeRoleOf($user)) {
$this->admin()->notify($this->admin()->translate('admin.users.user.cannot-change-role', $user->username()), 'error');
$this->admin()->redirect('/users/' . $user->username() . '/profile/');
$this->admin()->redirect('/users/' . $user->username() . '/profile/')->send(true);
}
// Handle incoming files
@ -209,7 +210,7 @@ class UsersController extends AbstractController
$hasUploaded = $uploader->upload(FileSystem::randomName());
} catch (TranslatedException $e) {
$this->admin()->notify($this->admin()->translate('admin.uploader.error', $e->getTranslatedMessage()), 'error');
$this->admin()->redirect('/users/' . $user->username() . '/profile/');
$this->admin()->redirect('/users/' . $user->username() . '/profile/')->send(true);
}
if ($hasUploaded) {

View File

@ -5,11 +5,11 @@ namespace Formwork\Controllers;
use Formwork\Formwork;
use Formwork\Page;
use Formwork\Response\FileResponse;
use Formwork\Response\RedirectResponse;
use Formwork\Response\Response;
use Formwork\Router\RouteParams;
use Formwork\Utils\Date;
use Formwork\Utils\FileSystem;
use Formwork\Utils\Header;
class PageController extends AbstractController
{
@ -28,7 +28,7 @@ class PageController extends AbstractController
$canonical = trim($page->canonical(), '/');
if ($params->get('page', '') !== $canonical) {
$route = empty($canonical) ? '' : $formwork->router()->rewrite(['page' => $canonical]);
Header::redirect($formwork->site()->uri($route), 301);
return new RedirectResponse($formwork->site()->uri($route), 301);
}
}