Add the timeout and unique checks.
authorGunnar Wrobel <p@rdus.de>
Tue, 30 Nov 2010 06:44:55 +0000 (07:44 +0100)
committerGunnar Wrobel <p@rdus.de>
Tue, 30 Nov 2010 12:48:28 +0000 (13:48 +0100)
framework/Token/lib/Horde/Token/Base.php
framework/Token/test/Horde/Token/Unit/FileTest.php

index 7be77b0..865ecff 100644 (file)
@@ -124,11 +124,12 @@ abstract class Horde_Token_Base
      * @param string  $token    The signed token.
      * @param string  $seed     The unique ID of the token.
      * @param int     $timeout  Timout of the token in seconds.
-     * @param boolean $unique   Can the token be used more than once?
+     *                          Values below zero represent no timeout.
+     * @param boolean $unique   Should validation of the token succeed only once?
      *
      * @return boolean True if the token was valid.
      */
-    public function validate($token, $seed = '', $timeout = 0, $unique = false)
+    public function validate($token, $seed = '', $timeout = -1, $unique = false)
     {
         $b = Horde_Url::uriB64Decode($token);
         $nonce = substr($b, 0, 6);
@@ -136,6 +137,14 @@ abstract class Horde_Token_Base
         if ($hash != $this->_hash($nonce . $seed)) {
             return false;
         }
+        $timestamp = unpack('N', substr($nonce, 0, 4));
+        $timestamp = array_pop($timestamp);
+        if ($timeout >= 0 && $timestamp + $timeout >= time()) {
+            return false;
+        }
+        if ($unique) {
+            return $this->verify($nonce);
+        }
         return true;
     }
 
index a458bed..623a29e 100644 (file)
@@ -75,6 +75,32 @@ class Horde_Token_Unit_Storage_FileTest extends PHPUnit_Framework_TestCase
         $this->assertFalse($t->validate($t->get('a'), 'b'));
     }
 
+    public function testImmediateTimeout()
+    {
+        $t = new Horde_Token_File(array('secret' => 'abc'));
+        $this->assertFalse($t->validate($t->get('a'), 'a', 1));
+    }
+
+    public function testTimeoutAfterOneSecond()
+    {
+        $t = new Horde_Token_File(array('secret' => 'abc'));
+        sleep(1);
+        $this->assertFalse($t->validate($t->get('a'), 'a', 1));
+    }
+
+    public function testUniqueToken()
+    {
+        $t = new Horde_Token_File(
+            array(
+                'secret' => 'abc',
+                'token_dir' => $this->_getTemporaryDirectory()
+            )
+        );
+        $token = $t->get('a');
+        $t->validate($token, 'a', -1, true);
+        $this->assertFalse($t->validate($token, 'a', -1, true));
+    }
+
     public function testNonces()
     {
         $t = new Horde_Token_File(array('secret' => 'abc'));