PageRenderTime 56ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Zikula/Core/Token/Generator.php

https://github.com/antoniom/core
PHP | 238 lines | 78 code | 23 blank | 137 comment | 1 complexity | 27893b6a419e5a3a4568be863f3ed08b MD5 | raw file
Possible License(s): GPL-3.0, LGPL-3.0, MIT
  1. <?php
  2. /**
  3. * Copyright 2010 Zikula Foundation
  4. *
  5. * This work is contributed to the Zikula Foundation under one or more
  6. * Contributor Agreements and licensed to You under the following license:
  7. *
  8. * @license GNU/LGPLv3 (or at your option, any later version).
  9. * @package Security_Token
  10. * @subpackage Generator
  11. *
  12. * Please see the NOTICE file distributed with this source code for further
  13. * information regarding copyright and licensing.
  14. */
  15. namespace Zikula\Core\Token;
  16. use Zikula\Core\Token\Storage\StorageInterface;
  17. /**
  18. * Token generator class.
  19. */
  20. class Generator
  21. {
  22. /**
  23. * Storage driver.
  24. *
  25. * @var \Zikula\Core\Token\Storage\StorageInterface
  26. */
  27. private $storage;
  28. /**
  29. * Token ID.
  30. *
  31. * @var string
  32. */
  33. private $id;
  34. /**
  35. * Secret.
  36. *
  37. * @var string
  38. */
  39. private $secret;
  40. /**
  41. * Generated token.
  42. *
  43. * @var string
  44. */
  45. private $token;
  46. /**
  47. * The token hash.
  48. *
  49. * @var string
  50. */
  51. private $hash;
  52. /**
  53. * Timestamp of generated token.
  54. *
  55. * @var integer
  56. */
  57. private $timestamp;
  58. /**
  59. * Max life of a token.
  60. *
  61. * @var integer
  62. */
  63. private $maxLifetime;
  64. /**
  65. * Constructor.
  66. *
  67. * @param StorageInterface $storage Storage driver.
  68. * @param string $secret Secret to sign tokens with.
  69. * @param integer $maxLifetime Max lifetime for a token.
  70. */
  71. public function __construct(StorageInterface $storage, $secret, $maxLifetime = 3600)
  72. {
  73. $this->storage = $storage;
  74. $this->secret = $secret;
  75. $this->maxLifetime = $maxLifetime;
  76. }
  77. /**
  78. * Save token.
  79. *
  80. * @return void
  81. */
  82. public function save()
  83. {
  84. $this->storage->save($this->id, $this->token, $this->timestamp);
  85. $this->garbageCollection();
  86. }
  87. /**
  88. * Delete token.
  89. *
  90. * @return void
  91. */
  92. public function delete()
  93. {
  94. $this->storage->delete($this->token);
  95. }
  96. /**
  97. * Generate a unique ID.
  98. *
  99. * @return string
  100. */
  101. public function uniqueId()
  102. {
  103. return uniqid('', true);
  104. }
  105. /**
  106. * Generate token based on ID.
  107. *
  108. * If tokens are intended to be one-time tokens then use a unique ID each
  109. * time. They are validated with delete=true. If the are per-session, then
  110. * they should be generated with the same unique ID and validated with
  111. * delete = false leaving storage expire/GC to remove the token.
  112. *
  113. * @param string $id Token ID.
  114. * @param integer $timestamp Create with this timestamp (defaults null = now)
  115. *
  116. * @return \Zikula\Core\Token\Generator
  117. */
  118. public function generate($id, $timestamp = null)
  119. {
  120. $this->id = $id;
  121. $this->timestamp = is_null($timestamp) ? time() : $timestamp;
  122. $this->hash = md5($this->id . $this->secret . $this->timestamp);
  123. $this->token = base64_encode("{$this->id}:{$this->hash}:{$this->timestamp}");
  124. return $this;
  125. }
  126. /**
  127. * Decode a token.
  128. *
  129. * @param string $token Token.
  130. *
  131. * @return array
  132. */
  133. public function decode($token)
  134. {
  135. return explode(':', base64_decode($token));
  136. }
  137. /**
  138. * Gets storage driver.
  139. *
  140. * @return \Zikula\Core\Token\Storage\StorageInterface
  141. */
  142. public function getStorage()
  143. {
  144. return $this->storage;
  145. }
  146. /**
  147. * Gets token ID.
  148. *
  149. * @return string
  150. */
  151. public function getId()
  152. {
  153. return $this->id;
  154. }
  155. /**
  156. * Gets signing secret.
  157. *
  158. * @return string
  159. */
  160. public function getSecret()
  161. {
  162. return $this->secret;
  163. }
  164. /**
  165. * Gets generated token.
  166. *
  167. * @return string
  168. */
  169. public function getToken()
  170. {
  171. return $this->token;
  172. }
  173. /**
  174. * Gets hash for of token.
  175. *
  176. * @return string
  177. */
  178. public function getHash()
  179. {
  180. return $this->hash;
  181. }
  182. /**
  183. * Gets timestamp of token creation.
  184. *
  185. * @return integer
  186. */
  187. public function getTimestamp()
  188. {
  189. return $this->timestamp;
  190. }
  191. /**
  192. * Runs garbage collection to clean up tokens that expire
  193. * before the session expired.
  194. *
  195. * Generates a number between 1 and $probability and runs
  196. * garbage collection if result is 1.
  197. *
  198. * @param integer $probability Defaults to 20, ie 1/20 = 5%
  199. */
  200. public function garbageCollection($probability = 20)
  201. {
  202. if (mt_rand(1, $probability) === 1) {
  203. $this->storage->gc($this->maxLifetime);
  204. }
  205. }
  206. /**
  207. * Gets the max lifetime in seconds.
  208. *
  209. * @return integer
  210. */
  211. public function getMaxLifetime()
  212. {
  213. return $this->maxLifetime;
  214. }
  215. }