123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- <?php
- /**
- * @package Grav\Plugin\Login
- *
- * @copyright Copyright (C) 2014 - 2017 RocketTheme, LLC. All rights reserved.
- * @license MIT License; see LICENSE file for details.
- */
- namespace Grav\Plugin\Login\RememberMe;
- use Grav\Common\Cache;
- use Grav\Common\Grav;
- use Doctrine\Common\Cache\CacheProvider;
- use Doctrine\Common\Cache\FilesystemCache;
- use Birke\Rememberme\Storage\StorageInterface;
- /**
- * Storage wrapper for Doctrine cache
- *
- * Used for storing the credential/token/persistentToken triplets.
- *
- * @author Sommerregen <sommerregen@benjamin-regler.de>
- */
- class TokenStorage implements StorageInterface
- {
- /**
- * @var CacheProvider
- */
- protected $driver;
- /**
- * @var string
- */
- protected $cache_dir;
- /**
- * Constructor
- *
- * @param string $path Path to storage directory
- * @throws \InvalidArgumentException
- */
- public function __construct($path = 'cache://rememberme')
- {
- /** @var Cache $cache */
- $cache = Grav::instance()['cache'];
- $this->cache_dir = Grav::instance()['locator']->findResource($path, true, true);
- // Setup cache
- $this->driver = $cache->getCacheDriver();
- if ($this->driver instanceof FilesystemCache) {
- $this->driver = new FilesystemCache($this->cache_dir);
- }
- // Set the cache namespace to our unique key
- $this->driver->setNamespace($cache->getKey());
- }
- /**
- * Return Tri-state value constant
- *
- * @param mixed $credential Unique credential (user id,
- * email address, user name)
- * @param string $token One-Time Token
- * @param string $persistentToken Persistent Token
- *
- * @return int
- */
- public function findTriplet($credential, $token, $persistentToken)
- {
- // Hash the tokens, because they can contain a salt and can be
- // accessed in the file system
- $persistentToken = sha1(trim($persistentToken));
- $token = sha1(trim($token));
- $id = $this->getId($credential);
- if (!$this->driver->contains($id)) {
- return self::TRIPLET_NOT_FOUND;
- }
- list($expire, $tokens) = $this->driver->fetch($id);
- if (isset($tokens[$persistentToken]) && $tokens[$persistentToken] === $token) {
- return self::TRIPLET_FOUND;
- }
- return self::TRIPLET_INVALID;
- }
- /**
- * Store the new token for the credential and the persistent token.
- * Create a new storage entry, if the combination of credential and
- * persistent token does not exist.
- *
- * @param mixed $credential
- * @param string $token
- * @param string $persistentToken
- * @param int $expire Timestamp when this triplet
- * will expire (0 = no expiry)
- */
- public function storeTriplet($credential, $token, $persistentToken, $expire = null)
- {
- // Hash the tokens, because they can contain a salt and can be
- // accessed in the file system
- $persistentToken = sha1(trim($persistentToken));
- $token = sha1(trim($token));
- $e = null;
- $tokens = [];
- $id = $this->getId($credential);
- if ($this->driver->contains($id)) {
- list($e, $tokens) = $this->driver->fetch($id);
- }
- // Get cache lifetime for tokens
- if ($expire === null && $e === null) {
- /** @var Cache $cache */
- $cache = Grav::instance()['cache'];
- $expire = $cache->getLifetime();
- } elseif ($expire === null) {
- $expire = $e;
- }
- // Update tokens
- $tokens[$persistentToken] = $token;
- $this->driver->save($id, [$expire, $tokens], $expire);
- return $this;
- }
- /**
- * Replace current token after successful authentication
- *
- * @param mixed $credential
- * @param string $token
- * @param string $persistentToken
- * @param int $expire
- */
- public function replaceTriplet($credential, $token, $persistentToken, $expire = null)
- {
- $this->cleanTriplet($credential, $persistentToken);
- $this->storeTriplet($credential, $token, $persistentToken, $expire);
- }
- /**
- * Remove one triplet of the user from the store
- *
- * @param mixed $credential
- * @param string $persistentToken
- */
- public function cleanTriplet($credential, $persistentToken)
- {
- // Hash the tokens, because they can contain a salt and can be
- // accessed in the file system
- $persistentToken = sha1(trim($persistentToken));
- // Delete token from storage
- $id = $this->getId($credential);
- if ($this->driver->contains($id)) {
- list($expire, $tokens) = $this->driver->fetch($id);
- unset($tokens[$persistentToken]);
- $this->driver->save($id, [$expire, $tokens], $expire);
- }
- }
- /**
- * Remove all triplets of a user, effectively logging him out on all
- * machines
- *
- * @param mixed $credential
- */
- public function cleanAllTriplets($credential)
- {
- $id = $this->getId($credential);
- $this->driver->delete($id);
- }
- /**
- * Helper method to clear RememberMe cache
- */
- public function clearCache()
- {
- $this->driver->flushAll();
- }
- /**
- * Get the cache id
- *
- * @param string $key A key to compute the cache id for
- * @return string The cache id
- */
- protected function getId($key)
- {
- /** @var Cache $cache */
- $cache = Grav::instance()['cache'];
- return 'login' . md5(trim($key) . $cache->getKey());
- }
- }
|