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

Added trusted ips and trusted hosts for api

This commit is contained in:
trendschau
2025-02-11 22:48:45 +01:00
parent d565d65dea
commit 9863855637
4 changed files with 58 additions and 18 deletions

View File

@@ -11,6 +11,13 @@ use Typemill\Static\Session;
class ApiAuthentication
{
protected $settings;
public function __construct($settings)
{
$this->settings = $settings;
}
public function __invoke(Request $request, RequestHandler $handler)
{
$routeContext = RouteContext::fromRequest($request);
@@ -26,18 +33,45 @@ class ApiAuthentication
return $response;
}
else
{
# return error message
}
}
# api authentication with basic auth
# inspired by tuupola
# api authentication with basic auth, inspired by tuupola
$ipAddress = $_SERVER['REMOTE_ADDR'] ?? null;
$host = $request->getUri()->getHost();
$scheme = $request->getUri()->getScheme();
$server_params = $request->getServerParams();
$apiaccess = true;
if(isset($this->settings['trustedipsforapi']) && $this->settings['trustedipsforapi'] !== '')
{
$trustedIPs = array_map('trim', explode(',', $this->settings['trustedipsforapi']));
if(!in_array($ipAddress, $trustedIPs))
{
$apiaccess = false;
}
}
if(isset($this->settings['trustedhostsforapi']) && $this->settings['trustedhostsforapi'] !== '')
{
$trustedHosts = array_map('trim', explode(',', $this->settings['trustedhostsforapi']));
if(!in_array($host, $trustedHosts))
{
$apiaccess = false;
}
}
if(!$apiaccess)
{
$response = new Response();
$response->getBody()->write(json_encode([
'message' => 'Not trusted.'
]));
return $response->withHeader('WWW-Authenticate', 'Basic realm=')->withStatus(401);
}
/*
# HTTP allowed only if secure is false or server is in relaxed array.
# use own logic for https proto forwarding
@@ -63,9 +97,6 @@ class ApiAuthentication
}
*/
########### WHY NOT USE BASIC AUTH PARAMS FROM URI ?
$params = [];
if (preg_match("/Basic\s+(.*)$/i", $request->getHeaderLine("Authorization"), $matches))

View File

@@ -21,7 +21,8 @@ class CorsHeadersMiddleware implements MiddlewareInterface
}
public function process(Request $request, RequestHandler $handler) :response
{
{
# not in use right now, see here: https://chatgpt.com/c/67aba713-a7b0-8005-993e-a43ec4add72a
# add the custom headers to the response after everything is processed
$response = $handler->handle($request);

View File

@@ -102,7 +102,7 @@ $app->group('/api/v1', function (RouteCollectorProxy $group) use ($acl) {
$group->get('/article/content', ControllerApiGlobals::class . ':getArticleContent')->setName('api.articlecontent.get')->add(new ApiAuthorization($acl, 'content', 'read')); # author
$group->get('/article/meta', ControllerApiGlobals::class . ':getArticleMeta')->setName('api.articlemeta.get')->add(new ApiAuthorization($acl, 'content', 'read')); # author
})->add(new CorsHeadersMiddleware($settings, $urlinfo))->add(new ApiAuthentication());
})->add(new ApiAuthentication($settings));
# api-routes from plugins
if(isset($routes['api']) && !empty($routes['api']))
@@ -119,12 +119,12 @@ if(isset($routes['api']) && !empty($routes['api']))
if($resources && $privilege)
{
# protected api requires authentication and authorization
$app->{$method}($route, $class)->setName($name)->add(new ApiAuthorization($acl, $resource, $privilege))->add(new CorsHeadersMiddleware($settings, $urlinfo))->add(new ApiAuthentication());
$app->{$method}($route, $class)->setName($name)->add(new ApiAuthorization($acl, $resource, $privilege))->add(new ApiAuthentication($settings));
}
else
{
# public api routes
$app->{$method}($route, $class)->setName($name)->add(new CorsHeadersMiddleware($settings, $urlinfo));
$app->{$method}($route, $class)->setName($name);
}
}
}

View File

@@ -287,11 +287,19 @@ fieldsetdeveloper:
label: "Allowed Domains for Content on Typemill (CSP-Headers)"
placeholder: 'https://www.google.com,*google.com'
description: "List all domains, separated by commas, to allow content integration, such as iframes, on your Typemill website. Domains will be added to the csp-header. Usually done with plugins and themes, but add manually if something is blocked."
corsdomains:
type: textarea
label: "Allowed Domains for API-Access (CORS-Headers)"
placeholder: 'https://my-website-that-uses-the-api.org,https://another-website-using-the-api.org'
description: "List all domains, separated by comma, that should have access to the Typemill API. Domains will be added to the cors-header."
# corsdomains:
# type: textarea
# label: "Allowed Domains for API-Access (CORS-Headers)"
# placeholder: 'https://my-website-that-uses-the-api.org,https://another-website-using-the-api.org'
# description: "List all domains, separated by comma, that should have access to the Typemill API. Domains will be added to the cors-header."
trustedipsforapi:
type: text
label: "Trusted IPs for api calls (comma separated)"
placeholder: "192.168.1.1, 203.0.113.0"
trustedhostsforapi:
type: text
label: "Trusted Hosts for api calls (comma separated)"
placeholder: "mydomain.org,sub.mydomain.org"
loginlink:
type: checkbox
label: "Login with link"