1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 /** 6 * @fileoverview ONC Data support class. Wraps a dictionary object containing 7 * ONC managed or unmanaged dictionaries. Supports nested dictionaries, 8 * e.g. data.getManagedProperty('VPN.Type'). 9 */ 10 11 cr.exportPath('cr.onc'); 12 13 /** 14 * @typedef {(Object|Array|string|undefined)} 15 */ 16 cr.onc.OncValue; 17 18 cr.define('cr.onc', function() { 19 'use strict'; 20 21 /** 22 * @constructor 23 */ 24 function OncData(data) { 25 this.data_ = data; 26 } 27 28 OncData.prototype = { 29 30 /** 31 * Returns either a managed property dictionary or an unmanaged value. 32 * @param {string} key The property key. 33 * @return {cr.onc.OncValue} The property value or dictionary if it exists, 34 * otherwise undefined. 35 */ 36 getManagedProperty: function(key) { 37 var data = this.data_; 38 while (true) { 39 var index = key.indexOf('.'); 40 if (index < 0) 41 break; 42 var keyComponent = key.substr(0, index); 43 if (!(keyComponent in data)) 44 return undefined; 45 data = data[keyComponent]; 46 key = key.substr(index + 1); 47 } 48 return data[key]; 49 }, 50 51 /** 52 * Sets the value of a property. Currently only supports unmanaged 53 * properties. 54 * @param {string} key The property key. 55 * @param {Object} value The property value to set. 56 */ 57 setManagedProperty: function(key, value) { 58 var data = this.data_; 59 while (true) { 60 var index = key.indexOf('.'); 61 if (index < 0) 62 break; 63 var keyComponent = key.substr(0, index); 64 if (!(keyComponent in data)) 65 data[keyComponent] = {}; 66 data = data[keyComponent]; 67 key = key.substr(index + 1); 68 } 69 if (!(key in data) || 70 (typeof data[key] != 'object') || 71 (!('Active' in data[key]) && !('Effective' in data[key]))) { 72 data[key] = value; 73 } else { 74 var effective = data[key]['Effective']; 75 assert(effective != 'UserPolicy' || data[key]['UserEditable']); 76 assert(effective != 'DevicePolicy' || data[key]['DeviceEditable']); 77 // For now, just update the active value. TODO(stevenjb): Eventually we 78 // should update the 'UserSetting' and 'Effective' properties correctly 79 // and send that back to Chrome. 80 data[key]['Active'] = value; 81 } 82 }, 83 84 /** 85 * Gets the active value of a property. 86 * @param {string} key The property key. 87 * @return {cr.onc.OncValue} The property value or undefined. 88 */ 89 getActiveValue: function(key) { 90 var property = this.getManagedProperty(key); 91 if (Array.isArray(property) || typeof property != 'object') 92 return property; 93 // Otherwise get the Active value (default behavior). 94 if ('Active' in property) 95 return property['Active']; 96 // If no Active value is defined, return the effective value if present. 97 var effective = this.getEffectiveValueFromProperty_( 98 /** @type {Object} */(property)); 99 if (effective != undefined) 100 return effective; 101 // Otherwise this is an Object but not a Managed one. 102 return property; 103 }, 104 105 /** 106 * Gets the translated ONC value from the result of getActiveValue() using 107 * loadTimeData. If no translation exists, returns the untranslated value. 108 * @param {string} key The property key. 109 * @return {cr.onc.OncValue} The translation if available or the value if 110 * not. 111 */ 112 getTranslatedValue: function(key) { 113 var value = this.getActiveValue(key); 114 if (typeof value != 'string') 115 return value; 116 var oncString = 'Onc' + key + value; 117 // Handle special cases 118 if (key == 'Name' && this.getActiveValue('Type') == 'Ethernet') 119 return loadTimeData.getString('ethernetName'); 120 if (key == 'VPN.Type' && value == 'L2TP-IPsec') { 121 var auth = this.getActiveValue('VPN.IPsec.AuthenticationType'); 122 if (auth != undefined) 123 oncString += auth; 124 } 125 oncString = oncString.replace(/\./g, '-'); 126 if (loadTimeData.valueExists(oncString)) 127 return loadTimeData.getString(oncString); 128 return value; 129 }, 130 131 /** 132 * Gets the recommended value of a property. 133 * @param {string} key The property key. 134 * @return {cr.onc.OncValue} The property value or undefined. 135 */ 136 getRecommendedValue: function(key) { 137 var property = this.getManagedProperty(key); 138 if (Array.isArray(property) || typeof property != 'object') 139 return undefined; 140 if (property['UserEditable']) 141 return property['UserPolicy']; 142 if (property['DeviceEditable']) 143 return property['DevicePolicy']; 144 // No value recommended by policy. 145 return undefined; 146 }, 147 148 /** 149 * Returns the Source of this configuration. If undefined returns 'None'. 150 * @return {string} The configuration source: 'None', 'User', 'Device', 151 * 'UserPolicy', or 'DevicePolicy'. 152 */ 153 getSource: function() { 154 var source = this.getActiveValue('Source'); 155 if (source == undefined) 156 return 'None'; 157 return source; 158 }, 159 160 /** 161 * Returns the WiFi security type (defaults to 'None'). 162 * @return {string} The security type. 163 */ 164 getWiFiSecurity: function() { 165 var security = this.getActiveValue('WiFi.Security'); 166 if (security == undefined) 167 return 'None'; 168 return security; 169 }, 170 171 /** 172 * Get the effective value from a Managed property ONC dictionary. 173 * @param {Object} property The managed property ONC dictionary. 174 * @return {cr.onc.OncValue} The effective value or undefined. 175 * @private 176 */ 177 getEffectiveValueFromProperty_: function(property) { 178 if ('Effective' in property) { 179 var effective = property.Effective; 180 if (effective in property) 181 return property[effective]; 182 } 183 return undefined; 184 } 185 }; 186 187 return { 188 OncData: OncData 189 }; 190 }); 191