From 3f31d4b00bc46c05b2555bff31dd8e88e9b0f656 Mon Sep 17 00:00:00 2001 From: fhanportainer <79428273+fhanportainer@users.noreply.github.com> Date: Mon, 29 Nov 2021 10:41:21 +1300 Subject: [PATCH] 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 orange --- app/assets/css/app.css | 48 ++++++++++++ app/portainer/feature-flags/feature-flags.css | 9 ++- .../oauth/components/oauth-settings/index.js | 2 + .../oauth-settings.controller.js | 17 ++++- .../oauth-settings/oauth-settings.html | 10 ++- .../settings/authentication/index.js | 7 +- .../authentication/internal-auth/index.js | 7 ++ .../internal-auth/internal-auth.html | 8 ++ .../ad-settings/ad-settings.controller.js | 7 +- .../ldap/ad-settings/ad-settings.html | 9 ++- .../authentication/ldap/ad-settings/index.js | 3 + .../ldap-connectivity-check.html | 8 +- .../ldap/ldap-custom-admin-group/index.js | 2 + .../ldap-custom-admin-group.css | 4 + .../ldap-custom-admin-group.html | 75 ++++++++++++++----- .../ldap/ldap-settings-custom/index.js | 4 + .../ldap-settings-custom.controller.js | 1 - .../ldap-settings-custom.css | 3 + .../ldap-settings-custom.html | 61 ++++++++------- .../ldap/ldap-settings-openldap/index.js | 4 +- .../ldap-settings-openldap.html | 6 ++ .../ldap/ldap-settings-test-login/index.js | 2 + .../ldap-settings-test-login.css | 4 + .../ldap-settings-test-login.html | 31 ++++++-- .../ldap/ldap-settings/index.js | 3 + .../ldap/ldap-settings/ldap-settings.html | 6 ++ .../save-auth-settings-button/index.js | 11 +++ .../save-auth-settings-button.html | 19 +++++ .../activity-logs-view.html | 4 +- .../auth-logs-view/auth-logs-view.html | 4 +- .../settingsAuthentication.html | 43 ++++------- .../settingsAuthenticationController.js | 3 +- 32 files changed, 328 insertions(+), 97 deletions(-) create mode 100644 app/portainer/settings/authentication/internal-auth/index.js create mode 100644 app/portainer/settings/authentication/internal-auth/internal-auth.html create mode 100644 app/portainer/settings/authentication/ldap/ldap-custom-admin-group/ldap-custom-admin-group.css create mode 100644 app/portainer/settings/authentication/ldap/ldap-settings-custom/ldap-settings-custom.css create mode 100644 app/portainer/settings/authentication/ldap/ldap-settings-test-login/ldap-settings-test-login.css create mode 100644 app/portainer/settings/authentication/save-auth-settings-button/index.js create mode 100644 app/portainer/settings/authentication/save-auth-settings-button/save-auth-settings-button.html diff --git a/app/assets/css/app.css b/app/assets/css/app.css index 91b058fe2..1b7693261 100644 --- a/app/assets/css/app.css +++ b/app/assets/css/app.css @@ -845,6 +845,54 @@ json-tree .branch-preview { 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 { word-break: break-all; white-space: normal; diff --git a/app/portainer/feature-flags/feature-flags.css b/app/portainer/feature-flags/feature-flags.css index 9ffda18d8..600296aee 100644 --- a/app/portainer/feature-flags/feature-flags.css +++ b/app/portainer/feature-flags/feature-flags.css @@ -6,15 +6,22 @@ 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); border-color: var(--BE-only); } +button.limited-be.oauth-save-settings-button { + background-color: var(--blue-2); + border-color: transparent; +} + ng-form.limited-be, form.limited-be, div.limited-be { border: solid 1px var(--BE-only); + box-shadow: var(--shadow-boxselector-color); padding: 10px; pointer-events: none; touch-action: none; diff --git a/app/portainer/oauth/components/oauth-settings/index.js b/app/portainer/oauth/components/oauth-settings/index.js index c7fc2712f..fb452d8cd 100644 --- a/app/portainer/oauth/components/oauth-settings/index.js +++ b/app/portainer/oauth/components/oauth-settings/index.js @@ -6,6 +6,8 @@ angular.module('portainer.oauth').component('oauthSettings', { bindings: { settings: '=', teams: '<', + onSaveSettings: '<', + saveButtonState: '<', }, controller, }); diff --git a/app/portainer/oauth/components/oauth-settings/oauth-settings.controller.js b/app/portainer/oauth/components/oauth-settings/oauth-settings.controller.js index 500560ad7..c67a06be0 100644 --- a/app/portainer/oauth/components/oauth-settings/oauth-settings.controller.js +++ b/app/portainer/oauth/components/oauth-settings/oauth-settings.controller.js @@ -8,6 +8,7 @@ export default class OAuthSettingsController { this.featureService = featureService; this.limitedFeature = HIDE_INTERNAL_AUTH; + this.limitedFeatureClass = 'limited-be'; this.state = { provider: 'custom', @@ -61,7 +62,7 @@ export default class OAuthSettingsController { } updateSSO() { - this.settings.HideInternalAuth = this.settings.SSO; + this.settings.HideInternalAuth = this.featureService.isLimitedToBE(this.limitedFeature) ? false : this.settings.SSO; } addTeamMembershipMapping() { @@ -72,6 +73,20 @@ export default class OAuthSettingsController { 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() { this.isLimitedToBE = this.featureService.isLimitedToBE(this.limitedFeature); diff --git a/app/portainer/oauth/components/oauth-settings/oauth-settings.html b/app/portainer/oauth/components/oauth-settings/oauth-settings.html index 4853aabc1..8116cd999 100644 --- a/app/portainer/oauth/components/oauth-settings/oauth-settings.html +++ b/app/portainer/oauth/components/oauth-settings/oauth-settings.html @@ -1,4 +1,4 @@ - +
Single Sign-On
@@ -379,4 +379,12 @@ +
diff --git a/app/portainer/settings/authentication/index.js b/app/portainer/settings/authentication/index.js index 897e48042..02b21a57f 100644 --- a/app/portainer/settings/authentication/index.js +++ b/app/portainer/settings/authentication/index.js @@ -1,10 +1,11 @@ import angular from 'angular'; - import ldapModule from './ldap'; - import { autoUserProvisionToggle } from './auto-user-provision-toggle'; +import { saveAuthSettingsButton } from './save-auth-settings-button'; +import { internalAuth } from './internal-auth'; export default angular .module('portainer.settings.authentication', [ldapModule]) - + .component('internalAuth', internalAuth) + .component('saveAuthSettingsButton', saveAuthSettingsButton) .component('autoUserProvisionToggle', autoUserProvisionToggle).name; diff --git a/app/portainer/settings/authentication/internal-auth/index.js b/app/portainer/settings/authentication/internal-auth/index.js new file mode 100644 index 000000000..1d4b2c595 --- /dev/null +++ b/app/portainer/settings/authentication/internal-auth/index.js @@ -0,0 +1,7 @@ +export const internalAuth = { + templateUrl: './internal-auth.html', + bindings: { + onSaveSettings: '<', + saveButtonState: '<', + }, +}; diff --git a/app/portainer/settings/authentication/internal-auth/internal-auth.html b/app/portainer/settings/authentication/internal-auth/internal-auth.html new file mode 100644 index 000000000..b54ee2fb1 --- /dev/null +++ b/app/portainer/settings/authentication/internal-auth/internal-auth.html @@ -0,0 +1,8 @@ +
+ Information +
+
+ When using internal authentication, Portainer will encrypt user passwords and store credentials locally. +
+ + diff --git a/app/portainer/settings/authentication/ldap/ad-settings/ad-settings.controller.js b/app/portainer/settings/authentication/ldap/ad-settings/ad-settings.controller.js index 41d29e0ef..969388459 100644 --- a/app/portainer/settings/authentication/ldap/ad-settings/ad-settings.controller.js +++ b/app/portainer/settings/authentication/ldap/ad-settings/ad-settings.controller.js @@ -3,8 +3,9 @@ import { HIDE_INTERNAL_AUTH } from '@/portainer/feature-flags/feature-ids'; export default class AdSettingsController { /* @ngInject */ - constructor(LDAPService) { + constructor(LDAPService, featureService) { this.LDAPService = LDAPService; + this.featureService = featureService; this.domainSuffix = ''; this.limitedFeatureId = HIDE_INTERNAL_AUTH; @@ -55,6 +56,10 @@ export default class AdSettingsController { this.settings.URLs.splice(index, 1); } + isSaveSettingButtonDisabled() { + return this.featureService.isLimitedToBE(this.limitedFeatureId) || !this.isLdapFormValid(); + } + $onInit() { this.tlscaCert = this.settings.TLSCACert; this.parseDomainName(this.settings.ReaderDN); diff --git a/app/portainer/settings/authentication/ldap/ad-settings/ad-settings.html b/app/portainer/settings/authentication/ldap/ad-settings/ad-settings.html index 0f022ae7c..48bf2c375 100644 --- a/app/portainer/settings/authentication/ldap/ad-settings/ad-settings.html +++ b/app/portainer/settings/authentication/ldap/ad-settings/ad-settings.html @@ -160,7 +160,14 @@ selected-admin-groups="$ctrl.selectedAdminGroups" default-admin-group-search-filter="'(objectClass=groupOfNames)'" limited-feature-id="$ctrl.limitedFeatureId" + is-limited-feature-self-contained="false" > - + +
diff --git a/app/portainer/settings/authentication/ldap/ad-settings/index.js b/app/portainer/settings/authentication/ldap/ad-settings/index.js index 59a474097..5308496d7 100644 --- a/app/portainer/settings/authentication/ldap/ad-settings/index.js +++ b/app/portainer/settings/authentication/ldap/ad-settings/index.js @@ -8,5 +8,8 @@ export const adSettings = { tlscaCert: '=', state: '=', connectivityCheck: '<', + onSaveSettings: '<', + saveButtonState: '<', + isLdapFormValid: '&?', }, }; diff --git a/app/portainer/settings/authentication/ldap/ldap-connectivity-check/ldap-connectivity-check.html b/app/portainer/settings/authentication/ldap/ldap-connectivity-check/ldap-connectivity-check.html index 0d88ade53..fa6381b32 100644 --- a/app/portainer/settings/authentication/ldap/ldap-connectivity-check/ldap-connectivity-check.html +++ b/app/portainer/settings/authentication/ldap/ldap-connectivity-check/ldap-connectivity-check.html @@ -1,10 +1,10 @@
-
@@ -78,6 +119,7 @@ Select Group(s) diff --git a/app/portainer/settings/authentication/ldap/ldap-settings-custom/index.js b/app/portainer/settings/authentication/ldap/ldap-settings-custom/index.js index 321223717..20aab4431 100644 --- a/app/portainer/settings/authentication/ldap/ldap-settings-custom/index.js +++ b/app/portainer/settings/authentication/ldap/ldap-settings-custom/index.js @@ -1,3 +1,4 @@ +import './ldap-settings-custom.css'; import controller from './ldap-settings-custom.controller'; export const ldapSettingsCustom = { @@ -11,5 +12,8 @@ export const ldapSettingsCustom = { connectivityCheck: '<', onSearchUsersClick: '<', onSearchGroupsClick: '<', + onSaveSettings: '<', + saveButtonState: '<', + saveButtonDisabled: '<', }, }; diff --git a/app/portainer/settings/authentication/ldap/ldap-settings-custom/ldap-settings-custom.controller.js b/app/portainer/settings/authentication/ldap/ldap-settings-custom/ldap-settings-custom.controller.js index b4c3de4d5..70c2ed83e 100644 --- a/app/portainer/settings/authentication/ldap/ldap-settings-custom/ldap-settings-custom.controller.js +++ b/app/portainer/settings/authentication/ldap/ldap-settings-custom/ldap-settings-custom.controller.js @@ -1,5 +1,4 @@ import { EXTERNAL_AUTH_LDAP } from '@/portainer/feature-flags/feature-ids'; - export default class LdapSettingsCustomController { constructor() { this.limitedFeatureId = EXTERNAL_AUTH_LDAP; diff --git a/app/portainer/settings/authentication/ldap/ldap-settings-custom/ldap-settings-custom.css b/app/portainer/settings/authentication/ldap/ldap-settings-custom/ldap-settings-custom.css new file mode 100644 index 000000000..5bff75661 --- /dev/null +++ b/app/portainer/settings/authentication/ldap/ldap-settings-custom/ldap-settings-custom.css @@ -0,0 +1,3 @@ +label[for='anonymous_mode'].control-label { + padding-top: 0; +} diff --git a/app/portainer/settings/authentication/ldap/ldap-settings-custom/ldap-settings-custom.html b/app/portainer/settings/authentication/ldap/ldap-settings-custom/ldap-settings-custom.html index f14977907..f287132fa 100644 --- a/app/portainer/settings/authentication/ldap/ldap-settings-custom/ldap-settings-custom.html +++ b/app/portainer/settings/authentication/ldap/ldap-settings-custom/ldap-settings-custom.html @@ -14,7 +14,7 @@

- + 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).

@@ -22,12 +22,11 @@
-
-
-
-
@@ -102,29 +102,38 @@ > -
- -
+ -
- -
+ + + diff --git a/app/portainer/settings/authentication/ldap/ldap-settings-openldap/index.js b/app/portainer/settings/authentication/ldap/ldap-settings-openldap/index.js index b88f8008c..1ae314bd0 100644 --- a/app/portainer/settings/authentication/ldap/ldap-settings-openldap/index.js +++ b/app/portainer/settings/authentication/ldap/ldap-settings-openldap/index.js @@ -8,9 +8,11 @@ export const ldapSettingsOpenLdap = { tlscaCert: '=', state: '=', connectivityCheck: '<', - onTlscaCertChange: '<', onSearchUsersClick: '<', onSearchGroupsClick: '<', + onSaveSettings: '<', + saveButtonState: '<', + saveButtonDisabled: '<', }, }; diff --git a/app/portainer/settings/authentication/ldap/ldap-settings-openldap/ldap-settings-openldap.html b/app/portainer/settings/authentication/ldap/ldap-settings-openldap/ldap-settings-openldap.html index b6893961b..04d66907d 100644 --- a/app/portainer/settings/authentication/ldap/ldap-settings-openldap/ldap-settings-openldap.html +++ b/app/portainer/settings/authentication/ldap/ldap-settings-openldap/ldap-settings-openldap.html @@ -184,4 +184,10 @@ > + diff --git a/app/portainer/settings/authentication/ldap/ldap-settings-test-login/index.js b/app/portainer/settings/authentication/ldap/ldap-settings-test-login/index.js index b5298616c..dc50fa903 100644 --- a/app/portainer/settings/authentication/ldap/ldap-settings-test-login/index.js +++ b/app/portainer/settings/authentication/ldap/ldap-settings-test-login/index.js @@ -1,3 +1,4 @@ +import './ldap-settings-test-login.css'; import controller from './ldap-settings-test-login.controller'; export const ldapSettingsTestLogin = { @@ -7,5 +8,6 @@ export const ldapSettingsTestLogin = { settings: '=', limitedFeatureId: '<', showBeIndicatorIfNeeded: '<', + isLimitedFeatureSelfContained: '<', }, }; diff --git a/app/portainer/settings/authentication/ldap/ldap-settings-test-login/ldap-settings-test-login.css b/app/portainer/settings/authentication/ldap/ldap-settings-test-login/ldap-settings-test-login.css new file mode 100644 index 000000000..02a1cccb3 --- /dev/null +++ b/app/portainer/settings/authentication/ldap/ldap-settings-test-login/ldap-settings-test-login.css @@ -0,0 +1,4 @@ +label[for='ldap_test_password'] { + font-size: 0.9em; + margin-right: 5px; +} diff --git a/app/portainer/settings/authentication/ldap/ldap-settings-test-login/ldap-settings-test-login.html b/app/portainer/settings/authentication/ldap/ldap-settings-test-login/ldap-settings-test-login.html index 5a0871a61..d352b9461 100644 --- a/app/portainer/settings/authentication/ldap/ldap-settings-test-login/ldap-settings-test-login.html +++ b/app/portainer/settings/authentication/ldap/ldap-settings-test-login/ldap-settings-test-login.html @@ -1,16 +1,31 @@ -
+
Test login +
- +
-
-
diff --git a/app/portainer/settings/authentication/save-auth-settings-button/index.js b/app/portainer/settings/authentication/save-auth-settings-button/index.js new file mode 100644 index 000000000..6aa7c94b5 --- /dev/null +++ b/app/portainer/settings/authentication/save-auth-settings-button/index.js @@ -0,0 +1,11 @@ +export const saveAuthSettingsButton = { + templateUrl: './save-auth-settings-button.html', + bindings: { + onSaveSettings: '<', + saveButtonDisabled: '<', + saveButtonState: '<', + limitedFeatureId: '<', + limitedFeatureClass: '<', + className: '<', + }, +}; diff --git a/app/portainer/settings/authentication/save-auth-settings-button/save-auth-settings-button.html b/app/portainer/settings/authentication/save-auth-settings-button/save-auth-settings-button.html new file mode 100644 index 000000000..d1b470c35 --- /dev/null +++ b/app/portainer/settings/authentication/save-auth-settings-button/save-auth-settings-button.html @@ -0,0 +1,19 @@ +
+ Actions +
+
+
+ +
+
diff --git a/app/portainer/user-activity/activity-logs-view/activity-logs-view.html b/app/portainer/user-activity/activity-logs-view/activity-logs-view.html index b33b728e7..6d32a918c 100644 --- a/app/portainer/user-activity/activity-logs-view/activity-logs-view.html +++ b/app/portainer/user-activity/activity-logs-view/activity-logs-view.html @@ -25,7 +25,9 @@

- +
diff --git a/app/portainer/user-activity/auth-logs-view/auth-logs-view.html b/app/portainer/user-activity/auth-logs-view/auth-logs-view.html index 6bc1030b9..31559a0be 100644 --- a/app/portainer/user-activity/auth-logs-view/auth-logs-view.html +++ b/app/portainer/user-activity/auth-logs-view/auth-logs-view.html @@ -25,7 +25,9 @@

- +
diff --git a/app/portainer/views/settings/authentication/settingsAuthentication.html b/app/portainer/views/settings/authentication/settingsAuthentication.html index 3520b5e2a..be3d9a3d5 100644 --- a/app/portainer/views/settings/authentication/settingsAuthentication.html +++ b/app/portainer/views/settings/authentication/settingsAuthentication.html @@ -37,14 +37,7 @@ -
-
- Information -
-
- When using internal authentication, Portainer will encrypt user passwords and store credentials locally. -
-
+ - - - -
- Actions -
-
-
- -
-
- + diff --git a/app/portainer/views/settings/authentication/settingsAuthenticationController.js b/app/portainer/views/settings/authentication/settingsAuthenticationController.js index 02b05c88e..456643781 100644 --- a/app/portainer/views/settings/authentication/settingsAuthenticationController.js +++ b/app/portainer/views/settings/authentication/settingsAuthenticationController.js @@ -182,7 +182,8 @@ function SettingsAuthenticationController($q, $scope, $state, Notifications, Set return ( _.compact(ldapSettings.URLs).length && (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)) ); }