diff --git a/src/Ltb/Directory/OpenLDAP.php b/src/Ltb/Directory/OpenLDAP.php index 1a4bbb2..b8f6fb4 100644 --- a/src/Ltb/Directory/OpenLDAP.php +++ b/src/Ltb/Directory/OpenLDAP.php @@ -221,18 +221,57 @@ public function resetAtNextConnection($ldap, $dn) : bool { } public function enableAccount($ldap, $dn) : bool { - // Not implemented - return false; + + $attrsToDelete = array( 'pwdAccountDisabled' => array() ); + + $update = \Ltb\PhpLDAP::ldap_mod_replace($ldap, $dn, $attrsToDelete); + $errno = \Ltb\PhpLDAP::ldap_errno($ldap); + + if ($errno) { + error_log("LDAP - Enabling account error $errno (".\Ltb\PhpLDAP::ldap_error($ldap).")"); + return false; + } else { + return true; + } } public function disableAccount($ldap, $dn) : bool { - // Not implemented - return false; + + # Date of disabling + $currentDate = gmdate("YmdHis")."Z"; + + $attrs = array( 'pwdAccountDisabled' => array($currentDate) ); + + $update = \Ltb\PhpLDAP::ldap_mod_replace($ldap, $dn, $attrs); + $errno = \Ltb\PhpLDAP::ldap_errno($ldap); + + if ($errno) { + error_log("LDAP - Disabling account error $errno (".\Ltb\PhpLDAP::ldap_error($ldap).")"); + return false; + } else { + return true; + } } public function isAccountEnabled($ldap, $dn) : bool { - // Not implemented - return true; + + # Get entry + $search = \Ltb\PhpLDAP::ldap_read($ldap, $dn, "(objectClass=*)", array('pwdAccountDisabled')); + $errno = \Ltb\PhpLDAP::ldap_errno($ldap); + + if ( $errno ) { + error_log("LDAP - Search error $errno (".\Ltb\PhpLDAP::ldap_error($ldap).")"); + return false; + } else { + $entry = \Ltb\PhpLDAP::ldap_get_entries($ldap, $search); + } + + if (empty($entry[0]['pwdaccountdisabled'][0])) { + return true; + } else { + return false; + } + } public function getLdapDate($date) : string { diff --git a/tests/Ltb/DirectoryTest.php b/tests/Ltb/DirectoryTest.php index e4ce2f4..4620fa1 100644 --- a/tests/Ltb/DirectoryTest.php +++ b/tests/Ltb/DirectoryTest.php @@ -1,6 +1,6 @@ -assertFalse($accountEnabled, "Account should be disabled"); } + public function test_openldap_isenabled_true(): void + { + + $ldap = "ldap_connection"; + $dn = "cn=dummy,dc=my-domain,dc=com"; + $search_result = "search_result"; + + $phpLDAPMock = Mockery::mock('overload:Ltb\PhpLDAP'); + + $phpLDAPMock->shouldreceive('ldap_read') + ->with($ldap, $dn, "(objectClass=*)", array('pwdAccountDisabled')) + ->andReturn($search_result); + + $phpLDAPMock->shouldreceive('ldap_errno') + ->with($ldap) + ->andReturn(false); + + $phpLDAPMock->shouldreceive('ldap_get_entries') + ->with($ldap, $search_result) + ->andReturn([ + 'count' => 1, + 0 => [ + 'count' => 0, + 'dn' => 'uid=test,ou=people,dc=my-domain,dc=com', + ] + ]); + + $accountEnabled = (new Ltb\Directory\OpenLDAP)->isAccountEnabled($ldap, $dn); + $this->assertTrue($accountEnabled, "OpenLDAP account should be enabled"); + } + + public function test_openldap_isenabled_false(): void + { + + $ldap = "ldap_connection"; + $dn = "cn=dummy,dc=my-domain,dc=com"; + $search_result = "search_result"; + + $phpLDAPMock = Mockery::mock('overload:Ltb\PhpLDAP'); + + $phpLDAPMock->shouldreceive('ldap_read') + ->with($ldap, $dn, "(objectClass=*)", array('pwdAccountDisabled')) + ->andReturn($search_result); + + $phpLDAPMock->shouldreceive('ldap_errno') + ->with($ldap) + ->andReturn(false); + + $phpLDAPMock->shouldreceive('ldap_get_entries') + ->with($ldap, $search_result) + ->andReturn( + [ + 'count' => 1, + 0 => + [ + 'pwdaccountdisabled' => + [ + 'count' => 1, + 0 => '00000101000000Z', + ], + 0 => 'pwdaccountdisabled', + 'count' => 1, + 'dn' => 'uid=test,ou=people,dc=my-domain,dc=com', + ], + ] + ); + + $accountEnabled = (new Ltb\Directory\OpenLDAP)->isAccountEnabled($ldap, $dn); + $this->assertFalse($accountEnabled, "OpenLDAP account should be disabled"); + } + + public function test_openldap_isenabled_error(): void + { + + $ldap = "ldap_connection"; + $dn = "invaliddn"; + $search_result = "search_result"; + + $phpLDAPMock = Mockery::mock('overload:Ltb\PhpLDAP'); + + $phpLDAPMock->shouldreceive('ldap_read') + ->with($ldap, $dn, "(objectClass=*)", array('pwdAccountDisabled')) + ->andReturn($search_result); + + $phpLDAPMock->shouldreceive('ldap_errno') + ->with($ldap) + ->andReturn(34); + + $phpLDAPMock->shouldreceive('ldap_error') + ->with($ldap) + ->andReturn("Invalid DN syntax"); + + + $accountEnabled = (new Ltb\Directory\OpenLDAP)->isAccountEnabled($ldap, $dn); + $this->assertFalse($accountEnabled, "OpenLDAP account should be considered disabled while error is encountered"); + } + + public function test_openldap_enable_account_ok(): void + { + $ldap = "ldap_connection"; + $dn = "cn=dummy,dc=my-domain,dc=com"; + $update_result = "update_result"; + + $phpLDAPMock = Mockery::mock('overload:Ltb\PhpLDAP'); + + $phpLDAPMock->shouldreceive('ldap_mod_replace') + ->with($ldap, $dn, [ 'pwdAccountDisabled' => [] ]) + ->andReturn($update_result); + + $phpLDAPMock->shouldreceive('ldap_errno') + ->with($ldap) + ->andReturn(0); + + $enableAccountResult = (new Ltb\Directory\OpenLDAP)->enableAccount($ldap, $dn); + $this->assertTrue($enableAccountResult, "Error while enabling OpenLDAP account"); + } + + public function test_openldap_enable_account_ko(): void + { + $ldap = "ldap_connection"; + $dn = "cn=dummy,dc=my-domain,dc=com"; + $update_result = "update_result"; + + $phpLDAPMock = Mockery::mock('overload:Ltb\PhpLDAP'); + + $phpLDAPMock->shouldreceive('ldap_mod_replace') + ->with($ldap, $dn, [ 'pwdAccountDisabled' => [] ]) + ->andReturn($update_result); + + $phpLDAPMock->shouldreceive('ldap_errno') + ->with($ldap) + ->andReturn(50); + + $phpLDAPMock->shouldreceive('ldap_error') + ->with($ldap) + ->andReturn("Insufficient rights"); + + $enableAccountResult = (new Ltb\Directory\OpenLDAP)->enableAccount($ldap, $dn); + $this->assertFalse($enableAccountResult, "Should have encountered error while enabling OpenLDAP account"); + } + + public function test_openldap_disable_account_ok(): void + { + $ldap = "ldap_connection"; + $dn = "cn=dummy,dc=my-domain,dc=com"; + $update_result = "update_result"; + + $phpLDAPMock = Mockery::mock('overload:Ltb\PhpLDAP'); + + $phpLDAPMock->shouldreceive('ldap_mod_replace') + ->with( + $ldap, + $dn, + \Mockery::on(function ($mod) { + if( preg_match('/^[0-9]{14}Z$/', $mod['pwdAccountDisabled'][0]) ) + return true; + else + return false; + }) + ) + ->andReturn($update_result); + + $phpLDAPMock->shouldreceive('ldap_errno') + ->with($ldap) + ->andReturn(0); + + $disableAccountResult = (new Ltb\Directory\OpenLDAP)->disableAccount($ldap, $dn); + $this->assertTrue($disableAccountResult, "Error while disabling OpenLDAP account"); + } + + public function test_openldap_disable_account_ko(): void + { + $ldap = "ldap_connection"; + $dn = "cn=dummy,dc=my-domain,dc=com"; + $update_result = "update_result"; + + $phpLDAPMock = Mockery::mock('overload:Ltb\PhpLDAP'); + + $phpLDAPMock->shouldreceive('ldap_mod_replace') + ->with( + $ldap, + $dn, + \Mockery::on(function ($mod) { + if( preg_match('/^[0-9]{14}Z$/', $mod['pwdAccountDisabled'][0]) ) + return true; + else + return false; + }) + ) + ->andReturn($update_result); + + $phpLDAPMock->shouldreceive('ldap_errno') + ->with($ldap) + ->andReturn(50); + + $phpLDAPMock->shouldreceive('ldap_error') + ->with($ldap) + ->andReturn("Insufficient rights"); + + $disableAccountResult = (new Ltb\Directory\OpenLDAP)->disableAccount($ldap, $dn); + $this->assertFalse($disableAccountResult, "Should have encountered error while disabling OpenLDAP account"); + } + }