mirror of
https://github.com/OpenXE-org/OpenXE.git
synced 2024-11-15 12:37:14 +01:00
115 lines
2.4 KiB
PHP
115 lines
2.4 KiB
PHP
|
<?php
|
||
|
|
||
|
namespace Xentral\Components\Http\Session;
|
||
|
|
||
|
use Xentral\Components\Http\Exception\CsrfTokenException;
|
||
|
use Xentral\Components\Http\Exception\InvalidArgumentException;
|
||
|
use Xentral\Components\Util\StringUtil;
|
||
|
|
||
|
final class CsrfTokenManager
|
||
|
{
|
||
|
/** @var int CSRF_TOKEN_LENGTH */
|
||
|
const CSRF_TOKEN_LENGTH = 32;
|
||
|
/** @var array $tokenData */
|
||
|
private $tokenData;
|
||
|
|
||
|
/**
|
||
|
* @param array $tokenData
|
||
|
*/
|
||
|
public function __construct($tokenData = [])
|
||
|
{
|
||
|
$this->tokenData = $tokenData;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $key
|
||
|
* @param string $value
|
||
|
* @param bool $remove
|
||
|
*
|
||
|
* @return bool
|
||
|
*/
|
||
|
public function isTokenValid($key, $value, $remove = true)
|
||
|
{
|
||
|
$this->ensureTokenKeyFormat($key);
|
||
|
$valid = false;
|
||
|
if (array_key_exists($key, $this->tokenData) && $this->tokenData[$key] === $value) {
|
||
|
$valid = true;
|
||
|
}
|
||
|
if ($valid === true && $remove === true) {
|
||
|
$this->removeToken($key);
|
||
|
}
|
||
|
|
||
|
return $valid;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param $key
|
||
|
*
|
||
|
* @throws CsrfTokenException
|
||
|
*
|
||
|
* @return string
|
||
|
*/
|
||
|
public function createToken($key)
|
||
|
{
|
||
|
$this->ensureTokenKeyFormat($key);
|
||
|
$token = StringUtil::random(self::CSRF_TOKEN_LENGTH, true);
|
||
|
$this->tokenData[$key] = $token;
|
||
|
|
||
|
if (strlen($token) < self::CSRF_TOKEN_LENGTH) {
|
||
|
throw new CsrfTokenException('Could not create CSRF token.');
|
||
|
}
|
||
|
|
||
|
return $token;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param $key
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
public function removeToken($key)
|
||
|
{
|
||
|
$this->ensureTokenKeyFormat($key);
|
||
|
unset($this->tokenData[$key]);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $key
|
||
|
*
|
||
|
* @throws InvalidArgumentException
|
||
|
*
|
||
|
* @return string
|
||
|
*/
|
||
|
public function refreshToken($key)
|
||
|
{
|
||
|
$this->ensureTokenKeyFormat($key);
|
||
|
$this->removeToken($key);
|
||
|
|
||
|
return $this->createToken($key);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param $target
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
public function dumpTokens(&$target)
|
||
|
{
|
||
|
$target = $this->tokenData;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $key
|
||
|
*
|
||
|
* @throws InvalidArgumentException
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
private function ensureTokenKeyFormat($key)
|
||
|
{
|
||
|
if (!preg_match('/^[a-z][a-z0-9_]*$/', $key)) {
|
||
|
throw new InvalidArgumentException('Invalid token key format.');
|
||
|
}
|
||
|
}
|
||
|
}
|