Skip to content

Commit

Permalink
Merge pull request #15 from visto9259/master
Browse files Browse the repository at this point in the history
Added typing, fixed deprecated test cases, updated docs
  • Loading branch information
visto9259 authored Feb 14, 2024
2 parents fc3b397 + a52ff1e commit 1a42e79
Show file tree
Hide file tree
Showing 19 changed files with 156 additions and 119 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build and test
name: Build

on:
push:
Expand Down
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# LmcCors


[![Build Status](https://travis-ci.com/LM-Commons/lmccors.svg?branch=master)](https://travis-ci.com/LM-Commons/lmccors)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/LM-Commons/LmcCors/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/LM-Commons/LmcCors/?branch=master)
![Build Status](https://github.com/lm-commons/lmccors/actions/workflows/build-test.yml/badge.svg)
[![Coverage Status](https://coveralls.io/repos/github/LM-Commons/LmcCors/badge.svg?branch=master)](https://coveralls.io/github/LM-Commons/LmcCors?branch=master)
[![Latest Stable Version](https://poser.pugx.org/lm-commons/lmc-cors/v)](//packagist.org/packages/lm-commons/lmc-cors)
[![License](https://poser.pugx.org/lm-commons/lmc-cors/license)](//packagist.org/packages/lm-commons/lmc-cors)
Expand All @@ -20,10 +19,11 @@ builds HTTP responses that follow the CORS documentation.
Install the module by typing (or add it to your `composer.json` file):

```sh
$ php composer.phar require lm-commons/lmc-cors
$ composer require lm-commons/lmc-cors
```

Then, enable it by adding "LmcCors" in your `application.config.php` or `modules.config.php` file.
Alternatively, the module will be added to the configuration during installation by the Laminas Component Installer

By default, LmcCors is configured to deny every CORS requests. To change that, you need to copy
the [`config/lmc_cors.global.php.dist`](config/lmc_cors.global.php.dist) file to your `autoload` folder
Expand All @@ -36,7 +36,7 @@ the [`config/lmc_cors.global.php.dist`](config/lmc_cors.global.php.dist) file to
CORS is a mechanism that allows to perform cross-origin requests from your browser.

For instance, let's say that your website is hosted in the domain `http://example.com`.
By default, user agents won't be allowed to perform AJAX requests to another domain for security
By default, user agents will not be allowed to perform AJAX requests to another domain for security
reasons (for instance `http://funny-domain.com`).

With CORS, you can allow your server to reply to such requests.
Expand All @@ -49,7 +49,7 @@ You can find better documentation on how CORS works on the web:
### Event registration

LmcCors registers the `LmcCors\Mvc\CorsRequestListener` with the `MvcEvent::EVENT_ROUTE` event, with a priority
of -1. This means that this listener is executed AFTER the route has been matched.
of 2. This means that this listener is executed BEFORE the route has been matched.

### Configuring the module

Expand All @@ -70,7 +70,7 @@ As by default, all the various options are set globally for all routes:
some browsers do not implement this feature correctly.
- `allowed_credentials`: (boolean) If true, it allows the browser to send cookies along with the request.

If you want to configure specific routes, you can add `ZfrCors\Options\CorsOptions::ROUTE_PARAM` to your route configuration:
If you want to configure specific routes, you can add `LmcCors\Options\CorsOptions::ROUTE_PARAM` to your route configuration:

```php
<?php
Expand Down Expand Up @@ -153,7 +153,7 @@ skipped till `Laminas\Mvc\MvcEvent::EVENT_FINISH`, which is responsible for actu

### Actual request

When an actual request is made, LmcCors first checks it the origin is allowed. If it is not, then a new response with
When an actual request is made, LmcCors first checks if the origin is allowed. If it is not, then a new response with
a 403 status code (Forbidden) is created and sent.

Please note that this will also prevent further MVC steps from being executed, since all subsequent MVC steps are
Expand Down
8 changes: 7 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@
"laminas/laminas-view": "^2.8.1",
"phpunit/phpunit": "^9.5.0",
"php-coveralls/php-coveralls": "^2.1",
"squizlabs/php_codesniffer": "^3.4"
"squizlabs/php_codesniffer": "^3.4",
"laminas/laminas-component-installer": "^3.4"
},
"autoload": {
"psr-4": {
Expand All @@ -68,5 +69,10 @@
"test": "phpunit",
"test-coverage": "phpunit --coverage-clover build/logs/clover.xml",
"upload-coverage": "php-coveralls -v"
},
"config": {
"allow-plugins": {
"laminas/laminas-component-installer": true
}
}
}
2 changes: 1 addition & 1 deletion src/Exception/InvalidOriginException.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class InvalidOriginException extends DomainException implements ExceptionInterfa
/**
* @return self
*/
public static function fromInvalidHeaderValue()
public static function fromInvalidHeaderValue(): InvalidOriginException
{
return new self('Provided header value supposed to be invalid.');
}
Expand Down
16 changes: 12 additions & 4 deletions src/Factory/CorsOptionsFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,34 @@

namespace LmcCors\Factory;

use Interop\Container\ContainerInterface;
use Laminas\ServiceManager\Exception\ServiceNotCreatedException;
use Laminas\ServiceManager\Factory\FactoryInterface;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use LmcCors\Options\CorsOptions;
use Psr\Container\NotFoundExceptionInterface;

/**
* CorsOptionsFactory
*
* @license MIT
* @author Florent Blaison <florent.blaison@gmail.com>
*/
class CorsOptionsFactory
class CorsOptionsFactory implements FactoryInterface
{
/**
* @param ContainerInterface $container
* @param $requestedName
* @param array|null $options
* @return CorsOptions
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function __invoke(ContainerInterface $container)
public function __invoke(ContainerInterface $container, $requestedName, ?array $options = null): CorsOptions
{
/* @var $config array */
$config = $container->has('config') ? $container->get('config') : [];
$config = isset($config['lmc_cors']) ? $config['lmc_cors'] : [];
$config = $config['lmc_cors'] ?? [];

return new CorsOptions($config);
}
Expand Down
18 changes: 12 additions & 6 deletions src/Factory/CorsRequestListenerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,33 @@

namespace LmcCors\Factory;

use Interop\Container\ContainerInterface;
use Laminas\ServiceManager\Factory\FactoryInterface;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use LmcCors\Mvc\CorsRequestListener;
use LmcCors\Service\CorsService;
use Psr\Container\NotFoundExceptionInterface;

/**
* CorsRequestListenerFactory
*
* @license MIT
* @author Florent Blaison <florent.blaison@gmail.com>
*/
class CorsRequestListenerFactory
class CorsRequestListenerFactory implements FactoryInterface
{
/**
* {@inheritDoc}
*
* @param ContainerInterface $container
* @param $requestedName
* @param $options
* @return CorsRequestListener
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function __invoke(ContainerInterface $container, $requestedName, $options = null)
public function __invoke(ContainerInterface $container, $requestedName, $options = null): CorsRequestListener
{
/* @var $corsService CorsService */
$corsService = $container->get('LmcCors\Service\CorsService');
$corsService = $container->get(CorsService::class);

return new CorsRequestListener($corsService);
}
Expand Down
16 changes: 11 additions & 5 deletions src/Factory/CorsServiceFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,32 @@
namespace LmcCors\Factory;

use Interop\Container\ContainerInterface;
use Laminas\ServiceManager\Factory\FactoryInterface;
use LmcCors\Options\CorsOptions;
use LmcCors\Service\CorsService;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

/**
* CorsServiceFactory
*
* @license MIT
* @author Florent Blaison <florent.blaison@gmail.com>
*/
class CorsServiceFactory
class CorsServiceFactory implements FactoryInterface
{
/**
* {@inheritDoc}
*
* @param ContainerInterface $container
* @param $requestedName
* @param $options
* @return CorsService
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function __invoke(ContainerInterface $container, $requestedName, $options = null)
public function __invoke(ContainerInterface $container, $requestedName, $options = null): CorsService
{
/* @var $corsOptions CorsOptions */
$corsOptions = $container->get('LmcCors\Options\CorsOptions');
$corsOptions = $container->get(CorsOptions::class);

return new CorsService($corsOptions);
}
Expand Down
10 changes: 6 additions & 4 deletions src/Module.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
use Laminas\EventManager\EventInterface;
use Laminas\ModuleManager\Feature\BootstrapListenerInterface;
use Laminas\ModuleManager\Feature\ConfigProviderInterface;
use Laminas\Mvc\Application;
use LmcCors\Mvc\CorsRequestListener;

/**
* @licence MIT
Expand All @@ -32,14 +34,14 @@ class Module implements BootstrapListenerInterface, ConfigProviderInterface
/**
* {@inheritDoc}
*/
public function onBootstrap(EventInterface $event)
public function onBootstrap(EventInterface $e): void
{
/* @var $application \Laminas\Mvc\Application */
$application = $event->getTarget();
/* @var $application Application */
$application = $e->getTarget();
$serviceManager = $application->getServiceManager();
$eventManager = $application->getEventManager();

/** @var \LmcCors\Mvc\CorsRequestListener $listener */
/** @var CorsRequestListener $listener */
$listener = $serviceManager->get('LmcCors\Mvc\CorsRequestListener');
$listener->attach($eventManager);
}
Expand Down
10 changes: 5 additions & 5 deletions src/Mvc/CorsRequestListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ class CorsRequestListener extends AbstractListenerAggregate
/**
* @var CorsService
*/
protected $corsService;
protected CorsService $corsService;

/**
* Whether or not a preflight request was detected
*
* @var bool
*/
protected $isPreflight = false;
protected bool $isPreflight = false;

/**
* @param CorsService $corsService
Expand All @@ -58,7 +58,7 @@ public function __construct(CorsService $corsService)
/**
* {@inheritDoc}
*/
public function attach(EventManagerInterface $events, $priority = 1)
public function attach(EventManagerInterface $events, $priority = 1): void
{
// Preflight can be handled during the route event, and should return early
$this->listeners[] = $events->attach(MvcEvent::EVENT_ROUTE, [$this, 'onCorsPreflight'], 2);
Expand Down Expand Up @@ -106,7 +106,7 @@ public function onCorsPreflight(MvcEvent $event)
$router = $event->getRouter();

$requestForMatching = clone $request;
// Use the request method for route deteciton, which is being used during the request.
// Use the request method for route detection, which is being used during the request.
$requestForMatching->setMethod($request->getHeader('Access-Control-Request-Method')->getFieldValue());

$routeMatch = $router->match($requestForMatching);
Expand All @@ -119,7 +119,7 @@ public function onCorsPreflight(MvcEvent $event)
*
* @param MvcEvent $event
*/
public function onCorsRequest(MvcEvent $event)
public function onCorsRequest(MvcEvent $event): void
{
// Do nothing if we previously created a preflight response
if ($this->isPreflight) {
Expand Down
Loading

0 comments on commit 1a42e79

Please sign in to comment.