Skip to content

Commit

Permalink
SECURITY-9707: GAP mTLS support
Browse files Browse the repository at this point in the history
Co-authored-by: Dora Kaszasne Sztanko <[email protected]>
  • Loading branch information
knagy and Dora Kaszasne Sztanko committed Aug 3, 2024
1 parent fc44e03 commit 0ec8ddf
Show file tree
Hide file tree
Showing 16 changed files with 288 additions and 379 deletions.
12 changes: 5 additions & 7 deletions .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,19 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
php-versions: ['8.0']

php-versions: ['8.1', '8.2', '8.3']
steps:
- name: Install prerequesits
run: sudo apt update && sudo apt install -y php-mbstring
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-versions }}
extensions: mbstring
tools: composer
- name: Install dependencies
run: |
composer update
composer style
composer install
run: composer install
- name: Test
run: composer test
- name: Code style
run: composer style
7 changes: 4 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.PHONY: test
.PHONY: install test style

test:
docker-compose run --rm app composer test
install: ; docker compose run --rm app composer install
test: ; docker compose run --rm app composer test
style: ; docker compose run --rm app composer style
23 changes: 18 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# session-validator-client-php ![Build status](https://travis-ci.org/emartech/session-validator-client-php.svg?branch=master)
# Session Validator Client PHP

PHP client for Emarsys session validator service

Expand All @@ -13,7 +13,17 @@ composer require emartech/session-validator-client
### Validating a single MSID

```php
$client = Client::create('https://service-url', 'escher_key', 'escher_secret');
$client = Client::create('https://session-validator.gservice.emarsys.net', 'escher_key', 'escher_secret');

var_dump($client->isValid('msid'));
```

### Requests without Escher

For mTLS on GAP.

```php
$client = Client::create('http://session-validator-web.security');

var_dump($client->isValid('msid'));
```
Expand All @@ -23,15 +33,15 @@ var_dump($client->isValid('msid'));
Returns an array of the invalid MSIDs.

```php
$client = Client::create('https://service-url', 'escher_key', 'escher_secret');
$client = Client::create('https://session-validator.gservice.emarsys.net', 'escher_key', 'escher_secret');

var_dump($client->filterInvalid(['msid1', 'msid2']));
```

### Caching results

```php
$client = Client::create('https://service-url', 'escher_key', 'escher_secret');
$client = Client::create('https://session-validator.gservice.emarsys.net', 'escher_key', 'escher_secret');
$cachedClient = CachedClient::create($client);

var_dump($cachedClient->isValid('msid'));
Expand All @@ -44,7 +54,7 @@ To enable logging, add a PSR-3 compatible logger to the client
```php
use Monolog\Logger;

$client = Client::create('https://service-url', 'escher_key', 'escher_secret');
$client = Client::create('https://session-validator.gservice.emarsys.net', 'escher_key', 'escher_secret');
$client->setLogger(new Logger('name'));
```

Expand All @@ -56,6 +66,9 @@ printf "\n" | pecl install apcu
```

### Local development

```bash
make install
make test
make style
```
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@
}
},
"require": {
"php": "^8.0",
"emartech/escher": "^3.0",
"php": ">=8.1",
"emartech/escher": "^4.0",
"guzzlehttp/guzzle": "^7.4",
"psr/log": "^3.0"
},
"require-dev": {
"phpunit/phpunit": "^8.4",
"phpunit/phpunit": "^10.0",
"squizlabs/php_codesniffer": "^3.3"
},
"suggest": {
Expand Down
3 changes: 1 addition & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
version: '3'
services:
app:
image: composer:2.3.7
image: composer:lts
working_dir: /home/app/src
volumes:
- .:/home/app/src
9 changes: 4 additions & 5 deletions src/Cache/ApcCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,19 @@

class ApcCache implements CacheInterface
{
/** @var int */
private $ttl;
private int $ttl;

public function __construct($ttl)
public function __construct(int $ttl)
{
$this->ttl = $ttl;
}

public function get($key)
public function get(string $key): mixed
{
return apcu_fetch($key);
}

public function set($key, $value)
public function set(string $key, mixed $value): bool
{
return apcu_add($key, $value, $this->ttl);
}
Expand Down
13 changes: 2 additions & 11 deletions src/Cache/CacheInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,7 @@

interface CacheInterface
{
/**
* @param string $key
* @return mixed
*/
public function get($key);
public function get(string $key): mixed;

/**
* @param string $key
* @param mixed $value
* @return bool
*/
public function set($key, $value);
public function set(string $key, mixed $value): bool;
}
10 changes: 4 additions & 6 deletions src/CachedClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@ class CachedClient implements ClientInterface
{
const CACHE_TTL = 300;

/** @var Client */
private $client;
/** @var CacheInterface */
private $cache;
private ClientInterface $client;
private CacheInterface $cache;

public static function create(ClientInterface $client)
{
Expand All @@ -25,7 +23,7 @@ public function __construct(ClientInterface $client, CacheInterface $cache)
$this->cache = $cache;
}

public function isValid($msid)
public function isValid(string $msid): bool
{
$cachedResult = $this->cache->get($msid);
if ($cachedResult) {
Expand All @@ -38,7 +36,7 @@ public function isValid($msid)
return $result;
}

public function filterInvalid(array $msids)
public function filterInvalid(array $msids): array
{
$result = $this->client->filterInvalid($msids);

Expand Down
56 changes: 30 additions & 26 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,41 @@
namespace SessionValidator;

use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;
use Psr\Http\Message\ResponseInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use SessionValidator\Http\EscherClient;
use SessionValidator\Http\EscherMiddleware;

class Client implements ClientInterface
{
const SERVICE_TIMEOUT = 0.25;

/** @var EscherClient */
private $client;
/** @var LoggerInterface */
private $logger;
private \GuzzleHttp\ClientInterface $httpClient;
private LoggerInterface $logger;

/** @var string */
private $serviceUrl;

public static function create($serviceUrl, $escherKey, $escherSecret)
public static function create(string $serviceUrl, ?string $escherKey = null, ?string $escherSecret = null)
{
$httpClient = EscherClient::create($escherKey, $escherSecret, [
$config = [
'http_errors' => false,
'timeout' => self::SERVICE_TIMEOUT,
]);
'base_uri' => $serviceUrl,
];
if ($escherKey && $escherSecret) {
$handler = HandlerStack::create();
$handler->push(EscherMiddleware::create($escherKey, $escherSecret), 'escher_signer');

$config['handler'] = $handler;
}
$httpClient = new \GuzzleHttp\Client($config);

return new self($httpClient, $serviceUrl);
return new self($httpClient);
}

public function __construct(EscherClient $client, $serviceUrl)
public function __construct(\GuzzleHttp\ClientInterface $client)
{
$this->client = $client;
$this->serviceUrl = $serviceUrl;
$this->httpClient = $client;

$this->logger = new NullLogger();
}
Expand All @@ -43,9 +47,9 @@ public function setLogger(LoggerInterface $logger)
$this->logger = $logger;
}

public function isValid($msid)
public function isValid(string $msid): bool
{
$response = $this->sendRequest('GET', "{$this->serviceUrl}/sessions/$msid");
$response = $this->sendRequest('GET', "/sessions/$msid");

if ($response) {
return $response->getStatusCode() === 200 || $response->getStatusCode() >= 500;
Expand All @@ -54,24 +58,24 @@ public function isValid($msid)
}
}

public function filterInvalid(array $msids)
public function filterInvalid(array $msids): array
{
$body = json_encode(['msids' => $msids]);

$response = $this->sendRequest('POST', "{$this->serviceUrl}/sessions/filter", $body);
$response = $this->sendRequest('POST', '/sessions/filter', $body);

if ($response && $response->getStatusCode() === 200) {
$responseData = json_decode($response->getBody(), true);
return $responseData['msids'];
$responseData = json_decode($response->getBody()->getContents(), true);
return $responseData;
} else {
return [];
}
}

private function sendRequest($method, $url, $body = '')
private function sendRequest(string $method, string $url, string $body = ''): ?Response
{
try {
$response = $this->client->request($method, $url, [
$response = $this->httpClient->request($method, $url, [
'headers' => ['Content-Type' => 'application/json'],
'body' => $body,
]);
Expand All @@ -80,11 +84,11 @@ private function sendRequest($method, $url, $body = '')
return $response;
} catch (GuzzleException $e) {
$this->logException($e);
return false;
return null;
}
}

private function logResult(ResponseInterface $response)
private function logResult(ResponseInterface $response): void
{
switch ($response->getStatusCode()) {
case 200:
Expand All @@ -99,7 +103,7 @@ private function logResult(ResponseInterface $response)
}
}

private function logException(GuzzleException $exception)
private function logException(GuzzleException $exception): void
{
$this->logger->info($exception->getMessage());
}
Expand Down
12 changes: 2 additions & 10 deletions src/ClientInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,7 @@

interface ClientInterface
{
/**
* @param string $msid
* @return bool
*/
public function isValid($msid);
public function isValid(string $msid): bool;

/**
* @param array $msids
* @return array
*/
public function filterInvalid(array $msids);
public function filterInvalid(array $msids): array;
}
Loading

0 comments on commit 0ec8ddf

Please sign in to comment.