aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2014-09-15 17:38:14 +0200
committerJulien Lancelot <julien.lancelot@sonarsource.com>2014-09-15 17:38:14 +0200
commit5931c7b499951578606a1fcb3ee2412bd0ae90b4 (patch)
tree595fc167fa6c3faa1de9ae4f229e4237837f334a /server
parenta31b72f90bc2fb0f04abf6f9646436e257204d27 (diff)
downloadsonarqube-5931c7b499951578606a1fcb3ee2412bd0ae90b4.tar.gz
sonarqube-5931c7b499951578606a1fcb3ee2412bd0ae90b4.zip
SONAR-5613 Update Issues Authorization Index when deleting a project
Diffstat (limited to 'server')
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/component/ComponentCleanerService.java59
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/component/package-info.java24
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java20
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/ComponentCleanerServiceMediumTest.java118
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/db/ComponentDaoTest.java5
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/controllers/provisioning_controller.rb7
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/models/project.rb2
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/models/resource_deletion_manager.rb2
9 files changed, 219 insertions, 20 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ComponentCleanerService.java b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentCleanerService.java
new file mode 100644
index 00000000000..79b36089bc5
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentCleanerService.java
@@ -0,0 +1,59 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.component;
+
+import org.sonar.api.ServerComponent;
+import org.sonar.api.resources.Scopes;
+import org.sonar.core.component.AuthorizedComponentDto;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.purge.PurgeDao;
+import org.sonar.server.db.DbClient;
+
+public class ComponentCleanerService implements ServerComponent {
+
+ private final DbClient dbClient;
+ private final PurgeDao purgeDao;
+
+ public ComponentCleanerService(DbClient dbClient, PurgeDao purgeDao) {
+ this.dbClient = dbClient;
+ this.purgeDao = purgeDao;
+ }
+
+ public void delete(String projectKey) {
+ DbSession session = dbClient.openSession(false);
+ try {
+ AuthorizedComponentDto project = dbClient.componentDao().getAuthorizedComponentByKey(projectKey, session);
+ if (!Scopes.PROJECT.equals(project.scope())) {
+ throw new IllegalArgumentException("Only project can be deleted");
+ }
+ purgeDao.deleteResourceTree(project.getId());
+ deletePermissionIndexes(session, projectKey);
+ session.commit();
+ } finally {
+ session.close();
+ }
+ }
+
+ private void deletePermissionIndexes(DbSession session, String projectKey) {
+ dbClient.issueAuthorizationDao().deleteByKey(session, projectKey);
+ }
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/component/package-info.java
new file mode 100644
index 00000000000..03729ae4c0e
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/component/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.
+ */
+
+@ParametersAreNonnullByDefault
+package org.sonar.server.component;
+
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
index cb48dbeff87..ace8404adfe 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
@@ -79,6 +79,7 @@ import org.sonar.server.activity.ws.ActivityMapping;
import org.sonar.server.authentication.ws.AuthenticationWs;
import org.sonar.server.batch.*;
import org.sonar.server.charts.ChartFactory;
+import org.sonar.server.component.ComponentCleanerService;
import org.sonar.server.component.DefaultComponentFinder;
import org.sonar.server.component.DefaultRubyComponentService;
import org.sonar.server.component.db.ComponentDao;
@@ -458,6 +459,7 @@ class ServerComponents {
pico.addSingleton(ProjectsWs.class);
pico.addSingleton(ComponentAppAction.class);
pico.addSingleton(EventsWs.class);
+ pico.addSingleton(ComponentCleanerService.class);
// issues
pico.addSingleton(ServerIssueStorage.class);
diff --git a/server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java b/server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
index f77088beb21..300589c85f4 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
@@ -30,17 +30,13 @@ import org.sonar.api.platform.PluginRepository;
import org.sonar.api.resources.Language;
import org.sonar.api.resources.ResourceType;
import org.sonar.api.resources.ResourceTypes;
-import org.sonar.api.web.Footer;
-import org.sonar.api.web.NavigationSection;
-import org.sonar.api.web.Page;
-import org.sonar.api.web.RubyRailsWebservice;
-import org.sonar.api.web.Widget;
+import org.sonar.api.web.*;
import org.sonar.core.persistence.Database;
import org.sonar.core.preview.PreviewCache;
-import org.sonar.core.purge.PurgeDao;
import org.sonar.core.resource.ResourceIndexerDao;
import org.sonar.core.resource.ResourceKeyUpdaterDao;
import org.sonar.core.timemachine.Periods;
+import org.sonar.server.component.ComponentCleanerService;
import org.sonar.server.db.migrations.DatabaseMigrator;
import org.sonar.server.measure.MeasureFilterEngine;
import org.sonar.server.measure.MeasureFilterResult;
@@ -48,11 +44,7 @@ import org.sonar.server.platform.Platform;
import org.sonar.server.platform.ServerIdGenerator;
import org.sonar.server.platform.ServerSettings;
import org.sonar.server.platform.SettingsChangeNotifier;
-import org.sonar.server.plugins.InstalledPluginReferentialFactory;
-import org.sonar.server.plugins.PluginDownloader;
-import org.sonar.server.plugins.ServerPluginJarsInstaller;
-import org.sonar.server.plugins.ServerPluginRepository;
-import org.sonar.server.plugins.UpdateCenterMatrixFactory;
+import org.sonar.server.plugins.*;
import org.sonar.server.rule.RuleRepositories;
import org.sonar.server.source.CodeColorizers;
import org.sonar.server.user.NewUserNotifier;
@@ -338,11 +330,11 @@ public final class JRubyFacade {
get(ResourceIndexerDao.class).indexResource(resourceId);
}
- public void deleteResourceTree(long rootProjectId) {
+ public void deleteResourceTree(String projectKey) {
try {
- get(PurgeDao.class).deleteResourceTree(rootProjectId);
+ get(ComponentCleanerService.class).delete(projectKey);
} catch (RuntimeException e) {
- LoggerFactory.getLogger(JRubyFacade.class).error("Fail to delete resource with ID: " + rootProjectId, e);
+ LoggerFactory.getLogger(JRubyFacade.class).error("Fail to delete resource with key: " + projectKey, e);
throw e;
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentCleanerServiceMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentCleanerServiceMediumTest.java
new file mode 100644
index 00000000000..f87765e1147
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentCleanerServiceMediumTest.java
@@ -0,0 +1,118 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.component;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.resources.Scopes;
+import org.sonar.api.security.DefaultGroups;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.component.ComponentDto;
+import org.sonar.core.permission.PermissionFacade;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.issue.index.IssueAuthorizationIndex;
+import org.sonar.server.tester.ServerTester;
+
+import java.util.Date;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class ComponentCleanerServiceMediumTest {
+
+ @ClassRule
+ public static ServerTester tester = new ServerTester();
+
+ DbClient db;
+ DbSession session;
+
+ ComponentCleanerService service;
+
+ @Before
+ public void setUp() throws Exception {
+ tester.clearDbAndIndexes();
+
+ db = tester.get(DbClient.class);
+ session = db.openSession(false);
+ service = tester.get(ComponentCleanerService.class);
+ }
+
+ @After
+ public void after() {
+ session.close();
+ }
+
+ @Test
+ public void delete_project() throws Exception {
+ ComponentDto project = new ComponentDto()
+ .setId(1L)
+ .setKey("MyProject")
+ .setScope(Scopes.PROJECT)
+ .setQualifier(Qualifiers.PROJECT)
+ .setProjectId(1L);
+ db.componentDao().insert(session, project);
+ session.commit();
+
+ service.delete(project.getKey());
+
+ assertThat(db.componentDao().getNullableByKey(session, project.key())).isNull();
+ }
+
+ @Test
+ public void remove_issue_permission_index_when_deleting_a_project() throws Exception {
+ ComponentDto project = new ComponentDto()
+ .setId(1L)
+ .setKey("MyProject")
+ .setScope(Scopes.PROJECT)
+ .setQualifier(Qualifiers.PROJECT)
+ .setProjectId(1L);
+ db.componentDao().insert(session, project);
+
+ // project can be seen by anyone
+ tester.get(PermissionFacade.class).insertGroupPermission(project.getId(), DefaultGroups.ANYONE, UserRole.USER, session);
+ db.issueAuthorizationDao().synchronizeAfter(session, new Date(0));
+
+ session.commit();
+
+ assertThat(tester.get(IssueAuthorizationIndex.class).getByKey(project.getKey())).isNotNull();
+
+ service.delete(project.getKey());
+
+ assertThat(tester.get(IssueAuthorizationIndex.class).getByKey(project.getKey())).isNull();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void fail_to_delete_not_project() throws Exception {
+ ComponentDto project = new ComponentDto()
+ .setId(1L)
+ .setKey("MyProject")
+ .setScope(Scopes.DIRECTORY)
+ .setQualifier(Qualifiers.DIRECTORY)
+ .setProjectId(1L);
+ db.componentDao().insert(session, project);
+ session.commit();
+
+ service.delete(project.getKey());
+ }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/db/ComponentDaoTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/db/ComponentDaoTest.java
index f710f66d1a4..4cad5f9e86c 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/db/ComponentDaoTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/db/ComponentDaoTest.java
@@ -187,7 +187,10 @@ public class ComponentDaoTest extends AbstractDaoTestCase {
AuthorizedComponentDto result = dao.getNullableAuthorizedComponentById(4L, session);
assertThat(result).isNotNull();
- assertThat(result.key()).isEqualTo("org.struts:struts-core:src/org/struts/RequestContext.java");
+ assertThat(result.getId()).isEqualTo(4);
+ assertThat(result.getKey()).isEqualTo("org.struts:struts-core:src/org/struts/RequestContext.java");
+ assertThat(result.qualifier()).isEqualTo("FIL");
+ assertThat(result.scope()).isEqualTo("FIL");
assertThat(dao.getNullableAuthorizedComponentById(111L, session)).isNull();
}
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/provisioning_controller.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/provisioning_controller.rb
index eaa7d6d8e46..4eb61160379 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/provisioning_controller.rb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/provisioning_controller.rb
@@ -45,12 +45,12 @@ class ProvisioningController < ApplicationController
bad_request('provisioning.missing.name') if @name.blank?
if @id.nil? or @id.empty?
- new_id = Internal.component_api.createComponent(@key, @name, 'TRK')
+ Internal.component_api.createComponent(@key, @name, 'TRK')
begin
Internal.permissions.applyDefaultPermissionTemplate(@key)
rescue
# Programmatic transaction rollback
- Java::OrgSonarServerUi::JRubyFacade.getInstance().deleteResourceTree(new_id)
+ Java::OrgSonarServerUi::JRubyFacade.getInstance().deleteResourceTree(@key)
raise
end
else
@@ -80,7 +80,8 @@ class ProvisioningController < ApplicationController
access_denied unless has_role?("provisioning")
@id = params[:id].to_i
- Java::OrgSonarServerUi::JRubyFacade.getInstance().deleteResourceTree(@id)
+ project = Project.first(:conditions => {:id => @id})
+ Java::OrgSonarServerUi::JRubyFacade.getInstance().deleteResourceTree(project.key)
flash.now[:notice]= Api::Utils.message('resource_viewer.resource_deleted')
redirect_to :action => 'index'
end
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/models/project.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/models/project.rb
index 533a9c0fe35..9b8d332ec12 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/app/models/project.rb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/app/models/project.rb
@@ -54,7 +54,7 @@ class Project < ActiveRecord::Base
def self.delete_resource_tree(project)
java_facade = Java::OrgSonarServerUi::JRubyFacade.getInstance()
if project && java_facade.getResourceTypeBooleanProperty(project.qualifier, 'deletable')
- java_facade.deleteResourceTree(project.id)
+ java_facade.deleteResourceTree(project.key)
end
end
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/models/resource_deletion_manager.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/models/resource_deletion_manager.rb
index e880e4fbadd..a62824b7a16 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/app/models/resource_deletion_manager.rb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/app/models/resource_deletion_manager.rb
@@ -103,7 +103,7 @@ class ResourceDeletionManager
@message = Api::Utils.message('bulk_deletion.deletion_manager.currently_deleting_x_out_of_x', :params => [(index+1).to_s, resource_ids.size.to_s])
if resource && java_facade.getResourceTypeBooleanProperty(resource.qualifier, 'deletable')
begin
- java_facade.deleteResourceTree(resource.id)
+ java_facade.deleteResourceTree(resource.key)
rescue Exception => e
@failed_deletions << resource.name
# no need to rethrow the exception as it has been logged by the Java component