--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.hotspot.ws;
+
+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.core.util.Uuids;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.db.issue.IssueDto;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.user.UserSession;
+
+import static java.lang.String.format;
+
+public class ShowAction implements HotspotsWsAction {
+
+ private static final String PARAM_HOTSPOT_KEY = "hotspot";
+
+ private final DbClient dbClient;
+ private final UserSession userSession;
+
+ public ShowAction(DbClient dbClient, UserSession userSession) {
+ this.dbClient = dbClient;
+ this.userSession = userSession;
+ }
+
+ @Override
+ public void define(WebService.NewController controller) {
+ WebService.NewAction action = controller
+ .createAction("show")
+ .setHandler(this)
+ .setDescription("Provides the details of a Security Hotpot.")
+ .setSince("8.1");
+
+ action.createParam(PARAM_HOTSPOT_KEY)
+ .setDescription("Key of the Security Hotspot")
+ .setExampleValue(Uuids.UUID_EXAMPLE_03)
+ .setRequired(true);
+ // FIXME add response example and test it
+ // action.setResponseExample()
+ }
+
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+ String hotspotKey = request.mandatoryParam(PARAM_HOTSPOT_KEY);
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ IssueDto hotspot = dbClient.issueDao().selectByKey(dbSession, hotspotKey)
+ .orElseThrow(() -> new NotFoundException(format("Hotspot with key '%s' does not exist", hotspotKey)));
+ ComponentDto project = dbClient.componentDao().selectByUuid(dbSession, hotspot.getProjectUuid())
+ .orElseThrow(() -> new NotFoundException(format("Project with uuid '%s' does not exist", hotspot.getProjectUuid())));
+ userSession.checkComponentPermission(UserRole.USER, project);
+
+
+ }
+ }
+}
import org.sonar.db.issue.IssueDto;
import org.sonar.db.protobuf.DbCommons;
import org.sonar.db.protobuf.DbIssues;
+import org.sonar.db.protobuf.DbIssues.Location;
import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.user.UserDto;
import org.sonar.markdown.Markdown;
import org.sonarqube.ws.Issues.Comment;
import org.sonarqube.ws.Issues.Comments;
import org.sonarqube.ws.Issues.Component;
-import org.sonarqube.ws.Issues.Flow;
import org.sonarqube.ws.Issues.Issue;
-import org.sonarqube.ws.Issues.Location;
import org.sonarqube.ws.Issues.Operation;
import org.sonarqube.ws.Issues.SearchWsResponse;
import org.sonarqube.ws.Issues.Transitions;
issueBuilder.setTextRange(convertTextRange(textRange));
}
for (DbIssues.Flow flow : locations.getFlowList()) {
- Flow.Builder targetFlow = Flow.newBuilder();
- for (DbIssues.Location flowLocation : flow.getLocationList()) {
+ Common.Flow.Builder targetFlow = Common.Flow.newBuilder();
+ for (Location flowLocation : flow.getLocationList()) {
targetFlow.addLocations(convertLocation(issueBuilder, flowLocation, data));
}
issueBuilder.addFlows(targetFlow);
}
}
- private static Location convertLocation(Issue.Builder issueBuilder, DbIssues.Location source, SearchResponseData data) {
- Location.Builder target = Location.newBuilder();
+ private static Common.Location convertLocation(Issue.Builder issueBuilder, Location source, SearchResponseData data) {
+ Common.Location.Builder target = Common.Location.newBuilder();
if (source.hasMsg()) {
target.setMsg(source.getMsg());
}
import org.sonar.server.ws.WsActionTester;
import org.sonarqube.ws.Common;
import org.sonarqube.ws.Common.Severity;
-import org.sonarqube.ws.Issues;
import org.sonarqube.ws.Issues.Issue;
import org.sonarqube.ws.Issues.SearchWsResponse;
SearchWsResponse result = ws.newRequest().executeProtobuf(SearchWsResponse.class);
assertThat(result.getIssuesCount()).isEqualTo(1);
- assertThat(result.getIssues(0).getFlows(0).getLocationsList()).extracting(Issues.Location::getComponent, Issues.Location::getMsg)
+ assertThat(result.getIssues(0).getFlows(0).getLocationsList()).extracting(Common.Location::getComponent, Common.Location::getMsg)
.containsExactlyInAnyOrder(
tuple(file.getKey(), "FLOW MESSAGE"),
tuple(anotherFile.getKey(), "ANOTHER FLOW MESSAGE"),
optional int32 endOffset = 4;
}
+message Flow {
+ repeated Location locations = 1;
+}
+
+message Location {
+ optional string component = 4;
+ optional string unusedComponentId = 1;
+ // Only when component is a file. Can be empty for a file if this is an issue global to the file.
+ optional sonarqube.ws.commons.TextRange textRange = 2;
+ optional string msg = 3;
+}
+
message Metric {
optional string key = 1;
optional string name = 2;
optional int32 line = 8;
optional string hash = 31;
optional sonarqube.ws.commons.TextRange textRange = 9;
- repeated Flow flows = 10;
+ repeated sonarqube.ws.commons.Flow flows = 10;
optional string resolution = 11;
optional string status = 12;
optional string message = 13;
repeated string actions = 1;
}
-message Flow {
- repeated Location locations = 1;
-}
-
-message Location {
- optional string component = 4;
- optional string unusedComponentId = 1;
- // Only when component is a file. Can be empty for a file if this is an issue global to the file.
- optional sonarqube.ws.commons.TextRange textRange = 2;
- optional string msg = 3;
-}
-
message Comment {
optional string key = 1;
optional string login = 2;