Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added user autocomplete from ldap in create view and a parameter to enable it #543

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/install/configuration-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ Number of expired storing records `session history`, values:

If this option is `true`, it will be possible to search users in LDAP.

To use this option you need to install kartik typeahead:
To use this option, you need to install [yetopen/yii2-usuario-ldap](https://github.com/YetOpen/yii2-usuario-ldap):

```shell
composer require kartik-v/yii2-widget-typeahead "dev-master"
composer require yetopen/yii2-usuario-ldap "*"
```

#### ldapUserAttributes (Type: `array`)
#### LDAPUserAttributes (Type: `array`)
AndreScara11 marked this conversation as resolved.
Show resolved Hide resolved

This array maps the user attributes to sync from ldap
AndreScara11 marked this conversation as resolved.
Show resolved Hide resolved

Expand All @@ -36,7 +36,7 @@ Default to:
]
```

#### ldapProfileAttributes (Type: `array`)
#### LDAPProfileAttributes (Type: `array`)

This array maps the profile attributes to sync from ldap
AndreScara11 marked this conversation as resolved.
Show resolved Hide resolved

Expand Down
2 changes: 1 addition & 1 deletion src/User/Bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ function () use ($model) {

if (Yii::$app->getModule('user')->searchUsersInLdap) {
if (!class_exists('kartik\typeahead\Typeahead')) {
throw new InvalidConfigException('The kartik-v/yii2-widget-typeahead library must be defined when searchUsersInLdap is true.');
throw new InvalidConfigException('The kartik-v/yii2-widget-typeahead library must be installed when searchUsersInLdap is true.');
}
}

Expand Down
6 changes: 5 additions & 1 deletion src/User/Controller/AdminController.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,11 @@ public function actionCreate()

$this->make(AjaxRequestModelValidator::class, [$user])->validate();

if ($user->load(Yii::$app->request->post()) && $user->validate()) {
if ($user->load(Yii::$app->request->post())) {
if (!$user->validate()) {
Yii::$app->session->setFlash('danger', implode(', ', $user->getErrorSummary(false)));
return $this->render('create', ['user' => $user]);
}
$this->trigger(UserEvent::EVENT_BEFORE_CREATE, $event);

$mailService = MailFactory::makeWelcomeMailerService($user);
Expand Down
27 changes: 23 additions & 4 deletions src/User/Model/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
* @property string $last_login_ip
* @property int $password_changed_at
* @property int $password_age
* @property int $ldap_uid
* Defined relations:
* @property SocialNetworkAccount[] $socialNetworkAccounts
* @property Profile $profile
Expand All @@ -74,10 +75,19 @@ class User extends ActiveRecord implements IdentityInterface
public const OLD_EMAIL_CONFIRMED = 0b01;
public const NEW_EMAIL_CONFIRMED = 0b10;

// ldap error
public const LDAP_INVALID_USER = -1;

/**
* @var string Plain password. Used for model validation
*/
public $password;

/**
* @var string Stores LDAP uid of the user during creation.
*/
public $ldapUid;

/**
* @var array connected account list
*/
Expand Down Expand Up @@ -140,12 +150,16 @@ public static function findIdentityByAccessToken($token, $type = null)
*/
public function beforeValidate()
{
if ($this->module->searchUsersInLdap && $this->source == UserSourceType::LDAP) {
if ($this->module->searchUsersInLdap && $this->source == UserSourceType::LDAP && $this->isNewRecord) {
if ($this->ldapUid == self::LDAP_INVALID_USER) {
$this->addError('ldapUid', Yii::t('usuario', 'Invalid LDAP user'));
return false;
}
/** @var UsuarioLdapComponent $ldapComponent */
$ldapComponent = Yii::$app->usuarioLdap;
$this->ldapUser = $ldapComponent->findLdapUser($this->email);
$this->ldapUser = $ldapComponent->findLdapUser($this->ldapUid);
if ($this->ldapUser !== null) {
$this->make(InitLdapUserService::class, [$this, $this->module->ldapUserAttributes, $this->ldapUser])->run();
$this->make(InitLdapUserService::class, [$this, $this->module->LDAPUserAttributes, $this->ldapUser])->run();
}
}
return parent::beforeValidate();
Expand Down Expand Up @@ -188,7 +202,7 @@ public function afterSave($insert, $changedAttributes)
if ($insert && $this->profile === null) {
$profile = $this->make(Profile::class);
if ($this->ldapUser !== null) {
$this->make(InitLdapUserService::class, [$profile, $this->module->ldapProfileAttributes, $this->ldapUser])->run();
$this->make(InitLdapUserService::class, [$profile, $this->module->LDAPProfileAttributes, $this->ldapUser])->run();
}
$profile->link('user', $this);
}
Expand Down Expand Up @@ -238,6 +252,7 @@ public function attributeLabels()
'last_login_ip' => Yii::t('usuario', 'Last login IP'),
'password_changed_at' => Yii::t('usuario', 'Last password change'),
'password_age' => Yii::t('usuario', 'Password age'),
'ldapUid' => Yii::t('usuario', 'Search'),
];
}

Expand Down Expand Up @@ -297,6 +312,10 @@ public function rules()
'twoFactorEnabledNumber' => ['auth_tf_enabled', 'boolean'],
'twoFactorTypeLength' => ['auth_tf_type', 'string', 'max' => 20],
'twoFactorMobilePhoneLength' => ['auth_tf_mobile_phone', 'string', 'max' => 20],

// ldapUid rules
'ldapUid' => ['ldapUid', 'string'],
'ldapUidRequired' => ['ldapUid', 'required', 'on' => $this->module->searchUsersInLdap],
];
}

Expand Down
4 changes: 2 additions & 2 deletions src/User/Module.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ class Module extends BaseModule
/**
* @var array user attributes to sync from ldap
*/
public $ldapUserAttributes = [
public $LDAPUserAttributes = [
'email' => 'mail',
'username' => 'samaccountname',
];
/**
* @var array profile attributes to sync from ldap
*/
public $ldapProfileAttributes = [];
public $LDAPProfileAttributes = [];
/**
* @var int|bool The time after which the expired 'session history' will be deleted
* if equals false records will not be deleted
Expand Down
1 change: 1 addition & 0 deletions src/User/resources/i18n/it/usuario.php
Original file line number Diff line number Diff line change
Expand Up @@ -319,4 +319,5 @@
'{0, date, MMMM dd, YYYY HH:mm}' => '{0, date, dd MMMM YYYY HH:mm}',
'{0} cannot be blank.' => '{0} non può essere vuoto.',
'Filter as you type...' => 'Digita per filtrare...',
'Invalid LDAP user' => 'Utente LDAP non valido',
];
41 changes: 22 additions & 19 deletions src/User/resources/views/admin/_user.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,16 @@
*/

use Da\User\Dictionary\UserSourceType;
use kartik\typeahead\Typeahead;
use dosamigos\selectize\SelectizeTextInput;
use yii\helpers\Html;
use yii\helpers\Url;

$source = Yii::$app->request->get('source') ?: $user->source;

$emailInputId = Html::getInputId($user, 'email');
$ldapUidId = Html::getInputId($user, 'ldapUid');
$sourceId = Html::getInputId($user, 'source');
$this->registerJs(<<<JS
function updateFromLdap(event, data) {
$("#$emailInputId").val(data.value).change();
function updateFromLdap(data) {
$("#$ldapUidId").val(data).change();
}
$('#$sourceId').change(function() {
var source = $(this).val();
Expand All @@ -36,21 +35,25 @@ function updateFromLdap(event, data) {
if ($user->isNewRecord) {
if (Yii::$app->getModule('user')->searchUsersInLdap && $source == UserSourceType::LDAP) {
echo $form->field($user, 'source')->dropDownList(UserSourceType::all(), ['value' => $source]);
echo $form->field($user, 'email')->widget(Typeahead::class, [
'options' => ['placeholder' => Yii::t('usuario', 'Filter as you type...'), 'autocomplete' => 'off'],
'pluginOptions' => ['highlight' => true],
'dataset' => [
[
'display' => 'value',
'remote' => [
'url' => Url::to(['/usuario-ldap/ldap/search']) . '?q=%QUERY', // You can add &limit to set a results limit, 20 to default
'wildcard' => '%QUERY'
]
]
echo $form->field($user, 'ldapUid')->widget(SelectizeTextInput::class, [
'loadUrl' => Url::to(['/usuario-ldap/ldap/search']),
'queryParam' => 'q',
'options' => [
'placeholder' => Yii::t('usuario', 'Filter as you type...'),
'autocomplete' => 'off',
],
// When the email is selected, get the username and change the source from local to ldap
'pluginEvents' => [
'typeahead:select' => 'updateFromLdap',
'clientOptions' => [
'valueField' => 'value',
'labelField' => 'label',
'searchField' => ['value', 'label', 'q'],
'create' => false,
'maxItems' => 1,
'onChange' => new \yii\web\JsExpression("
function(value) {
console.log(value);
updateFromLdap(value);
}
"),
],
]);
} else {
Expand Down