Use imported SafeTypes

This change removes usages of global Gerrit.SafeTypes replaces
them with direct import.

Change-Id: Ida8233178bf3bd50948986a14518adb5f30ae78f
This commit is contained in:
Dmitrii Filippov
2020-04-03 18:23:05 +02:00
parent 6fd3abd49a
commit ef366ab34f
4 changed files with 64 additions and 60 deletions

View File

@@ -14,62 +14,65 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function(window) {
'use strict';
window.Gerrit = window.Gerrit || {};
const SAFE_URL_PATTERN = /^(https?:\/\/|mailto:|[^:/?#]*(?:[/?#]|$))/i;
/** @polymerBehavior Gerrit.SafeTypes */
Gerrit.SafeTypes = {};
/** @polymerBehavior Gerrit.SafeTypes */
export const SafeTypes = {};
const SAFE_URL_PATTERN = /^(https?:\/\/|mailto:|[^:/?#]*(?:[/?#]|$))/i;
/**
* Wraps a string to be used as a URL. An error is thrown if the string cannot
* be considered safe.
*
* @constructor
* @param {string} url the unwrapped, potentially unsafe URL.
*/
SafeTypes.SafeUrl = function(url) {
if (!SAFE_URL_PATTERN.test(url)) {
throw new Error(`URL not marked as safe: ${url}`);
}
this._url = url;
};
/**
* Wraps a string to be used as a URL. An error is thrown if the string cannot
* be considered safe.
*
* @constructor
* @param {string} url the unwrapped, potentially unsafe URL.
*/
Gerrit.SafeTypes.SafeUrl = function(url) {
if (!SAFE_URL_PATTERN.test(url)) {
throw new Error(`URL not marked as safe: ${url}`);
/**
* Get the string representation of the safe URL.
*
* @returns {string}
*/
SafeTypes.SafeUrl.prototype.asString = function() {
return this._url;
};
SafeTypes.safeTypesBridge = function(value, type) {
// If the value is being bound to a URL, ensure the value is wrapped in the
// SafeUrl type first. If the URL is not safe, allow the SafeUrl constructor
// to surface the error.
if (type === 'URL') {
let safeValue = null;
if (value instanceof SafeTypes.SafeUrl) {
safeValue = value;
} else if (typeof value === 'string') {
safeValue = new SafeTypes.SafeUrl(value);
}
this._url = url;
};
/**
* Get the string representation of the safe URL.
*
* @returns {string}
*/
Gerrit.SafeTypes.SafeUrl.prototype.asString = function() {
return this._url;
};
Gerrit.SafeTypes.safeTypesBridge = function(value, type) {
// If the value is being bound to a URL, ensure the value is wrapped in the
// SafeUrl type first. If the URL is not safe, allow the SafeUrl constructor
// to surface the error.
if (type === 'URL') {
let safeValue = null;
if (value instanceof Gerrit.SafeTypes.SafeUrl) {
safeValue = value;
} else if (typeof value === 'string') {
safeValue = new Gerrit.SafeTypes.SafeUrl(value);
}
if (safeValue) {
return safeValue.asString();
}
if (safeValue) {
return safeValue.asString();
}
}
// If the value is being bound to a string or a constant, then the string
// can be used as is.
if (type === 'STRING' || type === 'CONSTANT') {
return value;
}
// If the value is being bound to a string or a constant, then the string
// can be used as is.
if (type === 'STRING' || type === 'CONSTANT') {
return value;
}
// Otherwise fail.
throw new Error(`Refused to bind value as ${type}: ${value}`);
};
// TODO(dmfilippov) Remove the following lines with assignments
// Plugins can use the behavior because it was accessible with
// the global Gerrit... variable. To avoid breaking changes in plugins
// temporary assign global variables.
window.Gerrit = window.Gerrit || {};
window.Gerrit.SafeTypes = SafeTypes;
// Otherwise fail.
throw new Error(`Refused to bind value as ${type}: ${value}`);
};
})(window);

View File

@@ -31,8 +31,8 @@ limitations under the License.
<script type="module">
import '../../test/common-test-setup.js';
import './safe-types-behavior.js';
import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
import {SafeTypes} from './safe-types-behavior.js';
suite('gr-tooltip-behavior tests', () => {
let element;
let sandbox;
@@ -40,7 +40,7 @@ suite('gr-tooltip-behavior tests', () => {
suiteSetup(() => {
Polymer({
is: 'safe-types-element',
behaviors: [Gerrit.SafeTypes],
behaviors: [SafeTypes],
});
});
@@ -79,12 +79,12 @@ suite('gr-tooltip-behavior tests', () => {
suite('safeTypesBridge', () => {
function acceptsString(value, type) {
assert.equal(Gerrit.SafeTypes.safeTypesBridge(value, type),
assert.equal(SafeTypes.safeTypesBridge(value, type),
value);
}
function rejects(value, type) {
assert.throws(() => { Gerrit.SafeTypes.safeTypesBridge(value, type); });
assert.throws(() => { SafeTypes.safeTypesBridge(value, type); });
}
test('accepts valid URL strings', () => {
@@ -99,7 +99,7 @@ suite('gr-tooltip-behavior tests', () => {
test('accepts SafeUrl values', () => {
const url = '/abc/123';
const safeUrl = new element.SafeUrl(url);
assert.equal(Gerrit.SafeTypes.safeTypesBridge(safeUrl, 'URL'), url);
assert.equal(SafeTypes.safeTypesBridge(safeUrl, 'URL'), url);
});
test('rejects non-string or non-SafeUrl types', () => {

View File

@@ -25,18 +25,18 @@ import './gr-app-init.js';
import './font-roboto-local-loader.js';
import '../scripts/bundled-polymer.js';
import 'polymer-resin/standalone/polymer-resin.js';
import '../behaviors/safe-types-behavior/safe-types-behavior.js';
import './gr-app-element.js';
import './change-list/gr-embed-dashboard/gr-embed-dashboard.js';
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js';
import {PolymerElement} from '@polymer/polymer/polymer-element.js';
import {htmlTemplate} from './gr-app_html.js';
import {SafeTypes} from '../behaviors/safe-types-behavior/safe-types-behavior.js';
security.polymer_resin.install({
allowedIdentifierPrefixes: [''],
reportHandler: security.polymer_resin.CONSOLE_LOGGING_REPORT_HANDLER,
safeTypesBridge: Gerrit.SafeTypes.safeTypesBridge,
safeTypesBridge: SafeTypes.safeTypesBridge,
});
/** @extends Polymer.Element */

View File

@@ -17,10 +17,11 @@
import '../scripts/bundled-polymer.js';
import 'polymer-resin/standalone/polymer-resin.js';
import '../behaviors/safe-types-behavior/safe-types-behavior.js';
import '@polymer/iron-test-helpers/iron-test-helpers.js';
import './test-router.js';
import moment from 'moment/src/moment.js';
import {SafeTypes} from '../behaviors/safe-types-behavior/safe-types-behavior.js';
self.moment = moment;
security.polymer_resin.install({
allowedIdentifierPrefixes: [''],
@@ -35,7 +36,7 @@ security.polymer_resin.install({
JSON.stringify(args));
}
},
safeTypesBridge: Gerrit.SafeTypes.safeTypesBridge,
safeTypesBridge: SafeTypes.safeTypesBridge,
});
// Default implementations of 'fixture' and 'stub' methods in