You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ListAction.java 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2023 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. package org.sonar.server.webhook.ws;
  21. import java.util.List;
  22. import java.util.Map;
  23. import javax.annotation.Nullable;
  24. import org.sonar.api.server.ws.Change;
  25. import org.sonar.api.server.ws.Request;
  26. import org.sonar.api.server.ws.Response;
  27. import org.sonar.api.server.ws.WebService;
  28. import org.sonar.db.DbClient;
  29. import org.sonar.db.DbSession;
  30. import org.sonar.db.project.ProjectDto;
  31. import org.sonar.db.webhook.WebhookDeliveryLiteDto;
  32. import org.sonar.db.webhook.WebhookDto;
  33. import org.sonar.server.component.ComponentFinder;
  34. import org.sonar.server.user.UserSession;
  35. import org.sonarqube.ws.Webhooks;
  36. import org.sonarqube.ws.Webhooks.ListResponse;
  37. import org.sonarqube.ws.Webhooks.ListResponseElement;
  38. import static org.apache.commons.lang.StringUtils.isNotBlank;
  39. import static org.sonar.api.utils.DateUtils.formatDateTime;
  40. import static org.sonar.server.webhook.HttpUrlHelper.obfuscateCredentials;
  41. import static org.sonar.server.webhook.ws.WebhooksWsParameters.LIST_ACTION;
  42. import static org.sonar.server.webhook.ws.WebhooksWsParameters.PROJECT_KEY_PARAM;
  43. import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
  44. import static org.sonar.server.ws.WsUtils.writeProtobuf;
  45. public class ListAction implements WebhooksWsAction {
  46. private final DbClient dbClient;
  47. private final UserSession userSession;
  48. private final WebhookSupport webhookSupport;
  49. private final ComponentFinder componentFinder;
  50. public ListAction(DbClient dbClient, UserSession userSession, WebhookSupport webhookSupport, ComponentFinder componentFinder) {
  51. this.dbClient = dbClient;
  52. this.userSession = userSession;
  53. this.webhookSupport = webhookSupport;
  54. this.componentFinder = componentFinder;
  55. }
  56. @Override
  57. public void define(WebService.NewController controller) {
  58. WebService.NewAction action = controller.createAction(LIST_ACTION)
  59. .setDescription("Search for global webhooks or project webhooks. Webhooks are ordered by name.<br>" +
  60. "Requires 'Administer' permission on the specified project, or global 'Administer' permission.")
  61. .setSince("7.1")
  62. .setResponseExample(getClass().getResource("example-webhooks-list.json"))
  63. .setHandler(this);
  64. action.createParam(PROJECT_KEY_PARAM)
  65. .setDescription("Project key")
  66. .setRequired(false)
  67. .setExampleValue(KEY_PROJECT_EXAMPLE_001);
  68. action.setChangelog(new Change("7.8", "Field 'secret' added to response"));
  69. action.setChangelog(new Change("10.1", "Field 'secret' replaced by flag 'hasSecret' in response"));
  70. }
  71. @Override
  72. public void handle(Request request, Response response) throws Exception {
  73. String projectKey = request.param(PROJECT_KEY_PARAM);
  74. userSession.checkLoggedIn();
  75. try (DbSession dbSession = dbClient.openSession(true)) {
  76. List<WebhookDto> webhookDtos = doHandle(dbSession, projectKey);
  77. Map<String, WebhookDeliveryLiteDto> lastDeliveries = loadLastDeliveriesOf(dbSession, webhookDtos);
  78. writeResponse(request, response, webhookDtos, lastDeliveries);
  79. }
  80. }
  81. private Map<String, WebhookDeliveryLiteDto> loadLastDeliveriesOf(DbSession dbSession, List<WebhookDto> webhookDtos) {
  82. return dbClient.webhookDeliveryDao().selectLatestDeliveries(dbSession, webhookDtos);
  83. }
  84. private List<WebhookDto> doHandle(DbSession dbSession, @Nullable String projectKey) {
  85. if (isNotBlank(projectKey)) {
  86. ProjectDto projectDto = componentFinder.getProjectByKey(dbSession, projectKey);
  87. webhookSupport.checkPermission(projectDto);
  88. webhookSupport.checkPermission(projectDto);
  89. return dbClient.webhookDao().selectByProject(dbSession, projectDto);
  90. } else {
  91. webhookSupport.checkPermission();
  92. return dbClient.webhookDao().selectGlobalWebhooks(dbSession);
  93. }
  94. }
  95. private static void writeResponse(Request request, Response response, List<WebhookDto> webhookDtos, Map<String, WebhookDeliveryLiteDto> lastDeliveries) {
  96. ListResponse.Builder responseBuilder = ListResponse.newBuilder();
  97. webhookDtos
  98. .forEach(webhook -> {
  99. ListResponseElement.Builder responseElementBuilder = responseBuilder.addWebhooksBuilder();
  100. responseElementBuilder
  101. .setKey(webhook.getUuid())
  102. .setName(webhook.getName())
  103. .setUrl(obfuscateCredentials(webhook.getUrl()))
  104. .setHasSecret(webhook.getSecret() != null);
  105. addLastDelivery(responseElementBuilder, webhook, lastDeliveries);
  106. });
  107. writeProtobuf(responseBuilder.build(), request, response);
  108. }
  109. private static void addLastDelivery(ListResponseElement.Builder responseElementBuilder, WebhookDto webhook, Map<String, WebhookDeliveryLiteDto> lastDeliveries) {
  110. if (lastDeliveries.containsKey(webhook.getUuid())) {
  111. WebhookDeliveryLiteDto delivery = lastDeliveries.get(webhook.getUuid());
  112. Webhooks.LatestDelivery.Builder builder = responseElementBuilder.getLatestDeliveryBuilder()
  113. .setId(delivery.getUuid())
  114. .setAt(formatDateTime(delivery.getCreatedAt()))
  115. .setSuccess(delivery.isSuccess());
  116. if (delivery.getHttpStatus() != null) {
  117. builder.setHttpStatus(delivery.getHttpStatus());
  118. }
  119. if (delivery.getDurationMs() != null) {
  120. builder.setDurationMs(delivery.getDurationMs());
  121. }
  122. builder.build();
  123. }
  124. }
  125. }