Redirect + HSTS support

This commit is contained in:
Belle Aerni 2023-11-10 02:50:54 -08:00
parent 01f0ab298e
commit cf6d13d1ad
8 changed files with 165 additions and 50 deletions

View file

@ -14,6 +14,7 @@
"elgigi/commonmark-emoji": "^2.0",
"embed/embed": "^4.4",
"league/commonmark": "^2.3",
"middlewares/https": "^2.0",
"nyholm/psr7": "^1.8",
"nyholm/psr7-server": "^1.1",
"psr/http-message": "2.0 as 1.1",

117
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "b2c8ceb8ed14d19e2688f7ec7710a7b9",
"content-hash": "03371ff18f92e62d0da1155ec5876278",
"packages": [
{
"name": "antcms/antloader",
@ -661,6 +661,121 @@
],
"time": "2022-12-11T20:36:23+00:00"
},
{
"name": "middlewares/https",
"version": "v2.0.1",
"source": {
"type": "git",
"url": "https://github.com/middlewares/https.git",
"reference": "afe80daea218c6be057b76b83de730d7da7b42b2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/middlewares/https/zipball/afe80daea218c6be057b76b83de730d7da7b42b2",
"reference": "afe80daea218c6be057b76b83de730d7da7b42b2",
"shasum": ""
},
"require": {
"middlewares/utils": "^3.0",
"php": "^7.2 || ^8.0",
"psr/http-server-middleware": "^1.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.0",
"laminas/laminas-diactoros": "^2.3",
"oscarotero/php-cs-fixer-config": "^1.0",
"phpstan/phpstan": "^0.12",
"phpunit/phpunit": "^8|^9",
"squizlabs/php_codesniffer": "^3.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Middlewares\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Middleware to redirect to https and adds the Strict-Transport-Security header",
"homepage": "https://github.com/middlewares/https",
"keywords": [
"Strict-Transport-Security",
"http",
"https",
"middleware",
"psr-15",
"psr-7"
],
"support": {
"issues": "https://github.com/middlewares/https/issues",
"source": "https://github.com/middlewares/https/tree/v2.0.1"
},
"time": "2020-12-02T00:06:18+00:00"
},
{
"name": "middlewares/utils",
"version": "v3.3.0",
"source": {
"type": "git",
"url": "https://github.com/middlewares/utils.git",
"reference": "670b135ce0dbd040eadb025a9388f9bd617cc010"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/middlewares/utils/zipball/670b135ce0dbd040eadb025a9388f9bd617cc010",
"reference": "670b135ce0dbd040eadb025a9388f9bd617cc010",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0",
"psr/container": "^1.0 || ^2.0",
"psr/http-factory": "^1.0",
"psr/http-message": "^1.0",
"psr/http-server-middleware": "^1.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^v2.16",
"guzzlehttp/psr7": "^2.0",
"laminas/laminas-diactoros": "^2.4",
"nyholm/psr7": "^1.0",
"oscarotero/php-cs-fixer-config": "^1.0",
"phpstan/phpstan": "^0.12",
"phpunit/phpunit": "^8|^9",
"slim/psr7": "^1.4",
"squizlabs/php_codesniffer": "^3.5",
"sunrise/http-message": "^1.0",
"sunrise/http-server-request": "^1.0",
"sunrise/stream": "^1.0.15",
"sunrise/uri": "^1.0.15"
},
"type": "library",
"autoload": {
"psr-4": {
"Middlewares\\Utils\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Common utils for PSR-15 middleware packages",
"homepage": "https://github.com/middlewares/utils",
"keywords": [
"PSR-11",
"http",
"middleware",
"psr-15",
"psr-17",
"psr-7"
],
"support": {
"issues": "https://github.com/middlewares/utils/issues",
"source": "https://github.com/middlewares/utils/tree/v3.3.0"
},
"time": "2021-07-04T17:56:23+00:00"
},
{
"name": "ml/iri",
"version": "1.1.4",

View file

@ -7,16 +7,20 @@ use AntCMS\AntPages;
use AntCMS\AntConfig;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\App;
use Psr\Http\Message\UriInterface;
class AntCMS
{
protected $antTwig;
protected ?Response $response = null;
protected ?Request $request = null;
protected ?App $app = null;
public function __construct()
public function __construct(?App $app)
{
$this->antTwig = new AntTwig();
$this->app = $app;
}
public function SetResponse(?Response $response): void
@ -39,6 +43,11 @@ class AntCMS
return $this->request;
}
public function getApp()
{
return $this->app;
}
/**
* Renders the page based on the request URI
*/
@ -257,7 +266,20 @@ class AntCMS
}
}
public static function redirect(string $url)
public function redirect(string|UriInterface $url, int $code = 307): Response
{
if (!is_string($url)) {
$url = $url->__toString();
}
$response = $this->response->withStatus($code);
return $response->withHeader('Location', $url);
}
/**
* Old redirect function.
* TODO: Remove this once the other functions have been updated to no longer rely on this
*/
public static function redirectWithoutRequest(string $url)
{
$url = '//' . AntTools::repairURL(AntConfig::currentConfig('baseURL') . $url);
header("Location: $url");

View file

@ -42,21 +42,6 @@ class AntRouting
$this->requestUri = implode('/', $this->uriExploded);
}
/**
* Used to detect if the current request is over HTTPS. If the request is over HTTP, it'll redirect to HTTPS.
*/
public function redirectHttps(): void
{
$scheme = $_SERVER['HTTPS'] ?? $_SERVER['REQUEST_SCHEME'] ?? $_SERVER['HTTP_X_FORWARDED_PROTO'] ?? null;
$isHttps = !empty($scheme) && (strcasecmp('on', $scheme) == 0 || strcasecmp('https', $scheme) == 0);
if (!$isHttps) {
$url = 'https://' . AntTools::repairURL($this->baseUrl . $this->requestUri);
header('Location: ' . $url);
exit;
}
}
/**
* Used to check if the current request URI matches a specified route.
* Supports using '*' as a wild-card. Ex: '/admin/*' will match '/admin/somthing' and '/admin'
@ -108,14 +93,6 @@ class AntRouting
exit;
}
/**
* @return bool Returns true if the current request URI is an index request.
*/
public function isIndex(): bool
{
return (in_array($this->requestUri, $this->indexes));
}
private function setExplodedUri(string $uri): void
{
$exploaded = explode('/', $uri);

View file

@ -30,7 +30,7 @@ class AntUsers
if (file_exists(antUsersList)) {
return AntYaml::parseFile(antUsersList);
} else {
AntCMS::redirect('/profile/firsttime');
AntCMS::redirectWithoutRequest('/profile/firsttime');
}
}
@ -101,7 +101,7 @@ class AntUsers
public static function setupFirstUser($data)
{
if (file_exists(antUsersList)) {
AntCMS::redirect('/');
AntCMS::redirectWithoutRequest('/');
}
$data['username'] = trim($data['username']);

View file

@ -90,7 +90,7 @@ class AdminPlugin extends AntPlugin
case 'save':
if (!$_POST['textarea']) {
AntCMS::redirect('/admin/config');
AntCMS::redirectWithoutRequest('/admin/config');
}
$yaml = AntYaml::parseYaml($_POST['textarea']);
@ -98,7 +98,7 @@ class AdminPlugin extends AntPlugin
AntYaml::saveFile(antConfigFile, $yaml);
}
AntCMS::redirect('/admin/config');
AntCMS::redirectWithoutRequest('/admin/config');
break;
default:
@ -141,7 +141,7 @@ class AdminPlugin extends AntPlugin
switch ($route[0] ?? 'none') {
case 'regenerate':
AntPages::generatePages();
AntCMS::redirect('/admin/pages');
AntCMS::redirectWithoutRequest('/admin/pages');
exit;
case 'edit':
@ -176,11 +176,11 @@ class AdminPlugin extends AntPlugin
$pagePath = AntTools::repairFilePath(antContentPath . '/' . implode('/', $route));
if (!isset($_POST['textarea'])) {
AntCMS::redirect('/admin/pages');
AntCMS::redirectWithoutRequest('/admin/pages');
}
file_put_contents($pagePath, $_POST['textarea']);
AntCMS::redirect('/admin/pages');
AntCMS::redirectWithoutRequest('/admin/pages');
exit;
case 'create':
@ -204,7 +204,7 @@ class AdminPlugin extends AntPlugin
AntYaml::saveFile(antPagesList, $pages);
}
AntCMS::redirect('/admin/pages');
AntCMS::redirectWithoutRequest('/admin/pages');
break;
case 'togglevisibility':
@ -218,7 +218,7 @@ class AdminPlugin extends AntPlugin
}
AntYaml::saveFile(antPagesList, $pages);
AntCMS::redirect('/admin/pages');
AntCMS::redirectWithoutRequest('/admin/pages');
break;
default:
@ -263,7 +263,7 @@ class AdminPlugin extends AntPlugin
$user = AntUsers::getUserPublicalKeys($route[1]);
if (!$user) {
AntCMS::redirect('/admin/users');
AntCMS::redirectWithoutRequest('/admin/users');
}
$user['username'] = $route[1];
@ -276,7 +276,7 @@ class AdminPlugin extends AntPlugin
$user = AntUsers::getUserPublicalKeys($route[1]);
if (!$user) {
AntCMS::redirect('/admin/users');
AntCMS::redirectWithoutRequest('/admin/users');
}
$user['username'] = $route[1];
@ -298,11 +298,11 @@ class AdminPlugin extends AntPlugin
}
AntUsers::updateUser($_POST['originalusername'], $data);
AntCMS::redirect('/admin/users');
AntCMS::redirectWithoutRequest('/admin/users');
break;
case 'savenew':
AntUsers::addUser($_POST);
AntCMS::redirect('/admin/users');
AntCMS::redirectWithoutRequest('/admin/users');
break;
default:

View file

@ -28,14 +28,14 @@ class ProfilePlugin extends AntPlugin
switch ($currentStep) {
case 'firsttime':
if (file_exists(antUsersList)) {
AntCMS::redirect('/admin');
AntCMS::redirectWithoutRequest('/admin');
}
echo $this->antTwig->renderWithSubLayout('profile_firstTime', $params);
break;
case 'submitfirst':
if (file_exists(antUsersList)) {
AntCMS::redirect('/admin');
AntCMS::redirectWithoutRequest('/admin');
}
if (isset($_POST['username']) && isset($_POST['password']) && isset($_POST['display-name'])) {
@ -45,9 +45,9 @@ class ProfilePlugin extends AntPlugin
'name' => $_POST['display-name'],
];
AntUsers::setupFirstUser($data);
AntCMS::redirect('/admin');
AntCMS::redirectWithoutRequest('/admin');
} else {
AntCMS::redirect('/profile/firsttime');
AntCMS::redirectWithoutRequest('/profile/firsttime');
}
break;
@ -56,7 +56,7 @@ class ProfilePlugin extends AntPlugin
$user = AntUsers::getUserPublicalKeys($this->antAuth->getUsername());
if (!$user) {
AntCMS::redirect('/profile');
AntCMS::redirectWithoutRequest('/profile');
}
$user['username'] = $this->antAuth->getUsername();
@ -70,7 +70,7 @@ class ProfilePlugin extends AntPlugin
$user = AntUsers::getUserPublicalKeys($this->antAuth->getUsername());
if (!$user) {
AntCMS::redirect('/profile');
AntCMS::redirectWithoutRequest('/profile');
}
$user['username'] = $this->antAuth->getUsername();
@ -92,7 +92,7 @@ class ProfilePlugin extends AntPlugin
}
AntUsers::updateUser($this->antAuth->getUsername(), $data);
AntCMS::redirect('/profile');
AntCMS::redirectWithoutRequest('/profile');
break;
case 'logout':

View file

@ -24,14 +24,14 @@ $requestUri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$baseUrl = AntConfig::currentConfig('baseURL');
$antRouting = new \AntCMS\AntRouting($baseUrl, $requestUri);
$antCMS = new AntCMS;
$app = AppFactory::create();
$app->addRoutingMiddleware();
$app->addErrorMiddleware(true, true, true);
$antCMS = new AntCMS($app);
if (AntConfig::currentConfig('forceHTTPS') && !\AntCMS\AntEnviroment::isCli()) {
$antRouting->redirectHttps();
$app->addMiddleware(new Middlewares\Https());
}
$app->get('/themes/{theme}/assets', function (Request $request, Response $response) use ($antCMS) {
@ -72,7 +72,7 @@ if ($antRouting->checkMatch('/plugin/*')) {
$app->get('/', function (Request $request, Response $response) use ($antCMS) {
if (!file_exists(antUsersList)) {
AntCMS::redirect('/profile/firsttime');
AntCMS::redirectWithoutRequest('/profile/firsttime');
}
$antCMS->setRequest($request);