Skip to content

Commit

Permalink
Merge pull request #38 from City-of-Helsinki/UHF-X-cors
Browse files Browse the repository at this point in the history
Add access-control-allow-origin header
  • Loading branch information
tuutti authored Sep 12, 2022
2 parents 0ebb059 + 4f49bbf commit 596cc59
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 0 deletions.
10 changes: 10 additions & 0 deletions helfi_proxy.services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ parameters:
- www.hel.fi
- www-test.hel.fi
- helfi-proxy.docker.so
helfi_proxy.valid_origin_domains:
- hel.fi
- docker.so
services:
helfi_proxy.http_middleware:
class: Drupal\helfi_proxy\HttpMiddleware\AssetHttpMiddleware
Expand Down Expand Up @@ -52,6 +55,13 @@ services:
tags:
- { name: event_subscriber }

helfi_proxy.cors_subscriber:
class: Drupal\helfi_proxy\EventSubscriber\CorsResponseSubscriber
arguments:
- '%helfi_proxy.valid_origin_domains%'
tags:
- { name: event_subscriber }

helfi_proxy.asset.css.optimizer:
public: false
class: Drupal\helfi_proxy\Asset\CssOptimizer
Expand Down
68 changes: 68 additions & 0 deletions src/EventSubscriber/CorsResponseSubscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

declare(strict_types = 1);

namespace Drupal\helfi_proxy\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

/**
* Adds required CORS headers to a response.
*/
final class CorsResponseSubscriber implements EventSubscriberInterface {

/**
* Constructs a new instance.
*
* @param array $validOriginDomains
* An array of domains.
*/
public function __construct(
private array $validOriginDomains
) {
}

/**
* Adds cors headers to a response.
*
* @param \Symfony\Component\HttpKernel\Event\ResponseEvent $event
* The event to respond to.
*/
public function onResponse(ResponseEvent $event) : void {
$requestDomain = $event->getRequest()->headers->get('Origin');

if (!$requestDomain) {
return;
}
$validHost = FALSE;

foreach ($this->validOriginDomains as $domain) {
if ($requestDomain === $domain) {
$validHost = TRUE;
}

// Allow subdomains as well.
if (str_ends_with($requestDomain, '.' . $domain)) {
$validHost = TRUE;
}
}
if (!$validHost) {
return;
}

$event->getResponse()->headers->add([
'Access-Control-Allow-Origin' => $requestDomain,
]);
}

/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() : array {
$events[KernelEvents::RESPONSE][] = ['onResponse', -100];
return $events;
}

}
59 changes: 59 additions & 0 deletions tests/src/Kernel/CorsResponseSubscriberTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

declare(strict_types = 1);

namespace Drupal\Tests\helfi_proxy\Kernel;

use Drupal\KernelTests\KernelTestBase;
use Symfony\Component\HttpFoundation\Request;

/**
* Tests CORS response subscriber.
*
* @coversDefaultClass \Drupal\helfi_proxy\EventSubscriber\CorsResponseSubscriber
* @group helfi_proxy
*/
class CorsResponseSubscriberTest extends KernelTestBase {

/**
* {@inheritdoc}
*/
protected static $modules = [
'path_alias',
'helfi_proxy',
];

/**
* Make sure cors headers are set properly.
*
* @dataProvider corsTestData
*/
public function testCors(mixed $domain, bool $expected) : void {
$request = Request::create('/', server: [
'HTTP_HOST' => 'localhost:8888',
]);
$request->headers->set('Origin', $domain);
$http_kernel = $this->container->get('http_kernel');
/** @var \Symfony\Component\HttpFoundation\Response $response */
$response = $http_kernel->handle($request);
$this->assertEquals($expected, $response->headers->has('Access-Control-Allow-Origin'));
}

/**
* Data provider for testCors().
*
* @return array[]
* The data.
*/
public function corsTestData() : array {
return [
['www.hel.fi', TRUE],
['hel.fi', TRUE],
['docker.so', TRUE],
['helfi-kymp.docker.so', TRUE],
['testdocker.so', FALSE],
[NULL, FALSE],
];
}

}

0 comments on commit 596cc59

Please sign in to comment.