Commit 0ee21671 authored by Steven Bennetts's avatar Steven Bennetts Committed by Commit Bot

Network config: Fix up network-property-list and support string arrays

In preparation for supporting OpenVPN.ExtraHosts, we need to support
string arrays in network-property-list. Some issues with policy
indicators were discovered as well.

This CL:
* Adds support for an editable StringArray type.
* Only shows policy indicators for fields that may be user editable.
  (Other indicators just provide noise).
* Treats properties with no entry in policy controlled configurations
  as not user editable.

Bug: 742666,819837
Cq-Include-Trybots: master.tryserver.chromium.linux:closure_compilation
Change-Id: I601e4cc0839bd1560bd1dc5af099aba3b19623dc
Reviewed-on: https://chromium-review.googlesource.com/955934
Commit-Queue: Steven Bennetts <stevenjb@chromium.org>
Reviewed-by: default avatarToni Barzic <tbarzic@chromium.org>
Cr-Commit-Position: refs/heads/master@{#542582}
parent b9a8ea33
......@@ -29,36 +29,33 @@
filter="[[computeFilter_(prefix, propertyDict, editFieldTypes)]]">
<div class="property-box single-column two-line stretch">
<!-- Property label -->
<div>[[getPropertyLabel_(item, prefix)]]</div>
<div class="layout horizontal center">
<div>[[getPropertyLabel_(item, prefix)]]</div>
<template is="dom-if" restamp
if="[[isEditTypeAny_(item, editFieldTypes)]]">
<cr-policy-network-indicator
property="[[getProperty_(item, propertyDict)]]">
</cr-policy-network-indicator>
</template>
</div>
<!-- Uneditable property value -->
<div class="layout horizontal"
hidden="[[isEditable_(item, '', propertyDict, editFieldTypes)]]">
<template is="dom-if" restamp
if="[[!isEditable_(item, propertyDict, editFieldTypes)]]">
<div class="secondary">
[[getPropertyValue_(item, prefix, propertyDict)]]
</div>
<cr-policy-network-indicator
property="[[getProperty_(item, propertyDict)]]">
</cr-policy-network-indicator>
</div>
</template>
<!-- Editable String property value -->
<template is="dom-if" if="[[isEditable_(
item, 'String', propertyDict, editFieldTypes)]]">
<template is="dom-if" restamp
if="[[isEditTypeInput_(item, propertyDict, editFieldTypes)]]">
<paper-input-container no-label-float>
<input id="[[item]]" is="iron-input" slot="input"
type="[[getEditInputType_(item, editFieldTypes)]]"
value="[[getPropertyValue_(item, prefix, propertyDict)]]"
on-change="onValueChange_">
</paper-input-container>
</template>
<!-- Editable Password property value -->
<template is="dom-if" if="[[isEditable_(
item, 'Password', propertyDict, editFieldTypes)]]">
<paper-input-container no-label-float>
<input id="[[item]]" is="iron-input" type="password" slot="input"
value="[[getPropertyValue_(item, prefix, propertyDict)]]"
on-change="onValueChange_">
</paper-input-container>
</template>
<!-- TODO(stevenjb): Support other types. -->
<!-- TODO(stevenjb): Support other types (number, boolean)? -->
</div>
</template>
</template>
......
......@@ -34,6 +34,8 @@ Polymer({
* Edit type of editable fields. May contain a property for any field in
* |fields|. Other properties will be ignored. Property values can be:
* 'String' - A text input will be displayed.
* 'StringArray' - A text input will be displayed that expects a comma
* separated list of strings.
* 'Password' - A string with input type = password.
* TODO(stevenjb): Support types with custom validation, e.g. IPAddress.
* TODO(stevenjb): Support 'Number'.
......@@ -64,17 +66,17 @@ Polymer({
onValueChange_: function(event) {
if (!this.propertyDict)
return;
var field = event.target.id;
var curValue = this.get(field, this.propertyDict);
if (typeof curValue == 'object') {
var key = event.target.id;
var curValue = this.get(key, this.propertyDict);
if (typeof curValue == 'object' && !Array.isArray(curValue)) {
// Extract the property from an ONC managed dictionary.
curValue = CrOnc.getActiveValue(
/** @type {!CrOnc.ManagedProperty} */ (curValue));
}
var newValue = event.target.value;
var newValue = this.getValueFromEditField_(key, event.target.value);
if (newValue == curValue)
return;
this.fire('property-change', {field: field, value: newValue});
this.fire('property-change', {field: key, value: newValue});
},
/**
......@@ -119,19 +121,68 @@ Polymer({
/**
* @param {string} key The property key.
* @param {string} type The field type.
* @param {!Object} propertyDict
* @param {!Object} editFieldTypes
* @return {boolean}
* @private
*/
isEditable_: function(key, type, propertyDict, editFieldTypes) {
isPropertyEditable_: function(key, propertyDict) {
var property = /** @type {!CrOnc.ManagedProperty|undefined} */ (
this.get(key, propertyDict));
if (this.isNetworkPolicyEnforced(property))
if (property === undefined) {
// Unspecified properties in policy configurations are not user
// modifiable. https://crbug.com/819837.
var source = propertyDict.Source;
return source != 'UserPolicy' && source != 'DevicePolicy';
}
return !this.isNetworkPolicyEnforced(property);
},
/**
* @param {string} key The property key.
* @param {!Object} editFieldTypes
* @return {boolean}
* @private
*/
isEditTypeAny_: function(key, editFieldTypes) {
return editFieldTypes[key] !== undefined;
},
/**
* @param {string} key The property key.
* @param {!Object} propertyDict
* @param {!Object} editFieldTypes
* @return {boolean}
* @private
*/
isEditTypeInput_: function(key, propertyDict, editFieldTypes) {
if (!this.isPropertyEditable_(key, propertyDict))
return false;
var editType = editFieldTypes[key];
return editType !== undefined && (type == '' || editType == type);
return editType == 'String' || editType == 'StringArray' ||
editType == 'Password';
},
/**
* @param {string} key The property key.
* @param {!Object} editFieldTypes
* @return {string}
* @private
*/
getEditInputType_: function(key, editFieldTypes) {
return editFieldTypes[key] == 'Password' ? 'password' : 'text';
},
/**
* @param {string} key The property key.
* @param {!Object} propertyDict
* @param {!Object} editFieldTypes
* @return {boolean}
* @private
*/
isEditable_: function(key, propertyDict, editFieldTypes) {
if (!this.isPropertyEditable_(key, propertyDict))
return false;
return this.isEditTypeAny_(key, editFieldTypes);
},
/**
......@@ -141,7 +192,13 @@ Polymer({
* @private
*/
getProperty_: function(key, propertyDict) {
return this.get(key, propertyDict);
var property = this.get(key, propertyDict);
if (property === undefined && propertyDict.Source) {
// Provide an empty property object with the network policy source.
// See https://crbug.com/819837 for more info.
return {Effective: propertyDict.Source};
}
return property;
},
/**
......@@ -155,16 +212,20 @@ Polymer({
var value = this.get(key, propertyDict);
if (value === undefined)
return '';
if (typeof value == 'object') {
if (typeof value == 'object' && !Array.isArray(value)) {
// Extract the property from an ONC managed dictionary
value =
CrOnc.getActiveValue(/** @type {!CrOnc.ManagedProperty} */ (value));
}
if (Array.isArray(value))
return value.join(', ');
var customValue = this.getCustomPropertyValue_(key, value);
if (customValue)
return customValue;
if (typeof value == 'number' || typeof value == 'boolean')
return value.toString();
assert(typeof value == 'string');
var valueStr = /** @type {string} */ (value);
var oncKey = 'Onc' + prefix + key;
......@@ -175,6 +236,20 @@ Polymer({
return valueStr;
},
/**
* Converts edit field values to the correct edit type.
* @param {string} key The property key.
* @param {*} fieldValue The value from the field.
* @return {*}
* @private
*/
getValueFromEditField_(key, fieldValue) {
var editType = this.editFieldTypes[key];
if (editType == 'StringArray')
return fieldValue.toString().split(/, */);
return fieldValue;
},
/**
* @param {string} key The property key.
* @param {*} value The property value.
......
......@@ -46,7 +46,7 @@ CrOnc.NetworkStateProperties;
/** @typedef {chrome.networkingPrivate.ManagedProperties} */
CrOnc.NetworkProperties;
/** @typedef {string|number|boolean|Object|Array<Object>} */
/** @typedef {string|number|boolean|Array<string>|Object|Array<Object>} */
CrOnc.NetworkPropertyType;
/**
......@@ -227,7 +227,7 @@ CrOnc.getActiveValue = function(property) {
if (property == undefined)
return undefined;
if (typeof property != 'object') {
if (typeof property != 'object' || Array.isArray(property)) {
console.error(
'getActiveValue called on non object: ' + JSON.stringify(property));
return undefined;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment