diff options
-rw-r--r-- | ChangeLog | 1 | ||||
-rw-r--r-- | app/Auth/ReverseProxyAuth.php | 3 | ||||
-rw-r--r-- | app/User/ReverseProxyUserProvider.php | 21 | ||||
-rw-r--r-- | tests/units/Auth/ReverseProxyAuthTest.php | 111 |
4 files changed, 133 insertions, 3 deletions
@@ -9,6 +9,7 @@ New features: Improvements: +* Preserve role for existing users when using ReverseProxy authentication * Handle priority for task and project duplication * Expose task reference field to the user interface * Improve ICal export diff --git a/app/Auth/ReverseProxyAuth.php b/app/Auth/ReverseProxyAuth.php index b9730c5c..fdf936b1 100644 --- a/app/Auth/ReverseProxyAuth.php +++ b/app/Auth/ReverseProxyAuth.php @@ -45,7 +45,8 @@ class ReverseProxyAuth extends Base implements PreAuthenticationProviderInterfac $username = $this->request->getRemoteUser(); if (! empty($username)) { - $this->userInfo = new ReverseProxyUserProvider($username); + $userProfile = $this->userModel->getByUsername($username); + $this->userInfo = new ReverseProxyUserProvider($username, $userProfile ?: array()); return true; } diff --git a/app/User/ReverseProxyUserProvider.php b/app/User/ReverseProxyUserProvider.php index 723b8155..34d2187d 100644 --- a/app/User/ReverseProxyUserProvider.php +++ b/app/User/ReverseProxyUserProvider.php @@ -22,14 +22,23 @@ class ReverseProxyUserProvider implements UserProviderInterface protected $username = ''; /** + * User profile if the user already exists + * + * @access protected + * @var array + */ + private $userProfile = array(); + + /** * Constructor * * @access public * @param string $username */ - public function __construct($username) + public function __construct($username, array $userProfile = array()) { $this->username = $username; + $this->userProfile = $userProfile; } /** @@ -84,7 +93,15 @@ class ReverseProxyUserProvider implements UserProviderInterface */ public function getRole() { - return REVERSE_PROXY_DEFAULT_ADMIN === $this->username ? Role::APP_ADMIN : Role::APP_USER; + if (REVERSE_PROXY_DEFAULT_ADMIN === $this->username) { + return Role::APP_ADMIN; + } + + if (isset($this->userProfile['role'])) { + return $this->userProfile['role']; + } + + return Role::APP_USER; } /** diff --git a/tests/units/Auth/ReverseProxyAuthTest.php b/tests/units/Auth/ReverseProxyAuthTest.php new file mode 100644 index 00000000..cdbc247d --- /dev/null +++ b/tests/units/Auth/ReverseProxyAuthTest.php @@ -0,0 +1,111 @@ +<?php + +use Kanboard\Auth\ReverseProxyAuth; +use Kanboard\Core\Security\Role; +use Kanboard\Model\UserModel; + +require_once __DIR__.'/../Base.php'; + +class ReverseProxyAuthTest extends Base +{ + public function setUp() + { + parent::setUp(); + + $this->container['request'] = $this + ->getMockBuilder('\Kanboard\Core\Http\Request') + ->setConstructorArgs(array($this->container)) + ->setMethods(array('getRemoteUser')) + ->getMock(); + } + + public function testGetName() + { + $provider = new ReverseProxyAuth($this->container); + $this->assertEquals('ReverseProxy', $provider->getName()); + } + + public function testAuthenticateSuccess() + { + $this->container['request'] + ->expects($this->once()) + ->method('getRemoteUser') + ->will($this->returnValue('admin')); + + $provider = new ReverseProxyAuth($this->container); + $this->assertTrue($provider->authenticate()); + } + + public function testAuthenticateFailure() + { + $this->container['request'] + ->expects($this->once()) + ->method('getRemoteUser') + ->will($this->returnValue('')); + + $provider = new ReverseProxyAuth($this->container); + $this->assertFalse($provider->authenticate()); + } + + public function testValidSession() + { + $this->container['request'] + ->expects($this->once()) + ->method('getRemoteUser') + ->will($this->returnValue('admin')); + + $this->container['sessionStorage']->user = array( + 'username' => 'admin' + ); + + $provider = new ReverseProxyAuth($this->container); + $this->assertTrue($provider->isValidSession()); + } + + public function testInvalidSession() + { + $this->container['request'] + ->expects($this->once()) + ->method('getRemoteUser') + ->will($this->returnValue('foobar')); + + $this->container['sessionStorage']->user = array( + 'username' => 'admin' + ); + + $provider = new ReverseProxyAuth($this->container); + $this->assertFalse($provider->isValidSession()); + } + + public function testRoleForNewUser() + { + $this->container['request'] + ->expects($this->once()) + ->method('getRemoteUser') + ->will($this->returnValue('someone')); + + $provider = new ReverseProxyAuth($this->container); + $this->assertTrue($provider->authenticate()); + + $user = $provider->getUser(); + $this->assertEquals(Role::APP_USER, $user->getRole()); + } + + public function testRoleIsPreservedForExistingUser() + { + $this->container['request'] + ->expects($this->once()) + ->method('getRemoteUser') + ->will($this->returnValue('someone')); + + $provider = new ReverseProxyAuth($this->container); + $userModel = new UserModel($this->container); + + $this->assertEquals(2, $userModel->create(array('username' => 'someone', 'role' => Role::APP_MANAGER))); + + $this->assertTrue($provider->authenticate()); + + $user = $provider->getUser(); + $this->assertEquals(Role::APP_MANAGER, $user->getRole()); + } +} |