RemembermeTest.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. <?php
  2. class RemembermeTest extends PHPUnit_Framework_TestCase
  3. {
  4. /**
  5. * @var Rememberme
  6. */
  7. protected $rememberme;
  8. /**
  9. * Default user id, used as credential information to check
  10. */
  11. protected $userid = 1;
  12. protected $validToken = "78b1e6d775cec5260001af137a79dbd5";
  13. protected $validPersistentToken = "0e0530c1430da76495955eb06eb99d95";
  14. protected $invalidToken = "7ae7c7caa0c7b880cb247bb281d527de";
  15. protected $cookie;
  16. protected $storage;
  17. function setUp() {
  18. $this->storage = $this->getMockBuilder(\Birke\Rememberme\Storage\StorageInterface::class)->getMock();
  19. $this->rememberme = new Birke\Rememberme\Authenticator($this->storage);
  20. $this->cookie = $this->getMockBuilder(\Birke\Rememberme\Cookie::class)->setMethods(['setcookie'])->getMock();
  21. $this->rememberme->setCookie($this->cookie);
  22. $_COOKIE = array();
  23. }
  24. /* Basic cases */
  25. public function testReturnFalseIfNoCookieExists()
  26. {
  27. $this->assertFalse($this->rememberme->login());
  28. }
  29. public function testReturnFalseIfCookieIsInvalid()
  30. {
  31. $_COOKIE = array($this->rememberme->getCookieName() => "DUMMY");
  32. $this->assertFalse($this->rememberme->login());
  33. $_COOKIE = array($this->rememberme->getCookieName() => $this->userid."|a");
  34. $this->assertFalse($this->rememberme->login());
  35. }
  36. public function testLoginTriesToFindTripletWithValuesFromCookie() {
  37. $_COOKIE[$this->rememberme->getCookieName()] = implode("|", array(
  38. $this->userid, $this->validToken, $this->validPersistentToken));
  39. $this->storage->expects($this->once())
  40. ->method("findTriplet")
  41. ->with($this->equalTo($this->userid), $this->equalTo($this->validToken), $this->equalTo($this->validPersistentToken));
  42. $this->rememberme->login();
  43. }
  44. /* Success cases */
  45. public function testReturnTrueIfTripletIsFound() {
  46. $_COOKIE[$this->rememberme->getCookieName()] = implode("|", array(
  47. $this->userid, $this->validToken, $this->validPersistentToken));
  48. $this->storage->expects($this->once())
  49. ->method("findTriplet")
  50. ->will($this->returnValue(Birke\Rememberme\Storage\StorageInterface::TRIPLET_FOUND));
  51. $this->assertEquals($this->userid, $this->rememberme->login());
  52. }
  53. public function testStoreNewTripletInCookieIfTripletIsFound() {
  54. $oldcookieValue = implode("|", array(
  55. $this->userid, $this->validToken, $this->validPersistentToken));
  56. $_COOKIE[$this->rememberme->getCookieName()] = $oldcookieValue;
  57. $this->storage->expects($this->once())
  58. ->method("findTriplet")
  59. ->will($this->returnValue(Birke\Rememberme\Storage\StorageInterface::TRIPLET_FOUND));
  60. $this->cookie->expects($this->once())
  61. ->method("setcookie")
  62. ->with(
  63. $this->anything(),
  64. $this->logicalAnd(
  65. $this->matchesRegularExpression('/^'.$this->userid.'\|[a-f0-9]{32,}\|'.$this->validPersistentToken.'$/'),
  66. $this->logicalNot($this->equalTo($oldcookieValue))
  67. )
  68. );
  69. $this->rememberme->login();
  70. }
  71. public function testReplaceTripletInStorageIfTripletIsFound() {
  72. $_COOKIE[$this->rememberme->getCookieName()] = implode("|", array(
  73. $this->userid, $this->validToken, $this->validPersistentToken));
  74. $this->storage->expects($this->once())
  75. ->method("findTriplet")
  76. ->will($this->returnValue(Birke\Rememberme\Storage\StorageInterface::TRIPLET_FOUND));
  77. $this->storage->expects($this->once())
  78. ->method("replaceTriplet")
  79. ->with(
  80. $this->equalTo($this->userid),
  81. $this->logicalAnd(
  82. $this->matchesRegularExpression('/^[a-f0-9]{32,}$/'),
  83. $this->logicalNot($this->equalTo($this->validToken))
  84. ),
  85. $this->equalTo($this->validPersistentToken)
  86. );
  87. $this->rememberme->login();
  88. }
  89. public function testCookieContainsUserIDAndHexTokensIfTripletIsFound()
  90. {
  91. $_COOKIE[$this->rememberme->getCookieName()] = implode("|", array(
  92. $this->userid, $this->validToken, $this->validPersistentToken));
  93. $this->storage->expects($this->once())
  94. ->method("findTriplet")
  95. ->will($this->returnValue(Birke\Rememberme\Storage\StorageInterface::TRIPLET_FOUND));
  96. $this->cookie->expects($this->once())
  97. ->method("setcookie")
  98. ->with($this->anything(),
  99. $this->matchesRegularExpression('/^'.$this->userid.'\|[a-f0-9]{32,}\|[a-f0-9]{32,}$/')
  100. );
  101. $this->rememberme->login();
  102. }
  103. public function testCookieContainsNewTokenIfTripletIsFound()
  104. {
  105. $oldcookieValue = implode("|", array(
  106. $this->userid, $this->validToken, $this->validPersistentToken));
  107. $_COOKIE[$this->rememberme->getCookieName()] = $oldcookieValue;
  108. $this->storage->expects($this->once())
  109. ->method("findTriplet")
  110. ->will($this->returnValue(Birke\Rememberme\Storage\StorageInterface::TRIPLET_FOUND));
  111. $this->cookie->expects($this->once())
  112. ->method("setcookie")
  113. ->with($this->anything(),
  114. $this->logicalAnd(
  115. $this->matchesRegularExpression('/^'.$this->userid.'\|[a-f0-9]{32,}\|'.$this->validPersistentToken.'$/'),
  116. $this->logicalNot($this->equalTo($oldcookieValue))
  117. )
  118. );
  119. $this->rememberme->login();
  120. }
  121. public function testCookieExpiryIsInTheFutureIfTripletIsFound()
  122. {
  123. $oldcookieValue = implode("|", array(
  124. $this->userid, $this->validToken, $this->validPersistentToken));
  125. $_COOKIE[$this->rememberme->getCookieName()] = $oldcookieValue;
  126. $now = time();
  127. $this->storage->expects($this->once())
  128. ->method("findTriplet")
  129. ->will($this->returnValue(Birke\Rememberme\Storage\StorageInterface::TRIPLET_FOUND));
  130. $this->cookie->expects($this->once())
  131. ->method("setcookie")
  132. ->with($this->anything(), $this->anything(), $this->greaterThan($now));
  133. $this->rememberme->login();
  134. }
  135. /* Failure Cases */
  136. public function testFalseIfTripletIsNotFound() {
  137. $_COOKIE[$this->rememberme->getCookieName()] = implode("|", array(
  138. $this->userid, $this->validToken, $this->validPersistentToken));
  139. $this->storage->expects($this->once())
  140. ->method("findTriplet")
  141. ->will($this->returnValue(Birke\Rememberme\Storage\StorageInterface::TRIPLET_NOT_FOUND));
  142. $this->assertFalse($this->rememberme->login());
  143. }
  144. public function testFalseIfTripletIsInvalid() {
  145. $_COOKIE[$this->rememberme->getCookieName()] = implode("|", array(
  146. $this->userid, $this->invalidToken, $this->validPersistentToken));
  147. $this->storage->expects($this->once())
  148. ->method("findTriplet")
  149. ->will($this->returnValue(Birke\Rememberme\Storage\StorageInterface::TRIPLET_INVALID));
  150. $this->assertFalse($this->rememberme->login());
  151. }
  152. public function testCookieIsExpiredIfTripletIsInvalid() {
  153. $_COOKIE[$this->rememberme->getCookieName()] = implode("|", array(
  154. $this->userid, $this->invalidToken, $this->validPersistentToken));
  155. $now = time();
  156. $this->storage->expects($this->once())
  157. ->method("findTriplet")
  158. ->will($this->returnValue(Birke\Rememberme\Storage\StorageInterface::TRIPLET_INVALID));
  159. $this->cookie->expects($this->once())
  160. ->method("setcookie")
  161. ->with($this->anything(), $this->anything(), $this->lessThan($now));
  162. $this->rememberme->login();
  163. }
  164. public function testAllStoredTokensAreClearedIfTripletIsInvalid() {
  165. $_COOKIE[$this->rememberme->getCookieName()] = implode("|", array(
  166. $this->userid, $this->invalidToken, $this->validPersistentToken));
  167. $this->storage->expects($this->any())
  168. ->method("findTriplet")
  169. ->will($this->returnValue(Birke\Rememberme\Storage\StorageInterface::TRIPLET_INVALID));
  170. $this->storage->expects($this->once())
  171. ->method("cleanAllTriplets")
  172. ->with($this->equalTo($this->userid));
  173. $this->rememberme->setCleanStoredTokensOnInvalidResult(true);
  174. $this->rememberme->login();
  175. $this->rememberme->setCleanStoredTokensOnInvalidResult(false);
  176. $this->rememberme->login();
  177. }
  178. public function testInvalidTripletStateIsStored() {
  179. $_COOKIE[$this->rememberme->getCookieName()] = implode("|", array(
  180. $this->userid, $this->invalidToken, $this->validPersistentToken));
  181. $this->storage->expects($this->once())
  182. ->method("findTriplet")
  183. ->will($this->returnValue(Birke\Rememberme\Storage\StorageInterface::TRIPLET_INVALID));
  184. $this->assertFalse($this->rememberme->loginTokenWasInvalid());
  185. $this->rememberme->login();
  186. $this->assertTrue($this->rememberme->loginTokenWasInvalid());
  187. }
  188. /* Cookie tests */
  189. public function testCookieNameCanBeSet() {
  190. $cookieName = "myCustomName";
  191. $this->rememberme->setCookieName($cookieName);
  192. $_COOKIE[$cookieName] = implode("|", array($this->userid, $this->validToken, $this->validPersistentToken));
  193. $this->storage->expects($this->once())
  194. ->method("findTriplet")
  195. ->will($this->returnValue(Birke\Rememberme\Storage\StorageInterface::TRIPLET_FOUND));
  196. $this->cookie->expects($this->once())
  197. ->method("setcookie")
  198. ->with($this->equalTo($cookieName));
  199. $this->assertEquals($this->userid, $this->rememberme->login());
  200. }
  201. public function testCookieIsSetToConfiguredExpiryDate() {
  202. $_COOKIE[$this->rememberme->getCookieName()] = implode("|", array(
  203. $this->userid, $this->validToken, $this->validPersistentToken));
  204. $now = time();
  205. $expireTime = 31556926; // 1 year
  206. $this->rememberme->setExpireTime($expireTime);
  207. $this->storage->expects($this->once())
  208. ->method("findTriplet")
  209. ->will($this->returnValue(Birke\Rememberme\Storage\StorageInterface::TRIPLET_FOUND));
  210. $this->cookie->expects($this->once())
  211. ->method("setcookie")
  212. ->with($this->anything(), $this->anything(), $this->equalTo($now+$expireTime, 10));
  213. $this->rememberme->login();
  214. }
  215. /* Salting test */
  216. public function testSaltIsAddedToTokensOnLogin() {
  217. $salt = "Mozilla Firefox 4.0";
  218. $_COOKIE[$this->rememberme->getCookieName()] = implode("|", array(
  219. $this->userid, $this->validToken, $this->validPersistentToken));
  220. $this->storage->expects($this->once())
  221. ->method("findTriplet")
  222. ->with($this->equalTo($this->userid), $this->equalTo($this->validToken.$salt), $this->equalTo($this->validPersistentToken.$salt))
  223. ->will($this->returnValue(Birke\Rememberme\Storage\StorageInterface::TRIPLET_FOUND));
  224. $this->storage->expects($this->once())
  225. ->method("replaceTriplet")
  226. ->with(
  227. $this->equalTo($this->userid),
  228. $this->matchesRegularExpression('/^[a-f0-9]{32,}'.preg_quote($salt)."$/"),
  229. $this->equalTo($this->validPersistentToken.$salt)
  230. );
  231. $this->rememberme->setSalt($salt);
  232. $this->rememberme->login();
  233. }
  234. public function testSaltIsAddedToTokensOnCookieIsValid() {
  235. $salt = "Mozilla Firefox 4.0";
  236. $_COOKIE[$this->rememberme->getCookieName()] = implode("|", array(
  237. $this->userid, $this->validToken, $this->validPersistentToken));
  238. $this->storage->expects($this->once())
  239. ->method("findTriplet")
  240. ->with($this->equalTo($this->userid), $this->equalTo($this->validToken.$salt), $this->equalTo($this->validPersistentToken.$salt));
  241. $this->rememberme->setSalt($salt);
  242. $this->rememberme->cookieIsValid($this->userid);
  243. }
  244. public function testSaltIsAddedToTokensOnCreateCookie() {
  245. $salt = "Mozilla Firefox 4.0";
  246. $testExpr = '/^[a-f0-9]{32,}'.preg_quote($salt).'$/';
  247. $this->storage->expects($this->once())
  248. ->method("storeTriplet")
  249. ->with(
  250. $this->equalTo($this->userid),
  251. $this->matchesRegularExpression($testExpr),
  252. $this->matchesRegularExpression($testExpr)
  253. );
  254. $this->rememberme->setSalt($salt);
  255. $this->rememberme->createCookie($this->userid);
  256. }
  257. public function testSaltIsAddedToTokensOnClearCookie() {
  258. $salt = "Mozilla Firefox 4.0";
  259. $_COOKIE[$this->rememberme->getCookieName()] = implode("|", array(
  260. $this->userid, $this->validToken, $this->validPersistentToken));
  261. $this->storage->expects($this->once())
  262. ->method("cleanTriplet")
  263. ->with(
  264. $this->equalTo($this->userid),
  265. $this->equalTo($this->validPersistentToken.$salt)
  266. );
  267. $this->rememberme->setSalt($salt);
  268. $this->rememberme->clearCookie(true);
  269. }
  270. /* Other functions */
  271. public function testCreateCookieCreatesCookieAndStoresTriplets() {
  272. $now = time();
  273. $this->cookie->expects($this->once())
  274. ->method("setcookie")
  275. ->with(
  276. $this->equalTo($this->rememberme->getCookieName()),
  277. $this->matchesRegularExpression('/^'.$this->userid.'\|[a-f0-9]{32,}\|[a-f0-9]{32,}$/'),
  278. $this->greaterThan($now)
  279. );
  280. $testExpr = '/^[a-f0-9]{32,}$/';
  281. $this->storage->expects($this->once())
  282. ->method("storeTriplet")
  283. ->with(
  284. $this->equalTo($this->userid),
  285. $this->matchesRegularExpression($testExpr),
  286. $this->matchesRegularExpression($testExpr)
  287. );
  288. $this->rememberme->createCookie($this->userid);
  289. }
  290. public function testClearCookieExpiresCookieAndDeletesTriplet() {
  291. $_COOKIE[$this->rememberme->getCookieName()] = implode("|", array(
  292. $this->userid, $this->validToken, $this->validPersistentToken));
  293. $now = time();
  294. $this->cookie->expects($this->once())
  295. ->method("setcookie")
  296. ->with(
  297. $this->equalTo($this->rememberme->getCookieName()),
  298. $this->anything(),
  299. $this->lessThan($now)
  300. );
  301. $this->storage->expects($this->once())
  302. ->method("cleanTriplet")
  303. ->with(
  304. $this->equalTo($this->userid),
  305. $this->equalTo($this->validPersistentToken)
  306. );
  307. $this->rememberme->clearCookie(true);
  308. }
  309. }