summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnold Daniels <arnold@jasny.net>2016-12-22 16:29:04 +0100
committerArnold Daniels <arnold@jasny.net>2016-12-22 16:29:04 +0100
commitecdd68ca23e9b48cc2b5338bebb9603e69bb4757 (patch)
treed0e3cf612f1d9a4cdd79d23d81a0ea68934fd78e
parent272376e298933d1f85f0803c1508156147941957 (diff)
downloadauth-ecdd68ca23e9b48cc2b5338bebb9603e69bb4757.zip
auth-ecdd68ca23e9b48cc2b5338bebb9603e69bb4757.tar.gz
auth-ecdd68ca23e9b48cc2b5338bebb9603e69bb4757.tar.bz2
Added tests
-rw-r--r--composer.json4
-rw-r--r--src/Auth.php74
-rw-r--r--tests/AuthTest.php147
3 files changed, 188 insertions, 37 deletions
diff --git a/composer.json b/composer.json
index aeff063..d571c81 100644
--- a/composer.json
+++ b/composer.json
@@ -1,6 +1,6 @@
{
"name": "jasny/auth",
- "description": "Authentication and level based authorization",
+ "description": "Authentication and authorization",
"keywords": ["auth"],
"license": "MIT",
"homepage": "http://jasny.github.com/auth",
@@ -16,7 +16,7 @@
"source": "https://github.com/jasny/auth"
},
"require": {
- "php": ">=5.4.0"
+ "php": ">=5.6.0"
},
"autoload": {
"psr-4": {
diff --git a/src/Auth.php b/src/Auth.php
index 44b753d..3d8274e 100644
--- a/src/Auth.php
+++ b/src/Auth.php
@@ -69,6 +69,40 @@ abstract class Auth
/**
+ * Get current authenticated user
+ *
+ * @return User|null
+ */
+ public function user()
+ {
+ if (!isset($this->user)) {
+ $uid = $this->getCurrentUserId();
+ $this->user = $uid ? ($this->fetchUserById($uid) ?: false) : false;
+ }
+
+ return $this->user ?: null;
+ }
+
+ /**
+ * Set the current user
+ *
+ * @param User $user
+ * @return boolean
+ */
+ public function setUser(User $user)
+ {
+ if ($user->onLogin() === false) {
+ return null;
+ }
+
+ $this->user = $user;
+ $this->persistCurrentUser();
+
+ return $this->user;
+ }
+
+
+ /**
* Hash a password
*
* @param string $password
@@ -76,6 +110,10 @@ abstract class Auth
*/
public function hashPassword($password)
{
+ if (!is_string($password) || $password === '') {
+ throw new \InvalidArgumentException("Password should be a (non-empty) string");
+ }
+
return password_hash($password, PASSWORD_BCRYPT);
}
@@ -100,7 +138,7 @@ abstract class Auth
*/
public function login($username, $password)
{
- $user = static::fetchUserByUsername($username);
+ $user = $this->fetchUserByUsername($username);
if (!$this->verifyCredentials($user, $password)) {
return null;
@@ -110,24 +148,6 @@ abstract class Auth
}
/**
- * Set the current user
- *
- * @param User $user
- * @return boolean
- */
- public static function setUser(User $user)
- {
- if ($user->onLogin() === false) {
- return null;
- }
-
- $this->user = $user;
- $this->persistCurrentUser();
-
- return $this->user;
- }
-
- /**
* Logout
*/
public function logout()
@@ -143,20 +163,4 @@ abstract class Auth
$this->user = false;
$this->persistCurrentUser();
}
-
-
- /**
- * Get current authenticated user
- *
- * @return User|null
- */
- public function user()
- {
- if (!isset($this->user)) {
- $uid = $this->getCurrentUserId();
- $this->user = $uid ? ($this->fetchUserById($uid) ?: false) : false;
- }
-
- return $this->user ?: null;
- }
}
diff --git a/tests/AuthTest.php b/tests/AuthTest.php
new file mode 100644
index 0000000..8e04951
--- /dev/null
+++ b/tests/AuthTest.php
@@ -0,0 +1,147 @@
+<?php
+
+namespace Jasny;
+
+use Jasny\Auth;
+use PHPUnit_Framework_TestCase as TestCase;
+use PHPUnit_Framework_MockObject_MockObject as MockObject;
+
+/**
+ * @covers Jasny\Auth
+ */
+class AuthTest extends TestCase
+{
+ /**
+ * @var Auth|MockObject
+ */
+ protected $auth;
+
+ public function setUp()
+ {
+ $this->auth = $this->getMockForAbstractClass(Auth::class);
+ }
+
+
+ public function testHashPassword()
+ {
+ $hash = $this->auth->hashPassword('abc');
+ $this->assertTrue(password_verify('abc', $hash));
+ }
+
+ public function invalidPasswordProvider()
+ {
+ return [
+ [''],
+ [array()],
+ [123]
+ ];
+ }
+
+ /**
+ * @dataProvider invalidPasswordProvider
+ * @expectedException \InvalidArgumentException
+ */
+ public function testHashPasswordWithInvalidArgument($password)
+ {
+ $this->auth->hashPassword($password);
+ }
+
+
+ public function testVerifyCredentials()
+ {
+ $hash = password_hash('abc', PASSWORD_BCRYPT);
+
+ $user = $this->createMock(Auth\User::class);
+ $user->method('getHashedPassword')->willReturn($hash);
+
+ $this->assertTrue($this->auth->verifyCredentials($user, 'abc'));
+
+ $this->assertFalse($this->auth->verifyCredentials($user, 'god'));
+ $this->assertFalse($this->auth->verifyCredentials($user, ''));
+ }
+
+
+ public function testLogin()
+ {
+ $hash = password_hash('abc', PASSWORD_BCRYPT);
+
+ $user = $this->createMock(Auth\User::class);
+ $user->method('getHashedPassword')->willReturn($hash);
+ $user->expects($this->once())->method('onLogin');
+
+ $this->auth->expects($this->once())->method('fetchUserByUsername')->with('john')->willReturn($user);
+ $this->auth->expects($this->once())->method('persistCurrentUser');
+
+ $result = $this->auth->login('john', 'abc');
+
+ $this->assertSame($user, $result);
+ $this->assertSame($user, $this->auth->user());
+ }
+
+ public function testLoginWithIncorrectPassword()
+ {
+ $hash = password_hash('abc', PASSWORD_BCRYPT);
+
+ $user = $this->createMock(Auth\User::class);
+ $user->method('getHashedPassword')->willReturn($hash);
+ $user->expects($this->never())->method('onLogin');
+
+ $this->auth->expects($this->once())->method('fetchUserByUsername')->with('john')->willReturn($user);
+ $this->auth->expects($this->never())->method('persistCurrentUser');
+
+ $result = $this->auth->login('john', 'god');
+
+ $this->assertNull($result);
+ $this->assertNull($this->auth->user());
+ }
+
+ /**
+ * @return Auth|MockObject
+ */
+ public function testSetUser()
+ {
+ $user = $this->createMock(Auth\User::class);
+
+ $this->auth->expects($this->once())->method('persistCurrentUser');
+
+ $result = $this->auth->setUser($user);
+
+ $this->assertSame($user, $result);
+ $this->assertSame($user, $this->auth->user());
+
+ return $this->auth;
+ }
+
+ public function testSetUserWithExistingUser()
+ {
+ $this->auth->expects($this->exactly(2))->method('persistCurrentUser');
+
+ $this->auth->setUser($this->createMock(Auth\User::class));
+
+ $user = $this->createMock(Auth\User::class);
+ $user->expects($this->once())->method('onLogin');
+
+ $result = $this->auth->setUser($user);
+
+ $this->assertSame($user, $result);
+ $this->assertSame($user, $this->auth->user());
+ }
+
+ public function testSetUserWithOnLoginFail()
+ {
+ $this->auth->expects($this->once())->method('persistCurrentUser');
+
+ $oldUser = $this->createMock(Auth\User::class);
+ $this->auth->setUser($oldUser);
+
+ $user = $this->createMock(Auth\User::class);
+ $user->expects($this->once())->method('onLogin')->willReturn(false);
+
+ $this->auth->expects($this->never())->method('persistCurrentUser');
+
+ $result = $this->auth->setUser($user);
+
+ $this->assertNull($result);
+ $this->assertSame($oldUser, $this->auth->user());
+ }
+}