diff --git a/composer.json b/composer.json index 58c2b6bedc..2a456999e9 100644 --- a/composer.json +++ b/composer.json @@ -74,6 +74,9 @@ "unicodeveloper/laravel-password": "^1.0", "watson/validating": "^6.1" }, + "suggest": { + "ext-ldap": "*" + }, "require-dev": { "brianium/paratest": "^6.6", "fakerphp/faker": "^1.16", diff --git a/tests/Support/Settings.php b/tests/Support/Settings.php index 0ca05a4752..30fe8c7017 100644 --- a/tests/Support/Settings.php +++ b/tests/Support/Settings.php @@ -79,6 +79,28 @@ class Settings ]); } + public function enableAnonymousLdap(): Settings + { + return $this->update([ + 'ldap_enabled' => 1, + 'ldap_server' => 'ldaps://ldap.example.com', +// 'ldap_uname' => 'fake_username', + 'ldap_pword' => Crypt::encrypt("fake_password"), + 'ldap_basedn' => 'CN=Users,DC=ad,DC=example,Dc=com' + ]); + } + + public function enableBadPasswordLdap(): Settings + { + return $this->update([ + 'ldap_enabled' => 1, + 'ldap_server' => 'ldaps://ldap.example.com', + 'ldap_uname' => 'fake_username', + 'ldap_pword' => "badly_encrypted_password!", + 'ldap_basedn' => 'CN=Users,DC=ad,DC=example,Dc=com' + ]); + } + /** * @param array $attributes Attributes to modify in the application's settings. */ diff --git a/tests/Unit/LdapTest.php b/tests/Unit/LdapTest.php index 7b94f1aac5..78e829c6e9 100644 --- a/tests/Unit/LdapTest.php +++ b/tests/Unit/LdapTest.php @@ -3,6 +3,7 @@ namespace Tests\Unit; use App\Models\Ldap; +use Exception; use Tests\Support\InteractsWithSettings; use Tests\TestCase; @@ -25,4 +26,83 @@ class LdapTest extends TestCase $blah = Ldap::connectToLdap(); $this->assertEquals('hello',$blah,"LDAP_connect should return 'hello'"); } + + // other test cases - with/without client-side certs? + // with/without LDAP version 3? + // with/without ignore cert validation? + // test (and mock) ldap_start_tls() ? + + public function testBindAdmin() + { + $this->settings->enableLdap(); + $this->getFunctionMock("App\\Models", "ldap_bind")->expects($this->once())->willReturn(true); + $this->assertNull(Ldap::bindAdminToLdap("dummy")); + } + + public function testBindBad() + { + $this->settings->enableLdap(); + $this->getFunctionMock("App\\Models", "ldap_bind")->expects($this->once())->willReturn(false); + $this->getFunctionMock("App\\Models","ldap_error")->expects($this->once())->willReturn("exception"); + $this->expectExceptionMessage("Could not bind to LDAP:"); + + $this->assertNull(Ldap::bindAdminToLdap("dummy")); + } + // other test cases - test donked password? + + public function testAnonymousBind() + { + //todo - would be nice to introspect somehow to make sure the right parameters were passed? + $this->settings->enableAnonymousLdap(); + $this->getFunctionMock("App\\Models", "ldap_bind")->expects($this->once())->willReturn(true); + $this->assertNull(Ldap::bindAdminToLdap("dummy")); + } + + public function testBadAnonymousBind() + { + $this->settings->enableAnonymousLdap(); + $this->getFunctionMock("App\\Models", "ldap_bind")->expects($this->once())->willReturn(false); + $this->getFunctionMock("App\\Models","ldap_error")->expects($this->once())->willReturn("exception"); + $this->expectExceptionMessage("Could not bind to LDAP:"); + + $this->assertNull(Ldap::bindAdminToLdap("dummy")); + } + + public function testBadEncryptedPassword() + { + $this->settings->enableBadPasswordLdap(); + + $this->expectExceptionMessage("Your app key has changed"); + $this->assertNull(Ldap::bindAdminToLdap("dummy")); + } + + public function testFindAndBind() + { + $this->settings->enableLdap(); + + $ldap_connect = $this->getFunctionMock("App\\Models", "ldap_connect"); + $ldap_connect->expects($this->once())->willReturn('hello'); + + $ldap_set_option = $this->getFunctionMock("App\\Models", "ldap_set_option"); + $ldap_set_option->expects($this->exactly(3)); + + $this->getFunctionMock("App\\Models", "ldap_bind")->expects($this->once())->willReturn(true); + + $this->getFunctionMock("App\\Models", "ldap_search")->expects($this->once())->willReturn(true); + + $this->getFunctionMock("App\\Models", "ldap_first_entry")->expects($this->once())->willReturn(true); + + $this->getFunctionMock("App\\Models", "ldap_get_attributes")->expects($this->once())->willReturn( + [ + "count" => 1, + 0 => [ + 'sn' => 'Surname', + 'firstName' => 'FirstName' + ] + ] + ); + + $results = Ldap::findAndBindUserLdap("username","password"); + $this->assertEqualsCanonicalizing(["count" =>1,0 =>['sn' => 'Surname','firstname' => 'FirstName']],$results); + } }