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-group-members/gr-group-members.html">
|
||||||
<link rel="import" href="../gr-plugin-list/gr-plugin-list.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/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-commands/gr-project-commands.html">
|
||||||
<link rel="import" href="../gr-project-detail-list/gr-project-detail-list.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>
|
project="[[params.project]]"></gr-project-commands>
|
||||||
</main>
|
</main>
|
||||||
</template>
|
</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">
|
<template is="dom-if" if="[[params.placeholder]]" restamp="true">
|
||||||
<gr-placeholder title="Admin" path="[[path]]"></gr-placeholder>
|
<gr-placeholder title="Admin" path="[[path]]"></gr-placeholder>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -69,6 +69,7 @@
|
|||||||
_showProjectList: Boolean,
|
_showProjectList: Boolean,
|
||||||
_showProjectDetailList: Boolean,
|
_showProjectDetailList: Boolean,
|
||||||
_showPluginList: Boolean,
|
_showPluginList: Boolean,
|
||||||
|
_showProjectAccess: Boolean,
|
||||||
},
|
},
|
||||||
|
|
||||||
behaviors: [
|
behaviors: [
|
||||||
@@ -110,6 +111,13 @@
|
|||||||
view: 'gr-project',
|
view: 'gr-project',
|
||||||
url: `/admin/projects/${this.encodeURL(this._projectName, true)}`,
|
url: `/admin/projects/${this.encodeURL(this._projectName, true)}`,
|
||||||
children: [{
|
children: [{
|
||||||
|
name: 'Access',
|
||||||
|
detailType: 'access',
|
||||||
|
view: 'gr-project-access',
|
||||||
|
url: `/admin/projects/` +
|
||||||
|
`${this.encodeURL(this._projectName, true)},access`,
|
||||||
|
},
|
||||||
|
{
|
||||||
name: 'Commands',
|
name: 'Commands',
|
||||||
detailType: 'commands',
|
detailType: 'commands',
|
||||||
view: 'gr-project-commands',
|
view: 'gr-project-commands',
|
||||||
@@ -187,6 +195,7 @@
|
|||||||
this.set('_showProjectDetailList',
|
this.set('_showProjectDetailList',
|
||||||
params.adminView === 'gr-project-detail-list');
|
params.adminView === 'gr-project-detail-list');
|
||||||
this.set('_showPluginList', params.adminView === 'gr-plugin-list');
|
this.set('_showPluginList', params.adminView === 'gr-plugin-list');
|
||||||
|
this.set('_showProjectAccess', params.adminView === 'gr-project-access');
|
||||||
if (params.project !== this._projectName) {
|
if (params.project !== this._projectName) {
|
||||||
this._projectName = params.project || '';
|
this._projectName = params.project || '';
|
||||||
// Reloads the admin menu.
|
// 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.
|
// Matches /admin/projects/<project>,commands.
|
||||||
PROJECT_COMMANDS: /^\/admin\/projects\/(.+),commands$/,
|
PROJECT_COMMANDS: /^\/admin\/projects\/(.+),commands$/,
|
||||||
|
|
||||||
|
// Matches /admin/projects/<project>,access.
|
||||||
|
PROJECT_ACCESS: /^\/admin\/projects\/(.+),access$/,
|
||||||
|
|
||||||
// Matches /admin/projects[,<offset>][/].
|
// Matches /admin/projects[,<offset>][/].
|
||||||
PROJECT_LIST_OFFSET: /^\/admin\/projects(,(\d+))?(\/)?$/,
|
PROJECT_LIST_OFFSET: /^\/admin\/projects(,(\d+))?(\/)?$/,
|
||||||
PROJECT_LIST_FILTER: '/admin/projects/q/filter::filter',
|
PROJECT_LIST_FILTER: '/admin/projects/q/filter::filter',
|
||||||
@@ -402,6 +405,9 @@
|
|||||||
this._mapRoute(RoutePattern.PROJECT_COMMANDS,
|
this._mapRoute(RoutePattern.PROJECT_COMMANDS,
|
||||||
'_handleProjectCommandsRoute', true);
|
'_handleProjectCommandsRoute', true);
|
||||||
|
|
||||||
|
this._mapRoute(RoutePattern.PROJECT_ACCESS,
|
||||||
|
'_handleProjectAccessRoute', true);
|
||||||
|
|
||||||
this._mapRoute(RoutePattern.BRANCH_LIST_OFFSET,
|
this._mapRoute(RoutePattern.BRANCH_LIST_OFFSET,
|
||||||
'_handleBranchListOffsetRoute');
|
'_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) {
|
_handleBranchListOffsetRoute(data) {
|
||||||
this._setParams({
|
this._setParams({
|
||||||
view: Gerrit.Nav.View.ADMIN,
|
view: Gerrit.Nav.View.ADMIN,
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ limitations under the License.
|
|||||||
'_handlePluginListFilterRoute',
|
'_handlePluginListFilterRoute',
|
||||||
'_handlePluginListOffsetRoute',
|
'_handlePluginListOffsetRoute',
|
||||||
'_handlePluginListRoute',
|
'_handlePluginListRoute',
|
||||||
|
'_handleProjectAccessRoute',
|
||||||
'_handleProjectCommandsRoute',
|
'_handleProjectCommandsRoute',
|
||||||
'_handleSettingsLegacyRoute',
|
'_handleSettingsLegacyRoute',
|
||||||
'_handleSettingsRoute',
|
'_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', () => {
|
suite('branch list routes', () => {
|
||||||
test('_handleBranchListOffsetRoute', () => {
|
test('_handleBranchListOffsetRoute', () => {
|
||||||
const data = {params: {0: 4321}};
|
const data = {params: {0: 4321}};
|
||||||
|
|||||||
@@ -201,6 +201,11 @@
|
|||||||
return this._fetchSharedCacheURL('/config/server/info');
|
return this._fetchSharedCacheURL('/config/server/info');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getProject(project) {
|
||||||
|
return this._fetchSharedCacheURL(
|
||||||
|
'/projects/' + encodeURIComponent(project));
|
||||||
|
},
|
||||||
|
|
||||||
getProjectConfig(project) {
|
getProjectConfig(project) {
|
||||||
return this._fetchSharedCacheURL(
|
return this._fetchSharedCacheURL(
|
||||||
'/projects/' + encodeURIComponent(project) + '/config');
|
'/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 {string} inputVal
|
||||||
* @param {number} opt_n
|
* @param {number} opt_n
|
||||||
@@ -1679,6 +1695,10 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getCapabilities(token) {
|
||||||
|
return this.fetchJSON('/config/server/capabilities');
|
||||||
|
},
|
||||||
|
|
||||||
setAssignee(changeNum, assignee) {
|
setAssignee(changeNum, assignee) {
|
||||||
const p = {assignee};
|
const p = {assignee};
|
||||||
return this.getChangeURLAndSend(changeNum, 'PUT', null, '/assignee', p);
|
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-permission/gr-permission_test.html',
|
||||||
'admin/gr-plugin-list/gr-plugin-list_test.html',
|
'admin/gr-plugin-list/gr-plugin-list_test.html',
|
||||||
'admin/gr-project/gr-project_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-commands/gr-project-commands_test.html',
|
||||||
'admin/gr-project-detail-list/gr-project-detail-list_test.html',
|
'admin/gr-project-detail-list/gr-project-detail-list_test.html',
|
||||||
'admin/gr-rule-editor/gr-rule-editor_test.html',
|
'admin/gr-rule-editor/gr-rule-editor_test.html',
|
||||||
|
|||||||
Reference in New Issue
Block a user