From 511df43fb7cee3ad6f64557d9516fc99179bab4d Mon Sep 17 00:00:00 2001 From: Lucas Bartholemy Date: Wed, 13 Mar 2019 22:06:32 +0100 Subject: [PATCH] LDAP module improvements --- protected/humhub/libs/SelfTest.php | 4 +- protected/humhub/models/Setting.php | 4 - .../modules/installer/libs/InitialData.php | 1 - protected/humhub/modules/ldap/Events.php | 21 +- protected/humhub/modules/ldap/Module.php | 1 - .../modules/ldap/authclient/LdapAuth.php | 152 ++++++++----- protected/humhub/modules/ldap/config.php | 2 + .../ldap/controllers/AdminController.php | 20 +- .../modules/ldap/helpers/LdapHelper.php | 42 +--- .../m190309_201944_rename_settings.php | 69 ++++++ .../modules/ldap/models/LdapSettings.php | 203 ++++++++++++++---- .../humhub/modules/ldap/views/admin/index.php | 2 +- .../modules/user/authclient/Collection.php | 16 +- 13 files changed, 365 insertions(+), 172 deletions(-) create mode 100644 protected/humhub/modules/ldap/migrations/m190309_201944_rename_settings.php diff --git a/protected/humhub/libs/SelfTest.php b/protected/humhub/libs/SelfTest.php index f7fd096d19..d7ba2d96ae 100644 --- a/protected/humhub/libs/SelfTest.php +++ b/protected/humhub/libs/SelfTest.php @@ -8,7 +8,7 @@ namespace humhub\libs; -use humhub\modules\user\authclient\ZendLdapClient; +use humhub\modules\ldap\helpers\LdapHelper; use Yii; /** @@ -249,7 +249,7 @@ class SelfTest // Checks LDAP Extension $title = 'LDAP Support'; - if (ZendLdapClient::isLdapAvailable()) { + if (LdapHelper::isLdapAvailable()) { $checks[] = [ 'title' => Yii::t('base', $title), 'state' => 'OK' diff --git a/protected/humhub/models/Setting.php b/protected/humhub/models/Setting.php index 39f1127771..d1963c41b2 100644 --- a/protected/humhub/models/Setting.php +++ b/protected/humhub/models/Setting.php @@ -136,10 +136,6 @@ class Setting extends ActiveRecord return ['allowGuestAccess', 'user']; } elseif ($name == 'defaultUserGroup' && $moduleId == 'authentication_internal') { return ['auth.allowGuestAccess', 'user']; - } elseif ($name == 'enabled' && $moduleId == 'authentication_ldap') { - return ['auth.ldap.enabled', 'user']; - } elseif ($name == 'enabled' && $moduleId == 'authentication_ldap') { - return ['auth.ldap.enabled', 'user']; } elseif ($name == 'systemEmailAddress' && $moduleId == 'mailing') { return ['mailer.systemEmailAddress', 'user']; } elseif ($name == 'systemEmailName' && $moduleId == 'mailing') { diff --git a/protected/humhub/modules/installer/libs/InitialData.php b/protected/humhub/modules/installer/libs/InitialData.php index 8381c83670..39e04a8923 100644 --- a/protected/humhub/modules/installer/libs/InitialData.php +++ b/protected/humhub/modules/installer/libs/InitialData.php @@ -38,7 +38,6 @@ class InitialData Yii::$app->settings->set('cronLastDailyRun', time()); // Authentication - Yii::$app->getModule('user')->settings->set('auth.ldap.refreshUsers', '1'); Yii::$app->getModule('user')->settings->set('auth.needApproval', '0'); Yii::$app->getModule('user')->settings->set('auth.anonymousRegistration', '1'); Yii::$app->getModule('user')->settings->set('auth.internalUsersCanInvite', '1'); diff --git a/protected/humhub/modules/ldap/Events.php b/protected/humhub/modules/ldap/Events.php index 2e0acfaf5c..4710d31b92 100644 --- a/protected/humhub/modules/ldap/Events.php +++ b/protected/humhub/modules/ldap/Events.php @@ -7,6 +7,9 @@ namespace humhub\modules\ldap; +use humhub\components\Event; +use humhub\modules\ldap\models\LdapSettings; +use humhub\modules\user\authclient\Collection; use Yii; use yii\base\BaseObject; use yii\helpers\Url; @@ -19,7 +22,7 @@ use yii\helpers\Url; class Events extends BaseObject { /** - * @param $event + * @param $event Event */ public static function onAuthenticationMenu($event) { @@ -30,4 +33,20 @@ class Events extends BaseObject 'isActive' => (Yii::$app->controller->module && Yii::$app->controller->module->id == 'ldap' && Yii::$app->controller->id == 'admin'), ]); } + + /** + * @param $event Event + */ + public static function onAuthClientCollectionSet($event) + { + if (LdapSettings::isEnabled()) { + + /** @var Collection $collection */ + $collection = $event->sender; + + $settings = new LdapSettings(); + $settings->loadSaved(); + $collection->setClient('ldap', $settings->getLdapAuth()); + } + } } diff --git a/protected/humhub/modules/ldap/Module.php b/protected/humhub/modules/ldap/Module.php index 4abd2ad196..552a3739b7 100644 --- a/protected/humhub/modules/ldap/Module.php +++ b/protected/humhub/modules/ldap/Module.php @@ -19,5 +19,4 @@ class Module extends \humhub\components\Module */ public $controllerNamespace = 'humhub\modules\ldap\controllers'; - } diff --git a/protected/humhub/modules/ldap/authclient/LdapAuth.php b/protected/humhub/modules/ldap/authclient/LdapAuth.php index 9bf0aa285e..718c5b24d2 100644 --- a/protected/humhub/modules/ldap/authclient/LdapAuth.php +++ b/protected/humhub/modules/ldap/authclient/LdapAuth.php @@ -6,12 +6,12 @@ * @license https://www.humhub.com/licences */ -namespace humhub\modules\user\authclient; +namespace humhub\modules\ldap\authclient; use DateTime; -use humhub\components\SettingsManager; use humhub\libs\StringHelper; -use humhub\modules\ldap\helpers\LdapHelper; +use humhub\modules\user\authclient\AuthClientHelpers; +use humhub\modules\user\authclient\BaseFormAuth; use humhub\modules\user\authclient\interfaces\ApprovalBypass; use humhub\modules\user\authclient\interfaces\AutoSyncUsers; use humhub\modules\user\authclient\interfaces\PrimaryClient; @@ -39,6 +39,61 @@ class LdapAuth extends BaseFormAuth implements AutoSyncUsers, SyncAttributes, Ap */ private $_ldap = null; + /** + * @var string the auth client id + */ + public $clientId = 'ldap'; + + /** + * The hostname of LDAP server that these options represent. This option is required. + * + * @var string + */ + public $hostname; + + /** + * The port on which the LDAP server is listening. + * + * @var int 389 + */ + public $port; + + /** + * Whether or not the LDAP client should use SSL encrypted transport. + * The useSsl and useStartTls options are mutually exclusive, but useStartTls should be favored + * if the server and LDAP client library support it. + * + * @var boolean + */ + public $useSsl = false; + + /** + * Whether or not the LDAP client should use TLS (aka SSLv2) encrypted transport. + * A value of TRUE is strongly favored in production environments to prevent passwords from be transmitted in clear text. + * + * The default value is FALSE, as servers frequently require that a certificate be installed separately after installation. + * The useSsl and useStartTls options are mutually exclusive. + * The useStartTls option should be favored over useSsl but not all servers support this newer mechanism. + * + * @var boolean + */ + public $useStartTls = false; + + /** + * The DN of the account used to perform account DN lookups. + * LDAP servers that require the username to be in DN form when performing the “bind” require this option. + * + * @var string + */ + public $bindUsername; + + /** + * The password of the account used to perform account DN lookups. + * + * @var string + */ + public $bindPassword; + /** * ID attribute to uniquely identify user. * If set to null, automatically a value email or objectguid will be used if available. @@ -67,6 +122,14 @@ class LdapAuth extends BaseFormAuth implements AutoSyncUsers, SyncAttributes, Ap */ public $userFilter = null; + /** + * The LDAP search filter used to search for accounts. + * This string is a printf()-style expression that must contain one ‘%s’ to accommodate the username. + * + * @var string the login filter + */ + public $loginFilter = null; + /** * Automatically refresh user profiles on cron run * @@ -91,45 +154,20 @@ class LdapAuth extends BaseFormAuth implements AutoSyncUsers, SyncAttributes, Ap { parent::init(); - /** @var SettingsManager $settings */ - $settings = Yii::$app->getModule('user')->settings; - - if ($this->idAttribute === null) { - $idAttribute = $settings->get('auth.ldap.idAttribute'); - if (!empty($idAttribute)) { - $this->idAttribute = strtolower($idAttribute); - } + if (empty($this->idAttribute)) { + $this->idAttribute = null; } + $this->idAttribute = strtolower($this->idAttribute); - if ($this->usernameAttribute === null) { - $usernameAttribute = $settings->get('auth.ldap.usernameAttribute'); - if (!empty($usernameAttribute)) { - $this->usernameAttribute = strtolower($usernameAttribute); - } else { - $this->usernameAttribute = 'samaccountname'; - } + if (empty($this->usernameAttribute)) { + $this->usernameAttribute = 'samaccountname'; } + $this->usernameAttribute = strtolower($this->usernameAttribute); - if ($this->emailAttribute === null) { - $emailAttribute = $settings->get('auth.ldap.emailAttribute'); - if (!empty($emailAttribute)) { - $this->emailAttribute = strtolower($emailAttribute); - } else { - $this->emailAttribute = 'mail'; - } - } - - if ($this->userFilter === null) { - $this->userFilter = $settings->get('auth.ldap.userFilter'); - } - - if ($this->baseDn === null) { - $this->baseDn = $settings->get('auth.ldap.baseDn'); - } - - if ($this->autoRefreshUsers === null) { - $this->autoRefreshUsers = (boolean) $settings->get('auth.ldap.refreshUsers'); + if (empty($this->emailAttribute)) { + $this->emailAttribute = 'mail'; } + $this->emailAttribute = strtolower($this->emailAttribute); } /** @@ -137,7 +175,7 @@ class LdapAuth extends BaseFormAuth implements AutoSyncUsers, SyncAttributes, Ap */ public function getId() { - return 'ldap'; + return $this->clientId; } /** @@ -145,7 +183,7 @@ class LdapAuth extends BaseFormAuth implements AutoSyncUsers, SyncAttributes, Ap */ protected function defaultName() { - return 'ldap'; + return $this->clientId; } /** @@ -153,7 +191,7 @@ class LdapAuth extends BaseFormAuth implements AutoSyncUsers, SyncAttributes, Ap */ protected function defaultTitle() { - return 'LDAP'; + return 'LDAP (' . $this->clientId . ')'; } /** @@ -168,7 +206,7 @@ class LdapAuth extends BaseFormAuth implements AutoSyncUsers, SyncAttributes, Ap * Find user based on ldap attributes * * @inheritdoc - * @see interfaces\PrimaryClient + * @see PrimaryClient * @return User the user */ public function getUser() @@ -360,11 +398,26 @@ class LdapAuth extends BaseFormAuth implements AutoSyncUsers, SyncAttributes, Ap * Returns Zend LDAP * * @return \Zend\Ldap\Ldap + * @throws LdapException */ public function getLdap() { if ($this->_ldap === null) { - $this->_ldap = LdapHelper::getLdapConnection(); + + $options = [ + 'host' => $this->hostname, + 'port' => $this->port, + 'username' => $this->bindUsername, + 'password' => $this->bindPassword, + 'useStartTls' => $this->useStartTls, + 'useSsl' => $this->useSsl, + 'bindRequiresDn' => true, + 'baseDn' => $this->baseDn, + 'accountFilterFormat' => $this->loginFilter, + ]; + + $this->_ldap = new Ldap($options); + $this->_ldap->bind(); } return $this->_ldap; @@ -403,7 +456,7 @@ class LdapAuth extends BaseFormAuth implements AutoSyncUsers, SyncAttributes, Ap */ public function syncUsers() { - if (!LdapHelper::isLdapEnabled() || !$this->autoRefreshUsers) { + if ($this->autoRefreshUsers !== true) { return; } @@ -459,23 +512,12 @@ class LdapAuth extends BaseFormAuth implements AutoSyncUsers, SyncAttributes, Ap } } - /** - * Checks if LDAP is supported - * - * @deprecated since version 1.2.3 - * @return boolean is LDAP supported (drivers, modules) - */ - public static function isLdapAvailable() - { - return LdapHelper::isLdapAvailable(); - } - /** * @param array $normalizeUserAttributeMap normalize user attribute map. */ public function setNormalizeUserAttributeMap($normalizeUserAttributeMap) { - // This method is called if an additional attribute mapping is specifed in the configuration file + // This method is called if an additional attribute mapping is specified in the configuration file // So automatically merge HumHub auto mapping with the given one $this->init(); // defaultNormalizeAttributeMap is available after init parent::setNormalizeUserAttributeMap(ArrayHelper::merge($this->defaultNormalizeUserAttributeMap(), $normalizeUserAttributeMap)); diff --git a/protected/humhub/modules/ldap/config.php b/protected/humhub/modules/ldap/config.php index c184a521fc..a0c065b231 100644 --- a/protected/humhub/modules/ldap/config.php +++ b/protected/humhub/modules/ldap/config.php @@ -7,6 +7,7 @@ use humhub\modules\admin\widgets\AuthenticationMenu; use humhub\modules\ldap\Events; +use humhub\modules\user\authclient\Collection; /** @noinspection MissedFieldInspection */ return [ @@ -15,6 +16,7 @@ return [ 'isCoreModule' => true, 'events' => [ [AuthenticationMenu::class, AuthenticationMenu::EVENT_INIT, [Events::class, 'onAuthenticationMenu']], + [Collection::class, Collection::EVENT_AFTER_CLIENTS_SET, [Events::class, 'onAuthClientCollectionSet']] ] ]; ?> diff --git a/protected/humhub/modules/ldap/controllers/AdminController.php b/protected/humhub/modules/ldap/controllers/AdminController.php index 215c6f6023..2a72158504 100644 --- a/protected/humhub/modules/ldap/controllers/AdminController.php +++ b/protected/humhub/modules/ldap/controllers/AdminController.php @@ -41,11 +41,9 @@ class AdminController extends Controller */ public function actionIndex() { - /** @var SettingsManager $settings */ - $settings = Yii::$app->getModule('user')->settings; - - $form = new LdapSettings(); - if ($form->load(Yii::$app->request->post()) && $form->validate() && $form->save()) { + $settings = new LdapSettings(); + $settings->loadSaved(); + if ($settings->load(Yii::$app->request->post()) && $settings->validate() && $settings->save()) { $this->view->saved(); return $this->redirect(['/ldap/admin']); } @@ -54,16 +52,12 @@ class AdminController extends Controller $userCount = 0; $errorMessage = ""; - if ($settings->get('auth.ldap.enabled')) { + if ($settings->enabled) { $enabled = true; try { - $ldapAuthClient = new LdapAuth(); + $ldapAuthClient = $settings->getLdapAuth(); $ldap = $ldapAuthClient->getLdap(); - $userCount = $ldap->count( - $settings->get('auth.ldap.userFilter'), - $settings->get('auth.ldap.baseDn'), - Ldap::SEARCH_SCOPE_SUB - ); + $userCount = $ldap->count($settings->userFilter, $settings->baseDn, Ldap::SEARCH_SCOPE_SUB); } catch (LdapException $ex) { $errorMessage = $ex->getMessage(); } catch (Exception $ex) { @@ -72,7 +66,7 @@ class AdminController extends Controller } return $this->render('index', [ - 'model' => $form, + 'model' => $settings, 'enabled' => $enabled, 'userCount' => $userCount, 'errorMessage' => $errorMessage diff --git a/protected/humhub/modules/ldap/helpers/LdapHelper.php b/protected/humhub/modules/ldap/helpers/LdapHelper.php index a47ea63a5c..53ed788b06 100644 --- a/protected/humhub/modules/ldap/helpers/LdapHelper.php +++ b/protected/humhub/modules/ldap/helpers/LdapHelper.php @@ -8,51 +8,14 @@ namespace humhub\modules\ldap\helpers; -use humhub\components\SettingsManager; -use Yii; -use Zend\Ldap\Ldap; - /** - * This class contains a lot of html helpers for the views + * This class contains LDAP helpers * * @since 0.5 */ class LdapHelper { - public static function getLdapConnection() - { - /** @var SettingsManager $settings */ - $settings = Yii::$app->getModule('user')->settings; - - $options = [ - 'host' => $settings->get('auth.ldap.hostname'), - 'port' => $settings->get('auth.ldap.port'), - 'username' => $settings->get('auth.ldap.username'), - 'password' => $settings->get('auth.ldap.password'), - 'useStartTls' => ($settings->get('auth.ldap.encryption') == 'tls'), - 'useSsl' => ($settings->get('auth.ldap.encryption') == 'ssl'), - 'bindRequiresDn' => true, - 'baseDn' => $settings->get('auth.ldap.baseDn'), - 'accountFilterFormat' => $settings->get('auth.ldap.loginFilter'), - ]; - - $ldap = new Ldap($options); - $ldap->bind(); - - return $ldap; - } - - /** - * Checks if LDAP support is enabled - * - * @return boolean is LDAP support is enabled - */ - public static function isLdapEnabled() - { - return (boolean) Yii::$app->getModule('user')->settings->get('auth.ldap.enabled'); - } - /** * Checks if LDAP is supported */ @@ -68,8 +31,5 @@ class LdapHelper return true; } - - - } diff --git a/protected/humhub/modules/ldap/migrations/m190309_201944_rename_settings.php b/protected/humhub/modules/ldap/migrations/m190309_201944_rename_settings.php new file mode 100644 index 0000000000..94d6c62bc6 --- /dev/null +++ b/protected/humhub/modules/ldap/migrations/m190309_201944_rename_settings.php @@ -0,0 +1,69 @@ + 'enabled', + 'auth.ldap.refreshUsers' => 'refreshUsers', + 'auth.ldap.hostname' => 'hostname', + 'auth.ldap.port' => 'port', + 'auth.ldap.encryption' => 'encryption', + 'auth.ldap.username' => 'username', + 'auth.ldap.password' => 'password', + 'auth.ldap.baseDn' => 'baseDn', + 'auth.ldap.loginFilter' => 'loginFilter', + 'auth.ldap.userFilter' => 'userFilter', + 'auth.ldap.usernameAttribute' => 'usernameAttribute', + 'auth.ldap.emailAttribute' => 'emailAttribute', + 'auth.ldap.idAttribute' => 'idAttribute', + ]; + + foreach ($renameSettings as $from => $to) { + $this->update('setting', ['name' => $to, 'module_id' => 'ldap'], ['name' => $from, 'module_id' => 'user']); + } + + } + + + + /** + * {@inheritdoc} + */ + public function safeDown() + { + echo "m190309_201944_rename_settings cannot be reverted.\n"; + + return false; + } + + /* + // Use up()/down() to run migration code without a transaction. + public function up() + { + + } + + public function down() + { + echo "m190309_201944_rename_settings cannot be reverted.\n"; + + return false; + } + */ +} diff --git a/protected/humhub/modules/ldap/models/LdapSettings.php b/protected/humhub/modules/ldap/models/LdapSettings.php index 4205ff5c51..7541c3587e 100644 --- a/protected/humhub/modules/ldap/models/LdapSettings.php +++ b/protected/humhub/modules/ldap/models/LdapSettings.php @@ -8,30 +8,95 @@ namespace humhub\modules\ldap\models; +use humhub\components\SettingsManager; +use humhub\modules\ldap\authclient\LdapAuth; use Yii; use yii\base\Model; /** - * AuthenticationLdapSettingsForm + * LdapSettings * + * @see LdapAuth for more information * @since 0.5 */ class LdapSettings extends Model { + const PASSWORD_FIELD_DUMMY = '---HIDDEN---'; + + /** + * @var boolean + */ public $enabled; + + /** + * @var boolean + */ public $refreshUsers; + + /** + * @var string + */ public $username; + + /** + * @var string + */ public $password; + + /** + * @var string + */ + public $passwordField; + + /** + * @var string + */ public $hostname; + + /** + * @var int + */ public $port; + + /** + * @var string + */ public $encryption; + + /** + * @var string + */ public $baseDn; + + /** + * @var string + */ public $loginFilter; + + /** + * @var string + */ public $userFilter; + + /** + * @var string + */ public $usernameAttribute; + + /** + * @var string + */ public $emailAttribute; + + /** + * @var string + */ public $idAttribute; + + /** + * @var array + */ public $encryptionTypes = [ '' => 'None', 'tls' => 'TLS (aka SSLV2)', @@ -44,26 +109,7 @@ class LdapSettings extends Model public function init() { parent::init(); - - $settings = Yii::$app->getModule('user')->settings; - - // Load Defaults - $this->enabled = $settings->get('auth.ldap.enabled'); - $this->refreshUsers = $settings->get('auth.ldap.refreshUsers'); - $this->username = $settings->get('auth.ldap.username'); - $this->password = $settings->get('auth.ldap.password'); - $this->hostname = $settings->get('auth.ldap.hostname'); - $this->port = $settings->get('auth.ldap.port'); - $this->encryption = $settings->get('auth.ldap.encryption'); - $this->baseDn = $settings->get('auth.ldap.baseDn'); - $this->loginFilter = $settings->get('auth.ldap.loginFilter'); - $this->userFilter = $settings->get('auth.ldap.userFilter'); - $this->usernameAttribute = $settings->get('auth.ldap.usernameAttribute'); - $this->emailAttribute = $settings->get('auth.ldap.emailAttribute'); - $this->idAttribute = $settings->get('auth.ldap.idAttribute'); - - if ($this->password != '') - $this->password = '---hidden---'; + $this->loadSaved(); } /** @@ -72,9 +118,9 @@ class LdapSettings extends Model public function rules() { return [ - [['enabled', 'refreshUsers', 'usernameAttribute', 'emailAttribute', 'username', 'password', 'hostname', 'port', 'idAttribute'], 'string', 'max' => 255], + [['enabled', 'refreshUsers', 'usernameAttribute', 'emailAttribute', 'username', 'passwordField', 'hostname', 'port', 'idAttribute'], 'string', 'max' => 255], [['baseDn', 'loginFilter', 'userFilter'], 'string'], - [['usernameAttribute', 'username', 'password', 'hostname', 'port', 'baseDn', 'loginFilter', 'userFilter'], 'required'], + [['usernameAttribute', 'username', 'passwordField', 'hostname', 'port', 'baseDn', 'loginFilter', 'userFilter'], 'required'], ['encryption', 'in', 'range' => ['', 'ssl', 'tls']], ]; } @@ -88,7 +134,7 @@ class LdapSettings extends Model 'enabled' => Yii::t('LdapModule.base', 'Enable LDAP Support'), 'refreshUsers' => Yii::t('LdapModule.base', 'Fetch/Update Users Automatically'), 'username' => Yii::t('LdapModule.base', 'Username'), - 'password' => Yii::t('LdapModule.base', 'Password'), + 'passwordField' => Yii::t('LdapModule.base', 'Password'), 'encryption' => Yii::t('LdapModule.base', 'Encryption'), 'hostname' => Yii::t('LdapModule.base', 'Hostname'), 'port' => Yii::t('LdapModule.base', 'Port'), @@ -109,17 +155,53 @@ class LdapSettings extends Model return [ 'encryption' => Yii::t('LdapModule.base', 'A TLS/SSL is strongly favored in production environments to prevent passwords from be transmitted in clear text.'), 'username' => Yii::t('LdapModule.base', 'The default credentials username. Some servers require that this be in DN form. This must be given in DN form if the LDAP server requires a DN to bind and binding should be possible with simple usernames.'), - 'password' => Yii::t('LdapModule.base', 'The default credentials password (used only with username above).'), + 'passwordField' => Yii::t('LdapModule.base', 'The default credentials password (used only with username above).'), 'baseDn' => Yii::t('LdapModule.base', 'The default base DN used for searching for accounts.'), 'loginFilter' => Yii::t('LdapModule.base', 'Defines the filter to apply, when login is attempted. %s replaces the username in the login action. Example: "(sAMAccountName=%s)" or "(uid=%s)"'), 'usernameAttribute' => Yii::t('LdapModule.base', 'LDAP Attribute for Username. Example: "uid" or "sAMAccountName"'), 'emailAttribute' => Yii::t('LdapModule.base', 'LDAP Attribute for E-Mail Address. Default: "mail"'), 'idAttribute' => Yii::t('LdapModule.base', 'Not changeable LDAP attribute to unambiguously identify the user in the directory. If empty the user will be determined automatically by e-mail address or username. Examples: objectguid (ActiveDirectory) or uidNumber (OpenLDAP)'), 'userFilter' => Yii::t('LdapModule.base', 'Limit access to users meeting this criteria. Example: "(objectClass=posixAccount)" or "(&(objectClass=person)(memberOf=CN=Workers,CN=Users,DC=myDomain,DC=com))"'), - + ]; } + + /** + * Loads the saved settings + * + * @return bool|void + */ + public function loadSaved() + { + /** @var SettingsManager $settings */ + $settings = Yii::$app->getModule('ldap')->settings; + + // Load Defaults + $this->enabled = $settings->get('enabled'); + + $this->username = $settings->get('username'); + $this->password = $settings->get('password'); + if (!empty($this->password)) { + $this->passwordField = static::PASSWORD_FIELD_DUMMY; + } + + $this->hostname = $settings->get('hostname'); + $this->port = $settings->get('port'); + $this->encryption = $settings->get('encryption'); + $this->baseDn = $settings->get('baseDn'); + + $this->loginFilter = $settings->get('loginFilter'); + $this->userFilter = $settings->get('userFilter'); + + $this->usernameAttribute = $settings->get('usernameAttribute'); + $this->emailAttribute = $settings->get('emailAttribute'); + $this->idAttribute = $settings->get('idAttribute'); + + $this->refreshUsers = $settings->get('refreshUsers'); + } + + /** * Saves the form * @@ -127,24 +209,63 @@ class LdapSettings extends Model */ public function save() { - $settings = Yii::$app->getModule('user')->settings; + /** @var SettingsManager $settings */ + $settings = Yii::$app->getModule('ldap')->settings; - $settings->set('auth.ldap.enabled', $this->enabled); - $settings->set('auth.ldap.refreshUsers', $this->refreshUsers); - $settings->set('auth.ldap.hostname', $this->hostname); - $settings->set('auth.ldap.port', $this->port); - $settings->set('auth.ldap.encryption', $this->encryption); - $settings->set('auth.ldap.username', $this->username); - if ($this->password != '---hidden---') - $settings->set('auth.ldap.password', $this->password); - $settings->set('auth.ldap.baseDn', $this->baseDn); - $settings->set('auth.ldap.loginFilter', $this->loginFilter); - $settings->set('auth.ldap.userFilter', $this->userFilter); - $settings->set('auth.ldap.usernameAttribute', $this->usernameAttribute); - $settings->set('auth.ldap.emailAttribute', $this->emailAttribute); - $settings->set('auth.ldap.idAttribute', $this->idAttribute); + $settings->set('enabled', $this->enabled); + $settings->set('hostname', $this->hostname); + $settings->set('port', $this->port); + $settings->set('encryption', $this->encryption); + $settings->set('username', $this->username); + if ($this->passwordField !== static::PASSWORD_FIELD_DUMMY) + $settings->set('password', $this->passwordField); + $settings->set('baseDn', $this->baseDn); + $settings->set('loginFilter', $this->loginFilter); + $settings->set('userFilter', $this->userFilter); + $settings->set('usernameAttribute', $this->usernameAttribute); + $settings->set('emailAttribute', $this->emailAttribute); + $settings->set('idAttribute', $this->idAttribute); + $settings->set('refreshUsers', $this->refreshUsers); return true; } + + /** + * Returns a configured LdapAuth instance + * + * @return LdapAuth + */ + public function getLdapAuth() + { + return new LdapAuth([ + 'hostname' => $this->hostname, + 'port' => $this->port, + 'bindUsername' => $this->username, + 'bindPassword' => $this->password, + 'useSsl' => ($this->encryption === 'ssl'), + 'useStartTls' => ($this->encryption === 'tls'), + 'baseDn' => $this->baseDn, + 'loginFilter' => $this->loginFilter, + 'userFilter' => $this->userFilter, + 'autoRefreshUsers' => ($this->refreshUsers), + 'emailAttribute' => $this->emailAttribute, + 'usernameAttribute' => $this->usernameAttribute, + 'idAttribute' => $this->idAttribute + ]); + } + + /** + * Checks whether LDAP is enabled or not. + * + * @return bool + */ + public static function isEnabled() + { + /** @var SettingsManager $settings */ + $settings = Yii::$app->getModule('ldap')->settings; + + return (bool)$settings->get('enabled'); + } + } diff --git a/protected/humhub/modules/ldap/views/admin/index.php b/protected/humhub/modules/ldap/views/admin/index.php index 747e9c7640..babfc92385 100644 --- a/protected/humhub/modules/ldap/views/admin/index.php +++ b/protected/humhub/modules/ldap/views/admin/index.php @@ -61,7 +61,7 @@ use yii\widgets\ActiveForm; field($model, 'port')->textInput() ?> field($model, 'encryption')->dropDownList($model->encryptionTypes) ?> field($model, 'username')->textInput() ?> - field($model, 'password')->passwordInput() ?> + field($model, 'passwordField')->passwordInput() ?> field($model, 'baseDn')->textInput() ?> field($model, 'loginFilter')->textArea() ?> field($model, 'userFilter')->textArea() ?> diff --git a/protected/humhub/modules/user/authclient/Collection.php b/protected/humhub/modules/user/authclient/Collection.php index 7b700e1680..f51f334b18 100644 --- a/protected/humhub/modules/user/authclient/Collection.php +++ b/protected/humhub/modules/user/authclient/Collection.php @@ -9,6 +9,7 @@ namespace humhub\modules\user\authclient; use Yii; +use yii\authclient\ClientInterface; use yii\base\Component; use yii\base\InvalidArgumentException; @@ -84,7 +85,7 @@ class Collection extends Component * Sets a client by id and config * * @param string $id auth client id. - * @param array $config auth client instance configuration. + * @param array|ClientInterface $config auth client instance configuration. */ public function setClient($id, $config) { @@ -106,6 +107,7 @@ class Collection extends Component * @param string $id auth client id. * @param array $config auth client instance configuration. * @return ClientInterface auth client instance. + * @throws \yii\base\InvalidConfigException */ protected function createClient($id, $config) { @@ -122,17 +124,7 @@ class Collection extends Component protected function getDefaultClients() { $clients = []; - - $clients['password'] = [ - 'class' => 'humhub\modules\user\authclient\Password' - ]; - - if (Yii::$app->getModule('user')->settings->get('auth.ldap.enabled')) { - $clients['ldap'] = [ - 'class' => 'humhub\modules\user\authclient\ZendLdapClient' - ]; - } - + $clients['password'] = ['class' => Password::class]; return $clients; }