1
0
mirror of https://github.com/typemill/typemill.git synced 2025-07-30 19:00:32 +02:00

Remove Credentials Middleware and Add Custom Headers and Cors Headers

This commit is contained in:
trendschau
2023-12-30 00:10:05 +01:00
parent 8a19620201
commit fb3f5f4673
9 changed files with 147 additions and 48 deletions

View File

@@ -12,10 +12,11 @@ class ControllerApiGlobals extends Controller
{
$navigation = new Navigation();
$systemNavigation = $navigation->getSystemNavigation(
$userrole = $request->getAttribute('c_userrole'),
$acl = $this->c->get('acl'),
$urlinfo = $this->c->get('urlinfo'),
$dispatcher = $this->c->get('dispatcher')
$userrole = $request->getAttribute('c_userrole'),
$acl = $this->c->get('acl'),
$urlinfo = $this->c->get('urlinfo'),
$dispatcher = $this->c->get('dispatcher'),
$parser = $this->routeParser
);
# won't work because api has no session, instead you have to pass user

View File

@@ -101,7 +101,7 @@ class ControllerWebAuth extends Controller
# generate new authcode
$authcodevalue = rand(10000, 99999);
$mail = new SimpleMail($settings);
$mail = new SimpleMail($this->settings);
$subject = Translations::translate('Your authentication code for Typemill');
$message = Translations::translate('Use the following authentication code to login into Typemill') . ': ' . $authcodevalue;

View File

@@ -63,6 +63,9 @@ class ApiAuthentication
}
*/
########### WHY NOT USE BASIC AUTH PARAMS FROM URI ?
$params = [];
if (preg_match("/Basic\s+(.*)$/i", $request->getHeaderLine("Authorization"), $matches))

View File

@@ -10,23 +10,33 @@ use Slim\Psr7\Response;
class CustomHeadersMiddleware implements MiddlewareInterface
{
protected $settings;
protected $urlinfo;
public function __construct($settings)
public function __construct($settings, $urlinfo)
{
$this->settings = $settings;
$this->urlinfo = $urlinfo;
}
public function process(Request $request, RequestHandler $handler) :response
{
$scheme = $request->getUri()->getScheme();
# add the custom headers to the response after everything is processed
$response = $handler->handle($request);
$response = $response->withoutHeader('Server');
$response = $response->withHeader('X-Powered-By', 'Typemill');
$headersOff = $this->settings['headersoff'] ?? false;
###################
# SECURITY HEADER #
###################
if(!$headersOff)
{
$response = $response
@@ -41,6 +51,38 @@ class CustomHeadersMiddleware implements MiddlewareInterface
}
}
###################
# CORS HEADER #
###################
$origin = $request->getHeaderLine('Origin');
$corsdomains = isset($this->settings['corsdomains']) ? trim($this->settings['corsdomains']) : false;
$whitelist = [];
if($corsdomains && $corsdomains != '')
{
$corsdomains = explode(",", $corsdomains);
foreach($corsdomains as $domain)
{
$domain = trim($domain);
if($domain != '')
{
$whitelist[] = $domain;
}
}
}
if(!$origin OR $origin == '' OR !isset($whitelist[$origin]))
{
# set current website as default origin and block all cross origin calls
$origin = $this->urlinfo['baseurl'];
}
$response = $response->withHeader('Access-Control-Allow-Origin', $origin)
->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS')
->withHeader('Access-Control-Allow-Credentials', 'true');
return $response;
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace Typemill\Middleware;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use Slim\Psr7\Response;
class RemoveCredentialsMiddleware implements MiddlewareInterface
{
public function process(Request $request, RequestHandler $handler) :response
{
$uri = $request->getUri();
# Remove user information (username:password) from the URI
$uri = $uri->withUserInfo('');
# Create a new request with the modified URI
$request = $request->withUri($uri);
# we could add basic auth credentials to request for later usage
$response = $handler->handle($request);
return $response;
}
}

View File

@@ -11,54 +11,52 @@ use Typemill\Models\User;
class SessionMiddleware implements MiddlewareInterface
{
protected $segments;
protected $segments;
protected $route;
protected $route;
public function __construct($segments, $route)
{
$this->segments = $segments;
protected $uri;
public function __construct($segments, $route, $uri)
{
$this->segments = $segments;
$this->route = $route;
$this->uri = $uri;
}
$this->route = $route;
}
public function process(Request $request, RequestHandler $handler) :response
{
$scheme = $request->getUri()->getScheme();
# start session
Session::startSessionForSegments($this->segments, $this->route, $scheme);
{
$uri = $request->getUri();
$authenticated = (
(isset($_SESSION['username'])) &&
(isset($_SESSION['login']))
)
? true : false;
$scheme = $request->getUri()->getScheme();
# start session
Session::startSessionForSegments($this->segments, $this->route, $scheme);
if($authenticated)
{
# add userdata to the request for later use
$user = new User();
$authenticated = (
(isset($_SESSION['username'])) &&
(isset($_SESSION['login']))
)
? true : false;
if($user->setUser($_SESSION['username']))
{
$userdata = $user->getUserData();
if($authenticated)
{
# add userdata to the request for later use
$user = new User();
$request = $request->withAttribute('c_username', $userdata['username']);
$request = $request->withAttribute('c_userrole', $userdata['userrole']);
if(isset($userdata['darkmode']))
{
$request = $request->withAttribute('c_darkmode', $userdata['darkmode']);
}
}
}
if($user->setUser($_SESSION['username']))
{
$userdata = $user->getUserData();
$request = $request->withAttribute('c_username', $userdata['username']);
$request = $request->withAttribute('c_userrole', $userdata['userrole']);
if(isset($userdata['darkmode']))
{
$request = $request->withAttribute('c_darkmode', $userdata['darkmode']);
}
}
}
$response = $handler->handle($request);
return $response;
}
}
}

View File

@@ -8,6 +8,8 @@ class Helpers{
public static function urlInfo($uri)
{
$uri = $uri->withUserInfo('');
$basepath = preg_replace('/(.*)\/.*/', '$1', $_SERVER['SCRIPT_NAME']);
$currentpath = $uri->getPath();
$route = str_replace($basepath, '', $currentpath);

View File

@@ -240,4 +240,9 @@ fieldsetdeveloper:
headersoff:
type: checkbox
label: Disable Custom Headers
checkboxlabel: Disable all custom headers of Typemill and send your own headers instead.
checkboxlabel: Disable all custom headers of Typemill and send your own headers instead.
corsdomains:
type: textarea
label: Allowed Domains for API-Access (CORS)
placeholder: 'https://my-website-that-uses-the-api.org,https://another-website-using-the-api.org'
description: Add all domains separated with comma, that should have access to the API. Domains will be added to the cors-header.

View File

@@ -21,6 +21,7 @@ use Typemill\Events\OnPluginsLoaded;
use Typemill\Events\OnSessionSegmentsLoaded;
use Typemill\Events\OnRolesPermissionsLoaded;
use Typemill\Events\OnResourcesLoaded;
use Typemill\Middleware\RemoveCredentialsMiddleware;
use Typemill\Middleware\SessionMiddleware;
use Typemill\Middleware\OldInputMiddleware;
use Typemill\Middleware\ValidationErrorsMiddleware;
@@ -75,6 +76,23 @@ $uriFactory = new UriFactory();
$uri = $uriFactory->createFromGlobals($_SERVER);
$urlinfo = Helpers::urlInfo($uri);
/* PROBLEM WITH URLINFO
* it contains basic authentication like
["basepath"]=> "/typemill"
["currentpath"]=> "/typemill/api/v1/mainnavi"
["route"]=> "/api/v1/mainnavi"
["scheme"]=> "http"
["authority"]=> "trendschau:password@localhost"
["protocol"]=> "http://trendschau:password@localhost"
["baseurl"] => "http://trendschau:password@localhost/typemill"
["currenturl"]=> "http://trendschau:password@localhost/typemill/api/v1/mainnavi"
* It probably contains wrong scheme when used with proxy
*/
$timer['settings'] = microtime(true);
/****************************
@@ -305,7 +323,7 @@ foreach($middleware as $pluginMiddleware)
}
}
$app->add(new CustomHeadersMiddleware($settings));
$app->add(new CustomHeadersMiddleware($settings, $urlinfo));
$app->add(new AssetMiddleware($assets, $container->get('view')));
@@ -346,7 +364,9 @@ $errorMiddleware->setErrorHandler(HttpNotFoundException::class, function ($reque
$app->add($errorMiddleware);
$app->add(new SessionMiddleware($session_segments, $urlinfo['route'], $uri));
$app->add(new SessionMiddleware($session_segments, $urlinfo['route']));
$app->add(new RemoveCredentialsMiddleware());
if(isset($settings['proxy']) && $settings['proxy'])
{