Skip to content

Commit

Permalink
Merge pull request #7 from MauricioKruijer/rfc8941-support
Browse files Browse the repository at this point in the history
RFC-8941 support
  • Loading branch information
mazedlx authored Oct 25, 2021
2 parents 3300fc0 + 9d60643 commit c9273fa
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 24 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

All notable changes to `laravel-feature-policy` will be documented in this file

## 1.2.0 - 2021-10-25

- implemented [RFC-8941](https://datatracker.ietf.org/doc/html/rfc8941) Structured Field Values for directive values

## 1.1.2 - 2021-01-02

- add PHP 8 support
Expand Down
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Set Feature-Policy headers in a Laravel app
# Set Permissions-Policy headers in a Laravel app

**NOW WITH PHP 8 SUPPORT**

Expand All @@ -8,7 +8,7 @@

This package is strongly inspired by [Spaties](https://spatie.be) [laravel-csp](https://github.com/spatie/laravel-csp) package. Thanks to [Freek van der Herten](https://github.com/freekmurze) and [Thomas Verhelst](https://github.com/TVke) for creating such an awesome package and doing all the heavy lifting!

With Feature-Policy you can control which web platform features to allow and disallow within your web applications. Feature-Policy is a Security Header (like Content-Security-Policy) that is brand new. The list of things you can restrict isn't final yet, I'll add them in time when the specification evolves.
With Permissions-Policy you can control which web platform permissions to allow and disallow within your web applications. Permissions-Policy is a Security Header (like Content-Security-Policy) that is brand new. The list of things you can restrict isn't final yet, I'll add them in time when the specification evolves.

## Installation

Expand All @@ -31,7 +31,7 @@ The contents of the `config/feature-policy.php` file look like this:

return [
/*
* A policy will determine which Feature-Policy headers will be set.
* A policy will determine which Permissions-Policy headers will be set.
* A valid policy extends `Mazedlx\FeaturePolicy\Policies\Policy`
*/
'policy' => Mazedlx\FeaturePolicy\Policies\Basic::class,
Expand Down Expand Up @@ -60,7 +60,7 @@ protected $middlewareGroups = [
];
```

Alternatively you can add the middleware to the a single route and route group:
Alternatively you can add the middleware to a single route and route group:

```php
// in a routes file
Expand All @@ -76,15 +76,15 @@ Route::get('/home', 'HomeController')->middleware(Mazedlx\FeaturePolicy\AddFeatu

## Usage

This package allows you to define Feature-Policy policies. A Feature-Policy policy determines which Feature-Policy directives will be set in the headers of the response.
This package allows you to define Permissions-Policy policies. A Feature-Policy policy determines which Permissions-Policy directives will be set in the headers of the response.

An example of a Feature-Policy directive is `microphone`:
An example of a Permissions-Policy directive is `microphone`:

`Feature-Policy: microphone 'self' https://spatie.be`
`Permissions-Policy: microphone=(self "https://spatie.be")`

In the above example by specifying `microphone` and allowing it for `'self'` the feature is diabled for all origins except our own and https://spatie.be.
In the above example by specifying `microphone` and allowing it for `self` makes the permission disabled for all origins except our own and https://spatie.be.

The full list of restrictable directives isn't final yet, but here are some of the things you have access to:
The full list of directives isn't final yet, but here are some of the things you have access to:

- accelerometer
- ambient-light-sensor
Expand All @@ -105,7 +105,7 @@ The full list of restrictable directives isn't final yet, but here are some of t

You can find the feature definitions at https://github.com/WICG/feature-policy/blob/master/features.md

You can add multiple policy options as an array or as a single string with space-sepearated options:
You can add multiple policy options as an array or as a single string with space-separated options:

```php
// in a policy
Expand Down
11 changes: 7 additions & 4 deletions src/Policies/Policy.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,11 @@ public function __toString()
->map(function (array $values, string $directive) {
$valueString = implode(' ', $values);

return "{$directive} {$valueString}";
})->implode(';');
return count($values) === 1
? "{$directive}={$valueString}"
: "{$directive}=({$valueString})";

})->implode(',');
}

protected function guardAgainstInvalidDirective(string $directive)
Expand All @@ -83,9 +86,9 @@ protected function isSpecialDirectiveValue(string $value)
protected function sanitizeValue(string $value): string
{
if ($this->isSpecialDirectiveValue($value)) {
return "'{$value}'";
return $value;
}

return $value;
return "\"{$value}\"";
}
}
2 changes: 1 addition & 1 deletion src/Value.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ abstract class Value
{
const ALL = '*';
const SELF = 'self';
const NONE = 'none';
const NONE = '()';
}
56 changes: 48 additions & 8 deletions tests/AddFeaturePolicyHeadersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public function it_sets_the_default_feature_policy_headers()
{
$headers = $this->getResponseHeaders();

$this->assertStringContainsString("geolocation 'self'", $headers->get('Permissions-Policy'));
$this->assertStringContainsString("geolocation=self", $headers->get('Permissions-Policy'));
}

/** @test */
Expand Down Expand Up @@ -77,7 +77,7 @@ public function configure()
$headers = $this->getResponseHeaders();

$this->assertEquals(
'camera src-1 src-2;fullscreen src-3 src-4',
'camera=("src-1" "src-2"),fullscreen=("src-3" "src-4")',
$headers->get('Permissions-Policy')
);
}
Expand All @@ -97,13 +97,13 @@ public function configure()
$headers = $this->getResponseHeaders();

$this->assertEquals(
'camera src-1 src-2',
'camera=("src-1" "src-2")',
$headers->get('Permissions-Policy')
);
}

/** @test */
public function it_quotes_special_directive_values()
public function it_doesnt_quotes_special_directive_values()
{
$policy = new class extends Policy {
public function configure()
Expand All @@ -117,7 +117,7 @@ public function configure()
$headers = $this->getResponseHeaders();

$this->assertEquals(
"camera 'self'",
"camera=self",
$headers->get('Permissions-Policy')
);
}
Expand All @@ -137,7 +137,7 @@ public function configure()
$headers = $this->getResponseHeaders();

$this->assertEquals(
"camera src-1 'self' src-2",
'camera=("src-1" self "src-2")',
$headers->get('Permissions-Policy')
);
}
Expand All @@ -157,7 +157,47 @@ public function configure()
$headers = $this->getResponseHeaders();

$this->assertEquals(
"camera 'self'",
'camera=self',
$headers->get('Permissions-Policy')
);
}

/** @test */
public function it_will_render_none_value()
{
$policy = new class extends Policy {
public function configure()
{
$this->addDirective(Directive::CAMERA, [Value::NONE]);
}
};

config(['feature-policy.policy' => get_class($policy)]);

$headers = $this->getResponseHeaders();

$this->assertEquals(
'camera=()',
$headers->get('Permissions-Policy')
);
}

/** @test */
public function it_will_render_all_value()
{
$policy = new class extends Policy {
public function configure()
{
$this->addDirective(Directive::CAMERA, [Value::ALL]);
}
};

config(['feature-policy.policy' => get_class($policy)]);

$headers = $this->getResponseHeaders();

$this->assertEquals(
'camera=*',
$headers->get('Permissions-Policy')
);
}
Expand All @@ -181,7 +221,7 @@ public function configure()
$headers = $this->getResponseHeaders('other-route');

$this->assertEquals(
'fullscreen custom-policy',
'fullscreen="custom-policy"',
$headers->get('Permissions-Policy')
);
}
Expand Down
2 changes: 1 addition & 1 deletion tests/MiddlewareTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function it_sets_the_default_feature_policy_headers()
{
$headers = $this->getResponseHeaders();

$this->assertStringContainsString("geolocation 'self'", $headers->get('Permissions-Policy'));
$this->assertStringContainsString('geolocation=self', $headers->get('Permissions-Policy'));
}

protected function getResponseHeaders(string $url = 'test-route'): HeaderBag
Expand Down

0 comments on commit c9273fa

Please sign in to comment.