mirror of https://github.com/portainer/portainer
feat(ce): fix small issues for Highlight Business Edition feature (#6043)
* feat(logs): added orange border to export button. * fix(ldap): fixed connectivity check radio button alignment issue * fix(be-feature): added box shadow to limited feature border * fix(be-feature): fixed hide internal auth toggle issue. * feat(ldap): added isLimitedFeatureSelfContained config to ldap-custom-admin-group and test-login components * feat(auth): moved save settings button in auth page to a component. * feat(oauth): use saveSettingsButton component in oauth * feat(oauth): use saveSettingsButton component in internal auth * feat(oauth): use saveSettingsButton component in MS active directory auth * feat(oauth): use saveSettingsButton component in ldap auth * feat(auth): added new component to index.js * removed css inline styles. * feat(ad): added disable check method to ad auth. * feat(ldap): moved save settings disable method to parent component * removed inline styles. * fix(ldap): fixed test login misalignment issue * fix(ldap): pass isLdapFormValid function from page component * fix(ldap): made the toggle button in custom admin group orange when it's limited to CE. * fix(auth): fixed save setting button in Microsoft Active Directory auth * fix(ldap): made the assign admin toggle bright orangepull/6167/head
parent
18c323185e
commit
3f31d4b00b
|
@ -845,6 +845,54 @@ json-tree .branch-preview {
|
||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.m-l-5 {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-l-20 {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-l-30 {
|
||||||
|
margin-left: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-r-2 {
|
||||||
|
margin-right: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-r-5 {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-t-10 {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-t-10 {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-b-10 {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-margin {
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-border {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dispay-flex {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-wrap {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
.text-wrap {
|
.text-wrap {
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
|
|
|
@ -6,15 +6,22 @@
|
||||||
border-color: var(--border-form-control-color);
|
border-color: var(--border-form-control-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
button.limited-be {
|
button.limited-be,
|
||||||
|
button[disabled].limited-be.oauth-save-settings-button {
|
||||||
background-color: var(--BE-only);
|
background-color: var(--BE-only);
|
||||||
border-color: var(--BE-only);
|
border-color: var(--BE-only);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button.limited-be.oauth-save-settings-button {
|
||||||
|
background-color: var(--blue-2);
|
||||||
|
border-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
ng-form.limited-be,
|
ng-form.limited-be,
|
||||||
form.limited-be,
|
form.limited-be,
|
||||||
div.limited-be {
|
div.limited-be {
|
||||||
border: solid 1px var(--BE-only);
|
border: solid 1px var(--BE-only);
|
||||||
|
box-shadow: var(--shadow-boxselector-color);
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
touch-action: none;
|
touch-action: none;
|
||||||
|
|
|
@ -6,6 +6,8 @@ angular.module('portainer.oauth').component('oauthSettings', {
|
||||||
bindings: {
|
bindings: {
|
||||||
settings: '=',
|
settings: '=',
|
||||||
teams: '<',
|
teams: '<',
|
||||||
|
onSaveSettings: '<',
|
||||||
|
saveButtonState: '<',
|
||||||
},
|
},
|
||||||
controller,
|
controller,
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,6 +8,7 @@ export default class OAuthSettingsController {
|
||||||
this.featureService = featureService;
|
this.featureService = featureService;
|
||||||
|
|
||||||
this.limitedFeature = HIDE_INTERNAL_AUTH;
|
this.limitedFeature = HIDE_INTERNAL_AUTH;
|
||||||
|
this.limitedFeatureClass = 'limited-be';
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
provider: 'custom',
|
provider: 'custom',
|
||||||
|
@ -61,7 +62,7 @@ export default class OAuthSettingsController {
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSSO() {
|
updateSSO() {
|
||||||
this.settings.HideInternalAuth = this.settings.SSO;
|
this.settings.HideInternalAuth = this.featureService.isLimitedToBE(this.limitedFeature) ? false : this.settings.SSO;
|
||||||
}
|
}
|
||||||
|
|
||||||
addTeamMembershipMapping() {
|
addTeamMembershipMapping() {
|
||||||
|
@ -72,6 +73,20 @@ export default class OAuthSettingsController {
|
||||||
this.settings.TeamMemberships.OAuthClaimMappings.splice(index, 1);
|
this.settings.TeamMemberships.OAuthClaimMappings.splice(index, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isOAuthTeamMembershipFormValid() {
|
||||||
|
if (this.settings.OAuthAutoMapTeamMemberships && this.settings.TeamMemberships) {
|
||||||
|
if (!this.settings.TeamMemberships.OAuthClaimName) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasInvalidMapping = this.settings.TeamMemberships.OAuthClaimMappings.some((m) => !(m.ClaimValRegex && m.Team));
|
||||||
|
if (hasInvalidMapping) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
$onInit() {
|
$onInit() {
|
||||||
this.isLimitedToBE = this.featureService.isLimitedToBE(this.limitedFeature);
|
this.isLimitedToBE = this.featureService.isLimitedToBE(this.limitedFeature);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<ng-form name="$ctrl.oauthSettingsForm">
|
<ng-form name="oauthSettingsForm">
|
||||||
<div class="col-sm-12 form-section-title">
|
<div class="col-sm-12 form-section-title">
|
||||||
Single Sign-On
|
Single Sign-On
|
||||||
</div>
|
</div>
|
||||||
|
@ -379,4 +379,12 @@
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<save-auth-settings-button
|
||||||
|
on-save-settings="($ctrl.onSaveSettings)"
|
||||||
|
save-button-state="($ctrl.saveButtonState)"
|
||||||
|
save-button-disabled="!$ctrl.isOAuthTeamMembershipFormValid() || oauthSettingsForm.$invalid"
|
||||||
|
limited-feature-id="$ctrl.limitedFeature"
|
||||||
|
limited-feature-class="$ctrl.limitedFeatureClass"
|
||||||
|
class-name="'oauth-save-settings-button'"
|
||||||
|
></save-auth-settings-button>
|
||||||
</ng-form>
|
</ng-form>
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import angular from 'angular';
|
import angular from 'angular';
|
||||||
|
|
||||||
import ldapModule from './ldap';
|
import ldapModule from './ldap';
|
||||||
|
|
||||||
import { autoUserProvisionToggle } from './auto-user-provision-toggle';
|
import { autoUserProvisionToggle } from './auto-user-provision-toggle';
|
||||||
|
import { saveAuthSettingsButton } from './save-auth-settings-button';
|
||||||
|
import { internalAuth } from './internal-auth';
|
||||||
|
|
||||||
export default angular
|
export default angular
|
||||||
.module('portainer.settings.authentication', [ldapModule])
|
.module('portainer.settings.authentication', [ldapModule])
|
||||||
|
.component('internalAuth', internalAuth)
|
||||||
|
.component('saveAuthSettingsButton', saveAuthSettingsButton)
|
||||||
.component('autoUserProvisionToggle', autoUserProvisionToggle).name;
|
.component('autoUserProvisionToggle', autoUserProvisionToggle).name;
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
export const internalAuth = {
|
||||||
|
templateUrl: './internal-auth.html',
|
||||||
|
bindings: {
|
||||||
|
onSaveSettings: '<',
|
||||||
|
saveButtonState: '<',
|
||||||
|
},
|
||||||
|
};
|
|
@ -0,0 +1,8 @@
|
||||||
|
<div class="col-sm-12 form-section-title">
|
||||||
|
Information
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-sm-12 text-muted small">
|
||||||
|
When using internal authentication, Portainer will encrypt user passwords and store credentials locally.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<save-auth-settings-button on-save-settings="($ctrl.onSaveSettings)" save-button-state="($ctrl.saveButtonState)"></save-auth-settings-button>
|
|
@ -3,8 +3,9 @@ import { HIDE_INTERNAL_AUTH } from '@/portainer/feature-flags/feature-ids';
|
||||||
|
|
||||||
export default class AdSettingsController {
|
export default class AdSettingsController {
|
||||||
/* @ngInject */
|
/* @ngInject */
|
||||||
constructor(LDAPService) {
|
constructor(LDAPService, featureService) {
|
||||||
this.LDAPService = LDAPService;
|
this.LDAPService = LDAPService;
|
||||||
|
this.featureService = featureService;
|
||||||
|
|
||||||
this.domainSuffix = '';
|
this.domainSuffix = '';
|
||||||
this.limitedFeatureId = HIDE_INTERNAL_AUTH;
|
this.limitedFeatureId = HIDE_INTERNAL_AUTH;
|
||||||
|
@ -55,6 +56,10 @@ export default class AdSettingsController {
|
||||||
this.settings.URLs.splice(index, 1);
|
this.settings.URLs.splice(index, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isSaveSettingButtonDisabled() {
|
||||||
|
return this.featureService.isLimitedToBE(this.limitedFeatureId) || !this.isLdapFormValid();
|
||||||
|
}
|
||||||
|
|
||||||
$onInit() {
|
$onInit() {
|
||||||
this.tlscaCert = this.settings.TLSCACert;
|
this.tlscaCert = this.settings.TLSCACert;
|
||||||
this.parseDomainName(this.settings.ReaderDN);
|
this.parseDomainName(this.settings.ReaderDN);
|
||||||
|
|
|
@ -160,7 +160,14 @@
|
||||||
selected-admin-groups="$ctrl.selectedAdminGroups"
|
selected-admin-groups="$ctrl.selectedAdminGroups"
|
||||||
default-admin-group-search-filter="'(objectClass=groupOfNames)'"
|
default-admin-group-search-filter="'(objectClass=groupOfNames)'"
|
||||||
limited-feature-id="$ctrl.limitedFeatureId"
|
limited-feature-id="$ctrl.limitedFeatureId"
|
||||||
|
is-limited-feature-self-contained="false"
|
||||||
></ldap-custom-admin-group>
|
></ldap-custom-admin-group>
|
||||||
|
|
||||||
<ldap-settings-test-login settings="$ctrl.settings" limited-feature-id="$ctrl.limitedFeatureId"></ldap-settings-test-login>
|
<ldap-settings-test-login settings="$ctrl.settings" limited-feature-id="$ctrl.limitedFeatureId" is-limited-feature-self-contained="false"></ldap-settings-test-login>
|
||||||
|
<save-auth-settings-button
|
||||||
|
on-save-settings="($ctrl.onSaveSettings)"
|
||||||
|
save-button-state="($ctrl.saveButtonState)"
|
||||||
|
limited-feature-id="$ctrl.limitedFeatureId"
|
||||||
|
save-button-disabled="($ctrl.isSaveSettingButtonDisabled())"
|
||||||
|
></save-auth-settings-button>
|
||||||
</ng-form>
|
</ng-form>
|
||||||
|
|
|
@ -8,5 +8,8 @@ export const adSettings = {
|
||||||
tlscaCert: '=',
|
tlscaCert: '=',
|
||||||
state: '=',
|
state: '=',
|
||||||
connectivityCheck: '<',
|
connectivityCheck: '<',
|
||||||
|
onSaveSettings: '<',
|
||||||
|
saveButtonState: '<',
|
||||||
|
isLdapFormValid: '&?',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="ldap_password" class="col-sm-3 control-label text-left">
|
<label for="ldap_password" class="col-sm-3 col-lg-2 control-label text-left">
|
||||||
Connectivity check
|
Connectivity check
|
||||||
<i class="fa fa-check green-icon" style="margin-left: 5px;" ng-if="$ctrl.state.successfulConnectivityCheck"></i>
|
<i class="fa fa-check green-icon m-l-5" ng-if="$ctrl.state.successfulConnectivityCheck"></i>
|
||||||
<i class="fa fa-times red-icon" style="margin-left: 5px;" ng-if="$ctrl.state.failedConnectivityCheck"></i>
|
<i class="fa fa-times red-icon m-l-5" ng-if="$ctrl.state.failedConnectivityCheck"></i>
|
||||||
</label>
|
</label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9 col-lg-10">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="btn btn-primary btn-sm"
|
class="btn btn-primary btn-sm"
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import './ldap-custom-admin-group.css';
|
||||||
import controller from './ldap-custom-admin-group.controller';
|
import controller from './ldap-custom-admin-group.controller';
|
||||||
|
|
||||||
export const ldapCustomAdminGroup = {
|
export const ldapCustomAdminGroup = {
|
||||||
|
@ -9,5 +10,6 @@ export const ldapCustomAdminGroup = {
|
||||||
defaultAdminGroupSearchFilter: '<',
|
defaultAdminGroupSearchFilter: '<',
|
||||||
onSearchClick: '<',
|
onSearchClick: '<',
|
||||||
limitedFeatureId: '<',
|
limitedFeatureId: '<',
|
||||||
|
isLimitedFeatureSelfContained: '<',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
.ldap-custom-admin-group-title {
|
||||||
|
float: initial;
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
|
@ -1,10 +1,10 @@
|
||||||
<div class="col-sm-12 form-section-title" style="float: initial;">
|
<div class="col-sm-12 form-section-title ldap-custom-admin-group-title" ng-style="$ctrl.isLimitedFeatureSelfContained && { 'padding-bottom': '15px' }">
|
||||||
Auto-populate team admins
|
Auto-populate team admins <be-feature-indicator feature="$ctrl.limitedFeatureId" class="space-left" ng-if="$ctrl.isLimitedFeatureSelfContained"></be-feature-indicator>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<rd-widget ng-repeat="config in $ctrl.settings.AdminGroupSearchSettings | limitTo: (1 - $ctrl.settings.AdminGroupSearchSettings)" style="display: block; margin-bottom: 10px;">
|
<rd-widget ng-repeat="config in $ctrl.settings.AdminGroupSearchSettings | limitTo: (1 - $ctrl.settings.AdminGroupSearchSettings)">
|
||||||
<rd-widget-body>
|
<rd-widget-body>
|
||||||
<div class="form-group" ng-if="$index > 0" style="margin-bottom: 10px;">
|
<div class="form-group m-b-10" ng-if="$index > 0">
|
||||||
<span class="col-sm-12 text-muted small">
|
<span class="col-sm-12 text-muted small">
|
||||||
Extra search configuration
|
Extra search configuration
|
||||||
</span>
|
</span>
|
||||||
|
@ -16,7 +16,17 @@
|
||||||
<portainer-tooltip position="bottom" message="The distinguished name of the element from which the LDAP server will search for groups."></portainer-tooltip>
|
<portainer-tooltip position="bottom" message="The distinguished name of the element from which the LDAP server will search for groups."></portainer-tooltip>
|
||||||
</label>
|
</label>
|
||||||
<div class="col-sm-8 col-md-4">
|
<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" />
|
<input
|
||||||
|
type="text"
|
||||||
|
class="form-control"
|
||||||
|
id="ldap_admin_group_basedn_{{ $index }}"
|
||||||
|
ng-model="config.GroupBaseDN"
|
||||||
|
placeholder="dc=ldap,dc=domain,dc=tld"
|
||||||
|
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||||
|
limited-feature-class=" {{ $ctrl.isLimitedFeatureSelfContained && 'limited-be' }}"
|
||||||
|
ng-disabled="{{ $ctrl.isLimitedFeatureSelfContained }}"
|
||||||
|
limited-feature-tabindex="-1"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label for="ldap_admin_group_att_{{ $index }}" class="col-sm-4 col-md-2 control-label text-left">
|
<label for="ldap_admin_group_att_{{ $index }}" class="col-sm-4 col-md-2 control-label text-left">
|
||||||
|
@ -24,7 +34,17 @@
|
||||||
<portainer-tooltip position="bottom" message="LDAP attribute which denotes the group membership."></portainer-tooltip>
|
<portainer-tooltip position="bottom" message="LDAP attribute which denotes the group membership."></portainer-tooltip>
|
||||||
</label>
|
</label>
|
||||||
<div class="col-sm-8 col-md-4">
|
<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" />
|
<input
|
||||||
|
type="text"
|
||||||
|
class="form-control"
|
||||||
|
id="ldap_admin_group_att_{{ $index }}"
|
||||||
|
ng-model="config.GroupAttribute"
|
||||||
|
placeholder="member"
|
||||||
|
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||||
|
limited-feature-class=" {{ $ctrl.isLimitedFeatureSelfContained && 'limited-be' }}"
|
||||||
|
ng-disabled="{{ $ctrl.isLimitedFeatureSelfContained }}"
|
||||||
|
limited-feature-tabindex="-1"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
@ -33,7 +53,17 @@
|
||||||
<portainer-tooltip position="bottom" message="The LDAP search filter used to select group elements, optional."></portainer-tooltip>
|
<portainer-tooltip position="bottom" message="The LDAP search filter used to select group elements, optional."></portainer-tooltip>
|
||||||
</label>
|
</label>
|
||||||
<div ng-class="{ 'col-sm-7 col-md-9': $index, 'col-sm-8 col-md-10': !$index }">
|
<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)" />
|
<input
|
||||||
|
type="text"
|
||||||
|
class="form-control"
|
||||||
|
id="ldap_admin_group_filter_{{ $index }}"
|
||||||
|
ng-model="config.GroupFilter"
|
||||||
|
placeholder="(objectClass=groupOfNames)"
|
||||||
|
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||||
|
limited-feature-class=" {{ $ctrl.isLimitedFeatureSelfContained && 'limited-be' }}"
|
||||||
|
ng-disabled="{{ $ctrl.isLimitedFeatureSelfContained }}"
|
||||||
|
limited-feature-tabindex="-1"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-1" ng-if="$index > 0">
|
<div class="col-sm-1" ng-if="$index > 0">
|
||||||
<button class="btn btn-sm btn-danger" type="button" ng-click="$ctrl.onRemoveClick($index)">
|
<button class="btn btn-sm btn-danger" type="button" ng-click="$ctrl.onRemoveClick($index)">
|
||||||
|
@ -44,20 +74,31 @@
|
||||||
</rd-widget-body>
|
</rd-widget-body>
|
||||||
</rd-widget>
|
</rd-widget>
|
||||||
|
|
||||||
<div class="form-group" style="margin-top: 10px;">
|
<div class="form-group m-t-10">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<button class="label label-default interactive" style="border: 0;" ng-click="$ctrl.onAddClick()">
|
<button
|
||||||
|
class="label label-default interactive no-border"
|
||||||
|
ng-click="$ctrl.onAddClick()"
|
||||||
|
limited-feature-dir="{{ $ctrl.limitedFeatureId }}"
|
||||||
|
limited-feature-class=" {{ $ctrl.isLimitedFeatureSelfContained && 'limited-be' }}"
|
||||||
|
limited-feature-disabled
|
||||||
|
>
|
||||||
<i class="fa fa-plus-circle" aria-hidden="true"></i> add group search configuration
|
<i class="fa fa-plus-circle" aria-hidden="true"></i> add group search configuration
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-12" style="margin-top: 10px;">
|
<div class="col-sm-12 m-t-10">
|
||||||
<button class="btn btm-sm btn-primary" type="button" ng-click="$ctrl.search()" limited-feature-dir="{{ $ctrl.limitedFeatureId }}" limited-feature-tabindex="-1">
|
<button
|
||||||
|
class="btn btm-sm btn-primary"
|
||||||
|
type="button"
|
||||||
|
ng-click="$ctrl.search()"
|
||||||
|
limited-feature-dir="{{ $ctrl.limitedFeatureId }}"
|
||||||
|
limited-feature-class=" {{ $ctrl.isLimitedFeatureSelfContained && 'limited-be' }}"
|
||||||
|
ng-disabled="{{ $ctrl.isLimitedFeatureSelfContained }}"
|
||||||
|
limited-feature-tabindex="-1"
|
||||||
|
>
|
||||||
Fetch Admin Group(s)
|
Fetch Admin Group(s)
|
||||||
</button>
|
</button>
|
||||||
<be-feature-indicator feature="$ctrl.limitedFeatureId" class="space-left"></be-feature-indicator>
|
<span ng-if="$ctrl.groups && $ctrl.groups.length === 0" class="m-l-30"> <i class="fa fa-exclamation-triangle text-warning" aria-hidden="true"></i> No groups found</span>
|
||||||
<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>
|
</div>
|
||||||
|
|
||||||
|
@ -66,7 +107,7 @@
|
||||||
<label for="admin-auto-populate" class="control-label text-left text-muted" ng-class="{ 'text-muted': !$ctrl.enableAssignAdminGroup }">
|
<label for="admin-auto-populate" class="control-label text-left text-muted" ng-class="{ 'text-muted': !$ctrl.enableAssignAdminGroup }">
|
||||||
Assign admin rights to group(s)
|
Assign admin rights to group(s)
|
||||||
</label>
|
</label>
|
||||||
<label class="switch" style="margin-left: 20px;">
|
<label class="switch m-l-20" ng-class="{ 'business limited': $ctrl.isLimitedFeatureSelfContained }">
|
||||||
<input id="admin-auto-populate" ng-disabled="!$ctrl.enableAssignAdminGroup" name="admin-auto-populate" type="checkbox" ng-model="$ctrl.settings.AdminAutoPopulate" /><i></i>
|
<input id="admin-auto-populate" ng-disabled="!$ctrl.enableAssignAdminGroup" name="admin-auto-populate" type="checkbox" ng-model="$ctrl.settings.AdminAutoPopulate" /><i></i>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -78,6 +119,7 @@
|
||||||
Select Group(s)
|
Select Group(s)
|
||||||
</label>
|
</label>
|
||||||
<span
|
<span
|
||||||
|
class="m-l-20"
|
||||||
isteven-multi-select
|
isteven-multi-select
|
||||||
ng-if="$ctrl.enableAssignAdminGroup"
|
ng-if="$ctrl.enableAssignAdminGroup"
|
||||||
input-model="$ctrl.groups"
|
input-model="$ctrl.groups"
|
||||||
|
@ -88,7 +130,6 @@
|
||||||
helper-elements="filter"
|
helper-elements="filter"
|
||||||
search-property="name"
|
search-property="name"
|
||||||
translation="{nothingSelected: 'Select one or more groups', search: 'Search...'}"
|
translation="{nothingSelected: 'Select one or more groups', search: 'Search...'}"
|
||||||
style="margin-left: 20px;"
|
|
||||||
>
|
>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import './ldap-settings-custom.css';
|
||||||
import controller from './ldap-settings-custom.controller';
|
import controller from './ldap-settings-custom.controller';
|
||||||
|
|
||||||
export const ldapSettingsCustom = {
|
export const ldapSettingsCustom = {
|
||||||
|
@ -11,5 +12,8 @@ export const ldapSettingsCustom = {
|
||||||
connectivityCheck: '<',
|
connectivityCheck: '<',
|
||||||
onSearchUsersClick: '<',
|
onSearchUsersClick: '<',
|
||||||
onSearchGroupsClick: '<',
|
onSearchGroupsClick: '<',
|
||||||
|
onSaveSettings: '<',
|
||||||
|
saveButtonState: '<',
|
||||||
|
saveButtonDisabled: '<',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { EXTERNAL_AUTH_LDAP } from '@/portainer/feature-flags/feature-ids';
|
import { EXTERNAL_AUTH_LDAP } from '@/portainer/feature-flags/feature-ids';
|
||||||
|
|
||||||
export default class LdapSettingsCustomController {
|
export default class LdapSettingsCustomController {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.limitedFeatureId = EXTERNAL_AUTH_LDAP;
|
this.limitedFeatureId = EXTERNAL_AUTH_LDAP;
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
label[for='anonymous_mode'].control-label {
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
|
@ -14,7 +14,7 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-12 small text-muted">
|
<div class="col-sm-12 small text-muted">
|
||||||
<p>
|
<p>
|
||||||
<i class="fa fa-info-circle blue-icon" aria-hidden="true" style="margin-right: 2px;"></i>
|
<i class="fa fa-info-circle blue-icon m-r-2" aria-hidden="true"></i>
|
||||||
You can configure multiple LDAP Servers for authentication fallback. Make sure all servers are using the same configuration (i.e. if TLS is enabled, they should all use the
|
You can configure multiple LDAP Servers for authentication fallback. Make sure all servers are using the same configuration (i.e. if TLS is enabled, they should all use the
|
||||||
same certificates).
|
same certificates).
|
||||||
</p>
|
</p>
|
||||||
|
@ -22,12 +22,11 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="ldap_url" class="col-sm-3 col-lg-2 control-label text-left" style="display: flex; flex-wrap: wrap;">
|
<label for="ldap_url" class="col-sm-3 col-lg-2 control-label text-left dispay-flex flex-wrap">
|
||||||
LDAP Server
|
LDAP Server
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="label label-default interactive"
|
class="label label-default interactive no-border"
|
||||||
style="border: 0;"
|
|
||||||
ng-click="$ctrl.addLDAPUrl()"
|
ng-click="$ctrl.addLDAPUrl()"
|
||||||
limited-feature-dir="{{ $ctrl.limitedFeatureId }}"
|
limited-feature-dir="{{ $ctrl.limitedFeatureId }}"
|
||||||
limited-feature-disabled
|
limited-feature-disabled
|
||||||
|
@ -37,7 +36,7 @@
|
||||||
</button>
|
</button>
|
||||||
</label>
|
</label>
|
||||||
<div class="col-sm-9 col-lg-10">
|
<div class="col-sm-9 col-lg-10">
|
||||||
<div ng-repeat="url in $ctrl.settings.URLs track by $index" style="display: flex; margin-bottom: 10px;">
|
<div class="m-b-10 dispay-flex" ng-repeat="url in $ctrl.settings.URLs track by $index">
|
||||||
<input type="text" class="form-control" id="ldap_url" ng-model="$ctrl.settings.URLs[$index]" placeholder="e.g. 10.0.0.10:389 or myldap.domain.tld:389" required />
|
<input type="text" class="form-control" id="ldap_url" ng-model="$ctrl.settings.URLs[$index]" placeholder="e.g. 10.0.0.10:389 or myldap.domain.tld:389" required />
|
||||||
<button ng-if="$index > 0" class="btn btn-sm btn-danger" type="button" ng-click="$ctrl.removeLDAPUrl($index)">
|
<button ng-if="$index > 0" class="btn btn-sm btn-danger" type="button" ng-click="$ctrl.removeLDAPUrl($index)">
|
||||||
<i class="fa fa-trash" aria-hidden="true"></i>
|
<i class="fa fa-trash" aria-hidden="true"></i>
|
||||||
|
@ -46,14 +45,15 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Anonymous mode-->
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-12">
|
<label for="anonymous_mode" class="control-label text-left col-sm-3 col-lg-2">
|
||||||
<label for="anonymous_mode" class="control-label text-left">
|
|
||||||
Anonymous mode
|
Anonymous mode
|
||||||
<portainer-tooltip position="bottom" message="Enable this option if the server is configured for Anonymous access."></portainer-tooltip>
|
<portainer-tooltip position="bottom" message="Enable this option if the server is configured for Anonymous access."></portainer-tooltip>
|
||||||
</label>
|
</label>
|
||||||
<label class="switch" style="margin-left: 20px;"> <input type="checkbox" id="anonymous_mode" ng-model="$ctrl.settings.AnonymousMode" /><i></i> </label>
|
<div class="col-sm-9 col-lg-10">
|
||||||
|
<label class="switch">
|
||||||
|
<input type="checkbox" id="anonymous_mode" ng-model="$ctrl.settings.AnonymousMode" limited-feature-dir="{{::$ctrl.limitedFeatureId}}" limited-feature-tabindex="-1" /><i></i>
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- !Anonymous mode-->
|
<!-- !Anonymous mode-->
|
||||||
|
@ -102,29 +102,38 @@
|
||||||
></ldap-connectivity-check>
|
></ldap-connectivity-check>
|
||||||
|
|
||||||
<ldap-custom-user-search
|
<ldap-custom-user-search
|
||||||
style="margin-top: 5px;"
|
class="m-r-5"
|
||||||
settings="$ctrl.settings.SearchSettings"
|
settings="$ctrl.settings.SearchSettings"
|
||||||
on-search-click="($ctrl.onSearchUsersClick)"
|
on-search-click="($ctrl.onSearchUsersClick)"
|
||||||
limited-feature-id="$ctrl.limitedFeatureId"
|
limited-feature-id="$ctrl.limitedFeatureId"
|
||||||
></ldap-custom-user-search>
|
></ldap-custom-user-search>
|
||||||
<ldap-custom-group-search
|
<ldap-custom-group-search
|
||||||
style="margin-top: 5px;"
|
class="m-r-5"
|
||||||
settings="$ctrl.settings.GroupSearchSettings"
|
settings="$ctrl.settings.GroupSearchSettings"
|
||||||
on-search-click="($ctrl.onSearchGroupsClick)"
|
on-search-click="($ctrl.onSearchGroupsClick)"
|
||||||
limited-feature-id="$ctrl.limitedFeatureId"
|
limited-feature-id="$ctrl.limitedFeatureId"
|
||||||
></ldap-custom-group-search>
|
></ldap-custom-group-search>
|
||||||
|
|
||||||
<div limited-feature-dir="{{ $ctrl.limitedFeatureId }}" limited-feature-class="limited-be" style="margin-bottom: 20px;">
|
<ldap-custom-admin-group
|
||||||
<ldap-custom-admin-group
|
class="m-r-5"
|
||||||
style="margin-top: 5px;"
|
|
||||||
settings="$ctrl.settings"
|
settings="$ctrl.settings"
|
||||||
on-search-click="($ctrl.onSearchAdminGroupsClick)"
|
on-search-click="($ctrl.onSearchAdminGroupsClick)"
|
||||||
selected-admin-groups="$ctrl.selectedAdminGroups"
|
selected-admin-groups="$ctrl.selectedAdminGroups"
|
||||||
default-admin-group-search-filter="'(objectClass=groupOfNames)'"
|
default-admin-group-search-filter="'(objectClass=groupOfNames)'"
|
||||||
limited-feature-id="$ctrl.limitedFeatureId"
|
limited-feature-id="$ctrl.limitedFeatureId"
|
||||||
></ldap-custom-admin-group>
|
is-limited-feature-self-contained="true"
|
||||||
</div>
|
></ldap-custom-admin-group>
|
||||||
|
|
||||||
<div limited-feature-dir="{{ $ctrl.limitedFeatureId }}" limited-feature-class="limited-be">
|
<ldap-settings-test-login
|
||||||
<ldap-settings-test-login settings="$ctrl.settings" limited-feature-id="$ctrl.limitedFeatureId" show-be-indicator-if-needed="true"></ldap-settings-test-login>
|
settings="$ctrl.settings"
|
||||||
</div>
|
limited-feature-id="$ctrl.limitedFeatureId"
|
||||||
|
show-be-indicator-if-needed="true"
|
||||||
|
is-limited-feature-self-contained="true"
|
||||||
|
></ldap-settings-test-login>
|
||||||
|
|
||||||
|
<save-auth-settings-button
|
||||||
|
on-save-settings="($ctrl.onSaveSettings)"
|
||||||
|
save-button-state="($ctrl.saveButtonState)"
|
||||||
|
save-button-disabled="!$ctrl.saveButtonDisabled()"
|
||||||
|
limited-feature-dir="{{ $ctrl.limitedFeatureId }}"
|
||||||
|
></save-auth-settings-button>
|
||||||
|
|
|
@ -8,9 +8,11 @@ export const ldapSettingsOpenLdap = {
|
||||||
tlscaCert: '=',
|
tlscaCert: '=',
|
||||||
state: '=',
|
state: '=',
|
||||||
connectivityCheck: '<',
|
connectivityCheck: '<',
|
||||||
|
|
||||||
onTlscaCertChange: '<',
|
onTlscaCertChange: '<',
|
||||||
onSearchUsersClick: '<',
|
onSearchUsersClick: '<',
|
||||||
onSearchGroupsClick: '<',
|
onSearchGroupsClick: '<',
|
||||||
|
onSaveSettings: '<',
|
||||||
|
saveButtonState: '<',
|
||||||
|
saveButtonDisabled: '<',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -184,4 +184,10 @@
|
||||||
></ldap-group-search>
|
></ldap-group-search>
|
||||||
|
|
||||||
<ldap-settings-test-login settings="$ctrl.settings" limited-feature-id="$ctrl.limitedFeatureId"></ldap-settings-test-login>
|
<ldap-settings-test-login settings="$ctrl.settings" limited-feature-id="$ctrl.limitedFeatureId"></ldap-settings-test-login>
|
||||||
|
<save-auth-settings-button
|
||||||
|
on-save-settings="($ctrl.onSaveSettings)"
|
||||||
|
save-button-state="($ctrl.saveButtonState)"
|
||||||
|
save-button-disabled="!$ctrl.saveButtonDisabled()"
|
||||||
|
limited-feature-id="$ctrl.limitedFeatureId"
|
||||||
|
></save-auth-settings-button>
|
||||||
</ng-form>
|
</ng-form>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import './ldap-settings-test-login.css';
|
||||||
import controller from './ldap-settings-test-login.controller';
|
import controller from './ldap-settings-test-login.controller';
|
||||||
|
|
||||||
export const ldapSettingsTestLogin = {
|
export const ldapSettingsTestLogin = {
|
||||||
|
@ -7,5 +8,6 @@ export const ldapSettingsTestLogin = {
|
||||||
settings: '=',
|
settings: '=',
|
||||||
limitedFeatureId: '<',
|
limitedFeatureId: '<',
|
||||||
showBeIndicatorIfNeeded: '<',
|
showBeIndicatorIfNeeded: '<',
|
||||||
|
isLimitedFeatureSelfContained: '<',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
label[for='ldap_test_password'] {
|
||||||
|
font-size: 0.9em;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
|
@ -1,16 +1,31 @@
|
||||||
<div class="col-sm-12 form-section-title">
|
<div class="col-sm-12 form-section-title" ng-style="$ctrl.isLimitedFeatureSelfContained && { 'padding-bottom': '15px' }">
|
||||||
Test login
|
Test login
|
||||||
|
<be-feature-indicator
|
||||||
|
ng-if="$ctrl.showBeIndicatorIfNeeded"
|
||||||
|
feature="$ctrl.limitedFeatureId"
|
||||||
|
class="space-left"
|
||||||
|
ng-if="$ctrl.isLimitedFeatureSelfContained"
|
||||||
|
></be-feature-indicator>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-inline">
|
<div class="form-inline">
|
||||||
<div class="form-group" style="margin: 0;">
|
<div class="form-group" style="margin: 0;">
|
||||||
<label for="ldap_test_username" style="font-size: 0.9em; margin-right: 5px;">
|
<label for="ldap_test_username" style="font-size: 0.9em; margin-right: 5px;">
|
||||||
Username
|
Username
|
||||||
</label>
|
</label>
|
||||||
<input type="text" class="form-control" id="ldap_test_username" ng-model="$ctrl.username" limited-feature-dir="{{::$ctrl.limitedFeatureId}}" limited-feature-tabindex="-1" />
|
<input
|
||||||
|
type="text"
|
||||||
|
class="form-control"
|
||||||
|
id="ldap_test_username"
|
||||||
|
ng-model="$ctrl.username"
|
||||||
|
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||||
|
limited-feature-class=" {{ $ctrl.isLimitedFeatureSelfContained && 'limited-be' }}"
|
||||||
|
ng-disabled="{{ $ctrl.isLimitedFeatureSelfContained }}"
|
||||||
|
limited-feature-tabindex="-1"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" style="margin: 0;">
|
<div class="form-group no-margin">
|
||||||
<label for="ldap_test_password" style="font-size: 0.9em; margin-right: 5px;">
|
<label for="ldap_test_password">
|
||||||
Password
|
Password
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
|
@ -20,18 +35,20 @@
|
||||||
ng-model="$ctrl.password"
|
ng-model="$ctrl.password"
|
||||||
autocomplete="new-password"
|
autocomplete="new-password"
|
||||||
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||||
|
limited-feature-class=" {{ $ctrl.isLimitedFeatureSelfContained && 'limited-be' }}"
|
||||||
|
ng-disabled="{{ $ctrl.isLimitedFeatureSelfContained }}"
|
||||||
limited-feature-tabindex="-1"
|
limited-feature-tabindex="-1"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" style="margin: 0;">
|
<div class="form-group no-margin">
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
class="btn btn-primary"
|
class="btn btn-primary"
|
||||||
ng-disabled="$ctrl.state.testStatus === $ctrl.TEST_STATUS.LOADING || !$ctrl.username || !$ctrl.password"
|
ng-disabled="$ctrl.state.testStatus === $ctrl.TEST_STATUS.LOADING || !$ctrl.username || !$ctrl.password"
|
||||||
ng-click="$ctrl.testLogin($ctrl.username, $ctrl.password)"
|
ng-click="$ctrl.testLogin($ctrl.username, $ctrl.password)"
|
||||||
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||||
limited-feature-disabled
|
limited-feature-class=" {{ $ctrl.isLimitedFeatureSelfContained && 'limited-be' }}"
|
||||||
limited-feature-tabindex="-1"
|
limited-feature-tabindex="-1"
|
||||||
>
|
>
|
||||||
<span ng-if="$ctrl.state.testStatus !== $ctrl.TEST_STATUS.LOADING">Test</span>
|
<span ng-if="$ctrl.state.testStatus !== $ctrl.TEST_STATUS.LOADING">Test</span>
|
||||||
|
@ -40,6 +57,4 @@
|
||||||
<i ng-if="$ctrl.state.testStatus === $ctrl.TEST_STATUS.SUCCESS" class="fa fa-check green-icon"></i>
|
<i ng-if="$ctrl.state.testStatus === $ctrl.TEST_STATUS.SUCCESS" class="fa fa-check green-icon"></i>
|
||||||
<i ng-if="$ctrl.state.testStatus === $ctrl.TEST_STATUS.FAILURE" class="fa fa-times red-icon"></i>
|
<i ng-if="$ctrl.state.testStatus === $ctrl.TEST_STATUS.FAILURE" class="fa fa-times red-icon"></i>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<be-feature-indicator ng-if="$ctrl.showBeIndicatorIfNeeded" feature="$ctrl.limitedFeatureId" class="space-left"></be-feature-indicator>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -7,5 +7,8 @@ export const ldapSettings = {
|
||||||
settings: '=',
|
settings: '=',
|
||||||
state: '<',
|
state: '<',
|
||||||
connectivityCheck: '<',
|
connectivityCheck: '<',
|
||||||
|
onSaveSettings: '<',
|
||||||
|
saveButtonState: '<',
|
||||||
|
isLdapFormValid: '<',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -27,6 +27,9 @@
|
||||||
connectivity-check="$ctrl.connectivityCheck"
|
connectivity-check="$ctrl.connectivityCheck"
|
||||||
on-search-users-click="($ctrl.searchUsers)"
|
on-search-users-click="($ctrl.searchUsers)"
|
||||||
on-search-groups-click="($ctrl.searchGroups)"
|
on-search-groups-click="($ctrl.searchGroups)"
|
||||||
|
on-save-settings="($ctrl.onSaveSettings)"
|
||||||
|
save-button-state="($ctrl.saveButtonState)"
|
||||||
|
save-button-disabled="$ctrl.isLdapFormValid"
|
||||||
></ldap-settings-custom>
|
></ldap-settings-custom>
|
||||||
<ldap-settings-open-ldap
|
<ldap-settings-open-ldap
|
||||||
ng-if="$ctrl.settings.ServerType === $ctrl.SERVER_TYPES.OPEN_LDAP"
|
ng-if="$ctrl.settings.ServerType === $ctrl.SERVER_TYPES.OPEN_LDAP"
|
||||||
|
@ -37,5 +40,8 @@
|
||||||
connectivity-check="$ctrl.connectivityCheck"
|
connectivity-check="$ctrl.connectivityCheck"
|
||||||
on-search-users-click="($ctrl.searchUsers)"
|
on-search-users-click="($ctrl.searchUsers)"
|
||||||
on-search-groups-click="($ctrl.searchGroups)"
|
on-search-groups-click="($ctrl.searchGroups)"
|
||||||
|
on-save-settings="($ctrl.onSaveSettings)"
|
||||||
|
save-button-state="($ctrl.saveButtonState)"
|
||||||
|
save-button-disabled="$ctrl.isLdapFormValid"
|
||||||
></ldap-settings-open-ldap>
|
></ldap-settings-open-ldap>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
export const saveAuthSettingsButton = {
|
||||||
|
templateUrl: './save-auth-settings-button.html',
|
||||||
|
bindings: {
|
||||||
|
onSaveSettings: '<',
|
||||||
|
saveButtonDisabled: '<',
|
||||||
|
saveButtonState: '<',
|
||||||
|
limitedFeatureId: '<',
|
||||||
|
limitedFeatureClass: '<',
|
||||||
|
className: '<',
|
||||||
|
},
|
||||||
|
};
|
|
@ -0,0 +1,19 @@
|
||||||
|
<div class="col-sm-12 form-section-title">
|
||||||
|
Actions
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
ng-class="[$ctrl.className, 'btn btn-primary btn-sm']"
|
||||||
|
ng-click="$ctrl.onSaveSettings()"
|
||||||
|
ng-disabled="$ctrl.saveButtonDisabled || $ctrl.saveButtonState"
|
||||||
|
button-spinner="$ctrl.saveButtonState"
|
||||||
|
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||||
|
limited-feature-class="{{::$ctrl.limitedFeatureClass}}"
|
||||||
|
>
|
||||||
|
<span ng-hide="$ctrl.saveButtonState">Save settings</span>
|
||||||
|
<span ng-show="$ctrl.saveButtonState">Saving...</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -25,7 +25,9 @@
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button type="button" class="btn btn-sm btn-primary" style="margin-right: 10px;"> <i class="fa fa-download space-right" aria-hidden="true"></i>Export as CSV </button>
|
<button type="button" class="btn btn-sm btn-primary m-r-10" limited-feature-dir="{{::$ctrl.limitedFeature}}" limited-feature-class="limited-be" limited-feature-disabled>
|
||||||
|
<i class="fa fa-download space-right" aria-hidden="true"></i>Export as CSV
|
||||||
|
</button>
|
||||||
<be-feature-indicator feature="$ctrl.limitedFeature"></be-feature-indicator>
|
<be-feature-indicator feature="$ctrl.limitedFeature"></be-feature-indicator>
|
||||||
</div>
|
</div>
|
||||||
</rd-widget-body>
|
</rd-widget-body>
|
||||||
|
|
|
@ -25,7 +25,9 @@
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button type="button" class="btn btn-sm btn-primary" style="margin-right: 10px;"><i class="fa fa-download space-right" aria-hidden="true"></i>Export as CSV </button>
|
<button type="button" class="btn btn-sm btn-primary m-r-10" limited-feature-dir="{{::$ctrl.limitedFeature}}" limited-feature-class="limited-be" limited-feature-disabled
|
||||||
|
><i class="fa fa-download space-right" aria-hidden="true"></i>Export as CSV
|
||||||
|
</button>
|
||||||
<be-feature-indicator feature="$ctrl.limitedFeature"></be-feature-indicator>
|
<be-feature-indicator feature="$ctrl.limitedFeature"></be-feature-indicator>
|
||||||
</div>
|
</div>
|
||||||
</rd-widget-body>
|
</rd-widget-body>
|
||||||
|
|
|
@ -37,14 +37,7 @@
|
||||||
|
|
||||||
<box-selector radio-name="authOptions" ng-model="authMethod" options="authOptions" on-change="(onChangeAuthMethod)"></box-selector>
|
<box-selector radio-name="authOptions" ng-model="authMethod" options="authOptions" on-change="(onChangeAuthMethod)"></box-selector>
|
||||||
|
|
||||||
<div ng-if="authenticationMethodSelected(1)">
|
<internal-auth ng-if="authenticationMethodSelected(1)" on-save-settings="(saveSettings)" save-button-state="state.actionInProgress"></internal-auth>
|
||||||
<div class="col-sm-12 form-section-title">
|
|
||||||
Information
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-sm-12 text-muted small">
|
|
||||||
When using internal authentication, Portainer will encrypt user passwords and store credentials locally.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ldap-settings
|
<ldap-settings
|
||||||
ng-if="authenticationMethodSelected(2)"
|
ng-if="authenticationMethodSelected(2)"
|
||||||
|
@ -52,6 +45,9 @@
|
||||||
tlsca-cert="formValues.TLSCACert"
|
tlsca-cert="formValues.TLSCACert"
|
||||||
state="state"
|
state="state"
|
||||||
connectivity-check="LDAPConnectivityCheck"
|
connectivity-check="LDAPConnectivityCheck"
|
||||||
|
on-save-settings="(saveSettings)"
|
||||||
|
save-button-state="state.actionInProgress"
|
||||||
|
is-ldap-form-valid="isLDAPFormValid"
|
||||||
></ldap-settings>
|
></ldap-settings>
|
||||||
|
|
||||||
<ad-settings
|
<ad-settings
|
||||||
|
@ -60,29 +56,18 @@
|
||||||
tlsca-cert="formValues.TLSCACert"
|
tlsca-cert="formValues.TLSCACert"
|
||||||
state="state"
|
state="state"
|
||||||
connectivity-check="LDAPConnectivityCheck"
|
connectivity-check="LDAPConnectivityCheck"
|
||||||
|
on-save-settings="(saveSettings)"
|
||||||
|
save-button-state="state.actionInProgress"
|
||||||
|
is-ldap-form-valid="isLDAPFormValid()"
|
||||||
></ad-settings>
|
></ad-settings>
|
||||||
|
|
||||||
<oauth-settings ng-if="authenticationMethodSelected(3)" settings="OAuthSettings" teams="teams"></oauth-settings>
|
<oauth-settings
|
||||||
|
ng-if="authenticationMethodSelected(3)"
|
||||||
<!-- actions -->
|
settings="OAuthSettings"
|
||||||
<div class="col-sm-12 form-section-title">
|
teams="teams"
|
||||||
Actions
|
on-save-settings="(saveSettings)"
|
||||||
</div>
|
save-button-state="state.actionInProgress"
|
||||||
<div class="form-group">
|
></oauth-settings>
|
||||||
<div class="col-sm-12">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn btn-primary btn-sm"
|
|
||||||
ng-click="saveSettings()"
|
|
||||||
ng-disabled="state.actionInProgress || (settings.AuthenticationMethod === 2 && !isLDAPFormValid()) || (settings.AuthenticationMethod === 3 && !isOAuthTeamMembershipFormValid()) || authSettingsForm.$invalid"
|
|
||||||
button-spinner="state.actionInProgress"
|
|
||||||
>
|
|
||||||
<span ng-hide="state.actionInProgress">Save settings</span>
|
|
||||||
<span ng-show="state.actionInProgress">Saving...</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- !actions -->
|
|
||||||
</form>
|
</form>
|
||||||
</rd-widget-body>
|
</rd-widget-body>
|
||||||
</rd-widget>
|
</rd-widget>
|
||||||
|
|
|
@ -182,7 +182,8 @@ function SettingsAuthenticationController($q, $scope, $state, Notifications, Set
|
||||||
return (
|
return (
|
||||||
_.compact(ldapSettings.URLs).length &&
|
_.compact(ldapSettings.URLs).length &&
|
||||||
(ldapSettings.AnonymousMode || (ldapSettings.ReaderDN && ldapSettings.Password)) &&
|
(ldapSettings.AnonymousMode || (ldapSettings.ReaderDN && ldapSettings.Password)) &&
|
||||||
(!isTLSMode || $scope.formValues.TLSCACert || ldapSettings.TLSConfig.TLSSkipVerify)
|
(!isTLSMode || $scope.formValues.TLSCACert || ldapSettings.TLSConfig.TLSSkipVerify) &&
|
||||||
|
(!$scope.settings.LDAPSettings.AdminAutoPopulate || ($scope.settings.LDAPSettings.AdminAutoPopulate && $scope.formValues.selectedAdminGroups.length > 0))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue