Permalink
Browse files

First import

  • Loading branch information...
rowanparker committed Nov 15, 2011
1 parent 32a5d9f commit 7ddc5071c8a8c49c556873b620d19e7322b379e8
Showing with 241 additions and 0 deletions.
  1. +95 −0 classes/kohana/lithe/auth.php
  2. +3 −0 classes/lithe/auth.php
  3. +9 −0 config/lithe-auth.php
  4. +134 −0 tests/phpunit/classes/LitheAuthTest.php
@@ -0,0 +1,95 @@
+<?php defined('SYSPATH') or die('No direct script access.');
+
+abstract class Kohana_Lithe_Auth
+{
+ /**
+ * Load the secret for an key
+ *
+ * @param string $key
+ * @return string secret
+ */
+ static public function secret($key)
+ {
+ return Kohana::$config->load('lithe-auth.secrets.'.$key);
+ }
+
+ /**
+ * Generate a hash for a given URI,
+ * time and key.
+ *
+ * @param string $uri
+ * @param string $time
+ * @param string $key
+ * @throws HTTP_Exception_403
+ * @return string Hash
+ */
+ static public function hash($uri, $time, $key)
+ {
+ $secret = static::secret($key);
+
+ if ( ! $secret) {
+ throw new HTTP_Exception_403('Key [:key] is not valid.',
+ array(':key'=>$key));
+ }
+
+ $algorithm = Kohana::$config->load('lithe-auth.algorithm');
+
+ $data = $uri . '-' . $time;
+
+ return hash_hmac($algorithm, $data, $secret);
+ }
+
+ /**
+ * Authenticate a [Request] received
+ *
+ * @todo Validate time range (e.g. last 30 seconds)
+ * @param Request $request
+ * @throws HTTP_Exception_403
+ * @return Request The [Request] object.
+ */
+ static public function authenticate(Request $request)
+ {
+ $hash = $request->headers('Lithe-hash');
+ $key = $request->headers('Lithe-key');
+ $time = $request->headers('Lithe-time');
+
+ if ($hash == NULL) {
+ throw new HTTP_Exception_403('No hash provided.');
+ }
+
+ if ($key == NULL) {
+ throw new HTTP_Exception_403('No key provided.');
+ }
+
+ if ( ! $time) {
+ throw new HTTP_Exception_403('No timestamp provided.');
+ }
+
+ if ($hash != static::hash($request->uri(), $time, $key)) {
+ throw new HTTP_Exception_403('Invalid hash.');
+ }
+
+ return $request;
+ }
+
+ /**
+ * Prepare a [Request] to send
+ *
+ * @param Request $request
+ * @param string $key
+ * @param string $time Timestamp for unit test
+ * @return Request The [Request] object.
+ */
+ static public function prepare(Request $request, $key, $time = NULL)
+ {
+ $time = ($time) ? $time : time();
+
+ $hash = static::hash($request->uri(), $time, $key);
+
+ $request->headers('Lithe-key', $key);
+ $request->headers('Lithe-hash', $hash);
+ $request->headers('Lithe-time', $time);
+
+ return $request;
+ }
+}
View
@@ -0,0 +1,3 @@
+<?php defined('SYSPATH') or die('No direct script access.');
+
+class Lithe_Auth extends Kohana_Lithe_Auth {}
View
@@ -0,0 +1,9 @@
+<?php defined('SYSPATH') or die('No direct access allowed.');
+
+return array (
+ 'algorithm' => 'sha512',
+
+ 'secrets' => array(
+ // 'key' => 'secret',
+ ),
+);
@@ -0,0 +1,134 @@
+<?php defined('SYSPATH') or die('No direct script access.');
+
+class LitheAuthTest extends Unittest_TestCase
+{
+ public function setUp()
+ {
+ parent::setUp();
+
+ $this->setEnvironment(array(
+ 'lithe-auth.algorithm' => 'sha512',
+ 'lithe-auth.secrets' => array(
+ 'test' => 'Kat9agaBukaqUBrERexABreStatehufR'
+ ),
+ ));
+ }
+
+ public function tearDown()
+ {
+ parent::tearDown();
+ }
+
+ public function testSecretLoadsForKey()
+ {
+ $secret = Lithe_Auth::secret('test');
+
+ $this->assertEquals(Kohana::$config->load('lithe-auth.secrets.test'), $secret);
+ }
+
+ /**
+ * @depends testSecretLoadsForKey
+ */
+ public function testCorrectHashGenerated()
+ {
+ $uri = 'some/random/uri';
+ $time = '12345';
+ $key = 'test';
+ $hash = '2678de6689a381b7aa7513769088b6ead1adca0c692df9fd318df6b86b8bbf5dbed68c25eeaa9a47eccce3da3ebf318d84d70e87f984cce7bffed3d4ed1c065e';
+
+ $this->assertEquals($hash, Lithe_Auth::hash($uri, $time, $key));
+ }
+
+ /**
+ * @depends testCorrectHashGenerated
+ * @expectedException HTTP_Exception_403
+ * @expectedExceptionMessage Key [foo] is not valid.
+ */
+ public function testExceptionThrownOnInvalidKey()
+ {
+ $uri = 'some/random/uri';
+ $time = '12345';
+ $key = 'foo';
+ Lithe_Auth::hash($uri, $time, $key);
+ }
+
+ /**
+ * @depends testCorrectHashGenerated
+ * @expectedException HTTP_Exception_403
+ * @expectedExceptionMessage No hash provided.
+ */
+ public function testExceptionThrownOnNoHashProvided()
+ {
+ $request = Request::factory();
+ Lithe_Auth::authenticate($request);
+ }
+
+ /**
+ * @depends testExceptionThrownOnNoHashProvided
+ * @expectedException HTTP_Exception_403
+ * @expectedExceptionMessage No key provided.
+ */
+ public function testExceptionThrownOnNoKeyProvided()
+ {
+ $request = Request::factory();
+ $request->headers('Lithe-hash', 'hash');
+ Lithe_Auth::authenticate($request);
+ }
+
+ /**
+ * @depends testExceptionThrownOnNoKeyProvided
+ * @expectedException HTTP_Exception_403
+ * @expectedExceptionMessage No timestamp provided.
+ */
+ public function testExceptionThrownOnNoTimestampProvided()
+ {
+ $request = Request::factory();
+ $request->headers('Lithe-hash', 'hash');
+ $request->headers('Lithe-key', 'test');
+ Lithe_Auth::authenticate($request);
+ }
+
+ /**
+ * @depends testExceptionThrownOnNoTimestampProvided
+ * @expectedException HTTP_Exception_403
+ * @expectedExceptionMessage Invalid hash.
+ */
+ public function testExceptionThrownOnInvalidHash()
+ {
+ $request = Request::factory();
+ $request->headers('Lithe-hash', 'hash');
+ $request->headers('Lithe-key', 'test');
+ $request->headers('Lithe-time', 'time');
+ Lithe_Auth::authenticate($request);
+ }
+
+ /**
+ * @depends testExceptionThrownOnInvalidHash
+ */
+ public function testAuthenticate()
+ {
+ try {
+ $request = Request::factory('some/random/uri');
+ $request->headers('Lithe-hash', '2678de6689a381b7aa7513769088b6ead1adca0c692df9fd318df6b86b8bbf5dbed68c25eeaa9a47eccce3da3ebf318d84d70e87f984cce7bffed3d4ed1c065e');
+ $request->headers('Lithe-key', 'test');
+ $request->headers('Lithe-time', '12345');
+ Lithe_Auth::authenticate($request);
+ } catch (Exception $e) {
+ $this->fail('An unexpected exception occured: ' . $e->getMessage());
+ }
+ }
+
+ public function testPrepare()
+ {
+ $time = '12345';
+ $key = 'test';
+ $hash = '2678de6689a381b7aa7513769088b6ead1adca0c692df9fd318df6b86b8bbf5dbed68c25eeaa9a47eccce3da3ebf318d84d70e87f984cce7bffed3d4ed1c065e';
+
+ $request = Request::factory('some/random/uri');
+ Lithe_Auth::prepare($request, $key, $time);
+
+ $this->assertEquals($key, $request->headers('Lithe-key'));
+ $this->assertEquals($time, $request->headers('Lithe-time'));
+ $this->assertEquals($hash, $request->headers('Lithe-hash'));
+ }
+}

0 comments on commit 7ddc507

Please sign in to comment.