Skip to content

Commit

Permalink
Added cache possibilities for secrets
Browse files Browse the repository at this point in the history
  • Loading branch information
cableman committed Oct 4, 2024
1 parent bcf2678 commit 1bda219
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 44 deletions.
2 changes: 1 addition & 1 deletion src/Vault/Secret.php → src/Vault/Model/Secret.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace ItkDev\Vault;
namespace ItkDev\Vault\Model;

final class Secret
{
Expand Down
2 changes: 1 addition & 1 deletion src/Vault/Token.php → src/Vault/Model/Token.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace ItkDev\Vault;
namespace ItkDev\Vault\Model;

final class Token
{
Expand Down
73 changes: 45 additions & 28 deletions src/Vault/Vault.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
use Psr\Http\Message\RequestFactoryInterface;
use Psr\Http\Message\StreamFactoryInterface;
use Psr\SimpleCache\CacheInterface;
use \ItkDev\Vault\Model\Secret;
use \ItkDev\Vault\Model\Token;

readonly class Vault implements VaultInterface
{
Expand Down Expand Up @@ -56,43 +58,58 @@ public function login(string $roleId, string $secretId, string $enginePath = 'ap
return $token;
}

public function getSecret(Token $token, string $path, string $secret, array $id): Secret
public function getSecret(Token $token, string $path, string $secret, array $id, bool $useCache = false, bool $reset = false, int $expire = 0): Secret
{
$secret = $this->getSecrets($token, $path, $secret, [$id]);
$secret = $this->getSecrets(
token: $token,
path: $path,
secret: $secret,
ids: [$id],
useCache: $useCache,
reset: $reset,
expire: $expire
);

return reset($secret);
}

// @TODO: Add cache of secret (handle vault offline).
public function getSecrets(Token $token, string $path, string $secret, array $ids): array
public function getSecrets(Token $token, string $path, string $secret, array $ids, bool $useCache = false, bool $reset = false, int $expire = 0): array
{
$url = sprintf('%s/v1/%s/data/%s', $this->vaultUrl, $path, $secret);

$request = $this->requestFactory->createRequest('GET', $url)
->withHeader('Content-Type', 'application/json')
->withHeader('Authorization', 'Bearer ' . $token->token);
$response = $this->httpClient->sendRequest($request);

$res = json_decode($response->getBody(), associative: true, flags: JSON_THROW_ON_ERROR);

$created = new DateTimeImmutable($res['data']['metadata']['created_time'], new DateTimeZone('UTC'));
$version = $res['data']['metadata']['version'];

$data = [];
if (!empty($ids)) {
$secrets = $res['data']['data'];
foreach ($ids as $id) {
if (isset($secrets[$id])) {
$data[$id] = new Secret(
id: $id,
value: $secrets[$id],
version: $version,
createdAt: $created
);
} else {
throw new \InvalidArgumentException(sprintf('Secret with ID "%s" not found.', $id));
$cacheKey = 'itkdev_vault_secret_' . $secret;
$data = $this->cache->get($cacheKey);

if (!$useCache || is_null($data) || $reset) {
$url = sprintf('%s/v1/%s/data/%s', $this->vaultUrl, $path, $secret);

$request = $this->requestFactory->createRequest('GET', $url)
->withHeader('Content-Type', 'application/json')
->withHeader('Authorization', 'Bearer ' . $token->token);
$response = $this->httpClient->sendRequest($request);

$res = json_decode($response->getBody(), associative: true, flags: JSON_THROW_ON_ERROR);

$created = new DateTimeImmutable($res['data']['metadata']['created_time'], new DateTimeZone('UTC'));
$version = $res['data']['metadata']['version'];

$data = [];
if (!empty($ids)) {
$secrets = $res['data']['data'];
foreach ($ids as $id) {
if (isset($secrets[$id])) {
$data[$id] = new Secret(
id: $id,
value: $secrets[$id],
version: $version,
createdAt: $created
);
} else {
throw new \InvalidArgumentException(sprintf('Secret with ID "%s" not found.', $id));
}
}
}

$this->cache->set($cacheKey, $data, $expire);
}

return $data;
Expand Down
19 changes: 5 additions & 14 deletions src/Vault/VaultInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,18 @@

namespace ItkDev\Vault;

use ItkDev\Vault\Model\Secret;
use ItkDev\Vault\Model\Token;

interface VaultInterface
{
public function login(string $roleId, string $secretId, string $enginePath = 'approle', bool $reset = false): Token;


public function getSecret(Token $token, string $path, string $secret, array $id): Secret;
public function getSecret(Token $token, string $path, string $secret, array $id, bool $useCache = false, bool $reset = false, int $expire = 0): Secret;

/**
* Retrieves secrets from a given path.
*
* @param Token $token
* The token used for authentication.
* @param string $path
* The path where secrets are stored.
* @param string $secret
* The specific secret to retrieve.
* @param array $ids
* An array of IDs to identify the secrets.
*
* @return array<Secret>
* An array of retrieved secrets.
*/
public function getSecrets(Token $token, string $path, string $secret, array $ids): array;
public function getSecrets(Token $token, string $path, string $secret, array $ids, bool $useCache = false, bool $reset = false, int $expire = 0): array;
}

0 comments on commit 1bda219

Please sign in to comment.