mirror of https://github.com/portainer/portainer
feat(ldap): LDAP admin auto population EE-568 (#5875)
* feat(ldap): added ldap custom admin group component * feat(ldap): added ldap custom admin group to LDAP and MS AD pages * fix(ui): LDAP group search config label * fix(ldap): removed testing code. * fix(ldap): fixed default text in ldap custom admin group componentpull/5884/head
parent
1ee363f8c9
commit
3d6c6e2604
|
@ -153,5 +153,14 @@
|
|||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
></ldap-group-search>
|
||||
|
||||
<ldap-custom-admin-group
|
||||
style="margin-top: 5px;"
|
||||
settings="$ctrl.settings"
|
||||
on-search-click="($ctrl.onSearchAdminGroupsClick)"
|
||||
selected-admin-groups="$ctrl.selectedAdminGroups"
|
||||
default-admin-group-search-filter="'(objectClass=groupOfNames)'"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
></ldap-custom-admin-group>
|
||||
|
||||
<ldap-settings-test-login settings="$ctrl.settings" limited-feature-id="$ctrl.limitedFeatureId"></ldap-settings-test-login>
|
||||
</ng-form>
|
||||
|
|
|
@ -14,6 +14,7 @@ import { ldapUserSearchItem } from './ldap-user-search-item';
|
|||
import { ldapSettingsDnBuilder } from './ldap-settings-dn-builder';
|
||||
import { ldapSettingsGroupDnBuilder } from './ldap-settings-group-dn-builder';
|
||||
import { ldapCustomGroupSearch } from './ldap-custom-group-search';
|
||||
import { ldapCustomAdminGroup } from './ldap-custom-admin-group';
|
||||
import { ldapSettingsSecurity } from './ldap-settings-security';
|
||||
import { ldapSettingsTestLogin } from './ldap-settings-test-login';
|
||||
import { ldapCustomUserSearch } from './ldap-custom-user-search';
|
||||
|
@ -37,6 +38,7 @@ export default angular
|
|||
.component('ldapSettingsDnBuilder', ldapSettingsDnBuilder)
|
||||
.component('ldapSettingsGroupDnBuilder', ldapSettingsGroupDnBuilder)
|
||||
.component('ldapCustomGroupSearch', ldapCustomGroupSearch)
|
||||
.component('ldapCustomAdminGroup', ldapCustomAdminGroup)
|
||||
.component('ldapSettingsOpenLdap', ldapSettingsOpenLdap)
|
||||
.component('ldapSettingsSecurity', ldapSettingsSecurity)
|
||||
.component('ldapSettingsTestLogin', ldapSettingsTestLogin)
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import controller from './ldap-custom-admin-group.controller';
|
||||
|
||||
export const ldapCustomAdminGroup = {
|
||||
templateUrl: './ldap-custom-admin-group.html',
|
||||
controller,
|
||||
bindings: {
|
||||
settings: '=',
|
||||
selectedAdminGroups: '=',
|
||||
defaultAdminGroupSearchFilter: '<',
|
||||
onSearchClick: '<',
|
||||
limitedFeatureId: '<',
|
||||
},
|
||||
};
|
|
@ -0,0 +1,49 @@
|
|||
export default class LdapCustomAdminGroupController {
|
||||
/* @ngInject */
|
||||
constructor($async, Notifications, LDAPService) {
|
||||
Object.assign(this, { $async, Notifications, LDAPService });
|
||||
|
||||
this.groups = null;
|
||||
this.groupstest = null;
|
||||
this.enableAssignAdminGroup = false;
|
||||
|
||||
this.onRemoveClick = this.onRemoveClick.bind(this);
|
||||
this.onAddClick = this.onAddClick.bind(this);
|
||||
this.search = this.search.bind(this);
|
||||
}
|
||||
|
||||
onAddClick() {
|
||||
this.settings.AdminGroupSearchSettings.push({ GroupBaseDN: '', GroupAttribute: '', GroupFilter: '' });
|
||||
}
|
||||
|
||||
onRemoveClick(index) {
|
||||
this.settings.AdminGroupSearchSettings.splice(index, 1);
|
||||
}
|
||||
|
||||
search() {
|
||||
return this.$async(async () => {
|
||||
try {
|
||||
this.groups = null;
|
||||
this.groups = await this.onSearchClick();
|
||||
this.enableAssignAdminGroup = this.groups && this.groups.length > 0;
|
||||
} catch (error) {
|
||||
this.Notifications.error('Failure', error, 'Failed to search groups');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async $onInit() {
|
||||
if (this.settings.AdminAutoPopulate && this.settings.AdminGroups && this.settings.AdminGroups.length > 0) {
|
||||
const settings = {
|
||||
...this.settings,
|
||||
AdminGroupSearchSettings: this.settings.AdminGroupSearchSettings.map((search) => ({ ...search, GroupFilter: search.GroupFilter || this.defaultAdminGroupSearchFilter })),
|
||||
};
|
||||
|
||||
this.groups = await this.LDAPService.adminGroups(settings);
|
||||
}
|
||||
|
||||
if (this.groups && this.groups.length > 0) {
|
||||
this.enableAssignAdminGroup = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
<div class="col-sm-12 form-section-title" style="float: initial;">
|
||||
Auto-populate team admins
|
||||
</div>
|
||||
|
||||
<rd-widget ng-repeat="config in $ctrl.settings.AdminGroupSearchSettings | limitTo: (1 - $ctrl.settings.AdminGroupSearchSettings)" style="display: block; margin-bottom: 10px;">
|
||||
<rd-widget-body>
|
||||
<div class="form-group" ng-if="$index > 0" style="margin-bottom: 10px;">
|
||||
<span class="col-sm-12 text-muted small">
|
||||
Extra search configuration
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="ldap_admin_group_basedn_{{ $index }}" class="col-sm-4 col-md-2 control-label text-left">
|
||||
Group Base DN
|
||||
<portainer-tooltip position="bottom" message="The distinguished name of the element from which the LDAP server will search for groups."></portainer-tooltip>
|
||||
</label>
|
||||
<div class="col-sm-8 col-md-4">
|
||||
<input type="text" class="form-control" id="ldap_admin_group_basedn_{{ $index }}" ng-model="config.GroupBaseDN" placeholder="dc=ldap,dc=domain,dc=tld" />
|
||||
</div>
|
||||
|
||||
<label for="ldap_admin_group_att_{{ $index }}" class="col-sm-4 col-md-2 control-label text-left">
|
||||
Group Membership Attribute
|
||||
<portainer-tooltip position="bottom" message="LDAP attribute which denotes the group membership."></portainer-tooltip>
|
||||
</label>
|
||||
<div class="col-sm-8 col-md-4">
|
||||
<input type="text" class="form-control" id="ldap_admin_group_att_{{ $index }}" ng-model="config.GroupAttribute" placeholder="member" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="ldap_admin_group_filter_{{ $index }}" class="col-sm-4 col-md-2 control-label text-left">
|
||||
Group Filter
|
||||
<portainer-tooltip position="bottom" message="The LDAP search filter used to select group elements, optional."></portainer-tooltip>
|
||||
</label>
|
||||
<div ng-class="{ 'col-sm-7 col-md-9': $index, 'col-sm-8 col-md-10': !$index }">
|
||||
<input type="text" class="form-control" id="ldap_admin_group_filter_{{ $index }}" ng-model="config.GroupFilter" placeholder="(objectClass=groupOfNames)" />
|
||||
</div>
|
||||
<div class="col-sm-1" ng-if="$index > 0">
|
||||
<button class="btn btn-sm btn-danger" type="button" ng-click="$ctrl.onRemoveClick($index)">
|
||||
<i class="fa fa-trash" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</rd-widget-body>
|
||||
</rd-widget>
|
||||
|
||||
<div class="form-group" style="margin-top: 10px;">
|
||||
<div class="col-sm-12">
|
||||
<button class="label label-default interactive" style="border: 0;" ng-click="$ctrl.onAddClick()">
|
||||
<i class="fa fa-plus-circle" aria-hidden="true"></i> add group search configuration
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-sm-12" style="margin-top: 10px;">
|
||||
<button class="btn btm-sm btn-primary" type="button" ng-click="$ctrl.search()" limited-feature-dir="{{ $ctrl.limitedFeatureId }}" limited-feature-tabindex="-1">
|
||||
Fetch Admin Group(s)
|
||||
</button>
|
||||
<be-feature-indicator feature="$ctrl.limitedFeatureId" class="space-left"></be-feature-indicator>
|
||||
<span ng-if="$ctrl.groups && $ctrl.groups.length === 0" style="margin-left: 30px;">
|
||||
<i class="fa fa-exclamation-triangle text-warning" aria-hidden="true"></i> No groups found</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<label for="admin-auto-populate" class="control-label text-left text-muted" ng-class="{ 'text-muted': !$ctrl.enableAssignAdminGroup }">
|
||||
Assign admin rights to group(s)
|
||||
</label>
|
||||
<label class="switch" style="margin-left: 20px;">
|
||||
<input id="admin-auto-populate" ng-disabled="!$ctrl.enableAssignAdminGroup" name="admin-auto-populate" type="checkbox" ng-model="$ctrl.settings.AdminAutoPopulate" /><i></i>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="$ctrl.settings.AdminAutoPopulate">
|
||||
<div class="col-sm-12">
|
||||
<label for="group-access" class="control-label text-left">
|
||||
Select Group(s)
|
||||
</label>
|
||||
<span
|
||||
isteven-multi-select
|
||||
ng-if="$ctrl.enableAssignAdminGroup"
|
||||
input-model="$ctrl.groups"
|
||||
output-model="$ctrl.selectedAdminGroups"
|
||||
button-label="name"
|
||||
item-label="name"
|
||||
tick-property="selected"
|
||||
helper-elements="filter"
|
||||
search-property="name"
|
||||
translation="{nothingSelected: 'Select one or more groups', search: 'Search...'}"
|
||||
style="margin-left: 20px;"
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
|
@ -1,5 +1,5 @@
|
|||
<div class="col-sm-12 form-section-title" style="float: initial;">
|
||||
Teams auto-population configurations
|
||||
Group search configurations
|
||||
</div>
|
||||
|
||||
<rd-widget ng-repeat="config in $ctrl.settings | limitTo: (1 - $ctrl.settings)" style="display: block; margin-bottom: 10px;">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class="col-sm-12 form-section-title" style="float: initial;">
|
||||
Teams auto-population configurations
|
||||
Group search configurations
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 10px;" ng-repeat="config in $ctrl.settings | limitTo: (1 - $ctrl.settings)">
|
||||
|
|
|
@ -114,6 +114,17 @@
|
|||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
></ldap-custom-group-search>
|
||||
|
||||
<div limited-feature-dir="{{ $ctrl.limitedFeatureId }}" limited-feature-class="limited-be" style="margin-bottom: 20px;">
|
||||
<ldap-custom-admin-group
|
||||
style="margin-top: 5px;"
|
||||
settings="$ctrl.settings"
|
||||
on-search-click="($ctrl.onSearchAdminGroupsClick)"
|
||||
selected-admin-groups="$ctrl.selectedAdminGroups"
|
||||
default-admin-group-search-filter="'(objectClass=groupOfNames)'"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
></ldap-custom-admin-group>
|
||||
</div>
|
||||
|
||||
<div limited-feature-dir="{{ $ctrl.limitedFeatureId }}" limited-feature-class="limited-be">
|
||||
<ldap-settings-test-login settings="$ctrl.settings" limited-feature-id="$ctrl.limitedFeatureId" show-be-indicator-if-needed="true"></ldap-settings-test-login>
|
||||
</div>
|
||||
|
|
|
@ -23,6 +23,13 @@ export function buildLdapSettingsModel() {
|
|||
GroupAttribute: '',
|
||||
},
|
||||
],
|
||||
AdminGroupSearchSettings: [
|
||||
{
|
||||
GroupBaseDN: '',
|
||||
GroupFilter: '',
|
||||
GroupAttribute: '',
|
||||
},
|
||||
],
|
||||
AutoCreateUsers: true,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -221,7 +221,7 @@ function SettingsAuthenticationController($q, $scope, $state, Notifications, Set
|
|||
if (settings.LDAPSettings.ServerType === 2) {
|
||||
$scope.formValues.ldap.adSettings = settings.LDAPSettings;
|
||||
} else {
|
||||
$scope.formValues.ldap.ldapSettings = settings.LDAPSettings;
|
||||
$scope.formValues.ldap.ldapSettings = Object.assign($scope.formValues.ldap.ldapSettings, settings.LDAPSettings);
|
||||
}
|
||||
|
||||
if (settings.LDAPSettings.URL) {
|
||||
|
|
Loading…
Reference in New Issue