Skip to content
This repository has been archived by the owner on Dec 30, 2020. It is now read-only.

Commit

Permalink
Add interval argument for rotatable key set (#292)
Browse files Browse the repository at this point in the history
* Fix RotatableJWKSet to rotate keys at interval
* Minor fixes and cleanup
* Change BaseJWKSet from trait to abstract class and minor fixes.
* Fix style issues and leftover debug code
  • Loading branch information
mdeboer authored and Spomky committed Oct 6, 2017
1 parent 66ab874 commit 744e7ca
Show file tree
Hide file tree
Showing 16 changed files with 281 additions and 39 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/vendor

phpunit.xml
composer.lock
1 change: 0 additions & 1 deletion examples/NestedTokens.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,3 @@
'zip' => 'DEF',
]
);
var_dump($jwe);
4 changes: 2 additions & 2 deletions src/Factory/JWKFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ public static function createStorableKey($filename, array $parameters)
/**
* {@inheritdoc}
*/
public static function createRotatableKeySet($filename, array $parameters, $nb_keys)
public static function createRotatableKeySet($filename, array $parameters, $nb_keys, $interval = null)
{
return new RotatableJWKSet($filename, $parameters, $nb_keys);
return new RotatableJWKSet($filename, $parameters, $nb_keys, $interval);
}

/**
Expand Down
9 changes: 5 additions & 4 deletions src/Factory/JWKFactoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,14 @@ public static function createKeySets(array $jwksets = []);
public static function createStorableKeySet($filename, array $parameters, $nb_keys);

/**
* @param string $filename
* @param array $parameters
* @param int $nb_keys
* @param string $filename
* @param array $parameters
* @param int $nb_keys
* @param int|null $interval
*
* @return \Jose\Object\JWKSetInterface
*/
public static function createRotatableKeySet($filename, array $parameters, $nb_keys);
public static function createRotatableKeySet($filename, array $parameters, $nb_keys, $interval = null);

/**
* @param string $filename
Expand Down
5 changes: 3 additions & 2 deletions src/Object/BaseJWKSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
/**
* Class BaseJWKSet.
*/
trait BaseJWKSet
abstract class BaseJWKSet
{
/**
* @var int
Expand Down Expand Up @@ -172,7 +172,8 @@ public function selectKey($type, $algorithm = null, array $restrictions = [])
Assertion::nullOrString($algorithm);

$result = [];
foreach ($this->getKeys() as $key) {
$keys = $this->getKeys();
foreach ($keys as $key) {
$ind = 0;

// Check usage
Expand Down
11 changes: 9 additions & 2 deletions src/Object/DownloadedJWKSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@
/**
* Class DownloadedJWKSet.
*/
abstract class DownloadedJWKSet implements JWKSetInterface
abstract class DownloadedJWKSet extends BaseJWKSet implements JWKSetInterface
{
use BaseJWKSet;
use JWKSetPEM;

/**
Expand Down Expand Up @@ -78,6 +77,14 @@ public function addKey(JWKInterface $key)
//Not available
}

/**
* {@inheritdoc}
*/
public function prependKey(JWKInterface $key)
{
//Not available
}

/**
* {@inheritdoc}
*/
Expand Down
13 changes: 10 additions & 3 deletions src/Object/JWKSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@
/**
* Class JWKSet.
*/
final class JWKSet implements JWKSetInterface
final class JWKSet extends BaseJWKSet implements JWKSetInterface
{
use BaseJWKSet;
use JWKSetPEM;

/**
Expand Down Expand Up @@ -49,12 +48,20 @@ public function addKey(JWKInterface $key)
$this->keys[] = $key;
}

/**
* {@inheritdoc}
*/
public function prependKey(JWKInterface $key)
{
array_unshift($this->keys, $key);
}

/**
* {@inheritdoc}
*/
public function removeKey($key)
{
if (isset($this->keys[$key])) {
if (array_key_exists($key, $this->keys)) {
unset($this->keys[$key]);
}
}
Expand Down
17 changes: 14 additions & 3 deletions src/Object/JWKSetInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,18 @@
interface JWKSetInterface extends \Countable, \Iterator, \JsonSerializable, \ArrayAccess
{
/**
* @param $index
* Get key from set at index.
*
* @param int $index
*
* @return \Jose\Object\JWKInterface
*/
public function getKey($index);

/**
* @param $index
* Check if set has key at index.
*
* @param int $index
*
* @return bool
*/
Expand All @@ -37,10 +41,17 @@ public function getKeys();
/**
* Add key in the key set.
*
* @param \Jose\Object\JWKInterface A key to store in the key set
* @param \Jose\Object\JWKInterface $key A key to store in the key set
*/
public function addKey(JWKInterface $key);

/**
* Prepend key to the set.
*
* @param \Jose\Object\JWKInterface $key A key to store in the key set
*/
public function prependKey(JWKInterface $key);

/**
* Remove key from the key set.
*
Expand Down
11 changes: 9 additions & 2 deletions src/Object/JWKSets.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@
/**
* Class JWKSets.
*/
final class JWKSets implements JWKSetsInterface
final class JWKSets extends BaseJWKSet implements JWKSetsInterface
{
use BaseJWKSet;
use JWKSetPEM;

/**
Expand Down Expand Up @@ -71,6 +70,14 @@ public function addKey(JWKInterface $key)
//Not available
}

/**
* {@inheritdoc}
*/
public function prependKey(JWKInterface $key)
{
//Not available
}

/**
* {@inheritdoc}
*/
Expand Down
11 changes: 9 additions & 2 deletions src/Object/PublicJWKSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@
/**
* Class PublicJWKSet.
*/
final class PublicJWKSet implements JWKSetInterface
final class PublicJWKSet extends BaseJWKSet implements JWKSetInterface
{
use BaseJWKSet;
use JWKSetPEM;

/**
Expand Down Expand Up @@ -59,6 +58,14 @@ public function addKey(JWKInterface $key)
$this->jwkset->addKey($key);
}

/**
* {@inheritdoc}
*/
public function prependKey(JWKInterface $key)
{
$this->jwkset->prependKey($key);
}

/**
* {@inheritdoc}
*/
Expand Down
71 changes: 59 additions & 12 deletions src/Object/RotatableJWKSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,71 @@
/**
* Class RotatableJWKSet.
*/
final class RotatableJWKSet extends StorableJWKSet implements RotatableInterface, JWKSetInterface
final class RotatableJWKSet extends StorableJWKSet implements RotatableInterface
{
/**
* Interval at which keys should be rotated.
*
* @var int|null
*/
private $interval;

/**
* RotatableJWKSet constructor.
*
* @param string $filename
* @param array $parameters
* @param int $nb_keys
* @param int|null $interval
*/
public function __construct($filename, array $parameters, $nb_keys, $interval = null)
{
parent::__construct($filename, $parameters, $nb_keys);

$this->interval = $interval;
}

/**
* {@inheritdoc}
*/
public function getJWKSet()
{
// Check if we need to rotate keys upon every interaction with the underlying JWK set
$this->rotateIfNeeded();

return parent::getJWKSet();
}

/**
* {@inheritdoc}
*/
public function rotate()
{
$this->loadObjectIfNeeded();
$jwkset = $this->getObject();

$keys = $jwkset->getKeys();
unset($keys[count($keys) - 1]);
$jwkset = new JWKSet();
$jwkset->addKey($this->createJWK());
foreach ($keys as $key) {
$jwkset->addKey($key);
}
$this->setObject($jwkset);
$jwkset = parent::getJWKSet();

// Remove last key in set
$jwkset->removeKey($jwkset->countKeys() - 1);

// Prepend new key to set
$jwkset->prependKey($this->createJWK());

// Save new key set
$this->saveObject($jwkset);
}

/**
* Rotate key set if last modification time is due.
*/
private function rotateIfNeeded()
{
if (isset($this->interval) && $this->interval >= 0) {
$modificationTime = $this->getLastModificationTime();

if (null === $modificationTime) {
$this->regen();
} elseif (($modificationTime + $this->interval) < time()) {
$this->rotate();
}
}
}
}
4 changes: 4 additions & 0 deletions src/Object/Storable.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,13 @@ abstract protected function createObjectFromFileContent(array $file_content);
*/
public function getLastModificationTime()
{
clearstatcache(null, $this->getFilename());

if (file_exists($this->getFilename())) {
return filemtime($this->getFilename());
}

return null;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Object/StorableJWK.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class StorableJWK implements StorableInterface, JWKInterface
protected $parameters;

/**
* RotatableJWK constructor.
* StorableJWK constructor.
*
* @param string $filename
* @param array $parameters
Expand Down
8 changes: 8 additions & 0 deletions src/Object/StorableJWKSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,14 @@ public function addKey(JWKInterface $key)
// Not available
}

/**
* {@inheritdoc}
*/
public function prependKey(JWKInterface $key)
{
//Not available
}

/**
* {@inheritdoc}
*/
Expand Down
Loading

0 comments on commit 744e7ca

Please sign in to comment.