summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/sonar-web/src/main/js/apps/global-permissions/groups-view.js22
-rw-r--r--server/sonar-web/src/main/js/apps/global-permissions/permission-groups.jsx1
-rw-r--r--server/sonar-web/src/main/js/apps/global-permissions/permission-users.jsx1
-rw-r--r--server/sonar-web/src/main/js/apps/global-permissions/permission.jsx12
-rw-r--r--server/sonar-web/src/main/js/apps/global-permissions/permissions-list.jsx2
-rw-r--r--server/sonar-web/src/main/js/apps/global-permissions/users-view.js22
-rw-r--r--server/sonar-web/src/main/js/apps/main/app.jsx2
-rw-r--r--server/sonar-web/src/main/js/apps/project-permissions/app.jsx9
-rw-r--r--server/sonar-web/src/main/js/apps/project-permissions/main-component.jsx55
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/controllers/project_roles_controller.rb4
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/views/project_roles/index.html.erb57
-rw-r--r--server/sonar-web/test/medium/global-permissions.spec.js2
-rw-r--r--server/sonar-web/test/medium/project-permissions.spec.js18
13 files changed, 130 insertions, 77 deletions
diff --git a/server/sonar-web/src/main/js/apps/global-permissions/groups-view.js b/server/sonar-web/src/main/js/apps/global-permissions/groups-view.js
index fbc0691ed6d..950c9888a61 100644
--- a/server/sonar-web/src/main/js/apps/global-permissions/groups-view.js
+++ b/server/sonar-web/src/main/js/apps/global-permissions/groups-view.js
@@ -4,6 +4,22 @@ define([
'./templates'
], function (Modal) {
+ function getSearchUrl(permission, project) {
+ var url = baseUrl + '/api/permissions/groups?ps=100&permission=' + permission;
+ if (project) {
+ url = url + '&projectId=' + project;
+ }
+ return url;
+ }
+
+ function getExtra (permission, project) {
+ var extra = { permission: permission };
+ if (project) {
+ extra.projectId = project;
+ }
+ return extra;
+ }
+
return Modal.extend({
template: Templates['global-permissions-groups'],
@@ -18,12 +34,10 @@ define([
return item.name;
},
queryParam: 'q',
- searchUrl: baseUrl + '/api/permissions/groups?ps=100&permission=' + this.options.permission,
+ searchUrl: getSearchUrl(this.options.permission, this.options.project),
selectUrl: baseUrl + '/api/permissions/add_group',
deselectUrl: baseUrl + '/api/permissions/remove_group',
- extra: {
- permission: this.options.permission
- },
+ extra: getExtra(this.options.permission, this.options.project),
selectParameter: 'groupName',
selectParameterValue: 'name',
parse: function (r) {
diff --git a/server/sonar-web/src/main/js/apps/global-permissions/permission-groups.jsx b/server/sonar-web/src/main/js/apps/global-permissions/permission-groups.jsx
index e710f3713b0..7a38d84c0a6 100644
--- a/server/sonar-web/src/main/js/apps/global-permissions/permission-groups.jsx
+++ b/server/sonar-web/src/main/js/apps/global-permissions/permission-groups.jsx
@@ -27,6 +27,7 @@ export default React.createClass({
e.preventDefault();
new GroupsView({
permission: this.props.permission.key,
+ project: this.props.project,
refresh: this.props.refresh
}).render();
}
diff --git a/server/sonar-web/src/main/js/apps/global-permissions/permission-users.jsx b/server/sonar-web/src/main/js/apps/global-permissions/permission-users.jsx
index 3d8fe5df33f..56f52feed0d 100644
--- a/server/sonar-web/src/main/js/apps/global-permissions/permission-users.jsx
+++ b/server/sonar-web/src/main/js/apps/global-permissions/permission-users.jsx
@@ -28,6 +28,7 @@ export default React.createClass({
e.preventDefault();
new UsersView({
permission: this.props.permission.key,
+ project: this.props.project,
refresh: this.props.refresh
}).render();
}
diff --git a/server/sonar-web/src/main/js/apps/global-permissions/permission.jsx b/server/sonar-web/src/main/js/apps/global-permissions/permission.jsx
index 1e87875a64b..ac259f521de 100644
--- a/server/sonar-web/src/main/js/apps/global-permissions/permission.jsx
+++ b/server/sonar-web/src/main/js/apps/global-permissions/permission.jsx
@@ -23,13 +23,19 @@ export default React.createClass({
requestUsers() {
const url = `${window.baseUrl}/api/permissions/users`;
- const data = { permission: this.props.permission.key, ps: MAX_ITEMS };
+ let data = { permission: this.props.permission.key, ps: MAX_ITEMS };
+ if (this.props.project) {
+ data.projectId = this.props.project;
+ }
$.get(url, data).done(r => this.setState({ users: r.users, totalUsers: r.paging && r.paging.total }));
},
requestGroups() {
const url = `${window.baseUrl}/api/permissions/groups`;
- const data = { permission: this.props.permission.key, ps: MAX_ITEMS };
+ let data = { permission: this.props.permission.key, ps: MAX_ITEMS };
+ if (this.props.project) {
+ data.projectId = this.props.project;
+ }
$.get(url, data).done(r => this.setState({ groups: r.groups, totalGroups: r.paging && r.paging.total }));
},
@@ -40,11 +46,13 @@ export default React.createClass({
<p className="spacer-top" dangerouslySetInnerHTML={{ __html: this.props.permission.description }}/>
<ul className="list-inline spacer-top">
<PermissionUsers permission={this.props.permission}
+ project={this.props.project}
max={MAX_ITEMS}
items={this.state.users}
total={this.state.totalUsers || this.props.permission.usersCount}
refresh={this.requestUsers}/>
<PermissionGroups permission={this.props.permission}
+ project={this.props.project}
max={MAX_ITEMS}
items={this.state.groups}
total={this.state.totalGroups || this.props.permission.groupsCount}
diff --git a/server/sonar-web/src/main/js/apps/global-permissions/permissions-list.jsx b/server/sonar-web/src/main/js/apps/global-permissions/permissions-list.jsx
index 432f020e1e1..e019fbcbfec 100644
--- a/server/sonar-web/src/main/js/apps/global-permissions/permissions-list.jsx
+++ b/server/sonar-web/src/main/js/apps/global-permissions/permissions-list.jsx
@@ -8,7 +8,7 @@ export default React.createClass({
renderPermissions() {
return this.props.permissions.map(permission => {
- return <Permission key={permission.key} permission={permission}/>
+ return <Permission key={permission.key} permission={permission} project={this.props.project}/>;
});
},
diff --git a/server/sonar-web/src/main/js/apps/global-permissions/users-view.js b/server/sonar-web/src/main/js/apps/global-permissions/users-view.js
index 1c0a0937038..8146bfef5e9 100644
--- a/server/sonar-web/src/main/js/apps/global-permissions/users-view.js
+++ b/server/sonar-web/src/main/js/apps/global-permissions/users-view.js
@@ -4,6 +4,22 @@ define([
'./templates'
], function (Modal) {
+ function getSearchUrl (permission, project) {
+ var url = baseUrl + '/api/permissions/users?ps=100&permission=' + permission;
+ if (project) {
+ url = url + '&projectId=' + project;
+ }
+ return url;
+ }
+
+ function getExtra (permission, project) {
+ var extra = { permission: permission };
+ if (project) {
+ extra.projectId = project;
+ }
+ return extra;
+ }
+
return Modal.extend({
template: Templates['global-permissions-users'],
@@ -18,12 +34,10 @@ define([
return item.name + '<br><span class="note">' + item.login + '</span>';
},
queryParam: 'q',
- searchUrl: baseUrl + '/api/permissions/users?ps=100&permission=' + this.options.permission,
+ searchUrl: getSearchUrl(this.options.permission, this.options.project),
selectUrl: baseUrl + '/api/permissions/add_user',
deselectUrl: baseUrl + '/api/permissions/remove_user',
- extra: {
- permission: this.options.permission
- },
+ extra: getExtra(this.options.permission, this.options.project),
selectParameter: 'login',
selectParameterValue: 'login',
parse: function (r) {
diff --git a/server/sonar-web/src/main/js/apps/main/app.jsx b/server/sonar-web/src/main/js/apps/main/app.jsx
index 97c3d781c2f..938b2e8e184 100644
--- a/server/sonar-web/src/main/js/apps/main/app.jsx
+++ b/server/sonar-web/src/main/js/apps/main/app.jsx
@@ -23,7 +23,7 @@ const APP_URL_MAPPING = {
'overview': 'overview/app',
'permission_templates': 'select-list/app',
'profiles': 'quality-profiles/app',
- 'project_roles': 'select-list/app',
+ 'project_roles': 'project-permissions/app',
'provisioning': 'provisioning/app',
'quality_gates': 'quality-gates/app',
'roles/global': 'global-permissions/app',
diff --git a/server/sonar-web/src/main/js/apps/project-permissions/app.jsx b/server/sonar-web/src/main/js/apps/project-permissions/app.jsx
index 478924e9233..54d4fee2fb6 100644
--- a/server/sonar-web/src/main/js/apps/project-permissions/app.jsx
+++ b/server/sonar-web/src/main/js/apps/project-permissions/app.jsx
@@ -1,11 +1,14 @@
import React from 'react';
import Main from './main';
-
-const $ = jQuery;
+import MainComponent from './main-component';
export default {
start(options) {
var el = document.querySelector(options.el);
- React.render(<Main/>, el);
+ if (options.component) {
+ React.render(<MainComponent component={options.component}/>, el);
+ } else {
+ React.render(<Main/>, el);
+ }
}
};
diff --git a/server/sonar-web/src/main/js/apps/project-permissions/main-component.jsx b/server/sonar-web/src/main/js/apps/project-permissions/main-component.jsx
new file mode 100644
index 00000000000..2df3f3694a9
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/project-permissions/main-component.jsx
@@ -0,0 +1,55 @@
+import _ from 'underscore';
+import React from 'react';
+import PermissionsList from '../global-permissions/permissions-list';
+
+let $ = jQuery;
+
+const PERMISSIONS_ORDER = ['user', 'codeviewer', 'issueadmin', 'admin'];
+
+export default React.createClass({
+ getInitialState() {
+ return { permissions: [] };
+ },
+
+ componentDidMount() {
+ this.requestPermissions();
+ },
+
+ sortPermissions(permissions) {
+ return _.sortBy(permissions, p => PERMISSIONS_ORDER.indexOf(p.key));
+ },
+
+ mergePermissionsToProjects(projects, basePermissions) {
+ return projects.map(project => {
+ // it's important to keep the order of the project permissions the same as the order of base permissions
+ let permissions = basePermissions.map(basePermission => {
+ let projectPermission = _.findWhere(project.permissions, { key: basePermission.key });
+ return _.extend({ usersCount: 0, groupsCount: 0 }, basePermission, projectPermission);
+ });
+ return _.extend({}, project, { permissions: permissions });
+ });
+ },
+
+ requestPermissions(page = 1, query = '') {
+ let url = `${window.baseUrl}/api/permissions/search_project_permissions`;
+ let data = { projectId: this.props.component.uuid, p: page, q: query };
+ $.get(url, data).done(r => {
+ let permissions = this.sortPermissions(r.permissions);
+ let projects = this.mergePermissionsToProjects(r.projects, permissions);
+ this.setState({ permissions: projects[0].permissions });
+ });
+ },
+
+ render() {
+ return (
+ <div className="page">
+ <header id="project-permissions-header" className="page-header">
+ <h1 className="page-title">{window.t('roles.page')}</h1>
+ <p className="page-description">{window.t('roles.page.description2')}</p>
+ </header>
+
+ <PermissionsList permissions={this.state.permissions} project={this.props.component.uuid}/>
+ </div>
+ );
+ }
+});
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/project_roles_controller.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/project_roles_controller.rb
index b6923e8d593..2dab45040b0 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/project_roles_controller.rb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/project_roles_controller.rb
@@ -22,11 +22,9 @@ class ProjectRolesController < ApplicationController
SECTION=Navigation::SECTION_RESOURCE
- # GET /project_roles/@project
def index
- @project=Project.by_key(params[:id])
+ @project = Project.by_key(params[:id])
access_denied unless is_admin?(@project)
- @snapshot=@project.last_snapshot
end
end
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/project_roles/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/project_roles/index.html.erb
index 3cc6ca69a66..e69de29bb2d 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/project_roles/index.html.erb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/project_roles/index.html.erb
@@ -1,57 +0,0 @@
-<div class="page">
- <header class="page-header">
- <h1 class="page-title"><%= message('project_links.page') -%></h1>
- <div class="page-actions">
- <div class="button-group">
- <%= link_to message('projects_role.apply_template'),
- {:controller => :roles, :action => :apply_template_form, :components => [@project.key], :names => @project.name, :results_count => 1},
- :id => "apply-template-#{u @project.kee}", :class => 'open-modal link-action button' %>
- </div>
- </div>
- <p class="page-description"><%= message('project_links.page.description') -%></p>
- </header>
-
- <table class="data width100">
- <thead>
- <tr>
- <th>&nbsp;</th>
- <th>
- <%= message('projects_role.user') -%><br/>
- <span class="small gray" style="font-size: 11px; font-weight: normal;"><%= message('projects_role.user.desc') -%></span>
- </th>
- <th>
- <%= message('projects_role.admin') -%><br/>
- <span class="small gray" style="font-size: 11px; font-weight: normal;"><%= message('projects_role.admin.desc') -%></span>
- </th>
- <th>
- <%= message('projects_role.issueadmin') -%><br/>
- <span class="small gray" style="font-size: 11px; font-weight: normal;"><%= message('projects_role.issueadmin.desc') -%></span>
- </th>
- <th>
- <%= message('projects_role.codeviewer') -%><br/>
- <span class="small gray" style="font-size: 11px; font-weight: normal;"><%= message('projects_role.codeviewer.desc') -%></span>
- </th>
- </tr>
- </thead>
- <tbody>
- <tr class="even">
- <td valign="top"><b>Users</b></td>
- <% ['user', 'admin', 'issueadmin', 'codeviewer'].each do |permission| -%>
- <td valign="top">
- <span id="<%= permission -%>-role-users"><%= users(permission, @project.id).map(&:name).join(', ') %></span>
- (<%= link_to_edit_roles_permission_form(message('select'), permission, @project.id, "select-#{permission}-edit-users") %>)<br/>
- </td>
- <% end %>
- </tr>
- <tr class="odd">
- <td valign="top"><b>Groups</b></td>
- <% ['user', 'admin', 'issueadmin', 'codeviewer'].each do |permission| -%>
- <td valign="top">
- <span id="<%= permission -%>-role-groups"><%= groups(permission, @project.id).map{|g| group_name(g)}.join(', ') %></span>
- (<%= link_to_edit_groups_permission_form(message('select'), permission, @project.id, "select-#{permission}-edit-groups") %>)<br/>
- </td>
- <% end %>
- </tr>
- </tbody>
- </table>
-</div>
diff --git a/server/sonar-web/test/medium/global-permissions.spec.js b/server/sonar-web/test/medium/global-permissions.spec.js
index dbc525846d6..9209f73907a 100644
--- a/server/sonar-web/test/medium/global-permissions.spec.js
+++ b/server/sonar-web/test/medium/global-permissions.spec.js
@@ -16,7 +16,7 @@ define(function (require) {
.checkElementInclude('#global-permissions-list > li h3', 'Administer System')
.checkElementInclude('#global-permissions-list > li p', 'Ability to perform all administration')
.checkElementInclude('#global-permissions-list > li ul > li:first-child', 'Administrator')
- .checkElementInclude('#global-permissions-list > li ul > li:last-child', '1')
+ .checkElementInclude('#global-permissions-list > li ul > li:last-child', '1');
});
});
});
diff --git a/server/sonar-web/test/medium/project-permissions.spec.js b/server/sonar-web/test/medium/project-permissions.spec.js
index 4eaf5a7db96..28edb1099f9 100644
--- a/server/sonar-web/test/medium/project-permissions.spec.js
+++ b/server/sonar-web/test/medium/project-permissions.spec.js
@@ -7,7 +7,7 @@ define(function (require) {
return this.remote
.open()
.mockFromFile('/api/permissions/search_project_permissions', 'permissions/project-permissions.json')
- .startApp('project-permissions/app')
+ .startApp('project-permissions/app', { component: null })
.checkElementExist('#project-permissions-header')
.checkElementExist('#projects')
.checkElementCount('#projects > thead > tr > th', 3)
@@ -18,5 +18,21 @@ define(function (require) {
.checkElementInclude('#projects > tbody > tr:first-child td:nth-child(3)', '1')
.checkElementInclude('#projects > tbody > tr:first-child td:nth-child(3)', '2');
});
+
+ bdd.it('should show permissions on the project page', function () {
+ return this.remote
+ .open()
+ .mockFromFile('/api/permissions/search_project_permissions', 'permissions/project-permissions.json')
+ .mockFromFile('/api/permissions/users', 'permissions/users.json')
+ .mockFromFile('/api/permissions/groups', 'permissions/groups.json')
+ .startApp('project-permissions/app')
+ .checkElementExist('#project-permissions-header')
+ .checkElementExist('#global-permissions-list')
+ .checkElementCount('#global-permissions-list > li', 2)
+ .checkElementInclude('#global-permissions-list > li h3', 'See Source Code')
+ .checkElementInclude('#global-permissions-list > li p', 'Ability to view the project\'s source code.')
+ .checkElementInclude('#global-permissions-list > li ul > li:first-child', 'Administrator')
+ .checkElementInclude('#global-permissions-list > li ul > li:last-child', '1');
+ });
});
});