您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

ListAction.java 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2019 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 java.util.Optional;
  24. import javax.annotation.Nullable;
  25. import org.sonar.api.server.ws.Change;
  26. import org.sonar.api.server.ws.Request;
  27. import org.sonar.api.server.ws.Response;
  28. import org.sonar.api.server.ws.WebService;
  29. import org.sonar.db.DbClient;
  30. import org.sonar.db.DbSession;
  31. import org.sonar.db.component.ComponentDto;
  32. import org.sonar.db.organization.OrganizationDto;
  33. import org.sonar.db.webhook.WebhookDeliveryLiteDto;
  34. import org.sonar.db.webhook.WebhookDto;
  35. import org.sonar.server.organization.DefaultOrganizationProvider;
  36. import org.sonar.server.user.UserSession;
  37. import org.sonarqube.ws.Webhooks;
  38. import org.sonarqube.ws.Webhooks.ListResponse;
  39. import org.sonarqube.ws.Webhooks.ListResponseElement;
  40. import static org.apache.commons.lang.StringUtils.isNotBlank;
  41. import static org.sonar.api.utils.DateUtils.formatDateTime;
  42. import static org.sonar.server.webhook.HttpUrlHelper.obfuscateCredentials;
  43. import static org.sonar.server.webhook.ws.WebhooksWsParameters.LIST_ACTION;
  44. import static org.sonar.server.webhook.ws.WebhooksWsParameters.ORGANIZATION_KEY_PARAM;
  45. import static org.sonar.server.webhook.ws.WebhooksWsParameters.PROJECT_KEY_PARAM;
  46. import static org.sonar.server.ws.KeyExamples.KEY_ORG_EXAMPLE_001;
  47. import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
  48. import static org.sonar.server.ws.WsUtils.checkFoundWithOptional;
  49. import static org.sonar.server.ws.WsUtils.checkStateWithOptional;
  50. import static org.sonar.server.ws.WsUtils.writeProtobuf;
  51. public class ListAction implements WebhooksWsAction {
  52. private final DbClient dbClient;
  53. private final UserSession userSession;
  54. private final DefaultOrganizationProvider defaultOrganizationProvider;
  55. private final WebhookSupport webhookSupport;
  56. public ListAction(DbClient dbClient, UserSession userSession, DefaultOrganizationProvider defaultOrganizationProvider, WebhookSupport webhookSupport) {
  57. this.dbClient = dbClient;
  58. this.userSession = userSession;
  59. this.defaultOrganizationProvider = defaultOrganizationProvider;
  60. this.webhookSupport = webhookSupport;
  61. }
  62. @Override
  63. public void define(WebService.NewController controller) {
  64. WebService.NewAction action = controller.createAction(LIST_ACTION)
  65. .setDescription("Search for global webhooks or project webhooks. Webhooks are ordered by name.<br>" +
  66. "Requires 'Administer' permission on the specified project, or global 'Administer' permission.")
  67. .setSince("7.1")
  68. .setResponseExample(getClass().getResource("example-webhooks-list.json"))
  69. .setHandler(this);
  70. action.createParam(ORGANIZATION_KEY_PARAM)
  71. .setDescription("Organization key. If no organization is provided, the default organization is used.")
  72. .setInternal(true)
  73. .setRequired(false)
  74. .setExampleValue(KEY_ORG_EXAMPLE_001);
  75. action.createParam(PROJECT_KEY_PARAM)
  76. .setDescription("Project key")
  77. .setRequired(false)
  78. .setExampleValue(KEY_PROJECT_EXAMPLE_001);
  79. action.setChangelog(new Change("7.8", "Field 'secret' added to response"));
  80. }
  81. @Override
  82. public void handle(Request request, Response response) throws Exception {
  83. String projectKey = request.param(PROJECT_KEY_PARAM);
  84. String organizationKey = request.param(ORGANIZATION_KEY_PARAM);
  85. userSession.checkLoggedIn();
  86. try (DbSession dbSession = dbClient.openSession(true)) {
  87. List<WebhookDto> webhookDtos = doHandle(dbSession, organizationKey, projectKey);
  88. Map<String, WebhookDeliveryLiteDto> lastDeliveries = loadLastDeliveriesOf(dbSession, webhookDtos);
  89. writeResponse(request, response, webhookDtos, lastDeliveries);
  90. }
  91. }
  92. private Map<String, WebhookDeliveryLiteDto> loadLastDeliveriesOf(DbSession dbSession, List<WebhookDto> webhookDtos) {
  93. return dbClient.webhookDeliveryDao().selectLatestDeliveries(dbSession, webhookDtos);
  94. }
  95. private List<WebhookDto> doHandle(DbSession dbSession, @Nullable String organizationKey, @Nullable String projectKey) {
  96. OrganizationDto organizationDto;
  97. if (isNotBlank(organizationKey)) {
  98. Optional<OrganizationDto> dtoOptional = dbClient.organizationDao().selectByKey(dbSession, organizationKey);
  99. organizationDto = checkFoundWithOptional(dtoOptional, "No organization with key '%s'", organizationKey);
  100. } else {
  101. organizationDto = defaultOrganizationDto(dbSession);
  102. }
  103. if (isNotBlank(projectKey)) {
  104. Optional<ComponentDto> optional = dbClient.componentDao().selectByKey(dbSession, projectKey);
  105. ComponentDto componentDto = checkFoundWithOptional(optional, "project %s does not exist", projectKey);
  106. webhookSupport.checkPermission(componentDto);
  107. webhookSupport.checkThatProjectBelongsToOrganization(componentDto, organizationDto, "Project '%s' does not belong to organisation '%s'", projectKey, organizationKey);
  108. webhookSupport.checkPermission(componentDto);
  109. return dbClient.webhookDao().selectByProject(dbSession, componentDto);
  110. } else {
  111. webhookSupport.checkPermission(organizationDto);
  112. return dbClient.webhookDao().selectByOrganization(dbSession, organizationDto);
  113. }
  114. }
  115. private static void writeResponse(Request request, Response response, List<WebhookDto> webhookDtos, Map<String, WebhookDeliveryLiteDto> lastDeliveries) {
  116. ListResponse.Builder responseBuilder = ListResponse.newBuilder();
  117. webhookDtos
  118. .forEach(webhook -> {
  119. ListResponseElement.Builder responseElementBuilder = responseBuilder.addWebhooksBuilder();
  120. responseElementBuilder
  121. .setKey(webhook.getUuid())
  122. .setName(webhook.getName())
  123. .setUrl(obfuscateCredentials(webhook.getUrl()));
  124. if (webhook.getSecret() != null) {
  125. responseElementBuilder.setSecret(webhook.getSecret());
  126. }
  127. addLastDelivery(responseElementBuilder, webhook, lastDeliveries);
  128. });
  129. writeProtobuf(responseBuilder.build(), request, response);
  130. }
  131. private static void addLastDelivery(ListResponseElement.Builder responseElementBuilder, WebhookDto webhook, Map<String, WebhookDeliveryLiteDto> lastDeliveries) {
  132. if (lastDeliveries.containsKey(webhook.getUuid())) {
  133. WebhookDeliveryLiteDto delivery = lastDeliveries.get(webhook.getUuid());
  134. Webhooks.LatestDelivery.Builder builder = responseElementBuilder.getLatestDeliveryBuilder()
  135. .setId(delivery.getUuid())
  136. .setAt(formatDateTime(delivery.getCreatedAt()))
  137. .setSuccess(delivery.isSuccess());
  138. if (delivery.getHttpStatus() != null) {
  139. builder.setHttpStatus(delivery.getHttpStatus());
  140. }
  141. if (delivery.getDurationMs() != null) {
  142. builder.setDurationMs(delivery.getDurationMs());
  143. }
  144. builder.build();
  145. }
  146. }
  147. private OrganizationDto defaultOrganizationDto(DbSession dbSession) {
  148. String uuid = defaultOrganizationProvider.get().getUuid();
  149. Optional<OrganizationDto> organizationDto = dbClient.organizationDao().selectByUuid(dbSession, uuid);
  150. return checkStateWithOptional(organizationDto, "the default organization '%s' was not found", uuid);
  151. }
  152. }