diff options
author | Arnold Daniels <arnold@jasny.net> | 2016-12-22 16:29:04 +0100 |
---|---|---|
committer | Arnold Daniels <arnold@jasny.net> | 2016-12-22 16:29:04 +0100 |
commit | ecdd68ca23e9b48cc2b5338bebb9603e69bb4757 (patch) | |
tree | d0e3cf612f1d9a4cdd79d23d81a0ea68934fd78e | |
parent | 272376e298933d1f85f0803c1508156147941957 (diff) | |
download | auth-ecdd68ca23e9b48cc2b5338bebb9603e69bb4757.zip auth-ecdd68ca23e9b48cc2b5338bebb9603e69bb4757.tar.gz auth-ecdd68ca23e9b48cc2b5338bebb9603e69bb4757.tar.bz2 |
Added tests
-rw-r--r-- | composer.json | 4 | ||||
-rw-r--r-- | src/Auth.php | 74 | ||||
-rw-r--r-- | tests/AuthTest.php | 147 |
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()); + } +} |