From b0994ba68e7cbaa077d81006fb0f25bcbd049353 Mon Sep 17 00:00:00 2001
From: Frederic Guillot <fred@kanboard.net>
Date: Sun, 6 Sep 2015 14:28:06 -0400
Subject: Add unit tests for LDAP and ReverseProxy auth

---
 tests/units/Auth/LdapTest.php         | 377 ++++++++++++++++++++++++++++++++--
 tests/units/Auth/ReverseProxyTest.php |  37 ++++
 tests/units/Base.php                  |   3 -
 3 files changed, 402 insertions(+), 15 deletions(-)
 create mode 100644 tests/units/Auth/ReverseProxyTest.php

(limited to 'tests/units')

diff --git a/tests/units/Auth/LdapTest.php b/tests/units/Auth/LdapTest.php
index 8d470d88..5c453b39 100644
--- a/tests/units/Auth/LdapTest.php
+++ b/tests/units/Auth/LdapTest.php
@@ -13,25 +13,40 @@ function ldap_set_option()
 {
 }
 
-function ldap_bind($ldap, $ldap_username, $ldap_password)
+function ldap_bind($link_identifier, $bind_rdn, $bind_password)
 {
-    return LdapTest::$functions->ldap_bind($ldap, $ldap_username, $ldap_password);
+    return LdapTest::$functions->ldap_bind($link_identifier, $bind_rdn, $bind_password);
+}
+
+function ldap_search($link_identifier, $base_dn, $filter, array $attributes)
+{
+    return LdapTest::$functions->ldap_search($link_identifier, $base_dn, $filter, $attributes);
+}
+
+function ldap_get_entries($link_identifier, $result_identifier)
+{
+    return LdapTest::$functions->ldap_get_entries($link_identifier, $result_identifier);
 }
 
 class LdapTest extends \Base
 {
     public static $functions;
+    private $ldap;
 
     public function setUp()
     {
         parent::setup();
 
+        $this->ldap = $ldap = new Ldap($this->container);
+
         self::$functions = $this
             ->getMockBuilder('stdClass')
             ->setMethods(array(
                 'ldap_connect',
                 'ldap_set_option',
                 'ldap_bind',
+                'ldap_search',
+                'ldap_get_entries',
             ))
             ->getMock();
     }
@@ -53,8 +68,7 @@ class LdapTest extends \Base
             )
             ->will($this->returnValue('my_ldap_resource'));
 
-        $ldap = new Ldap($this->container);
-        $this->assertNotFalse($ldap->connect());
+        $this->assertNotFalse($this->ldap->connect('my_ldap_server'));
     }
 
     public function testConnectFailure()
@@ -68,8 +82,7 @@ class LdapTest extends \Base
             )
             ->will($this->returnValue(false));
 
-        $ldap = new Ldap($this->container);
-        $this->assertFalse($ldap->connect());
+        $this->assertFalse($this->ldap->connect('my_ldap_server'));
     }
 
     public function testBindAnonymous()
@@ -84,8 +97,7 @@ class LdapTest extends \Base
             )
             ->will($this->returnValue(true));
 
-        $ldap = new Ldap($this->container);
-        $this->assertTrue($ldap->bind('my_ldap_connection', 'my_user', 'my_password', 'anonymous'));
+        $this->assertTrue($this->ldap->bind('my_ldap_connection', 'my_user', 'my_password', 'anonymous'));
     }
 
     public function testBindUser()
@@ -100,8 +112,7 @@ class LdapTest extends \Base
             )
             ->will($this->returnValue(true));
 
-        $ldap = new Ldap($this->container);
-        $this->assertTrue($ldap->bind('my_ldap_connection', 'my_user', 'my_password', 'user', 'uid=%s', 'something'));
+        $this->assertTrue($this->ldap->bind('my_ldap_connection', 'my_user', 'my_password', 'user', 'uid=%s', 'something'));
     }
 
     public function testBindProxy()
@@ -116,7 +127,349 @@ class LdapTest extends \Base
             )
             ->will($this->returnValue(true));
 
-        $ldap = new Ldap($this->container);
-        $this->assertTrue($ldap->bind('my_ldap_connection', 'my_user', 'my_password', 'proxy', 'someone', 'something'));
+        $this->assertTrue($this->ldap->bind('my_ldap_connection', 'my_user', 'my_password', 'proxy', 'someone', 'something'));
+    }
+
+    public function testSearchSuccess()
+    {
+        $entries = array(
+            'count' => 1,
+            0 => array(
+                'count' => 2,
+                'dn' => 'uid=my_user,ou=People,dc=kanboard,dc=local',
+                'displayname' => array(
+                    'count' => 1,
+                    0 => 'My user',
+                ),
+                'mail' => array(
+                    'count' => 2,
+                    0 => 'user1@localhost',
+                    1 => 'user2@localhost',
+                ),
+                0 => 'displayname',
+                1 => 'mail',
+            )
+        );
+
+        $expected = array(
+            'username' => 'my_user',
+            'name' => 'My user',
+            'email' => 'user1@localhost',
+        );
+
+        self::$functions
+            ->expects($this->at(0))
+            ->method('ldap_search')
+            ->with(
+                $this->equalTo('my_ldap_connection'),
+                $this->equalTo('ou=People,dc=kanboard,dc=local'),
+                $this->equalTo('uid=my_user'),
+                $this->equalTo(array(LDAP_ACCOUNT_FULLNAME, LDAP_ACCOUNT_EMAIL))
+            )
+            ->will($this->returnValue('my_result_identifier'));
+
+        self::$functions
+            ->expects($this->at(1))
+            ->method('ldap_get_entries')
+            ->with(
+                $this->equalTo('my_ldap_connection'),
+                $this->equalTo('my_result_identifier')
+            )
+            ->will($this->returnValue($entries));
+
+        self::$functions
+            ->expects($this->at(2))
+            ->method('ldap_bind')
+            ->with(
+                $this->equalTo('my_ldap_connection'),
+                $this->equalTo('uid=my_user,ou=People,dc=kanboard,dc=local'),
+                $this->equalTo('my_password')
+            )
+            ->will($this->returnValue(true));
+
+        $this->assertEquals($expected, $this->ldap->search('my_ldap_connection', 'my_user', 'my_password', 'ou=People,dc=kanboard,dc=local', 'uid=%s'));
+    }
+
+    public function testSearchWithBadPassword()
+    {
+        $entries = array(
+            'count' => 1,
+            0 => array(
+                'count' => 2,
+                'dn' => 'uid=my_user,ou=People,dc=kanboard,dc=local',
+                'displayname' => array(
+                    'count' => 1,
+                    0 => 'My user',
+                ),
+                'mail' => array(
+                    'count' => 2,
+                    0 => 'user1@localhost',
+                    1 => 'user2@localhost',
+                ),
+                0 => 'displayname',
+                1 => 'mail',
+            )
+        );
+
+        self::$functions
+            ->expects($this->at(0))
+            ->method('ldap_search')
+            ->with(
+                $this->equalTo('my_ldap_connection'),
+                $this->equalTo('ou=People,dc=kanboard,dc=local'),
+                $this->equalTo('uid=my_user'),
+                $this->equalTo(array(LDAP_ACCOUNT_FULLNAME, LDAP_ACCOUNT_EMAIL))
+            )
+            ->will($this->returnValue('my_result_identifier'));
+
+        self::$functions
+            ->expects($this->at(1))
+            ->method('ldap_get_entries')
+            ->with(
+                $this->equalTo('my_ldap_connection'),
+                $this->equalTo('my_result_identifier')
+            )
+            ->will($this->returnValue($entries));
+
+        self::$functions
+            ->expects($this->at(2))
+            ->method('ldap_bind')
+            ->with(
+                $this->equalTo('my_ldap_connection'),
+                $this->equalTo('uid=my_user,ou=People,dc=kanboard,dc=local'),
+                $this->equalTo('my_password')
+            )
+            ->will($this->returnValue(false));
+
+        $this->assertFalse($this->ldap->search('my_ldap_connection', 'my_user', 'my_password', 'ou=People,dc=kanboard,dc=local', 'uid=%s'));
+    }
+
+    public function testSearchWithUserNotFound()
+    {
+        self::$functions
+            ->expects($this->at(0))
+            ->method('ldap_search')
+            ->with(
+                $this->equalTo('my_ldap_connection'),
+                $this->equalTo('ou=People,dc=kanboard,dc=local'),
+                $this->equalTo('uid=my_user'),
+                $this->equalTo(array(LDAP_ACCOUNT_FULLNAME, LDAP_ACCOUNT_EMAIL))
+            )
+            ->will($this->returnValue('my_result_identifier'));
+
+        self::$functions
+            ->expects($this->at(1))
+            ->method('ldap_get_entries')
+            ->with(
+                $this->equalTo('my_ldap_connection'),
+                $this->equalTo('my_result_identifier')
+            )
+            ->will($this->returnValue(array()));
+
+        $this->assertFalse($this->ldap->search('my_ldap_connection', 'my_user', 'my_password', 'ou=People,dc=kanboard,dc=local', 'uid=%s'));
+    }
+
+    public function testSuccessfulAuthentication()
+    {
+        $this->container['userSession'] = $this
+            ->getMockBuilder('\Model\UserSession')
+            ->setConstructorArgs(array($this->container))
+            ->setMethods(array('refresh'))
+            ->getMock();
+
+        $this->container['user'] = $this
+            ->getMockBuilder('\Model\User')
+            ->setConstructorArgs(array($this->container))
+            ->setMethods(array('getByUsername'))
+            ->getMock();
+
+        $ldap = $this
+            ->getMockBuilder('\Auth\Ldap')
+            ->setConstructorArgs(array($this->container))
+            ->setMethods(array('findUser'))
+            ->getMock();
+
+        $ldap
+            ->expects($this->once())
+            ->method('findUser')
+            ->with(
+                $this->equalTo('user'),
+                $this->equalTo('password')
+            )
+            ->will($this->returnValue(array('username' => 'user', 'name' => 'My user', 'email' => 'user@here')));
+
+        $this->container['user']
+            ->expects($this->once())
+            ->method('getByUsername')
+            ->with(
+                $this->equalTo('user')
+            )
+            ->will($this->returnValue(array('id' => 2, 'username' => 'user', 'is_ldap_user' => 1)));
+
+        $this->container['userSession']
+            ->expects($this->once())
+            ->method('refresh');
+
+        $this->assertTrue($ldap->authenticate('user', 'password'));
+    }
+
+    public function testAuthenticationWithExistingLocalUser()
+    {
+        $this->container['userSession'] = $this
+            ->getMockBuilder('\Model\UserSession')
+            ->setConstructorArgs(array($this->container))
+            ->setMethods(array('refresh'))
+            ->getMock();
+
+        $this->container['user'] = $this
+            ->getMockBuilder('\Model\User')
+            ->setConstructorArgs(array($this->container))
+            ->setMethods(array('getByUsername'))
+            ->getMock();
+
+        $ldap = $this
+            ->getMockBuilder('\Auth\Ldap')
+            ->setConstructorArgs(array($this->container))
+            ->setMethods(array('findUser'))
+            ->getMock();
+
+        $ldap
+            ->expects($this->once())
+            ->method('findUser')
+            ->with(
+                $this->equalTo('user'),
+                $this->equalTo('password')
+            )
+            ->will($this->returnValue(array('username' => 'user', 'name' => 'My user', 'email' => 'user@here')));
+
+        $this->container['user']
+            ->expects($this->once())
+            ->method('getByUsername')
+            ->with(
+                $this->equalTo('user')
+            )
+            ->will($this->returnValue(array('id' => 2, 'username' => 'user', 'is_ldap_user' => 0)));
+
+        $this->container['userSession']
+            ->expects($this->never())
+            ->method('refresh');
+
+        $this->assertFalse($ldap->authenticate('user', 'password'));
+    }
+
+    public function testAuthenticationWithAutomaticAccountCreation()
+    {
+        $this->container['userSession'] = $this
+            ->getMockBuilder('\Model\UserSession')
+            ->setConstructorArgs(array($this->container))
+            ->setMethods(array('refresh'))
+            ->getMock();
+
+        $this->container['user'] = $this
+            ->getMockBuilder('\Model\User')
+            ->setConstructorArgs(array($this->container))
+            ->setMethods(array('getByUsername'))
+            ->getMock();
+
+        $ldap = $this
+            ->getMockBuilder('\Auth\Ldap')
+            ->setConstructorArgs(array($this->container))
+            ->setMethods(array('findUser', 'createUser'))
+            ->getMock();
+
+        $ldap
+            ->expects($this->at(0))
+            ->method('findUser')
+            ->with(
+                $this->equalTo('user'),
+                $this->equalTo('password')
+            )
+            ->will($this->returnValue(array('username' => 'user', 'name' => 'My user', 'email' => 'user@here')));
+
+        $ldap
+            ->expects($this->at(1))
+            ->method('createUser')
+            ->with(
+                $this->equalTo('user'),
+                $this->equalTo('My user'),
+                $this->equalTo('user@here')
+            )
+            ->will($this->returnValue(true));
+
+        $this->container['user']
+            ->expects($this->at(0))
+            ->method('getByUsername')
+            ->with(
+                $this->equalTo('user')
+            )
+            ->will($this->returnValue(null));
+
+        $this->container['user']
+            ->expects($this->at(1))
+            ->method('getByUsername')
+            ->with(
+                $this->equalTo('user')
+            )
+            ->will($this->returnValue(array('id' => 2, 'username' => 'user', 'is_ldap_user' => 1)));
+
+        $this->container['userSession']
+            ->expects($this->once())
+            ->method('refresh');
+
+        $this->assertTrue($ldap->authenticate('user', 'password'));
+    }
+
+    public function testAuthenticationWithAutomaticAccountCreationFailed()
+    {
+        $this->container['userSession'] = $this
+            ->getMockBuilder('\Model\UserSession')
+            ->setConstructorArgs(array($this->container))
+            ->setMethods(array('refresh'))
+            ->getMock();
+
+        $this->container['user'] = $this
+            ->getMockBuilder('\Model\User')
+            ->setConstructorArgs(array($this->container))
+            ->setMethods(array('getByUsername'))
+            ->getMock();
+
+        $ldap = $this
+            ->getMockBuilder('\Auth\Ldap')
+            ->setConstructorArgs(array($this->container))
+            ->setMethods(array('findUser', 'createUser'))
+            ->getMock();
+
+        $ldap
+            ->expects($this->at(0))
+            ->method('findUser')
+            ->with(
+                $this->equalTo('user'),
+                $this->equalTo('password')
+            )
+            ->will($this->returnValue(array('username' => 'user', 'name' => 'My user', 'email' => 'user@here')));
+
+        $ldap
+            ->expects($this->at(1))
+            ->method('createUser')
+            ->with(
+                $this->equalTo('user'),
+                $this->equalTo('My user'),
+                $this->equalTo('user@here')
+            )
+            ->will($this->returnValue(false));
+
+        $this->container['user']
+            ->expects($this->once())
+            ->method('getByUsername')
+            ->with(
+                $this->equalTo('user')
+            )
+            ->will($this->returnValue(null));
+
+        $this->container['userSession']
+            ->expects($this->never())
+            ->method('refresh');
+
+        $this->assertFalse($ldap->authenticate('user', 'password'));
     }
 }
diff --git a/tests/units/Auth/ReverseProxyTest.php b/tests/units/Auth/ReverseProxyTest.php
new file mode 100644
index 00000000..bbab7c0d
--- /dev/null
+++ b/tests/units/Auth/ReverseProxyTest.php
@@ -0,0 +1,37 @@
+<?php
+
+require_once __DIR__.'/../Base.php';
+
+use Auth\ReverseProxy;
+use Model\User;
+
+class ReverseProxyTest extends Base
+{
+    public function setUp()
+    {
+        parent::setup();
+        $_SERVER = array();
+    }
+
+    public function testFailedAuthentication()
+    {
+        $auth = new ReverseProxy($this->container);
+        $this->assertFalse($auth->authenticate());
+    }
+
+    public function testSuccessfulAuthentication()
+    {
+        $_SERVER[REVERSE_PROXY_USER_HEADER] = 'my_user';
+
+        $a = new ReverseProxy($this->container);
+        $u = new User($this->container);
+
+        $this->assertTrue($a->authenticate());
+
+        $user = $u->getByUsername('my_user');
+        $this->assertNotEmpty($user);
+        $this->assertEquals(0, $user['is_admin']);
+        $this->assertEquals(1, $user['is_ldap_user']);
+        $this->assertEquals(1, $user['disable_login_form']);
+    }
+}
diff --git a/tests/units/Base.php b/tests/units/Base.php
index a48ae5ec..0a045a09 100644
--- a/tests/units/Base.php
+++ b/tests/units/Base.php
@@ -1,9 +1,6 @@
 <?php
 
 require __DIR__.'/../../vendor/autoload.php';
-
-define('LDAP_SERVER', 'my_ldap_server');
-
 require __DIR__.'/../../app/constants.php';
 
 use Symfony\Component\EventDispatcher\EventDispatcher;
-- 
cgit v1.2.3