aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien HENRY <julien.henry@sonarsource.com>2013-11-28 15:34:32 +0100
committerJulien HENRY <julien.henry@sonarsource.com>2013-11-28 15:35:47 +0100
commite33bd845702cc6de1bdd4db0eea2a8a5218d5f96 (patch)
tree1ef309ea49f12250ebd3a41c59c95f1accb86d71
parentef54b378e1523bdd38342e3e841df0870a3ab60f (diff)
downloadsonarqube-e33bd845702cc6de1bdd4db0eea2a8a5218d5f96.tar.gz
sonarqube-e33bd845702cc6de1bdd4db0eea2a8a5218d5f96.zip
SONAR-2447 Check "Administer Issue" permission when displaying "set severity" action
-rw-r--r--sonar-server/src/main/java/org/sonar/server/issue/IssueService.java1
-rw-r--r--sonar-server/src/main/java/org/sonar/server/issue/SetSeverityAction.java19
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/issue/_issue.html.erb10
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/issues/_bulk_change_form.html.erb6
-rw-r--r--sonar-server/src/test/java/org/sonar/server/issue/SetSeverityActionTest.java30
5 files changed, 53 insertions, 13 deletions
diff --git a/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java b/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java
index 3e02d66e516..e1aa16fb324 100644
--- a/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java
+++ b/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java
@@ -182,6 +182,7 @@ public class IssueService implements ServerComponent {
verifyLoggedIn(userSession);
IssueQueryResult queryResult = loadIssue(issueKey);
DefaultIssue issue = (DefaultIssue) queryResult.first();
+ userSession.checkProjectPermission(UserRole.ISSUE_ADMIN, issue.projectKey());
IssueChangeContext context = IssueChangeContext.createUser(new Date(), userSession.login());
if (issueUpdater.setManualSeverity(issue, severity, context)) {
diff --git a/sonar-server/src/main/java/org/sonar/server/issue/SetSeverityAction.java b/sonar-server/src/main/java/org/sonar/server/issue/SetSeverityAction.java
index e2b466145f2..2d43ba048ee 100644
--- a/sonar-server/src/main/java/org/sonar/server/issue/SetSeverityAction.java
+++ b/sonar-server/src/main/java/org/sonar/server/issue/SetSeverityAction.java
@@ -23,15 +23,16 @@ package org.sonar.server.issue;
import com.google.common.base.Strings;
import org.sonar.api.ServerComponent;
import org.sonar.api.issue.Issue;
+import org.sonar.api.issue.condition.Condition;
import org.sonar.api.issue.condition.IsUnResolved;
import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.api.web.UserRole;
import org.sonar.core.issue.IssueUpdater;
import org.sonar.server.user.UserSession;
import java.util.List;
import java.util.Map;
-
public class SetSeverityAction extends Action implements ServerComponent {
public static final String KEY = "set_severity";
@@ -41,12 +42,26 @@ public class SetSeverityAction extends Action implements ServerComponent {
public SetSeverityAction(IssueUpdater issueUpdater) {
super(KEY);
this.issueUpdater = issueUpdater;
- super.setConditions(new IsUnResolved());
+ super.setConditions(new IsUnResolved(), new Condition() {
+ @Override
+ public boolean matches(Issue issue) {
+ return isCurrentUserIssueAdmin(((DefaultIssue) issue).projectKey());
+ }
+ });
+ }
+
+ boolean isCurrentUserIssueAdmin(String projectKey) {
+ return UserSession.get().hasProjectPermission(UserRole.ISSUE_ADMIN, projectKey);
}
@Override
public boolean verify(Map<String, Object> properties, List<Issue> issues, UserSession userSession) {
severity(properties);
+ for (Issue issue : issues) {
+ if (!isCurrentUserIssueAdmin(((DefaultIssue) issue).projectKey())) {
+ return false;
+ }
+ }
return true;
}
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/issue/_issue.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/issue/_issue.html.erb
index d73587fc55e..caa3053f748 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/issue/_issue.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/issue/_issue.html.erb
@@ -123,10 +123,12 @@
<div class="dropdown">
<a href="#" class="link-action link-more" onclick="showDropdownMenuOnElement($j(this).next('.dropdown-menu')); return false;"><%= message('more_actions') -%></a>
<ul style="display: none" class="dropdown-menu">
- <% unless issue.resolution %>
- <li>
- <a href="#" onclick="return issueForm('severity', this)" class="link-action spacer-right"><%= message("issue.set_severity") -%></a>
- </li>
+ <% if Java::OrgSonarServerUser::UserSession.get().hasProjectPermission('issueadmin', issue.projectKey) %>
+ <% unless issue.resolution %>
+ <li>
+ <a href="#" onclick="return issueForm('severity', this)" class="link-action spacer-right"><%= message("issue.set_severity") -%></a>
+ </li>
+ <% end %>
<% end %>
<% # Display remaining transitions
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/issues/_bulk_change_form.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/issues/_bulk_change_form.html.erb
index 0c7bdfe6cba..8eff6837910 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/issues/_bulk_change_form.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/issues/_bulk_change_form.html.erb
@@ -7,6 +7,7 @@
transitions_by_issues = {}
unresolved_issues = 0
+ unresolved_issues_user_can_admin = 0
issues.each do |issue|
transitions = Internal.issues.listTransitions(issue)
transitions.each do |transition|
@@ -15,6 +16,9 @@
transitions_by_issues[transition.key] = issues_for_transition
end
unresolved_issues += 1 unless issue.resolution()
+ if Java::OrgSonarServerUser::UserSession.get().hasProjectPermission('issueadmin', issue.projectKey)
+ unresolved_issues_user_can_admin += 1 unless issue.resolution()
+ end
end
%>
<form id="bulk-change-form" method="post" action="<%= ApplicationController.root_context -%>/issues/bulk_change">
@@ -71,7 +75,7 @@
<input id="set-severity-action" name="actions[]" type="checkbox" value="set_severity"/>
<%= severity_dropdown_tag('set_severity.severity', severitiy_select_option_tags, {:show_search_box => false},
{:id => 'severity'}) -%>
- <span style="float:right" class="note">(<%= message('issue_bulk_change.x_issues', :params => unresolved_issues.to_s) -%>)</span>
+ <span style="float:right" class="note">(<%= message('issue_bulk_change.x_issues', :params => unresolved_issues_user_can_admin.to_s) -%>)</span>
</div>
<% end %>
diff --git a/sonar-server/src/test/java/org/sonar/server/issue/SetSeverityActionTest.java b/sonar-server/src/test/java/org/sonar/server/issue/SetSeverityActionTest.java
index c2272d40bbd..9826f32f4c7 100644
--- a/sonar-server/src/test/java/org/sonar/server/issue/SetSeverityActionTest.java
+++ b/sonar-server/src/test/java/org/sonar/server/issue/SetSeverityActionTest.java
@@ -26,8 +26,11 @@ import org.junit.Test;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.api.web.UserRole;
import org.sonar.core.issue.IssueUpdater;
import org.sonar.server.user.MockUserSession;
+import org.sonar.server.user.UserSession;
+import org.sonar.server.user.UserSessionTestUtils;
import java.util.Map;
@@ -36,7 +39,10 @@ import static org.fest.assertions.Assertions.assertThat;
import static org.fest.assertions.Fail.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
public class SetSeverityActionTest {
@@ -44,13 +50,17 @@ public class SetSeverityActionTest {
private IssueUpdater issueUpdater = mock(IssueUpdater.class);
+ private UserSession userSession;
+
@Before
- public void before(){
+ public void before() {
action = new SetSeverityAction(issueUpdater);
+ userSession = mock(UserSession.class);
+ UserSessionTestUtils.setUserSession(userSession);
}
@Test
- public void should_execute(){
+ public void should_execute() {
String severity = "MINOR";
Map<String, Object> properties = newHashMap();
properties.put("severity", severity);
@@ -77,9 +87,17 @@ public class SetSeverityActionTest {
}
@Test
- public void should_support_only_unresolved_issues(){
- assertThat(action.supports(new DefaultIssue().setResolution(null))).isTrue();
- assertThat(action.supports(new DefaultIssue().setResolution(Issue.RESOLUTION_FIXED))).isFalse();
+ public void should_support_only_unresolved_issues() {
+ when(userSession.hasProjectPermission(UserRole.ISSUE_ADMIN, "foo:bar")).thenReturn(true);
+ assertThat(action.supports(new DefaultIssue().setProjectKey("foo:bar").setResolution(null))).isTrue();
+ assertThat(action.supports(new DefaultIssue().setProjectKey("foo:bar").setResolution(Issue.RESOLUTION_FIXED))).isFalse();
+ }
+
+ @Test
+ public void should_support_only_issues_with_issue_admin_permission() {
+ when(userSession.hasProjectPermission(UserRole.ISSUE_ADMIN, "foo:bar")).thenReturn(true);
+ assertThat(action.supports(new DefaultIssue().setProjectKey("foo:bar").setResolution(null))).isTrue();
+ assertThat(action.supports(new DefaultIssue().setProjectKey("foo:bar2").setResolution(null))).isFalse();
}
}