Merge pull request #1428 from pipoprods/feat/ldap-auth

This commit is contained in:
ArthurHoaro 2020-06-25 16:53:18 +02:00 committed by GitHub
commit 78c2f122e0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 117 additions and 13 deletions

View file

@ -1,6 +1,7 @@
<?php <?php
namespace Shaarli\Security; namespace Shaarli\Security;
use Exception;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
/** /**
@ -139,11 +140,34 @@ public function isLoggedIn()
*/ */
public function checkCredentials($remoteIp, $clientIpId, $login, $password) public function checkCredentials($remoteIp, $clientIpId, $login, $password)
{ {
$hash = sha1($password . $login . $this->configManager->get('credentials.salt')); // Check login matches config
if ($login !== $this->configManager->get('credentials.login')) {
return false;
}
if ($login != $this->configManager->get('credentials.login') // Check credentials
|| $hash != $this->configManager->get('credentials.hash') try {
$useLdapLogin = !empty($this->configManager->get('ldap.host'));
if ((false === $useLdapLogin && $this->checkCredentialsFromLocalConfig($login, $password))
|| (true === $useLdapLogin && $this->checkCredentialsFromLdap($login, $password))
) { ) {
$this->sessionManager->storeLoginInfo($clientIpId);
logm(
$this->configManager->get('resource.log'),
$remoteIp,
'Login successful'
);
return true;
}
}
catch(Exception $exception) {
logm(
$this->configManager->get('resource.log'),
$remoteIp,
'Exception while checking credentials: ' . $exception
);
}
logm( logm(
$this->configManager->get('resource.log'), $this->configManager->get('resource.log'),
$remoteIp, $remoteIp,
@ -152,13 +176,50 @@ public function checkCredentials($remoteIp, $clientIpId, $login, $password)
return false; return false;
} }
$this->sessionManager->storeLoginInfo($clientIpId);
logm( /**
$this->configManager->get('resource.log'), * Check user credentials from local config
$remoteIp, *
'Login successful' * @param string $login Username
* @param string $password Password
*
* @return bool true if the provided credentials are valid, false otherwise
*/
public function checkCredentialsFromLocalConfig($login, $password) {
$hash = sha1($password . $login . $this->configManager->get('credentials.salt'));
return $login == $this->configManager->get('credentials.login')
&& $hash == $this->configManager->get('credentials.hash');
}
/**
* Check user credentials are valid through LDAP bind
*
* @param string $remoteIp Remote client IP address
* @param string $clientIpId Client IP address identifier
* @param string $login Username
* @param string $password Password
*
* @return bool true if the provided credentials are valid, false otherwise
*/
public function checkCredentialsFromLdap($login, $password, $connect = null, $bind = null)
{
$connect = $connect ?? function($host) {
$resource = ldap_connect($host);
ldap_set_option($resource, LDAP_OPT_PROTOCOL_VERSION, 3);
return $resource;
};
$bind = $bind ?? function($handle, $dn, $password) {
return ldap_bind($handle, $dn, $password);
};
return $bind(
$connect($this->configManager->get('ldap.host')),
sprintf($this->configManager->get('ldap.dn'), $login),
$password
); );
return true;
} }
/** /**

View file

@ -122,6 +122,11 @@ Must be an associative array: `translation domain => translation path`.
- **enable_thumbnails**: Enable or disable thumbnail display. - **enable_thumbnails**: Enable or disable thumbnail display.
- **enable_localcache**: Enable or disable local cache. - **enable_localcache**: Enable or disable local cache.
### LDAP
- **host**: LDAP host used for user authentication
- **dn**: user DN template (`sprintf` format, `%s` being replaced by user login)
## Configuration file example ## Configuration file example
```json ```json
@ -223,6 +228,10 @@ Must be an associative array: `translation domain => translation path`.
"extensions": { "extensions": {
"demo": "plugins/demo_plugin/languages/" "demo": "plugins/demo_plugin/languages/"
} }
},
"ldap": {
"host": "ldap://localhost",
"dn": "uid=%s,ou=people,dc=example,dc=org"
} }
} ?> } ?>
``` ```

View file

@ -78,6 +78,7 @@ public function setUp()
'security.ban_after' => 2, 'security.ban_after' => 2,
'security.ban_duration' => 3600, 'security.ban_duration' => 3600,
'security.trusted_proxies' => [$this->trustedProxy], 'security.trusted_proxies' => [$this->trustedProxy],
'ldap.host' => '',
]); ]);
$this->cookie = []; $this->cookie = [];
@ -296,4 +297,37 @@ public function testCheckCredentialsGoodLoginAndPassword()
$this->loginManager->checkCredentials('', '', $this->login, $this->password) $this->loginManager->checkCredentials('', '', $this->login, $this->password)
); );
} }
/**
* Check user credentials through LDAP - server unreachable
*/
public function testCheckCredentialsFromUnreachableLdap()
{
$this->configManager->set('ldap.host', 'dummy');
$this->assertFalse(
$this->loginManager->checkCredentials('', '', $this->login, $this->password)
);
}
/**
* Check user credentials through LDAP - wrong login and password supplied
*/
public function testCheckCredentialsFromLdapWrongLoginAndPassword()
{
$this->configManager->set('ldap.host', 'dummy');
$this->assertFalse(
$this->loginManager->checkCredentialsFromLdap($this->login, $this->password, function() { return null; }, function() { return false; })
);
}
/**
* Check user credentials through LDAP - correct login and password supplied
*/
public function testCheckCredentialsFromLdapGoodLoginAndPassword()
{
$this->configManager->set('ldap.host', 'dummy');
$this->assertTrue(
$this->loginManager->checkCredentialsFromLdap($this->login, $this->password, function() { return null; }, function() { return true; })
);
}
} }