Merge "Introduce gr-project-access"
This commit is contained in:
@@ -33,6 +33,7 @@ limitations under the License.
|
||||
<link rel="import" href="../gr-group-members/gr-group-members.html">
|
||||
<link rel="import" href="../gr-plugin-list/gr-plugin-list.html">
|
||||
<link rel="import" href="../gr-project/gr-project.html">
|
||||
<link rel="import" href="../gr-project-access/gr-project-access.html">
|
||||
<link rel="import" href="../gr-project-commands/gr-project-commands.html">
|
||||
<link rel="import" href="../gr-project-detail-list/gr-project-detail-list.html">
|
||||
|
||||
@@ -127,6 +128,11 @@ limitations under the License.
|
||||
project="[[params.project]]"></gr-project-commands>
|
||||
</main>
|
||||
</template>
|
||||
<template is="dom-if" if="[[_showProjectAccess]]" restamp="true">
|
||||
<main class="table">
|
||||
<gr-project-access project="[[params.project]]"></gr-project-access>
|
||||
</main>
|
||||
</template>
|
||||
<template is="dom-if" if="[[params.placeholder]]" restamp="true">
|
||||
<gr-placeholder title="Admin" path="[[path]]"></gr-placeholder>
|
||||
</template>
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
_showProjectList: Boolean,
|
||||
_showProjectDetailList: Boolean,
|
||||
_showPluginList: Boolean,
|
||||
_showProjectAccess: Boolean,
|
||||
},
|
||||
|
||||
behaviors: [
|
||||
@@ -110,6 +111,13 @@
|
||||
view: 'gr-project',
|
||||
url: `/admin/projects/${this.encodeURL(this._projectName, true)}`,
|
||||
children: [{
|
||||
name: 'Access',
|
||||
detailType: 'access',
|
||||
view: 'gr-project-access',
|
||||
url: `/admin/projects/` +
|
||||
`${this.encodeURL(this._projectName, true)},access`,
|
||||
},
|
||||
{
|
||||
name: 'Commands',
|
||||
detailType: 'commands',
|
||||
view: 'gr-project-commands',
|
||||
@@ -187,6 +195,7 @@
|
||||
this.set('_showProjectDetailList',
|
||||
params.adminView === 'gr-project-detail-list');
|
||||
this.set('_showPluginList', params.adminView === 'gr-plugin-list');
|
||||
this.set('_showProjectAccess', params.adminView === 'gr-project-access');
|
||||
if (params.project !== this._projectName) {
|
||||
this._projectName = params.project || '';
|
||||
// Reloads the admin menu.
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<!--
|
||||
Copyright (C) 2017 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="../../../bower_components/polymer/polymer.html">
|
||||
|
||||
<link rel="import" href="../../../behaviors/gr-access-behavior/gr-access-behavior.html">
|
||||
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
|
||||
<link rel="import" href="../../../behaviors/gr-url-encoding-behavior.html">
|
||||
|
||||
<link rel="import" href="../../../styles/gr-menu-page-styles.html">
|
||||
<link rel="import" href="../../../styles/shared-styles.html">
|
||||
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
|
||||
<link rel="import" href="../gr-access-section/gr-access-section.html">
|
||||
|
||||
<script src="../../../scripts/util.js"></script>
|
||||
|
||||
<dom-module id="gr-project-access">
|
||||
<template>
|
||||
<style include="shared-styles"></style>
|
||||
<style include="gr-menu-page-styles"></style>
|
||||
<main>
|
||||
<template
|
||||
is="dom-repeat"
|
||||
items="{{_sections}}"
|
||||
as="section">
|
||||
<gr-access-section
|
||||
capabilities="[[_capabilities]]"
|
||||
section="{{section}}"
|
||||
labels="[[_labels]]"
|
||||
editing="[[_editing]]"></gr-access-section>
|
||||
</template>
|
||||
<template is="dom-if" if="[[_inheritsFrom]]">
|
||||
<h3 id="inheritsFrom">Rights Inherit From
|
||||
<a href$="[[_computeParentHref(_inheritsFrom.name)]]" rel="noopener">
|
||||
[[_inheritsFrom.name]]</a>
|
||||
</h3>
|
||||
</template>
|
||||
</main>
|
||||
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
|
||||
</template>
|
||||
<script src="gr-project-access.js"></script>
|
||||
</dom-module>
|
||||
@@ -0,0 +1,80 @@
|
||||
// Copyright (C) 2017 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-project-access',
|
||||
|
||||
properties: {
|
||||
project: {
|
||||
type: String,
|
||||
observer: '_projectChanged',
|
||||
},
|
||||
|
||||
_capabilities: Object,
|
||||
/** @type {?} */
|
||||
_inheritsFrom: Object,
|
||||
_labels: Object,
|
||||
_local: Object,
|
||||
_editing: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
_sections: Array,
|
||||
},
|
||||
|
||||
behaviors: [
|
||||
Gerrit.AccessBehavior,
|
||||
Gerrit.BaseUrlBehavior,
|
||||
Gerrit.URLEncodingBehavior,
|
||||
],
|
||||
|
||||
_projectChanged(project) {
|
||||
const promises = [];
|
||||
if (!this._sections) {
|
||||
this._sections = [];
|
||||
}
|
||||
promises.push(this.$.restAPI.getProjectAccessRights(project).then(res => {
|
||||
this._inheritsFrom = res.inherits_from;
|
||||
this._local = res.local;
|
||||
return this.toSortedArray(this._local);
|
||||
}));
|
||||
|
||||
promises.push(this.$.restAPI.getCapabilities().then(res => {
|
||||
return res;
|
||||
}));
|
||||
|
||||
promises.push(this.$.restAPI.getProject(project).then(res => {
|
||||
return res.labels;
|
||||
}));
|
||||
|
||||
return Promise.all(promises).then(value => {
|
||||
this._capabilities = value[1];
|
||||
this._labels = value[2];
|
||||
|
||||
// Use splice instead of setting _sections directly so that dom-repeat
|
||||
// renders new sections properly. Otherwise, gr-access-section is not
|
||||
// aware that the section has updated.
|
||||
this.splice(...['_sections', 0, this._sections.length]
|
||||
.concat(value[0]));
|
||||
});
|
||||
},
|
||||
|
||||
_computeParentHref(projectName) {
|
||||
return this.getBaseUrl() +
|
||||
`/admin/projects/${this.encodeURL(projectName, true)},access`;
|
||||
},
|
||||
});
|
||||
})();
|
||||
@@ -0,0 +1,118 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Copyright (C) 2017 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.
|
||||
-->
|
||||
|
||||
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
|
||||
<title>gr-project-access</title>
|
||||
|
||||
<script src="../../../bower_components/page/page.js"></script>
|
||||
<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
|
||||
<script src="../../../bower_components/web-component-tester/browser.js"></script>
|
||||
<link rel="import" href="../../../test/common-test-setup.html"/>
|
||||
<link rel="import" href="gr-project-access.html">
|
||||
|
||||
<script>void(0);</script>
|
||||
|
||||
<test-fixture id="basic">
|
||||
<template>
|
||||
<gr-project-access></gr-project-access>
|
||||
</template>
|
||||
</test-fixture>
|
||||
|
||||
<script>
|
||||
suite('gr-project-access tests', () => {
|
||||
let element;
|
||||
let sandbox;
|
||||
|
||||
setup(() => {
|
||||
sandbox = sinon.sandbox.create();
|
||||
element = fixture('basic');
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
test('_projectChanged called when project name changes', () => {
|
||||
sandbox.stub(element, '_projectChanged');
|
||||
element.project = 'New Project';
|
||||
assert.isTrue(element._projectChanged.called);
|
||||
});
|
||||
|
||||
test('_projectChanged', done => {
|
||||
const capabilitiesRes = {
|
||||
accessDatabase: {
|
||||
id: 'accessDatabase',
|
||||
name: 'Access Database',
|
||||
},
|
||||
};
|
||||
const accessRes = {
|
||||
local: {
|
||||
GLOBAL_CAPABILITIES: {
|
||||
permissions: {
|
||||
accessDatabase: {
|
||||
rules: {
|
||||
123: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const projectRes = {
|
||||
labels: {
|
||||
'Code-Review': {},
|
||||
},
|
||||
};
|
||||
const accessStub = sandbox.stub(element.$.restAPI,
|
||||
'getProjectAccessRights') .returns(Promise.resolve(accessRes));
|
||||
const capabilitiesStub = sandbox.stub(element.$.restAPI,
|
||||
'getCapabilities').returns(Promise.resolve(capabilitiesRes));
|
||||
const projectStub = sandbox.stub(element.$.restAPI, 'getProject').returns(
|
||||
Promise.resolve(projectRes));
|
||||
|
||||
element._projectChanged('New Project').then(() => {
|
||||
assert.isTrue(accessStub.called);
|
||||
assert.isTrue(capabilitiesStub.called);
|
||||
assert.isTrue(projectStub.called);
|
||||
assert.isNotOk(element._inheritsFrom);
|
||||
assert.deepEqual(element._local, accessRes.local);
|
||||
assert.deepEqual(element._sections,
|
||||
element.toSortedArray(accessRes.local));
|
||||
assert.deepEqual(element._labels, projectRes.labels);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('_computeParentHref', () => {
|
||||
const projectName = 'test-project';
|
||||
assert.equal(element._computeParentHref(projectName),
|
||||
'/admin/projects/test-project,access');
|
||||
});
|
||||
|
||||
test('inherit section', () => {
|
||||
sandbox.stub(element, '_computeParentHref');
|
||||
assert.isNotOk(Polymer.dom(element.root).querySelector('#inheritsFrom'));
|
||||
assert.isFalse(element._computeParentHref.called);
|
||||
element._inheritsFrom = {
|
||||
name: 'another-project',
|
||||
};
|
||||
flushAsynchronousOperations();
|
||||
assert.isOk(Polymer.dom(element.root).querySelector('#inheritsFrom'));
|
||||
assert.isTrue(element._computeParentHref.called);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -45,6 +45,9 @@
|
||||
// Matches /admin/projects/<project>,commands.
|
||||
PROJECT_COMMANDS: /^\/admin\/projects\/(.+),commands$/,
|
||||
|
||||
// Matches /admin/projects/<project>,access.
|
||||
PROJECT_ACCESS: /^\/admin\/projects\/(.+),access$/,
|
||||
|
||||
// Matches /admin/projects[,<offset>][/].
|
||||
PROJECT_LIST_OFFSET: /^\/admin\/projects(,(\d+))?(\/)?$/,
|
||||
PROJECT_LIST_FILTER: '/admin/projects/q/filter::filter',
|
||||
@@ -402,6 +405,9 @@
|
||||
this._mapRoute(RoutePattern.PROJECT_COMMANDS,
|
||||
'_handleProjectCommandsRoute', true);
|
||||
|
||||
this._mapRoute(RoutePattern.PROJECT_ACCESS,
|
||||
'_handleProjectAccessRoute', true);
|
||||
|
||||
this._mapRoute(RoutePattern.BRANCH_LIST_OFFSET,
|
||||
'_handleBranchListOffsetRoute');
|
||||
|
||||
@@ -598,6 +604,15 @@
|
||||
});
|
||||
},
|
||||
|
||||
_handleProjectAccessRoute(data) {
|
||||
this._setParams({
|
||||
view: Gerrit.Nav.View.ADMIN,
|
||||
adminView: 'gr-project-access',
|
||||
detailType: 'access',
|
||||
project: data.params[0],
|
||||
});
|
||||
},
|
||||
|
||||
_handleBranchListOffsetRoute(data) {
|
||||
this._setParams({
|
||||
view: Gerrit.Nav.View.ADMIN,
|
||||
|
||||
@@ -102,6 +102,7 @@ limitations under the License.
|
||||
'_handlePluginListFilterRoute',
|
||||
'_handlePluginListOffsetRoute',
|
||||
'_handlePluginListRoute',
|
||||
'_handleProjectAccessRoute',
|
||||
'_handleProjectCommandsRoute',
|
||||
'_handleSettingsLegacyRoute',
|
||||
'_handleSettingsRoute',
|
||||
@@ -655,6 +656,16 @@ limitations under the License.
|
||||
});
|
||||
});
|
||||
|
||||
test('_handleProjectAccessRoute', () => {
|
||||
const data = {params: {0: 4321}};
|
||||
assertDataToParams(data, '_handleProjectAccessRoute', {
|
||||
view: Gerrit.Nav.View.ADMIN,
|
||||
adminView: 'gr-project-access',
|
||||
detailType: 'access',
|
||||
project: 4321,
|
||||
});
|
||||
});
|
||||
|
||||
suite('branch list routes', () => {
|
||||
test('_handleBranchListOffsetRoute', () => {
|
||||
const data = {params: {0: 4321}};
|
||||
|
||||
@@ -201,6 +201,11 @@
|
||||
return this._fetchSharedCacheURL('/config/server/info');
|
||||
},
|
||||
|
||||
getProject(project) {
|
||||
return this._fetchSharedCacheURL(
|
||||
'/projects/' + encodeURIComponent(project));
|
||||
},
|
||||
|
||||
getProjectConfig(project) {
|
||||
return this._fetchSharedCacheURL(
|
||||
'/projects/' + encodeURIComponent(project) + '/config');
|
||||
@@ -1016,6 +1021,17 @@
|
||||
);
|
||||
},
|
||||
|
||||
getProjectAccessRights(projectName) {
|
||||
return this._fetchSharedCacheURL(
|
||||
`/projects/${encodeURIComponent(projectName)}/access`);
|
||||
},
|
||||
|
||||
setProjectAccessRights(projectName, projectInfo) {
|
||||
return this.send(
|
||||
'POST', `/projects/${encodeURIComponent(projectName)}/access`,
|
||||
projectInfo);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} inputVal
|
||||
* @param {number} opt_n
|
||||
@@ -1679,6 +1695,10 @@
|
||||
});
|
||||
},
|
||||
|
||||
getCapabilities(token) {
|
||||
return this.fetchJSON('/config/server/capabilities');
|
||||
},
|
||||
|
||||
setAssignee(changeNum, assignee) {
|
||||
const p = {assignee};
|
||||
return this.getChangeURLAndSend(changeNum, 'PUT', null, '/assignee', p);
|
||||
|
||||
@@ -45,6 +45,7 @@ limitations under the License.
|
||||
'admin/gr-permission/gr-permission_test.html',
|
||||
'admin/gr-plugin-list/gr-plugin-list_test.html',
|
||||
'admin/gr-project/gr-project_test.html',
|
||||
'admin/gr-project-access/gr-project-access_test.html',
|
||||
'admin/gr-project-commands/gr-project-commands_test.html',
|
||||
'admin/gr-project-detail-list/gr-project-detail-list_test.html',
|
||||
'admin/gr-rule-editor/gr-rule-editor_test.html',
|
||||
|
||||
Reference in New Issue
Block a user