123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- /*
- * SonarQube
- * Copyright (C) 2009-2018 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.organization.ws;
-
- import java.util.Collection;
- import java.util.List;
- import java.util.Set;
- 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.core.util.stream.MoreCollectors;
- import org.sonar.db.DbClient;
- import org.sonar.db.DbSession;
- import org.sonar.db.component.ComponentDto;
- import org.sonar.db.organization.OrganizationDto;
- import org.sonar.db.qualitygate.QualityGateDto;
- import org.sonar.db.qualityprofile.QProfileDto;
- import org.sonar.db.user.UserDto;
- import org.sonar.server.component.ComponentCleanerService;
- import org.sonar.server.organization.BillingValidations;
- import org.sonar.server.organization.BillingValidationsProxy;
- import org.sonar.server.organization.DefaultOrganization;
- import org.sonar.server.organization.DefaultOrganizationProvider;
- import org.sonar.server.organization.OrganizationFlags;
- import org.sonar.server.project.Project;
- import org.sonar.server.project.ProjectLifeCycleListeners;
- import org.sonar.server.qualityprofile.QProfileFactory;
- import org.sonar.server.user.UserSession;
- import org.sonar.server.user.index.UserIndexer;
-
- import static com.google.common.base.Preconditions.checkArgument;
- import static org.sonar.db.permission.OrganizationPermission.ADMINISTER;
- import static org.sonar.server.organization.ws.OrganizationsWsSupport.PARAM_KEY;
- import static org.sonar.server.organization.ws.OrganizationsWsSupport.PARAM_ORGANIZATION;
- import static org.sonar.server.ws.KeyExamples.KEY_ORG_EXAMPLE_002;
- import static org.sonar.server.ws.WsUtils.checkFoundWithOptional;
-
- public class DeleteAction implements OrganizationsWsAction {
- private static final String ACTION = "delete";
-
- private final UserSession userSession;
- private final DbClient dbClient;
- private final DefaultOrganizationProvider defaultOrganizationProvider;
- private final ComponentCleanerService componentCleanerService;
- private final OrganizationFlags organizationFlags;
- private final UserIndexer userIndexer;
- private final QProfileFactory qProfileFactory;
- private final ProjectLifeCycleListeners projectLifeCycleListeners;
- private final BillingValidationsProxy billingValidations;
-
- public DeleteAction(UserSession userSession, DbClient dbClient, DefaultOrganizationProvider defaultOrganizationProvider, ComponentCleanerService componentCleanerService,
- OrganizationFlags organizationFlags, UserIndexer userIndexer, QProfileFactory qProfileFactory, ProjectLifeCycleListeners projectLifeCycleListeners,
- BillingValidationsProxy billingValidations) {
- this.userSession = userSession;
- this.dbClient = dbClient;
- this.defaultOrganizationProvider = defaultOrganizationProvider;
- this.componentCleanerService = componentCleanerService;
- this.organizationFlags = organizationFlags;
- this.userIndexer = userIndexer;
- this.qProfileFactory = qProfileFactory;
- this.projectLifeCycleListeners = projectLifeCycleListeners;
- this.billingValidations = billingValidations;
- }
-
- @Override
- public void define(WebService.NewController context) {
- WebService.NewAction action = context.createAction(ACTION)
- .setPost(true)
- .setDescription("Delete an organization.<br/>" +
- "Require 'Administer System' permission on the specified organization. Organization support must be enabled.")
- .setInternal(true)
- .setSince("6.2")
- .setHandler(this);
-
- action.createParam(PARAM_ORGANIZATION)
- .setRequired(true)
- .setDescription("Organization key")
- .setDeprecatedKey(PARAM_KEY, "6.4")
- .setExampleValue(KEY_ORG_EXAMPLE_002);
- }
-
- @Override
- public void handle(Request request, Response response) throws Exception {
- userSession.checkLoggedIn();
-
- try (DbSession dbSession = dbClient.openSession(false)) {
- organizationFlags.checkEnabled(dbSession);
-
- String key = request.mandatoryParam(PARAM_ORGANIZATION);
- preventDeletionOfDefaultOrganization(key, defaultOrganizationProvider.get());
-
- OrganizationDto organization = checkFoundWithOptional(dbClient.organizationDao().selectByKey(dbSession, key), "Organization with key '%s' not found", key);
- if (organization.isGuarded()) {
- userSession.checkIsSystemAdministrator();
- } else {
- userSession.checkPermission(ADMINISTER, organization);
- }
-
- deleteProjects(dbSession, organization);
- deletePermissions(dbSession, organization);
- deleteGroups(dbSession, organization);
- deleteQualityProfiles(dbSession, organization);
- deleteQualityGates(dbSession, organization);
- deleteOrganizationAlmBinding(dbSession, organization);
- deleteOrganization(dbSession, organization);
- billingValidations.onDelete(new BillingValidations.Organization(organization.getKey(), organization.getUuid()));
-
- response.noContent();
- }
- }
-
- private void deleteProjects(DbSession dbSession, OrganizationDto organization) {
- List<ComponentDto> roots = dbClient.componentDao().selectProjectsByOrganization(dbSession, organization.getUuid());
- try {
- componentCleanerService.delete(dbSession, roots);
- } finally {
- Set<Project> projects = roots.stream()
- .filter(DeleteAction::isMainProject)
- .map(Project::from)
- .collect(MoreCollectors.toSet());
- projectLifeCycleListeners.onProjectsDeleted(projects);
- }
- }
-
- private static boolean isMainProject(ComponentDto p) {
- return Scopes.PROJECT.equals(p.scope())
- && Qualifiers.PROJECT.equals(p.qualifier())
- && p.getMainBranchProjectUuid() == null;
- }
-
- private void deletePermissions(DbSession dbSession, OrganizationDto organization) {
- dbClient.permissionTemplateDao().deleteByOrganization(dbSession, organization.getUuid());
- dbClient.userPermissionDao().deleteByOrganization(dbSession, organization.getUuid());
- dbClient.groupPermissionDao().deleteByOrganization(dbSession, organization.getUuid());
- }
-
- private void deleteGroups(DbSession dbSession, OrganizationDto organization) {
- dbClient.groupDao().deleteByOrganization(dbSession, organization.getUuid());
- }
-
- private void deleteQualityProfiles(DbSession dbSession, OrganizationDto organization) {
- List<QProfileDto> profiles = dbClient.qualityProfileDao().selectOrderedByOrganizationUuid(dbSession, organization);
- qProfileFactory.delete(dbSession, profiles);
- }
-
- private void deleteQualityGates(DbSession dbSession, OrganizationDto organization) {
- Collection<QualityGateDto> qualityGates = dbClient.qualityGateDao().selectAll(dbSession, organization);
- dbClient.qualityGateDao().deleteByUuids(dbSession, qualityGates.stream()
- .filter(q -> !q.isBuiltIn())
- .map(QualityGateDto::getUuid)
- .collect(MoreCollectors.toList()));
- dbClient.qualityGateDao().deleteOrgQualityGatesByOrganization(dbSession, organization);
- }
-
- private void deleteOrganizationAlmBinding(DbSession dbSession, OrganizationDto organization){
- dbClient.organizationAlmBindingDao().deleteByOrganization(dbSession, organization);
- }
-
- private void deleteOrganization(DbSession dbSession, OrganizationDto organization) {
- Collection<String> uuids = dbClient.organizationMemberDao().selectUserUuidsByOrganizationUuid(dbSession, organization.getUuid());
- dbClient.organizationMemberDao().deleteByOrganizationUuid(dbSession, organization.getUuid());
- dbClient.organizationDao().deleteByUuid(dbSession, organization.getUuid());
- dbClient.userDao().cleanHomepage(dbSession, organization);
- dbClient.webhookDao().selectByOrganizationUuid(dbSession, organization.getUuid())
- .forEach(wh -> dbClient.webhookDeliveryDao().deleteByWebhook(dbSession, wh));
- dbClient.webhookDao().deleteByOrganization(dbSession, organization);
- List<UserDto> users = dbClient.userDao().selectByUuids(dbSession, uuids);
- userIndexer.commitAndIndex(dbSession, users);
- }
-
- private static void preventDeletionOfDefaultOrganization(String key, DefaultOrganization defaultOrganization) {
- checkArgument(!defaultOrganization.getKey().equals(key), "Default Organization can't be deleted");
- }
- }
|