This is an automated email from the ASF dual-hosted git repository.
duncangrant pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-ui.git
The following commit(s) were added to refs/heads/master by this push:
new aadfc2d fields detected as likely "sensitive" now masked in composer
by default
new 356fe46 Merge pull request #181 from ahgittin/mask-secrets-in-composer
aadfc2d is described below
commit aadfc2d40d82d502b5a5285923f41fea99902413
Author: Alex Heneveld <[email protected]>
AuthorDate: Mon Dec 14 13:01:07 2020 +0000
fields detected as likely "sensitive" now masked in composer by default
with a little "eye" icon which toggles whether the value is masked
(omitted) or shown.
uses same logic as the `sensitive-field` util widget, viz containing
"secret" or "password" or "private" etc
---
.../components/spec-editor/spec-editor.directive.js | 12 ++++++++++++
.../app/components/spec-editor/spec-editor.less | 12 ++++++++++--
.../components/spec-editor/spec-editor.template.html | 18 +++++++++++++++---
3 files changed, 37 insertions(+), 5 deletions(-)
diff --git
a/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.directive.js
b/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.directive.js
index 4930f21..feb0b27 100644
---
a/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.directive.js
+++
b/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.directive.js
@@ -28,6 +28,7 @@ import brooklynDslEditor from '../dsl-editor/dsl-editor';
import brooklynDslViewer from '../dsl-viewer/dsl-viewer';
import template from './spec-editor.template.html';
import {graphicalState} from '../../views/main/graphical/graphical.state';
+import {SENSITIVE_FIELD_REGEX} from
'brooklyn-ui-utils/sensitive-field/sensitive-field';
const MODULE_NAME = 'brooklyn.components.spec-editor';
const ANY_MEMBERSPEC_REGEX = /(^.*[m,M]ember[s,S]pec$)/;
@@ -708,6 +709,17 @@ export function specEditorDirective($rootScope,
$templateCache, $injector, $sani
}
return widgetMetadata["enabled"] ? 'enabled' : 'disabled';
};
+ specEditor.isSensitiveField = (item) => {
+ // should the field support masking
+ return SENSITIVE_FIELD_REGEX.test(item.name);
+ };
+ specEditor.isHiddenSensitiveField = (item) => {
+ // is the field currently in a masked state
+ return specEditor.isSensitiveField(item) &&
!item.isHiddenSensitiveFieldUnmasked;
+ };
+ specEditor.setSensitiveFieldUnmasked = (item, val) => {
+ item.isHiddenSensitiveFieldUnmasked = val;
+ };
specEditor.customConfigWidgetError = (item) => {
var widgetMetadata =
scope.state.config.customConfigWidgetMetadata[item.name];
if (!widgetMetadata || !widgetMetadata["error"]) return null;
diff --git
a/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.less
b/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.less
index 00abd58..3a6e045 100644
--- a/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.less
+++ b/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.less
@@ -349,12 +349,11 @@ spec-editor {
order: 10;
padding-top: 3px;
}
- .label-rhs-buttons {
+ .label-rhs-buttons, .label-rhs-buttons-sensitive-hidden {
flex: 1 0 auto;
align-items: center;
text-align: right;
order: 20;
- display: none;
.spacer {
flex: 1 0 auto;
}
@@ -365,6 +364,9 @@ spec-editor {
color: @brand-primary;
}
}
+ .label-rhs-buttons {
+ display: none;
+ }
.control-value {
flex: 1 0 auto;
line-height: 20px;
@@ -458,6 +460,12 @@ spec-editor {
}
}
}
+ .hide-masked-sensitive-value {
+ display: none !important;
+ }
+ .sensitive-field-hidden .sensitive-field-hidden-icon {
+ margin-top: 5px; //align with icons when expanded
+ }
}
.param-fields {
width: 100%;
diff --git
a/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.template.html
b/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.template.html
index c09efa8..6c46db0 100644
---
a/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.template.html
+++
b/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.template.html
@@ -339,7 +339,7 @@
</span>
</label>
- <span class="label-rhs-buttons">
+ <span class="label-rhs-buttons"
ng-if="!specEditor.isHiddenSensitiveField(item)">
<span class="spacer"> </span>
<span class="custom-widget-enable-button"
ng-if="specEditor.getCustomConfigWidgetMode(item) !== null">
<i class="fa fa-fw fa-sun-o"
ng-click="specEditor.toggleCustomConfigWidgetMode(item)" aria-hidden="true"
title="{{specEditor.getCustomConfigWidgetModeTitle(item)}} [{{item.name}}]"></i>
@@ -363,9 +363,21 @@
<i class="fa fa-fw fa-eraser"
ng-click="model.removeConfig(item.name)" aria-hidden="true" title="Clear
configuration [{{item.name}}]"></i>
<span class="sr-only">Clear configuration
[{{item.name}}]</span>
</span>
+ <span class="sensitive-field-visible"
ng-if="specEditor.isSensitiveField(item) &&
!specEditor.isHiddenSensitiveField(item)">
+ <i class="fa fa-fw fa-eye"
ng-click="specEditor.setSensitiveFieldUnmasked(item, false)" aria-hidden="true"
title="Hide sensitive field value [{{item.name}}]"></i>
+ <span class="sr-only">Hide sensitive field value
[{{item.name}}]</span>
+ </span>
</span>
-
- <div class="control-value" ng-class="{ 'inline-control':
item.widgetMode==='boolean', 'unset': !defined(config[item.name]),
'has-default': defined(item.defaultValue) && item.defaultValue!=null,
'code-mode-active': state.config.codeModeActive[item.name] }">
+
+ <span class="label-rhs-buttons-sensitive-hidden"
ng-if="specEditor.isHiddenSensitiveField(item)">
+ <span class="spacer"> </span>
+ <span class="sensitive-field-hidden">
+ <i class="fa fa-fw fa-eye-slash
sensitive-field-hidden-icon"
ng-click="specEditor.setSensitiveFieldUnmasked(item, true)" aria-hidden="true"
title="Reveal masked sensitive field value [{{item.name}}]"></i>
+ <span class="sr-only">Reveal masked sensitive
field value [{{item.name}}]</span>
+ </span>
+ </span>
+
+ <div class="control-value" ng-class="{ 'inline-control':
item.widgetMode==='boolean', 'unset': !defined(config[item.name]),
'has-default': defined(item.defaultValue) && item.defaultValue!=null,
'code-mode-active': state.config.codeModeActive[item.name],
'hide-masked-sensitive-value': specEditor.isHiddenSensitiveField(item) }">
<div ng-switch-when="boolean" class="boolean">
<div class="btn-group btn-block" role="group">
<button type="button" class="btn btn-xs
btn-default" ng-class="{'btn-success active': config[item.name] === false,
'active': config[item.name] === undefined && item.defaultValue === false}"
ng-click="config[item.name] = false"
ng-focus="specEditor.recordConfigFocus(item)">false</button>