Add PolyGerrit UI for configuring uploadvalidator Change-Id: Ibf85cb72d482f71d2491a56df66f50837780edf5
diff --git a/BUILD b/BUILD index 3a5a223..4a6aab6 100644 --- a/BUILD +++ b/BUILD
@@ -9,6 +9,7 @@ "Gerrit-PluginName: uploadvalidator", "Gerrit-ApiVersion: 2.16", "Gerrit-Module: com.googlesource.gerrit.plugins.uploadvalidator.Module", + "Gerrit-HttpModule: com.googlesource.gerrit.plugins.uploadvalidator.HttpModule", ], resources = glob(["src/main/resources/**/*"]), )
diff --git a/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/HttpModule.java b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/HttpModule.java new file mode 100644 index 0000000..c5cc519 --- /dev/null +++ b/src/main/java/com/googlesource/gerrit/plugins/uploadvalidator/HttpModule.java
@@ -0,0 +1,29 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.googlesource.gerrit.plugins.uploadvalidator; + +import com.google.gerrit.extensions.registration.DynamicSet; +import com.google.gerrit.extensions.webui.JavaScriptPlugin; +import com.google.gerrit.extensions.webui.WebUiPlugin; +import com.google.gerrit.httpd.plugins.HttpPluginModule; + +public class HttpModule extends HttpPluginModule { + + @Override + protected void configureServlets() { + DynamicSet.bind(binder(), WebUiPlugin.class) + .toInstance(new JavaScriptPlugin("gr-uploadvalidator.html")); + } +}
diff --git a/src/main/resources/static/gr-uploadvalidator-config-table.html b/src/main/resources/static/gr-uploadvalidator-config-table.html new file mode 100644 index 0000000..d688f01 --- /dev/null +++ b/src/main/resources/static/gr-uploadvalidator-config-table.html
@@ -0,0 +1,63 @@ +<!-- +@license +Copyright (C) 2019 The Android Open Source Project +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> + +<dom-module id="gr-uploadvalidator-config-table"> + <template> + <style include="shared-styles"></style> + <style include="gr-table-styles"> + .genericList { + margin-bottom: 1em; + } + + input#newEntry { + width: 100%; + } + </style> + <fieldset> + <section> + <table class="genericList"> + <tbody> + <template id="list" is="dom-repeat" items="{{entries}}"> + <tr> + <td class="nameColumn">{{item}}</td> + <td class="deleteColumn"> + <gr-button id="{{item}}" + class="deleteEntryButton" + on-click="_handleDeleteEntry"> + Delete + </gr-button> + </td> + </tr> + </template> + <tr> + <td class="nameColumn"> + <iron-input> + <input id="newEntry" type="text"> + </iron-input> + </td> + <td class="deleteColumn"> + <gr-button id="addEntry" + on-click="_handleAddEntry" + disabled="[[disabled]]"> + Add + </gr-button> + </td> + </tr> + </tbody> + </table> + </section> + </fieldset> + </template> + <script src="gr-uploadvalidator-config-table.js"></script> +</dom-module>
diff --git a/src/main/resources/static/gr-uploadvalidator-config-table.js b/src/main/resources/static/gr-uploadvalidator-config-table.js new file mode 100644 index 0000000..89d6bd9 --- /dev/null +++ b/src/main/resources/static/gr-uploadvalidator-config-table.js
@@ -0,0 +1,57 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the 'License'); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +(function () { + 'use strict'; + + Polymer({ + is: 'gr-uploadvalidator-config-table', + + properties: { + disabled: { + type: Boolean, + reflectToAttribute: true, + }, + entries: { + type: Array, + value(){ return []; }, + }, + }, + + _handleAddEntry() { + if (this.$.newEntry.value === '') { + return; + } + + if (!this.entries.includes(this.$.newEntry.value)) { + this.push('entries', this.$.newEntry.value); + this.fire('listChanged', { + entry: this.$.newEntry.value, + allEntries: this.entries, + }); + } else { + this.fire('show-alert', {message: 'Value already exists.'}); + } + this.$.newEntry.value = ''; + }, + + _handleDeleteEntry(event) { + this.splice('entries', this.entries.indexOf(event.path[1].id), 1); + this.fire('listChanged', { + entry: event.target.id, + allEntries: this.entries.slice(), + }); + }, + }) +})();
diff --git a/src/main/resources/static/gr-uploadvalidator-config.html b/src/main/resources/static/gr-uploadvalidator-config.html new file mode 100644 index 0000000..83f399b --- /dev/null +++ b/src/main/resources/static/gr-uploadvalidator-config.html
@@ -0,0 +1,189 @@ +<!-- +@license +Copyright (C) 2019 The Android Open Source Project +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> + +<link rel="import" href="./gr-uploadvalidator-config-table.html"> + +<dom-module id="gr-uploadvalidator-config"> + <template> + <style include="shared-styles"></style> + <style include="gr-form-styles"></style> + <style> + .sectionTitle { + padding-top: 2em; + } + </style> + <fieldset class="gr-form-styles"> + <h2 class="sectionTitle">Uploadvalidator Options</h2> + <section> + <section> + <h3>Author Email Pattern</h3> + <gr-uploadvalidator-config-table id="allowedAuthorEmailPattern" + entries=[[_changedConfig.allowedAuthorEmailPattern.values]]> + </gr-uploadvalidator-config-table> + </section> + <section> + <h3>Committer Email Pattern</h3> + <gr-uploadvalidator-config-table id="allowedCommitterEmailPattern" + entries=[[_changedConfig.allowedCommitterEmailPattern.values]]> + </gr-uploadvalidator-config-table> + </section> + <section> + <h3>Binary Types</h3> + <gr-uploadvalidator-config-table id="binaryTypes" + entries=[[_changedConfig.binaryTypes.values]]> + </gr-uploadvalidator-config-table> + </section> + <section> + <h3>Blocked Content</h3> + <span class="title">List Type</span> + <span class="value"> + <gr-select id="blockedContentTypeWhitelist" + bind-value="{{_changedConfig.blockedContentTypeWhitelist.value}}" + on-change="_handlePrefsChanged"> + <select> + <option value="true">Whitelist</option> + <option value="false">Blacklist</option> + </select> + </gr-select> + </span> + <gr-uploadvalidator-config-table id="blockedContentType" + entries=[[_changedConfig.blockedContentType.values]]> + </gr-uploadvalidator-config-table> + </section> + <section> + <h3>Blocked File Extensions</h3> + <gr-uploadvalidator-config-table id="blockedFileExtension" + entries=[[_changedConfig.blockedFileExtension.values]]> + </gr-uploadvalidator-config-table> + </section> + <section> + <h3>Blocked Keyword Pattern</h3> + <gr-uploadvalidator-config-table id="blockedKeywordPattern" + entries=[[_changedConfig.blockedKeywordPattern.values]]> + </gr-uploadvalidator-config-table> + </section> + <section> + <h3>Invalid Filename Pattern</h3> + <gr-uploadvalidator-config-table id="invalidFilenamePattern" + entries=[[_changedConfig.invalidFilenamePattern.values]]> + </gr-uploadvalidator-config-table> + </section> + <section> + <h3>Projects</h3> + <gr-uploadvalidator-config-table id="project" + entries=[[_changedConfig.project.values]]> + </gr-uploadvalidator-config-table> + </section> + <section> + <h3>Refs</h3> + <gr-uploadvalidator-config-table id="ref" + entries=[[_changedConfig.ref.values]]> + </gr-uploadvalidator-config-table> + </section> + <section> + <h3>Required Footers</h3> + <gr-uploadvalidator-config-table id="requiredFooter" + entries=[[_changedConfig.requiredFooter.values]]> + </gr-uploadvalidator-config-table> + </section> + <section> + <span class="title">Max Path Length</span> + <span class="value"> + <iron-input bind-value="{{_changedConfig.maxPathLength.value}}"> + <input id="maxPathLength" + value="{{_changedConfig.maxPathLength.value::input}}" + prevent-invalid-input + allowed-pattern="[0-9]" + type="number" + on-keypress="_handlePrefsChanged" + on-change="_handlePrefsChanged"> + </iron-input> + </span> + </section> + <section> + <span class="title">Reject Duplicate Pathnames Locale</span> + <span class="value"> + <gr-select id="rejectDuplicatePathnamesLocale" + bind-value="{{_changedConfig.rejectDuplicatePathnamesLocale.value}}" + on-change="_handlePrefsChanged"> + <select> + <template is="dom-repeat" + items="[[_changedConfig.rejectDuplicatePathnamesLocale.permitted_values]]"> + <option value="[[item]]">[[item]]</option> + </template> + </select> + </gr-select> + </span> + </section> + <section> + <span class="title">Reject Duplicate Pathnames</span> + <span class="value"> + <gr-select id="rejectDuplicatePathnames" + bind-value="{{_changedConfig.rejectDuplicatePathnames.value}}" + on-change="_handlePrefsChanged"> + <select> + <option value="true">True</option> + <option value="false">False</option> + </select> + </gr-select> + </span> + </section> + <section> + <span class="title">Reject Submodules</span> + <span class="value"> + <gr-select id="rejectSubmodule" + bind-value="{{_changedConfig.rejectSubmodule.value}}" + on-change="_handlePrefsChanged"> + <select> + <option value="true">True</option> + <option value="false">False</option> + </select> + </gr-select> + </span> + </section> + <section> + <span class="title">Reject Symbolic Links</span> + <span class="value"> + <gr-select id="rejectSymlink" + bind-value="{{_changedConfig.rejectSymlink.value}}" + on-change="_handlePrefsChanged"> + <select> + <option value="true">True</option> + <option value="false">False</option> + </select> + </gr-select> + </span> + </section> + <section> + <span class="title">Reject Windows Line Endings</span> + <span class="value"> + <gr-select id="rejectWindowsLineEndings" + bind-value="{{_changedConfig.rejectWindowsLineEndings.value}}" + on-change="_handlePrefsChanged"> + <select> + <option value="true">True</option> + <option value="false">False</option> + </select> + </gr-select> + </span> + </section> + <gr-button id="saveButton" + on-click="_handlePrefsSave" + disabled="[[!_prefsChanged]]"> + Save Changes + </gr-button> + </fieldset> + </template> + <script src="gr-uploadvalidator-config.js"></script> +</dom-module>
diff --git a/src/main/resources/static/gr-uploadvalidator-config.js b/src/main/resources/static/gr-uploadvalidator-config.js new file mode 100644 index 0000000..508231c --- /dev/null +++ b/src/main/resources/static/gr-uploadvalidator-config.js
@@ -0,0 +1,79 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the 'License'); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +(function () { + 'use strict'; + + Polymer({ + is: 'gr-uploadvalidator-config', + + properties: { + repoName: String, + _config: Object, + _changedConfig: Object, + _prefsChanged: { + type: Boolean, + value: false, + }, + _projectRestApi: Object, + }, + + listeners: { + listChanged: '_handleListDataChanged', + }, + + attached() { + this._projectRestApi = this.plugin.restApi('/projects/'); + + this._getPreferences().then(() => { + this._changedConfig = Object.assign({}, this._config); + }); + }, + + _getPreferences() { + return this._projectRestApi.get(`${this.repoName}/config`) + .then(config => { + if (!config) { + return; + } + + if (config.plugin_config && config.plugin_config.uploadvalidator) { + this._config = config.plugin_config.uploadvalidator; + } + }) + }, + + _handleListDataChanged(event) { + this._changedConfig[event.target.id] = { values: event.detail.allEntries }; + this._handlePrefsChanged(); + }, + + _handlePrefsChanged() { + this._prefsChanged = true; + }, + + _handlePrefsSave() { + let body = { plugin_config_values: {} }; + body.plugin_config_values.uploadvalidator = this._changedConfig; + + this._projectRestApi.put(`${this.repoName}/config`, body) + .then(() => { + this._prefsChanged = false; + }).catch(response => { + this.fire('show-error', { message: response }); + }); + }, + + }); +})();
diff --git a/src/main/resources/static/gr-uploadvalidator.html b/src/main/resources/static/gr-uploadvalidator.html new file mode 100644 index 0000000..767915a --- /dev/null +++ b/src/main/resources/static/gr-uploadvalidator.html
@@ -0,0 +1,26 @@ +<!-- +@license +Copyright (C) 2019 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> + +<link rel="import" href="./gr-uploadvalidator-config.html"> + +<dom-module id="gr-uploadvalidator"> + <script> + Gerrit.install(plugin => { + plugin.registerCustomComponent('repo-config', 'gr-uploadvalidator-config'); + }); + </script> +</dom-module>