fix(authentication): frontend changes (#3456)

* fix(authentication): frontend changes

* fix(authentication): suggested changes

* fix(authentication): support AnonymousMode boolean

* feat(authentication): support empty vals + move from scope to formValues

* feat(authentication): allow test of TLS & anon

* feat(authentication): remove unneeded whitespace

* feat(authentication): remove un-needed whitespace

* feat(refactor): rebase + cleanup logic
pull/3556/head
William 2020-02-06 09:06:22 +13:00 committed by GitHub
parent 6f59f130a1
commit 167d4319b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 93 additions and 41 deletions

View File

@ -90,37 +90,54 @@
<portainer-tooltip position="bottom" message="URL or IP address of the LDAP server."></portainer-tooltip> <portainer-tooltip position="bottom" message="URL or IP address of the LDAP server."></portainer-tooltip>
</label> </label>
<div class="col-sm-9 col-lg-10"> <div class="col-sm-9 col-lg-10">
<input type="text" class="form-control" id="ldap_url" ng-model="LDAPSettings.URL" placeholder="e.g. 10.0.0.10:389 or myldap.domain.tld:389"> <input type="text" class="form-control" id="ldap_url" ng-model="formValues.LDAPSettings.URL" placeholder="e.g. 10.0.0.10:389 or myldap.domain.tld:389">
</div> </div>
</div> </div>
<!-- Anonymous mode-->
<div class="form-group"> <div class="form-group">
<label for="ldap_username" class="col-sm-3 col-lg-2 control-label text-left"> <div class="col-sm-12">
Reader DN <label for="anonymous_mode" class="control-label text-left">
<portainer-tooltip position="bottom" message="Account that will be used to search for users."></portainer-tooltip> Anonymous mode
</label> <portainer-tooltip position="bottom" message="Enable this option if the server is configured for Anonymous access."></portainer-tooltip>
<div class="col-sm-9 col-lg-10"> </label>
<input type="text" class="form-control" id="ldap_username" ng-model="LDAPSettings.ReaderDN" placeholder="cn=readonly-account,dc=ldap,dc=domain,dc=tld"> <label class="switch" style="margin-left: 20px;">
<input type="checkbox" id="anonymous_mode" ng-model="formValues.LDAPSettings.AnonymousMode"><i></i>
</label>
</div> </div>
</div> </div>
<!-- !Anonymous mode-->
<div class="form-group"> <div ng-if="!formValues.LDAPSettings.AnonymousMode">
<label for="ldap_password" class="col-sm-3 col-lg-2 control-label text-left"> <div class="form-group">
Password <label for="ldap_username" class="col-sm-3 col-lg-2 control-label text-left">
</label> Reader DN
<div class="col-sm-9 col-lg-10"> <portainer-tooltip position="bottom" message="Account that will be used to search for users."></portainer-tooltip>
<input type="password" class="form-control" id="ldap_password" ng-model="LDAPSettings.Password" placeholder="password"> </label>
<div class="col-sm-9 col-lg-10">
<input type="text" class="form-control" id="ldap_username" ng-model="formValues.LDAPSettings.ReaderDN" placeholder="cn=readonly-account,dc=ldap,dc=domain,dc=tld">
</div>
</div>
<div class="form-group">
<label for="ldap_password" class="col-sm-3 col-lg-2 control-label text-left">
Password
<portainer-tooltip position="bottom" message="If you do not enter a password, Portainer will leave the current password unchanged."></portainer-tooltip>
</label>
<div class="col-sm-9 col-lg-10">
<input type="password" class="form-control" id="ldap_password" ng-model="formValues.LDAPSettings.Password" placeholder="password">
</div>
</div> </div>
</div> </div>
<div class="form-group" ng-if="!LDAPSettings.TLSConfig.TLS && !LDAPSettings.StartTLS"> <div class="form-group" ng-if="!formValues.LDAPSettings.TLSConfig.TLS && !formValues.LDAPSettings.StartTLS">
<label for="ldap_password" class="col-sm-3 col-lg-2 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="state.successfulConnectivityCheck"></i> <i class="fa fa-check green-icon" style="margin-left: 5px;" ng-if="state.successfulConnectivityCheck"></i>
<i class="fa fa-times red-icon" style="margin-left: 5px;" ng-if="state.failedConnectivityCheck"></i> <i class="fa fa-times red-icon" style="margin-left: 5px;" ng-if="state.failedConnectivityCheck"></i>
</label> </label>
<div class="col-sm-9 col-lg-10"> <div class="col-sm-9 col-lg-10">
<button type="button" class="btn btn-primary btn-sm" ng-disabled="state.connectivityCheckInProgress || !LDAPSettings.URL || !LDAPSettings.ReaderDN || !LDAPSettings.Password" ng-click="LDAPConnectivityCheck()" button-spinner="state.connectivityCheckInProgress"> <button type="button" class="btn btn-primary btn-sm" ng-disabled="(state.connectivityCheckInProgress) || (!formValues.LDAPSettings.URL) || ((!formValues.LDAPSettings.ReaderDN || !formValues.LDAPSettings.Password) && !formValues.LDAPSettings.AnonymousMode)" ng-click="LDAPConnectivityCheck()" button-spinner="state.connectivityCheckInProgress">
<span ng-hide="state.connectivityCheckInProgress">Test connectivity</span> <span ng-hide="state.connectivityCheckInProgress">Test connectivity</span>
<span ng-show="state.connectivityCheckInProgress">Testing connectivity...</span> <span ng-show="state.connectivityCheckInProgress">Testing connectivity...</span>
</button> </button>
@ -132,28 +149,28 @@
</div> </div>
<!-- starttls --> <!-- starttls -->
<div class="form-group" ng-if="!LDAPSettings.TLSConfig.TLS"> <div class="form-group" ng-if="!formValues.LDAPSettings.TLSConfig.TLS">
<div class="col-sm-12"> <div class="col-sm-12">
<label for="tls" class="control-label text-left"> <label for="tls" class="control-label text-left">
Use StartTLS Use StartTLS
<portainer-tooltip position="bottom" message="Enable this option if want to use StartTLS to secure the connection to the server. Ignored if Use TLS is selected."></portainer-tooltip> <portainer-tooltip position="bottom" message="Enable this option if want to use StartTLS to secure the connection to the server. Ignored if Use TLS is selected."></portainer-tooltip>
</label> </label>
<label class="switch" style="margin-left: 20px;"> <label class="switch" style="margin-left: 20px;">
<input type="checkbox" ng-model="LDAPSettings.StartTLS"><i></i> <input type="checkbox" ng-model="formValues.LDAPSettings.StartTLS"><i></i>
</label> </label>
</div> </div>
</div> </div>
<!-- !starttls --> <!-- !starttls -->
<!-- tls-checkbox --> <!-- tls-checkbox -->
<div class="form-group" ng-if="!LDAPSettings.StartTLS"> <div class="form-group" ng-if="!formValues.LDAPSettings.StartTLS">
<div class="col-sm-12"> <div class="col-sm-12">
<label for="tls" class="control-label text-left"> <label for="tls" class="control-label text-left">
Use TLS Use TLS
<portainer-tooltip position="bottom" message="Enable this option if you need to specify TLS certificates to connect to the LDAP server."></portainer-tooltip> <portainer-tooltip position="bottom" message="Enable this option if you need to specify TLS certificates to connect to the LDAP server."></portainer-tooltip>
</label> </label>
<label class="switch" style="margin-left: 20px;"> <label class="switch" style="margin-left: 20px;">
<input type="checkbox" ng-model="LDAPSettings.TLSConfig.TLS"><i></i> <input type="checkbox" ng-model="formValues.LDAPSettings.TLSConfig.TLS"><i></i>
</label> </label>
</div> </div>
</div> </div>
@ -167,22 +184,22 @@
<portainer-tooltip position="bottom" message="Skip the verification of the server TLS certificate. Not recommended on unsecured networks."></portainer-tooltip> <portainer-tooltip position="bottom" message="Skip the verification of the server TLS certificate. Not recommended on unsecured networks."></portainer-tooltip>
</label> </label>
<label class="switch" style="margin-left: 20px;"> <label class="switch" style="margin-left: 20px;">
<input type="checkbox" ng-model="LDAPSettings.TLSConfig.TLSSkipVerify"><i></i> <input type="checkbox" ng-model="formValues.LDAPSettings.TLSConfig.TLSSkipVerify"><i></i>
</label> </label>
</div> </div>
</div> </div>
<!-- !tls-skip-verify --> <!-- !tls-skip-verify -->
<!-- tls-certs --> <!-- tls-certs -->
<div ng-if="LDAPSettings.TLSConfig.TLS || LDAPSettings.StartTLS"> <div ng-if="formValues.LDAPSettings.TLSConfig.TLS || formValues.LDAPSettings.StartTLS">
<!-- ca-input --> <!-- ca-input -->
<div class="form-group" ng-if="!LDAPSettings.TLSConfig.TLSSkipVerify"> <div class="form-group" ng-if="!formValues.LDAPSettings.TLSConfig.TLSSkipVerify">
<label class="col-sm-2 control-label text-left">TLS CA certificate</label> <label class="col-sm-2 control-label text-left">TLS CA certificate</label>
<div class="col-sm-10"> <div class="col-sm-10">
<button class="btn btn-sm btn-primary" ngf-select ng-model="formValues.TLSCACert">Select file</button> <button class="btn btn-sm btn-primary" ngf-select ng-model="formValues.TLSCACert">Select file</button>
<span style="margin-left: 5px;"> <span style="margin-left: 5px;">
{{ formValues.TLSCACert.name }} {{ formValues.TLSCACert.name }}
<i class="fa fa-check green-icon" ng-if="formValues.TLSCACert && formValues.TLSCACert === LDAPSettings.TLSConfig.TLSCACert" aria-hidden="true"></i> <i class="fa fa-check green-icon" ng-if="formValues.TLSCACert && formValues.TLSCACert === formValues.LDAPSettings.TLSConfig.TLSCACert" aria-hidden="true"></i>
<i class="fa fa-times red-icon" ng-if="!formValues.TLSCACert" aria-hidden="true"></i> <i class="fa fa-times red-icon" ng-if="!formValues.TLSCACert" aria-hidden="true"></i>
<i class="fa fa-circle-notch fa-spin" ng-if="state.uploadInProgress"></i> <i class="fa fa-circle-notch fa-spin" ng-if="state.uploadInProgress"></i>
</span> </span>
@ -192,14 +209,14 @@
</div> </div>
<!-- !tls-certs --> <!-- !tls-certs -->
<div class="form-group" ng-if="LDAPSettings.TLSConfig.TLS || LDAPSettings.StartTLS"> <div class="form-group" ng-if="formValues.LDAPSettings.TLSConfig.TLS || formValues.LDAPSettings.StartTLS">
<label for="ldap_password" class="col-sm-3 col-lg-2 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="state.successfulConnectivityCheck"></i> <i class="fa fa-check green-icon" style="margin-left: 5px;" ng-if="state.successfulConnectivityCheck"></i>
<i class="fa fa-times red-icon" style="margin-left: 5px;" ng-if="state.failedConnectivityCheck"></i> <i class="fa fa-times red-icon" style="margin-left: 5px;" ng-if="state.failedConnectivityCheck"></i>
</label> </label>
<div class="col-sm-9 col-lg-10"> <div class="col-sm-9 col-lg-10">
<button type="button" class="btn btn-primary btn-sm" ng-click="LDAPConnectivityCheck()" ng-disabled="!LDAPSettings.URL || !LDAPSettings.ReaderDN || !LDAPSettings.Password || (!formValues.TLSCACert && !LDAPSettings.TLSConfig.TLSSkipVerify)">Test connectivity</button> <button type="button" class="btn btn-primary btn-sm" ng-click="LDAPConnectivityCheck()" ng-disabled="(!formValues.LDAPSettings.URL) || (!formValues.TLSCACert && !formValues.LDAPSettings.TLSConfig.TLSSkipVerify) || ((!formValues.LDAPSettings.ReaderDN || !formValues.LDAPSettings.Password) && !formValues.LDAPSettings.AnonymousMode)">Test connectivity</button>
<i id="connectivityCheckSpinner" class="fa fa-cog fa-spin" style="margin-left: 5px; display: none;"></i> <i id="connectivityCheckSpinner" class="fa fa-cog fa-spin" style="margin-left: 5px; display: none;"></i>
</div> </div>
</div> </div>
@ -218,7 +235,7 @@
Automatic user provisioning Automatic user provisioning
</label> </label>
<label class="switch" style="margin-left: 20px;"> <label class="switch" style="margin-left: 20px;">
<input type="checkbox" ng-model="LDAPSettings.AutoCreateUsers"><i></i> <input type="checkbox" ng-model="formValues.LDAPSettings.AutoCreateUsers"><i></i>
</label> </label>
</div> </div>
</div> </div>
@ -228,7 +245,7 @@
</div> </div>
<!-- search-settings --> <!-- search-settings -->
<div ng-repeat="config in LDAPSettings.SearchSettings | limitTo: (1 - LDAPSettings.SearchSettings)" style="margin-top: 5px;"> <div ng-repeat="config in formValues.LDAPSettings.SearchSettings | limitTo: (1 - formValues.LDAPSettings.SearchSettings)" style="margin-top: 5px;">
<div class="form-group" ng-if="$index > 0"> <div class="form-group" ng-if="$index > 0">
<span class="col-sm-12 text-muted small"> <span class="col-sm-12 text-muted small">
@ -282,7 +299,7 @@
</div> </div>
<!-- group-search-settings --> <!-- group-search-settings -->
<div ng-repeat="groupConfig in LDAPSettings.GroupSearchSettings | limitTo: (1 - LDAPSettings.GroupSearchSettings)" style="margin-top: 5px;"> <div ng-repeat="groupConfig in formValues.LDAPSettings.GroupSearchSettings | limitTo: (1 - formValues.LDAPSettings.GroupSearchSettings)" style="margin-top: 5px;">
<div class="form-group" ng-if="$index > 0"> <div class="form-group" ng-if="$index > 0">
<span class="col-sm-12 text-muted small"> <span class="col-sm-12 text-muted small">

View File

@ -11,7 +11,32 @@ function($q, $scope, $state, Notifications, SettingsService, FileUploadService,
}; };
$scope.formValues = { $scope.formValues = {
TLSCACert: '' TLSCACert: '',
LDAPSettings: {
AnonymousMode: true,
ReaderDN: '',
URL: '',
TLSConfig: {
TLS: false,
TLSSkipVerify: false
},
StartTLS: false,
SearchSettings: [
{
BaseDN: '',
Filter: '',
UserNameAttribute: ''
}
],
GroupSearchSettings: [
{
GroupBaseDN: '',
GroupFilter: '',
GroupAttribute: ''
}
],
AutoCreateUsers: true
}
}; };
$scope.goToOAuthExtensionView = function() { $scope.goToOAuthExtensionView = function() {
@ -23,32 +48,37 @@ function($q, $scope, $state, Notifications, SettingsService, FileUploadService,
}; };
$scope.addSearchConfiguration = function() { $scope.addSearchConfiguration = function() {
$scope.LDAPSettings.SearchSettings.push({ BaseDN: '', UserNameAttribute: '', Filter: '' }); $scope.formValues.LDAPSettings.SearchSettings.push({ BaseDN: '', UserNameAttribute: '', Filter: '' });
}; };
$scope.removeSearchConfiguration = function(index) { $scope.removeSearchConfiguration = function(index) {
$scope.LDAPSettings.SearchSettings.splice(index, 1); $scope.formValues.LDAPSettings.SearchSettings.splice(index, 1);
}; };
$scope.addGroupSearchConfiguration = function() { $scope.addGroupSearchConfiguration = function() {
$scope.LDAPSettings.GroupSearchSettings.push({ GroupBaseDN: '', GroupAttribute: '', GroupFilter: '' }); $scope.formValues.LDAPSettings.GroupSearchSettings.push({ GroupBaseDN: '', GroupAttribute: '', GroupFilter: '' });
}; };
$scope.removeGroupSearchConfiguration = function(index) { $scope.removeGroupSearchConfiguration = function(index) {
$scope.LDAPSettings.GroupSearchSettings.splice(index, 1); $scope.formValues.LDAPSettings.GroupSearchSettings.splice(index, 1);
}; };
$scope.LDAPConnectivityCheck = function() { $scope.LDAPConnectivityCheck = function() {
var settings = $scope.settings; var settings = angular.copy($scope.settings);
var TLSCAFile = $scope.formValues.TLSCACert !== settings.LDAPSettings.TLSConfig.TLSCACert ? $scope.formValues.TLSCACert : null; var TLSCAFile = $scope.formValues.TLSCACert !== settings.LDAPSettings.TLSConfig.TLSCACert ? $scope.formValues.TLSCACert : null;
var uploadRequired = ($scope.LDAPSettings.TLSConfig.TLS || $scope.LDAPSettings.StartTLS) && !$scope.LDAPSettings.TLSConfig.TLSSkipVerify; if ($scope.formValues.LDAPSettings.AnonymousMode){
settings.LDAPSettings['ReaderDN'] = '';
settings.LDAPSettings['Password'] = '';
}
var uploadRequired = ($scope.formValues.LDAPSettings.TLSConfig.TLS || $scope.formValues.LDAPSettings.StartTLS) && !$scope.formValues.LDAPSettings.TLSConfig.TLSSkipVerify;
$scope.state.uploadInProgress = uploadRequired; $scope.state.uploadInProgress = uploadRequired;
$scope.state.connectivityCheckInProgress = true; $scope.state.connectivityCheckInProgress = true;
$q.when(!uploadRequired || FileUploadService.uploadLDAPTLSFiles(TLSCAFile, null, null)) $q.when(!uploadRequired || FileUploadService.uploadLDAPTLSFiles(TLSCAFile, null, null))
.then(function success() { .then(function success() {
addLDAPDefaultPort(settings, $scope.LDAPSettings.TLSConfig.TLS); addLDAPDefaultPort(settings, $scope.formValues.LDAPSettings.TLSConfig.TLS);
return SettingsService.checkLDAPConnectivity(settings); return SettingsService.checkLDAPConnectivity(settings);
}) })
.then(function success() { .then(function success() {
@ -68,16 +98,21 @@ function($q, $scope, $state, Notifications, SettingsService, FileUploadService,
}; };
$scope.saveSettings = function() { $scope.saveSettings = function() {
var settings = $scope.settings; var settings = angular.copy($scope.settings);
var TLSCAFile = $scope.formValues.TLSCACert !== settings.LDAPSettings.TLSConfig.TLSCACert ? $scope.formValues.TLSCACert : null; var TLSCAFile = $scope.formValues.TLSCACert !== settings.LDAPSettings.TLSConfig.TLSCACert ? $scope.formValues.TLSCACert : null;
var uploadRequired = ($scope.LDAPSettings.TLSConfig.TLS || $scope.LDAPSettings.StartTLS) && !$scope.LDAPSettings.TLSConfig.TLSSkipVerify; if ($scope.formValues.LDAPSettings.AnonymousMode){
settings.LDAPSettings['ReaderDN'] = '';
settings.LDAPSettings['Password'] = '';
}
var uploadRequired = ($scope.formValues.LDAPSettings.TLSConfig.TLS || $scope.formValues.LDAPSettings.StartTLS) && !$scope.formValues.LDAPSettings.TLSConfig.TLSSkipVerify;
$scope.state.uploadInProgress = uploadRequired; $scope.state.uploadInProgress = uploadRequired;
$scope.state.actionInProgress = true; $scope.state.actionInProgress = true;
$q.when(!uploadRequired || FileUploadService.uploadLDAPTLSFiles(TLSCAFile, null, null)) $q.when(!uploadRequired || FileUploadService.uploadLDAPTLSFiles(TLSCAFile, null, null))
.then(function success() { .then(function success() {
addLDAPDefaultPort(settings, $scope.LDAPSettings.TLSConfig.TLS); addLDAPDefaultPort(settings, $scope.formValues.LDAPSettings.TLSConfig.TLS);
return SettingsService.update(settings); return SettingsService.update(settings);
}) })
.then(function success() { .then(function success() {
@ -109,7 +144,7 @@ function($q, $scope, $state, Notifications, SettingsService, FileUploadService,
var settings = data.settings; var settings = data.settings;
$scope.teams = data.teams; $scope.teams = data.teams;
$scope.settings = settings; $scope.settings = settings;
$scope.LDAPSettings = settings.LDAPSettings; $scope.formValues.LDAPSettings = settings.LDAPSettings;
$scope.OAuthSettings = settings.OAuthSettings; $scope.OAuthSettings = settings.OAuthSettings;
$scope.formValues.TLSCACert = settings.LDAPSettings.TLSConfig.TLSCACert; $scope.formValues.TLSCACert = settings.LDAPSettings.TLSConfig.TLSCACert;
$scope.oauthAuthenticationAvailable = data.oauthAuthentication; $scope.oauthAuthenticationAvailable = data.oauthAuthentication;