This repository has been archived by the owner on Nov 8, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit afd4a83
Showing
28 changed files
with
798 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
vendor/ | ||
composer.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
sudo: required | ||
|
||
language: php | ||
|
||
php: | ||
- 7.1 | ||
|
||
before_install: | ||
- composer self-update | ||
|
||
install: | ||
- composer install --no-interaction --prefer-dist --no-scripts --no-progress --no-suggest --optimize-autoloader --classmap-authoritative | ||
|
||
script: | ||
- ./vendor/bin/phing ci | ||
|
||
after_script: | ||
- > | ||
wget https://github.com/satooshi/php-coveralls/releases/download/v1.0.1/coveralls.phar | ||
&& php coveralls.phar --verbose --config Tests/.coveralls.yml; | ||
after_failure: | ||
- for i in $(find Tests -name \*.actual); do echo "--- $i"; cat $i; echo; echo; done | ||
|
||
cache: | ||
directories: | ||
- $HOME/.composer/cache |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
declare(strict_types = 1); | ||
namespace Klapuch\Internal; | ||
|
||
final class CombinedExtension implements Extension { | ||
private $extensions; | ||
|
||
public function __construct(Extension ...$extensions) { | ||
$this->extensions = $extensions; | ||
} | ||
|
||
public function improve(): void { | ||
foreach ($this->extensions as $extension) | ||
$extension->improve(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<?php | ||
declare(strict_types = 1); | ||
namespace Klapuch\Internal; | ||
|
||
final class CspHeader { | ||
private $directives; | ||
private $nonce; | ||
|
||
public function __construct(array $directives) { | ||
$this->directives = $directives; | ||
} | ||
|
||
public function nonce(): string { | ||
if ($this->nonce === null) | ||
$this->nonce = base64_encode(random_bytes(16)); | ||
return $this->nonce; | ||
} | ||
|
||
public function __toString(): string { | ||
if (!$this->directives) | ||
return ''; | ||
return 'Content-Security-Policy: ' . $this->withNonce( | ||
$this->format($this->directives) | ||
); | ||
} | ||
|
||
private function format(array $directives): string { | ||
return implode( | ||
'; ', | ||
array_map( | ||
function(string $directive, string $constraint): string { | ||
return $directive . ' ' . $constraint; | ||
}, | ||
array_keys($directives), | ||
$directives | ||
) | ||
); | ||
} | ||
|
||
private function withNonce(string $header): string { | ||
return str_replace('nonce', 'nonce-' . $this->nonce(), $header); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<?php | ||
declare(strict_types = 1); | ||
namespace Klapuch\Internal; | ||
|
||
interface Extension { | ||
/** | ||
* Improve the current setting | ||
* @return void | ||
*/ | ||
public function improve(): void; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?php | ||
declare(strict_types = 1); | ||
namespace Klapuch\Internal; | ||
|
||
final class HeaderExtension implements Extension { | ||
private $headers; | ||
|
||
public function __construct(array $headers) { | ||
$this->headers = $headers; | ||
} | ||
|
||
public function improve(): void { | ||
(new RawHeaderExtension( | ||
array_map( | ||
function(string $field, string $value): string { | ||
return sprintf('%s:%s', $field, $value); | ||
}, | ||
array_keys($this->headers), | ||
$this->headers | ||
) | ||
))->improve(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
declare(strict_types = 1); | ||
namespace Klapuch\Internal; | ||
|
||
final class IniSetExtension implements Extension { | ||
private $settings; | ||
|
||
public function __construct(array $settings) { | ||
$this->settings = $settings; | ||
} | ||
|
||
public function improve(): void { | ||
foreach ($this->settings as $name => $value) | ||
ini_set($name, (string) $value); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
declare(strict_types = 1); | ||
namespace Klapuch\Internal; | ||
|
||
final class InternationalExtension implements Extension { | ||
private $timezone; | ||
|
||
public function __construct(string $timezone) { | ||
$this->timezone = $timezone; | ||
} | ||
|
||
public function improve(): void { | ||
mb_internal_encoding('UTF-8'); | ||
if (@date_default_timezone_set($this->timezone) === false) { | ||
throw new \InvalidArgumentException( | ||
sprintf('Timezone "%s" is invalid', $this->timezone) | ||
); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
declare(strict_types = 1); | ||
namespace Klapuch\Internal; | ||
|
||
final class RawHeaderExtension implements Extension { | ||
private $headers; | ||
|
||
public function __construct(array $headers) { | ||
$this->headers = $headers; | ||
} | ||
|
||
public function improve(): void { | ||
foreach ($this->headers as $header) | ||
header((string) $header); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
<?php | ||
declare(strict_types = 1); | ||
namespace Klapuch\Internal; | ||
|
||
final class SessionExtension implements Extension { | ||
private const TIMER = '_timer', | ||
DEFAULT_BREAK = 20; | ||
private const PROPRIETARIES = ['SameSite']; | ||
private $settings; | ||
private $break; | ||
|
||
public function __construct(array $settings, int $break = self::DEFAULT_BREAK) { | ||
$this->settings = $settings; | ||
$this->break = $break; | ||
} | ||
|
||
public function improve(): void { | ||
if (session_status() === PHP_SESSION_NONE) | ||
session_start($this->native($this->settings)); | ||
if ($this->elapsed($this->break)) | ||
session_regenerate_id(true); | ||
header(static::raw($this->settings)); | ||
$_SESSION[self::TIMER] = time(); | ||
} | ||
|
||
private function elapsed(int $break): bool { | ||
return isset($_SESSION[self::TIMER]) | ||
&& (time() - $_SESSION[self::TIMER]) > $break; | ||
} | ||
|
||
/** | ||
* Just the native and supported php setting | ||
* @param array $settings | ||
* @return array | ||
*/ | ||
private function native(array $settings): array { | ||
return array_diff_ukey( | ||
$settings, | ||
array_flip(self::PROPRIETARIES), | ||
'strcasecmp' | ||
); | ||
} | ||
|
||
/** | ||
* The raw cookie header | ||
* @param array $settings | ||
* @return string | ||
*/ | ||
private static function raw(array $settings): string { | ||
$matches = array_intersect_ukey( | ||
array_flip(self::PROPRIETARIES), | ||
$settings, | ||
'strcasecmp' | ||
); | ||
$headers = array_combine( | ||
array_flip($matches), | ||
array_intersect_ukey($settings, $matches, 'strcasecmp') | ||
); | ||
return sprintf( | ||
'%s; %s', | ||
current(preg_grep('~^Set-Cookie: ~', headers_list())), | ||
implode( | ||
';', | ||
array_map( | ||
function(string $field, string $value): string { | ||
return sprintf('%s=%s', $field, $value); | ||
}, | ||
array_keys($headers), | ||
$headers | ||
) | ||
) | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Internal | ||
[![Build Status](https://travis-ci.org/klapuch/Internal.svg?branch=master)](https://travis-ci.org/klapuch/Internal) [![Build status](https://ci.appveyor.com/api/projects/status/80sjyunbbtmdneyp?svg=true)](https://ci.appveyor.com/project/facedown/project) [![Coverage Status](https://coveralls.io/repos/github/klapuch/Internal/badge.svg?branch=master)](https://coveralls.io/github/klapuch/Internal?branch=master) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
service_name: travis-ci | ||
coverage_clover: coverage.xml | ||
json_path: coverage.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
*.actual | ||
*.expected |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
* | ||
!.gitignore |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<?php | ||
declare(strict_types = 1); | ||
/** | ||
* @testCase | ||
* @phpVersion > 7.1 | ||
*/ | ||
namespace Klapuch\Internal\Unit; | ||
|
||
use Klapuch\Internal; | ||
use Tester; | ||
use Tester\Assert; | ||
|
||
require __DIR__ . '/../bootstrap.php'; | ||
|
||
final class CombinedExtension extends Tester\TestCase { | ||
public function testConvertingIntegerToString() { | ||
ob_start(); | ||
(new Internal\CombinedExtension( | ||
new class implements Internal\Extension { | ||
function improve(): void { | ||
echo 'a'; | ||
} | ||
}, | ||
new class implements Internal\Extension { | ||
function improve(): void { | ||
echo 'b'; | ||
} | ||
}, | ||
new class implements Internal\Extension { | ||
function improve(): void { | ||
echo 'c'; | ||
} | ||
} | ||
))->improve(); | ||
Assert::same('abc', ob_get_clean()); | ||
} | ||
} | ||
|
||
|
||
(new CombinedExtension())->run(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
<?php | ||
declare(strict_types = 1); | ||
/** | ||
* @testCase | ||
* @phpVersion > 7.1 | ||
*/ | ||
namespace Klapuch\Internal\Unit; | ||
|
||
use Klapuch\Internal; | ||
use Tester; | ||
use Tester\Assert; | ||
|
||
require __DIR__ . '/../bootstrap.php'; | ||
|
||
final class CspHeader extends Tester\TestCase { | ||
public function testNoHeaderOnNoPassedDirectives() { | ||
Assert::same('', (string) new Internal\CspHeader([])); | ||
} | ||
|
||
/** | ||
* @dataProvider directives | ||
*/ | ||
public function testFormattedDirectives(string $header, array $directives) { | ||
Assert::same( | ||
'Content-Security-Policy: ' . $header, | ||
(string) new Internal\CspHeader($directives) | ||
); | ||
} | ||
|
||
protected function directives(): array { | ||
// expected => given | ||
return [ | ||
["default-src 'self'", ['default-src' => "'self'"]], | ||
["script-src 'self' 'unsafe-inline'", ['script-src' => "'self' 'unsafe-inline'"]], | ||
["default-src 'self'; child-src 'none'", ['default-src' => "'self'", 'child-src' => "'none'"]], | ||
]; | ||
} | ||
|
||
public function testGeneratingNonceJustOnce() { | ||
$csp = new Internal\CspHeader([]); | ||
Assert::true(strlen($csp->nonce()) === 24); | ||
Assert::same($csp->nonce(), $csp->nonce()); | ||
} | ||
|
||
public function testPassingNonce() { | ||
$csp = new Internal\CspHeader(['sctipt-src' => 'nonce']); | ||
Assert::contains('nonce-' . $csp->nonce(), (string) $csp); | ||
} | ||
} | ||
|
||
|
||
(new CspHeader())->run(); |
Oops, something went wrong.