]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-9227 Forbid adding a notification on project without BROWSE permission
authorEric Hartmann <hartmann.eric@gmail.com>
Tue, 12 Sep 2017 14:37:01 +0000 (16:37 +0200)
committerEric Hartmann <hartmann.eric@gmail.Com>
Mon, 2 Oct 2017 11:03:35 +0000 (13:03 +0200)
server/sonar-server/src/main/java/org/sonar/server/notification/ws/AddAction.java
server/sonar-server/src/test/java/org/sonar/server/notification/ws/AddActionTest.java

index 51685ce0c1fc73270b6d5988b5d7b24fbae77b64..65eab55e15a7b91bb4bf27e06a032a0d61f34967 100644 (file)
@@ -21,13 +21,13 @@ package org.sonar.server.notification.ws;
 
 import java.util.List;
 import java.util.Optional;
-import javax.annotation.CheckForNull;
 import org.sonar.api.notifications.NotificationChannel;
 import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.resources.Scopes;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
+import org.sonar.api.web.UserRole;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.component.ComponentDto;
@@ -124,8 +124,8 @@ public class AddAction implements NotificationsWsAction {
     try (DbSession dbSession = dbClient.openSession(false)) {
       checkPermissions(request);
       UserDto user = getUser(dbSession, request);
-      ComponentDto project = searchProject(dbSession, request);
-      notificationUpdater.add(dbSession, request.getChannel(), request.getType(), user, project);
+      Optional<ComponentDto> project = searchProject(dbSession, request);
+      notificationUpdater.add(dbSession, request.getChannel(), request.getType(), user, project.orElse(null));
       dbSession.commit();
     }
   }
@@ -135,12 +135,12 @@ public class AddAction implements NotificationsWsAction {
     return checkFound(dbClient.userDao().selectByLogin(dbSession, login), "User '%s' not found", login);
   }
 
-  @CheckForNull
-  private ComponentDto searchProject(DbSession dbSession, AddRequest request) {
+  private Optional<ComponentDto> searchProject(DbSession dbSession, AddRequest request) {
     Optional<ComponentDto> project = request.getProject() == null ? empty() : Optional.of(componentFinder.getByKey(dbSession, request.getProject()));
     project.ifPresent(p -> checkRequest(Qualifiers.PROJECT.equals(p.qualifier()) && Scopes.PROJECT.equals(p.scope()),
       "Component '%s' must be a project", request.getProject()));
-    return project.orElse(null);
+    project.ifPresent(p -> userSession.checkComponentPermission(UserRole.USER, p));
+    return project;
   }
 
   private void checkPermissions(AddRequest request) {
index 4f7437cca4a725d85e25df1fb1ba4ee746311462..3f024bd13eefc66c3e466a864e6c4abf277ce1da 100644 (file)
@@ -25,6 +25,7 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.notifications.Notification;
 import org.sonar.api.notifications.NotificationChannel;
+import org.sonar.api.web.UserRole;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbTester;
 import org.sonar.db.component.ComponentDto;
@@ -120,17 +121,28 @@ public class AddActionTest {
   }
 
   @Test
-  public void add_a_project_notification() {
+  public void add_notification_on_private_with_USER_permission() {
     ComponentDto project = db.components().insertPrivateProject();
+    userSession.addProjectPermission(UserRole.USER, project);
 
     call(request.setProject(project.getDbKey()));
 
     db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUserId(), project);
   }
 
+  @Test
+  public void add_notification_on_public_project() {
+    ComponentDto project = db.components().insertPublicProject();
+    userSession.registerComponents(project);
+    call(request.setProject(project.getDbKey()));
+
+    db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUserId(), project);
+  }
+
   @Test
   public void add_a_global_notification_when_a_project_one_exists() {
     ComponentDto project = db.components().insertPrivateProject();
+    userSession.addProjectPermission(UserRole.USER, project);
     call(request.setProject(project.getDbKey()));
 
     call(request.setProject(null));
@@ -140,10 +152,24 @@ public class AddActionTest {
   }
 
   @Test
-  public void add_a_project_notification_when_a_global_one_exists() {
+  public void add_a_notification_on_private_project_when_a_global_one_exists() {
     ComponentDto project = db.components().insertPrivateProject();
     call(request);
 
+    userSession.addProjectPermission(UserRole.USER, project);
+    call(request.setProject(project.getDbKey()));
+
+    db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUserId(), project);
+    db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUserId(), null);
+  }
+
+
+  @Test
+  public void add_a_notification_on_public_project_when_a_global_one_exists() {
+    ComponentDto project = db.components().insertPublicProject();
+    userSession.registerComponents(project);
+    call(request);
+
     call(request.setProject(project.getDbKey()));
 
     db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUserId(), project);
@@ -211,8 +237,19 @@ public class AddActionTest {
   }
 
   @Test
-  public void fail_when_unknown_project_dispatcher() {
+  public void fail_when_unknown_project_dispatcher_on_private_project() {
     ComponentDto project = db.components().insertPrivateProject();
+    userSession.addProjectPermission(UserRole.USER, project);
+
+    expectedException.expect(BadRequestException.class);
+    expectedException.expectMessage("Value of parameter 'type' (Dispatcher42) must be one of: [Dispatcher1, Dispatcher3]");
+
+    call(request.setType("Dispatcher42").setProject(project.getDbKey()));
+  }
+
+  @Test
+  public void fail_when_unknown_project_dispatcher_on_public_project() {
+    ComponentDto project = db.components().insertPublicProject();
 
     expectedException.expect(BadRequestException.class);
     expectedException.expectMessage("Value of parameter 'type' (Dispatcher42) must be one of: [Dispatcher1, Dispatcher3]");
@@ -264,6 +301,18 @@ public class AddActionTest {
     call(request.setProject(branch.getDbKey()));
   }
 
+  @Test
+  public void fail_when_user_does_not_have_USER_permission_on_private_project() {
+    ComponentDto project = db.components().insertPrivateProject();
+    userSession.logIn().setNonRoot().setNonSystemAdministrator();
+
+    expectedException.expect(ForbiddenException.class);
+
+    call(request
+      .setProject(project.getDbKey())
+      .setLogin(userSession.getLogin()));
+  }
+
   private TestResponse call(AddRequest.Builder wsRequestBuilder) {
     AddRequest wsRequest = wsRequestBuilder.build();
     TestRequest request = ws.newRequest();