From 685bb0c85b1dd8666855da48ea3da258a10a9421 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Lievremont Date: Wed, 3 Dec 2014 15:43:17 +0100 Subject: [PATCH] SONAR-5819 Check sourceviewer permission on /api/sources/lines WS --- .../sonar/server/source/ws/LinesAction.java | 11 ++++- .../server/source/ws/LinesActionTest.java | 46 ++++++++++++++++--- .../sonar/server/source/ws/SourcesWsTest.java | 3 +- 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/source/ws/LinesAction.java b/server/sonar-server/src/main/java/org/sonar/server/source/ws/LinesAction.java index 3d780801976..9f0451682b2 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/source/ws/LinesAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/source/ws/LinesAction.java @@ -27,10 +27,14 @@ import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.text.JsonWriter; +import org.sonar.api.web.UserRole; +import org.sonar.core.component.ComponentDto; +import org.sonar.server.component.ComponentService; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.source.HtmlSourceDecorator; import org.sonar.server.source.index.SourceLineDoc; import org.sonar.server.source.index.SourceLineIndex; +import org.sonar.server.user.UserSession; import java.util.Date; import java.util.List; @@ -39,10 +43,12 @@ public class LinesAction implements RequestHandler { private final SourceLineIndex sourceLineIndex; private final HtmlSourceDecorator htmlSourceDecorator; + private final ComponentService componentService; - public LinesAction(SourceLineIndex sourceLineIndex, HtmlSourceDecorator htmlSourceDecorator) { + public LinesAction(SourceLineIndex sourceLineIndex, HtmlSourceDecorator htmlSourceDecorator, ComponentService componentService) { this.sourceLineIndex = sourceLineIndex; this.htmlSourceDecorator = htmlSourceDecorator; + this.componentService = componentService; } void define(WebService.NewController controller) { @@ -82,6 +88,9 @@ public class LinesAction implements RequestHandler { @Override public void handle(Request request, Response response) { String fileUuid = request.mandatoryParam("uuid"); + ComponentDto component = componentService.getByUuid(fileUuid); + UserSession.get().checkComponentPermission(UserRole.CODEVIEWER, component.key()); + int from = Math.max(request.mandatoryParamAsInt("from"), 1); int to = (Integer) ObjectUtils.defaultIfNull(request.paramAsInt("to"), Integer.MAX_VALUE); diff --git a/server/sonar-server/src/test/java/org/sonar/server/source/ws/LinesActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/source/ws/LinesActionTest.java index 9059a316e18..2039584edec 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/source/ws/LinesActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/source/ws/LinesActionTest.java @@ -31,12 +31,17 @@ import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.runners.MockitoJUnitRunner; import org.mockito.stubbing.Answer; +import org.sonar.api.web.UserRole; +import org.sonar.core.component.ComponentDto; +import org.sonar.server.component.ComponentService; +import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.search.BaseNormalizer; import org.sonar.server.source.HtmlSourceDecorator; import org.sonar.server.source.index.SourceLineDoc; import org.sonar.server.source.index.SourceLineIndex; import org.sonar.server.source.index.SourceLineIndexDefinition; +import org.sonar.server.user.MockUserSession; import org.sonar.server.ws.WsTester; import java.util.Date; @@ -60,6 +65,9 @@ public class LinesActionTest { @Mock HtmlSourceDecorator htmlSourceDecorator; + @Mock + ComponentService componentService; + WsTester tester; @Before @@ -69,7 +77,7 @@ public class LinesActionTest { mock(ShowAction.class), mock(RawAction.class), mock(ScmAction.class), - new LinesAction(sourceLineIndex, htmlSourceDecorator), + new LinesAction(sourceLineIndex, htmlSourceDecorator, componentService), mock(HashAction.class) ) ); @@ -142,6 +150,10 @@ public class LinesActionTest { line3 )); + String componentKey = "componentKey"; + when(componentService.getByUuid(componentUuid)).thenReturn(new ComponentDto().setKey(componentKey)); + MockUserSession.set().setLogin("login").addComponentPermission(UserRole.CODEVIEWER, "polop", componentKey); + WsTester.TestRequest request = tester.newGetRequest("api/sources", "lines").setParam("uuid", componentUuid); // Using non-strict match b/c of dates request.execute().assertJson(getClass(), "show_source.json", false); @@ -149,11 +161,15 @@ public class LinesActionTest { @Test public void fail_to_show_source_if_no_source_found() throws Exception { - String componentKey = "src/Foo.java"; + String componentUuid = "abcd"; when(sourceLineIndex.getLines(anyString(), anyInt(), anyInt())).thenReturn(Lists.newArrayList()); + String componentKey = "componentKey"; + when(componentService.getByUuid(componentUuid)).thenReturn(new ComponentDto().setKey(componentKey)); + MockUserSession.set().setLogin("login").addComponentPermission(UserRole.CODEVIEWER, "polop", componentKey); + try { - WsTester.TestRequest request = tester.newGetRequest("api/sources", "lines").setParam("uuid", componentKey); + WsTester.TestRequest request = tester.newGetRequest("api/sources", "lines").setParam("uuid", componentUuid); request.execute(); fail(); } catch (Exception e) { @@ -163,7 +179,7 @@ public class LinesActionTest { @Test public void show_source_with_from_and_to_params() throws Exception { - String fileKey = "src/Foo.java"; + String fileUuid = "efgh"; Map fieldMap = Maps.newHashMap(); fieldMap.put(SourceLineIndexDefinition.FIELD_PROJECT_UUID, "abcd"); fieldMap.put(SourceLineIndexDefinition.FIELD_FILE_UUID, "efgh"); @@ -179,14 +195,32 @@ public class LinesActionTest { fieldMap.put(SourceLineIndexDefinition.FIELD_OVERALL_COVERED_CONDITIONS, null); fieldMap.put(SourceLineIndexDefinition.FIELD_DUPLICATIONS, null); fieldMap.put(BaseNormalizer.UPDATED_AT_FIELD, new Date()); - when(sourceLineIndex.getLines(fileKey, 3, 3)).thenReturn(newArrayList( + + String componentKey = "componentKey"; + when(componentService.getByUuid(fileUuid)).thenReturn(new ComponentDto().setKey(componentKey)); + MockUserSession.set().setLogin("login").addComponentPermission(UserRole.CODEVIEWER, "polop", componentKey); + + when(sourceLineIndex.getLines(fileUuid, 3, 3)).thenReturn(newArrayList( new SourceLineDoc(fieldMap) )); WsTester.TestRequest request = tester .newGetRequest("api/sources", "lines") - .setParam("uuid", fileKey) + .setParam("uuid", fileUuid) .setParam("from", "3") .setParam("to", "3"); request.execute().assertJson(getClass(), "show_source_with_params_from_and_to.json"); } + + @Test(expected = ForbiddenException.class) + public void should_check_permission() throws Exception { + String fileUuid = "efgh"; + + String componentKey = "componentKey"; + when(componentService.getByUuid(fileUuid)).thenReturn(new ComponentDto().setKey(componentKey)); + MockUserSession.set().setLogin("login"); + + tester.newGetRequest("api/sources", "lines") + .setParam("uuid", fileUuid) + .execute(); + } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/source/ws/SourcesWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/source/ws/SourcesWsTest.java index b562d89d504..20aed4eee31 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/source/ws/SourcesWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/source/ws/SourcesWsTest.java @@ -23,6 +23,7 @@ package org.sonar.server.source.ws; import org.junit.Test; import org.sonar.api.server.ws.WebService; import org.sonar.core.source.db.FileSourceDao; +import org.sonar.server.component.ComponentService; import org.sonar.server.db.DbClient; import org.sonar.server.source.HtmlSourceDecorator; import org.sonar.server.source.SourceService; @@ -37,7 +38,7 @@ public class SourcesWsTest { ShowAction showAction = new ShowAction(mock(SourceService.class), mock(DbClient.class)); RawAction rawAction = new RawAction(mock(DbClient.class), mock(SourceService.class)); ScmAction scmAction = new ScmAction(mock(SourceService.class), new ScmWriter()); - LinesAction linesAction = new LinesAction(mock(SourceLineIndex.class), mock(HtmlSourceDecorator.class)); + LinesAction linesAction = new LinesAction(mock(SourceLineIndex.class), mock(HtmlSourceDecorator.class), mock(ComponentService.class)); HashAction hashAction = new HashAction(mock(DbClient.class), mock(FileSourceDao.class)); WsTester tester = new WsTester(new SourcesWs(showAction, rawAction, scmAction, linesAction, hashAction)); -- 2.39.5