]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-5561 Create query to load issue authorization from db
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Fri, 5 Sep 2014 15:50:55 +0000 (17:50 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Tue, 9 Sep 2014 09:41:03 +0000 (11:41 +0200)
server/sonar-server/src/main/java/org/sonar/server/issue/db/IssueAuthorizationDao.java
server/sonar-server/src/main/java/org/sonar/server/issue/db/IssueDao.java
server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
server/sonar-server/src/main/java/org/sonar/server/search/IndexSynchronizer.java
server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueAuthorizationDaoTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueBackendMediumTest.java
server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueAuthorizationDaoTest/find_after_date.xml [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueAuthorizationDaoTest/find_after_date_return_dtos_after_given_date.xml [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/issue/db/IssueAuthorizationDto.java
sonar-core/src/main/java/org/sonar/core/issue/db/IssueAuthorizationMapper.java
sonar-core/src/main/resources/org/sonar/core/issue/db/IssueAuthorizationMapper.xml

index 24ae9bf7d31039f50e3a34a077b52c99f7b0d458..64074abe00db5f21ddddcf120f0fed8b585d5b16 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.server.issue.db;
 
 import com.google.common.annotations.VisibleForTesting;
 import org.sonar.api.utils.System2;
+import org.sonar.api.web.UserRole;
 import org.sonar.core.issue.db.IssueAuthorizationDto;
 import org.sonar.core.issue.db.IssueAuthorizationMapper;
 import org.sonar.core.persistence.DaoComponent;
@@ -30,6 +31,10 @@ import org.sonar.server.db.BaseDao;
 import org.sonar.server.search.IndexDefinition;
 
 import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import static com.google.common.collect.Maps.newHashMap;
 
 public class IssueAuthorizationDao extends BaseDao<IssueAuthorizationMapper, IssueAuthorizationDto, String> implements DaoComponent {
 
@@ -44,29 +49,38 @@ public class IssueAuthorizationDao extends BaseDao<IssueAuthorizationMapper, Iss
 
   @Override
   protected IssueAuthorizationDto doGetNullableByKey(DbSession session, String key) {
-    return mapper(session).selectByKey(key);
+    throw new IllegalStateException("Not implemented");
   }
 
   @Override
-  protected IssueAuthorizationDto doUpdate(DbSession session, IssueAuthorizationDto issueAuthorization) {
-    // TODO ?
-    // mapper(session).update(issueAuthorization);
-    return issueAuthorization;
-  }
+  protected Iterable<IssueAuthorizationDto> findAfterDate(DbSession session, Date date) {
 
-  @Override
-  protected IssueAuthorizationDto doInsert(DbSession session, IssueAuthorizationDto issueAuthorization) {
-    // TODO ?
-    // Preconditions.checkNotNull(issueAuthorization.getKey(), "Cannot insert IssueAuthorization with empty key!");
-    // Preconditions.checkNotNull(issueAuthorization.getPermission(), "Cannot insert IssueAuthorization with no permission!");
-    // mapper(session).insert(issueAuthorization);
-    return issueAuthorization;
-  }
+    Map<String, Object> params = newHashMap();
+    params.put("date", date);
+    params.put("permission", UserRole.USER);
 
-  @Override
-  protected Iterable<IssueAuthorizationDto> findAfterDate(DbSession session, Date date) {
-    // TODO ?
-    // return mapper(session).selectAfterDate(new Timestamp(date.getTime()));
-    return null;
+    Map<String, IssueAuthorizationDto> authorizationDtoMap = newHashMap();
+
+    List<Map<String, String>> rows = session.selectList("org.sonar.core.issue.db.IssueAuthorizationMapper.selectAfterDate", params);
+    for (Map<String, String> row : rows) {
+      String project = row.get("PROJECT");
+      String user = row.get("USER");
+      String group = row.get("PERMISSION_GROUP");
+      IssueAuthorizationDto issueAuthorizationDto = authorizationDtoMap.get(project);
+      if (issueAuthorizationDto == null) {
+        issueAuthorizationDto = new IssueAuthorizationDto()
+          .setProject(project)
+          .setPermission(UserRole.USER);
+      }
+      if (group != null) {
+        issueAuthorizationDto.addGroup(group);
+      }
+      if (user != null) {
+        issueAuthorizationDto.addUser(user);
+      }
+      authorizationDtoMap.put(project, issueAuthorizationDto);
+    }
+
+    return authorizationDtoMap.values();
   }
 }
index 390e39d49b8707b7ebe55399b93ebe263636252d..45ea1ad6b33d61804cf8730ec8a1a363fe38eb34 100644 (file)
@@ -62,6 +62,7 @@ public class IssueDao extends BaseDao<IssueMapper, IssueDto, String> implements
     return issue;
   }
 
+
   @Override
   protected Iterable<IssueDto> findAfterDate(DbSession session, Date date) {
     return mapper(session).selectAfterDate(new Timestamp(date.getTime()));
index 63ebb72d92f013c3e3f98f679f507bf0b7f091b9..153e75b83ff79b4b319163e12d6a4ba4c5d59bab 100644 (file)
@@ -51,13 +51,7 @@ import org.sonar.core.measure.db.MeasureFilterDao;
 import org.sonar.core.metric.DefaultMetricFinder;
 import org.sonar.core.notification.DefaultNotificationManager;
 import org.sonar.core.permission.PermissionFacade;
-import org.sonar.core.persistence.DaoUtils;
-import org.sonar.core.persistence.DatabaseVersion;
-import org.sonar.core.persistence.DefaultDatabase;
-import org.sonar.core.persistence.MyBatis;
-import org.sonar.core.persistence.PreviewDatabaseFactory;
-import org.sonar.core.persistence.SemaphoreUpdater;
-import org.sonar.core.persistence.SemaphoresImpl;
+import org.sonar.core.persistence.*;
 import org.sonar.core.preview.PreviewCache;
 import org.sonar.core.profiling.Profiling;
 import org.sonar.core.purge.PurgeProfiler;
@@ -91,46 +85,21 @@ import org.sonar.server.charts.ChartFactory;
 import org.sonar.server.component.DefaultComponentFinder;
 import org.sonar.server.component.DefaultRubyComponentService;
 import org.sonar.server.component.persistence.ComponentDao;
-import org.sonar.server.component.ws.ComponentAppAction;
-import org.sonar.server.component.ws.ComponentsWs;
-import org.sonar.server.component.ws.EventsWs;
-import org.sonar.server.component.ws.ProjectsWs;
-import org.sonar.server.component.ws.ResourcesWs;
+import org.sonar.server.component.ws.*;
 import org.sonar.server.config.ws.PropertiesWs;
 import org.sonar.server.db.DatabaseChecker;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.db.EmbeddedDatabaseFactory;
 import org.sonar.server.db.migrations.DatabaseMigrations;
 import org.sonar.server.db.migrations.DatabaseMigrator;
-import org.sonar.server.debt.DebtCharacteristicsXMLImporter;
-import org.sonar.server.debt.DebtModelBackup;
-import org.sonar.server.debt.DebtModelLookup;
-import org.sonar.server.debt.DebtModelOperations;
-import org.sonar.server.debt.DebtModelPluginRepository;
-import org.sonar.server.debt.DebtModelService;
-import org.sonar.server.debt.DebtModelXMLExporter;
-import org.sonar.server.debt.DebtRulesXMLImporter;
+import org.sonar.server.debt.*;
 import org.sonar.server.duplication.ws.DuplicationsJsonWriter;
 import org.sonar.server.duplication.ws.DuplicationsParser;
 import org.sonar.server.duplication.ws.DuplicationsWs;
-import org.sonar.server.issue.ActionService;
-import org.sonar.server.issue.AssignAction;
-import org.sonar.server.issue.CommentAction;
-import org.sonar.server.issue.DefaultIssueFinder;
-import org.sonar.server.issue.InternalRubyIssueService;
-import org.sonar.server.issue.IssueBulkChangeService;
-import org.sonar.server.issue.IssueChangelogFormatter;
-import org.sonar.server.issue.IssueChangelogService;
-import org.sonar.server.issue.IssueCommentService;
-import org.sonar.server.issue.IssueService;
-import org.sonar.server.issue.IssueStatsFinder;
-import org.sonar.server.issue.PlanAction;
-import org.sonar.server.issue.PublicRubyIssueService;
-import org.sonar.server.issue.ServerIssueStorage;
-import org.sonar.server.issue.SetSeverityAction;
-import org.sonar.server.issue.TransitionAction;
+import org.sonar.server.issue.*;
 import org.sonar.server.issue.actionplan.ActionPlanService;
 import org.sonar.server.issue.actionplan.ActionPlanWs;
+import org.sonar.server.issue.db.IssueAuthorizationDao;
 import org.sonar.server.issue.db.IssueDao;
 import org.sonar.server.issue.filter.IssueFilterService;
 import org.sonar.server.issue.filter.IssueFilterWriter;
@@ -161,84 +130,22 @@ import org.sonar.server.platform.ws.L10nWs;
 import org.sonar.server.platform.ws.RestartHandler;
 import org.sonar.server.platform.ws.ServerWs;
 import org.sonar.server.platform.ws.SystemWs;
-import org.sonar.server.plugins.InstalledPluginReferentialFactory;
-import org.sonar.server.plugins.PluginDownloader;
-import org.sonar.server.plugins.ServerExtensionInstaller;
-import org.sonar.server.plugins.ServerPluginJarInstaller;
-import org.sonar.server.plugins.ServerPluginJarsInstaller;
-import org.sonar.server.plugins.ServerPluginRepository;
-import org.sonar.server.plugins.UpdateCenterClient;
-import org.sonar.server.plugins.UpdateCenterMatrixFactory;
+import org.sonar.server.plugins.*;
 import org.sonar.server.qualitygate.QgateProjectFinder;
 import org.sonar.server.qualitygate.QualityGates;
 import org.sonar.server.qualitygate.RegisterQualityGates;
-import org.sonar.server.qualitygate.ws.QGatesAppAction;
-import org.sonar.server.qualitygate.ws.QGatesCopyAction;
-import org.sonar.server.qualitygate.ws.QGatesCreateAction;
-import org.sonar.server.qualitygate.ws.QGatesCreateConditionAction;
-import org.sonar.server.qualitygate.ws.QGatesDeleteConditionAction;
-import org.sonar.server.qualitygate.ws.QGatesDeselectAction;
-import org.sonar.server.qualitygate.ws.QGatesDestroyAction;
-import org.sonar.server.qualitygate.ws.QGatesListAction;
-import org.sonar.server.qualitygate.ws.QGatesRenameAction;
-import org.sonar.server.qualitygate.ws.QGatesSearchAction;
-import org.sonar.server.qualitygate.ws.QGatesSelectAction;
-import org.sonar.server.qualitygate.ws.QGatesSetAsDefaultAction;
-import org.sonar.server.qualitygate.ws.QGatesShowAction;
-import org.sonar.server.qualitygate.ws.QGatesUnsetDefaultAction;
-import org.sonar.server.qualitygate.ws.QGatesUpdateConditionAction;
-import org.sonar.server.qualitygate.ws.QGatesWs;
-import org.sonar.server.qualityprofile.BuiltInProfiles;
-import org.sonar.server.qualityprofile.QProfileBackuper;
-import org.sonar.server.qualityprofile.QProfileCopier;
-import org.sonar.server.qualityprofile.QProfileExporters;
-import org.sonar.server.qualityprofile.QProfileFactory;
-import org.sonar.server.qualityprofile.QProfileLoader;
-import org.sonar.server.qualityprofile.QProfileLookup;
-import org.sonar.server.qualityprofile.QProfileProjectLookup;
-import org.sonar.server.qualityprofile.QProfileProjectOperations;
-import org.sonar.server.qualityprofile.QProfileRepositoryExporter;
-import org.sonar.server.qualityprofile.QProfileReset;
-import org.sonar.server.qualityprofile.QProfileService;
-import org.sonar.server.qualityprofile.QProfiles;
-import org.sonar.server.qualityprofile.RegisterQualityProfiles;
-import org.sonar.server.qualityprofile.RuleActivator;
-import org.sonar.server.qualityprofile.RuleActivatorContextFactory;
+import org.sonar.server.qualitygate.ws.*;
+import org.sonar.server.qualityprofile.*;
 import org.sonar.server.qualityprofile.db.ActiveRuleDao;
 import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
 import org.sonar.server.qualityprofile.index.ActiveRuleNormalizer;
-import org.sonar.server.qualityprofile.ws.BulkRuleActivationActions;
-import org.sonar.server.qualityprofile.ws.ProfilesWs;
-import org.sonar.server.qualityprofile.ws.QProfileRestoreBuiltInAction;
-import org.sonar.server.qualityprofile.ws.QProfilesWs;
-import org.sonar.server.qualityprofile.ws.RuleActivationActions;
-import org.sonar.server.rule.DefaultRuleFinder;
-import org.sonar.server.rule.DeprecatedRulesDefinition;
-import org.sonar.server.rule.RegisterRules;
-import org.sonar.server.rule.RubyRuleService;
-import org.sonar.server.rule.RuleCreator;
-import org.sonar.server.rule.RuleDefinitionsLoader;
-import org.sonar.server.rule.RuleDeleter;
-import org.sonar.server.rule.RuleOperations;
-import org.sonar.server.rule.RuleRepositories;
-import org.sonar.server.rule.RuleService;
-import org.sonar.server.rule.RuleUpdater;
+import org.sonar.server.qualityprofile.ws.*;
+import org.sonar.server.rule.*;
 import org.sonar.server.rule.db.RuleDao;
 import org.sonar.server.rule.index.RuleIndex;
 import org.sonar.server.rule.index.RuleNormalizer;
-import org.sonar.server.rule.ws.ActiveRuleCompleter;
-import org.sonar.server.rule.ws.AppAction;
-import org.sonar.server.rule.ws.DeleteAction;
-import org.sonar.server.rule.ws.RuleMapping;
-import org.sonar.server.rule.ws.RulesWebService;
-import org.sonar.server.rule.ws.SearchAction;
-import org.sonar.server.rule.ws.TagsAction;
-import org.sonar.server.rule.ws.UpdateAction;
-import org.sonar.server.search.IndexClient;
-import org.sonar.server.search.IndexQueue;
-import org.sonar.server.search.IndexSynchronizer;
-import org.sonar.server.search.SearchClient;
-import org.sonar.server.search.SearchHealth;
+import org.sonar.server.rule.ws.*;
+import org.sonar.server.search.*;
 import org.sonar.server.source.CodeColorizers;
 import org.sonar.server.source.DeprecatedSourceDecorator;
 import org.sonar.server.source.HtmlSourceDecorator;
@@ -247,27 +154,9 @@ import org.sonar.server.source.ws.ScmAction;
 import org.sonar.server.source.ws.ScmWriter;
 import org.sonar.server.source.ws.ShowAction;
 import org.sonar.server.source.ws.SourcesWs;
-import org.sonar.server.startup.CleanPreviewAnalysisCache;
-import org.sonar.server.startup.CopyRequirementsFromCharacteristicsToRules;
-import org.sonar.server.startup.GeneratePluginIndex;
-import org.sonar.server.startup.GwtPublisher;
-import org.sonar.server.startup.JdbcDriverDeployer;
-import org.sonar.server.startup.LogServerId;
-import org.sonar.server.startup.RegisterDashboards;
-import org.sonar.server.startup.RegisterDebtModel;
-import org.sonar.server.startup.RegisterMetrics;
-import org.sonar.server.startup.RegisterNewMeasureFilters;
-import org.sonar.server.startup.RegisterPermissionTemplates;
-import org.sonar.server.startup.RegisterServletFilters;
-import org.sonar.server.startup.RenameDeprecatedPropertyKeys;
-import org.sonar.server.startup.ServerMetadataPersister;
+import org.sonar.server.startup.*;
 import org.sonar.server.test.CoverageService;
-import org.sonar.server.test.ws.CoverageShowAction;
-import org.sonar.server.test.ws.CoverageWs;
-import org.sonar.server.test.ws.TestsCoveredFilesAction;
-import org.sonar.server.test.ws.TestsShowAction;
-import org.sonar.server.test.ws.TestsTestCasesAction;
-import org.sonar.server.test.ws.TestsWs;
+import org.sonar.server.test.ws.*;
 import org.sonar.server.text.MacroInterpreter;
 import org.sonar.server.text.RubyTextService;
 import org.sonar.server.ui.JRubyI18n;
@@ -275,22 +164,11 @@ import org.sonar.server.ui.JRubyProfiling;
 import org.sonar.server.ui.PageDecorations;
 import org.sonar.server.ui.Views;
 import org.sonar.server.updatecenter.ws.UpdateCenterWs;
-import org.sonar.server.user.DefaultUserService;
-import org.sonar.server.user.DoPrivileged;
-import org.sonar.server.user.GroupMembershipFinder;
-import org.sonar.server.user.GroupMembershipService;
-import org.sonar.server.user.NewUserNotifier;
-import org.sonar.server.user.SecurityRealmFactory;
+import org.sonar.server.user.*;
 import org.sonar.server.user.ws.FavoritesWs;
 import org.sonar.server.user.ws.UserPropertiesWs;
 import org.sonar.server.user.ws.UsersWs;
-import org.sonar.server.util.BooleanTypeValidation;
-import org.sonar.server.util.FloatTypeValidation;
-import org.sonar.server.util.IntegerTypeValidation;
-import org.sonar.server.util.StringListTypeValidation;
-import org.sonar.server.util.StringTypeValidation;
-import org.sonar.server.util.TextTypeValidation;
-import org.sonar.server.util.TypeValidations;
+import org.sonar.server.util.*;
 import org.sonar.server.ws.ListingWs;
 import org.sonar.server.ws.WebServiceEngine;
 
@@ -341,6 +219,7 @@ class ServerComponents {
       System2.INSTANCE,
       RuleDao.class,
       IssueDao.class,
+      IssueAuthorizationDao.class,
       ActiveRuleDao.class,
       MeasureDao.class,
       MetricDao.class,
index 31240ef46a149868533468de6f5302868d23428f..ee9caa8174d8bc727639fb33efc3c7f205cb7595 100644 (file)
@@ -51,6 +51,8 @@ public class IndexSynchronizer {
     long start = System.currentTimeMillis();
     synchronize(session, db.ruleDao(), index.get(RuleIndex.class));
     synchronize(session, db.issueDao(), index.get(IssueIndex.class));
+    // TODO
+    //synchronize(session, db.issueAuthorizationDao(), index.get(IssueAuthorizationIndex.class));
     synchronize(session, db.activeRuleDao(), index.get(ActiveRuleIndex.class));
     synchronize(session, db.activityDao(), index.get(ActivityIndex.class));
     session.commit();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueAuthorizationDaoTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueAuthorizationDaoTest.java
new file mode 100644 (file)
index 0000000..38a1d7e
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * 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.issue.db;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.api.utils.System2;
+import org.sonar.core.issue.db.IssueAuthorizationDto;
+import org.sonar.core.persistence.AbstractDaoTestCase;
+import org.sonar.core.persistence.DbSession;
+
+import java.util.Date;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class IssueAuthorizationDaoTest extends AbstractDaoTestCase {
+
+  private IssueAuthorizationDao dao;
+  private DbSession session;
+
+  @Before
+  public void before() throws Exception {
+    this.session = getMyBatis().openSession(false);
+    this.dao = new IssueAuthorizationDao(System2.INSTANCE);
+  }
+
+  @After
+  public void after() {
+    this.session.close();
+  }
+
+  @Test(expected = IllegalStateException.class)
+  public void get_nullable_by_key_is_not_implemented(){
+    assertThat(dao.getNullableByKey(session, "sonar"));
+  }
+
+  @Test
+  public void find_after_date(){
+    setupData("find_after_date");
+
+    Iterable<IssueAuthorizationDto> results = dao.findAfterDate(session, new Date(0));
+    assertThat(results).hasSize(1);
+
+    IssueAuthorizationDto dto = results.iterator().next();
+    assertThat(dto.getProject()).isEqualTo("org.struts:struts");
+    assertThat(dto.getKey()).isEqualTo("org.struts:struts");
+    assertThat(dto.getPermission()).isEqualTo("user");
+    assertThat(dto.getGroups()).containsExactly("anyone", "devs");
+    assertThat(dto.getUsers()).containsExactly("user1");
+  }
+
+  @Test
+  public void find_after_date_return_dtos_after_given_date(){
+    setupData("find_after_date_return_dtos_after_given_date");
+
+    assertThat(dao.findAfterDate(session, new Date(0))).hasSize(2);
+
+    assertThat(dao.findAfterDate(session, DateUtils.parseDate("2014-09-01"))).hasSize(1);
+  }
+}
index a3449edb748c8e8cd7e5973a1e5d2f8fc2261b65..01b25f0396a9d4306d8aafd460ec99bd3024b410 100644 (file)
@@ -49,6 +49,8 @@ import org.sonar.server.search.IndexDefinition;
 import org.sonar.server.search.SearchClient;
 import org.sonar.server.tester.ServerTester;
 
+import javax.annotation.Nullable;
+
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -189,6 +191,11 @@ public class IssueBackendMediumTest {
     assertThat(indexClient.get(IssueIndex.class).countAll()).isEqualTo(1);
   }
 
+  @Test
+  public void synchronize_issue_authorization_index() throws Exception {
+
+  }
+
   @Test
   public void issue_authorization_on_group() throws Exception {
     SearchClient searchClient = tester.get(SearchClient.class);
@@ -341,11 +348,11 @@ public class IssueBackendMediumTest {
     return issue;
   }
 
-  private IndexRequestBuilder addIssueAuthorization(final SearchClient searchClient, ComponentDto project, List<String> users, List<String> groups) {
+  private IndexRequestBuilder addIssueAuthorization(final SearchClient searchClient, ComponentDto project, @Nullable List<String> users, @Nullable List<String> groups) {
     return addIssueAuthorization(searchClient, project, users, groups, true);
   }
 
-  private IndexRequestBuilder addIssueAuthorization(final SearchClient searchClient, ComponentDto project, List<String> users, List<String> groups, boolean refresh) {
+  private IndexRequestBuilder addIssueAuthorization(final SearchClient searchClient, ComponentDto project, @Nullable List<String> users, @Nullable List<String> groups, boolean refresh) {
     Map<String, Object> permissionSource = newHashMap();
     permissionSource.put("_parent", project.key());
     permissionSource.put("permission", "read");
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueAuthorizationDaoTest/find_after_date.xml b/server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueAuthorizationDaoTest/find_after_date.xml
new file mode 100644 (file)
index 0000000..9236b6d
--- /dev/null
@@ -0,0 +1,27 @@
+<dataset>
+
+  <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+            description="the description" long_name="Apache Struts"
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]"
+            authorization_updated_at="2014-01-01"/>
+
+  <groups id="100" name="devs"/>
+
+  <users id="10" login="user1" name="User 1" email="user1@company.net" active="[true]"/>
+
+  <user_roles id="1" user_id="10" resource_id="1" role="user"/>
+  <user_roles id="2" user_id="10" resource_id="1" role="admin"/>
+  <user_roles id="3" user_id="10" resource_id="2" role="user"/>
+
+  <group_roles id="1" group_id="100" resource_id="1" role="user"/>
+  <group_roles id="2" group_id="100" resource_id="1" role="admin"/>
+  <group_roles id="3" group_id="100" resource_id="2" role="user"/>
+
+  <!-- Anyone group -->
+
+  <group_roles id="4" group_id="[null]" resource_id="1" role="user"/>
+  <group_roles id="5" group_id="[null]" resource_id="1" role="admin"/>
+  <group_roles id="6" group_id="[null]" resource_id="2" role="user"/>
+
+
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueAuthorizationDaoTest/find_after_date_return_dtos_after_given_date.xml b/server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueAuthorizationDaoTest/find_after_date_return_dtos_after_given_date.xml
new file mode 100644 (file)
index 0000000..eff0502
--- /dev/null
@@ -0,0 +1,44 @@
+<dataset>
+
+  <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+            description="the description" long_name="Apache Struts"
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]"
+            authorization_updated_at="2014-01-01"/>
+
+  <projects id="2" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.sonar.sample" name="Sample"
+            description="the description" long_name="Sample"
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]"
+            authorization_updated_at="2014-09-05"/>
+
+  <groups id="100" name="devs"/>
+
+  <!-- Permissions for user 1 -->
+
+  <users id="10" login="user1" name="User 1" email="user1@company.net" active="[true]"/>
+
+  <user_roles id="1" user_id="10" resource_id="1" role="user"/>
+  <user_roles id="2" user_id="10" resource_id="1" role="admin"/>
+  <user_roles id="3" user_id="10" resource_id="2" role="user"/>
+
+  <group_roles id="1" group_id="100" resource_id="1" role="user"/>
+  <group_roles id="2" group_id="100" resource_id="1" role="admin"/>
+  <group_roles id="3" group_id="100" resource_id="2" role="user"/>
+
+  <!-- Anyone group -->
+
+  <group_roles id="4" group_id="[null]" resource_id="1" role="user"/>
+  <group_roles id="5" group_id="[null]" resource_id="1" role="admin"/>
+  <group_roles id="6" group_id="[null]" resource_id="2" role="user"/>
+
+
+  <!-- Permissions for user 2 -->
+
+  <users id="11" login="user2" name="User 2" email="user2@company.net" active="[true]"/>
+
+  <user_roles id="4" user_id="10" resource_id="1" role="user"/>
+  <user_roles id="5" user_id="10" resource_id="2" role="user"/>
+
+  <group_roles id="10" group_id="100" resource_id="1" role="user"/>
+  <group_roles id="11" group_id="100" resource_id="2" role="user"/>
+
+</dataset>
index d66f0c9d231fef9dc64a01d5dd69f1f5696f7f4a..0c0b767c403e426b4f815b004ee44b76b34530dd 100644 (file)
@@ -25,16 +25,18 @@ import org.sonar.core.persistence.Dto;
 import java.io.Serializable;
 import java.util.List;
 
+import static com.google.common.collect.Lists.newArrayList;
+
 public final class IssueAuthorizationDto extends Dto<String> implements Serializable {
 
   private String project;
   private String permission;
-  private List<String> groups;
-  private List<String> users;
+  private List<String> groups = newArrayList();
+  private List<String> users = newArrayList();
 
   @Override
   public String getKey() {
-    return null;
+    return project;
   }
 
   public String getProject() {
@@ -64,6 +66,11 @@ public final class IssueAuthorizationDto extends Dto<String> implements Serializ
     return this;
   }
 
+  public IssueAuthorizationDto addGroup(String group) {
+    groups.add(group);
+    return this;
+  }
+
   public List<String> getUsers() {
     return users;
   }
@@ -72,4 +79,10 @@ public final class IssueAuthorizationDto extends Dto<String> implements Serializ
     this.users = users;
     return this;
   }
+
+  public IssueAuthorizationDto addUser(String user) {
+    users.add(user);
+    return this;
+  }
+
 }
index d327f7f938df879f435f2d8914a9c524720f00de..ca81eccafae3b7cd93c5149b8f2dae59c839bf17 100644 (file)
 
 package org.sonar.core.issue.db;
 
+import org.apache.ibatis.annotations.Param;
+
+import java.util.Date;
+
 public interface IssueAuthorizationMapper {
 
   IssueAuthorizationDto selectByKey(String key);
 
+  IssueAuthorizationDto selectAfterDate(@Param("date") Date date, @Param("permission") String permission);
+
 }
index 59dd14960149052c9e3dca29595c5dfa93d11c3f..d4cf8ba718fa57f94537580592d871681c0c9554 100644 (file)
@@ -4,13 +4,50 @@
 
 <mapper namespace="org.sonar.core.issue.db.IssueAuthorizationMapper">
 
-  <select id="selectByKey" parameterType="String" resultType="IssueAuthorization">
-    select *
-    from issues i
-    inner join rules r on r.id=i.rule_id
-    inner join projects p on p.id=i.component_id
-    inner join projects root on root.id=i.root_component_id
-    where i.kee=#{kee}
+  <select id="selectAfterDate" parameterType="map" resultType="map">
+    SELECT
+      project_authorization.project as project,
+      project_authorization.login as user,
+      project_authorization.permission_group as permission_group,
+      project_authorization.permission_role as permission_role
+    FROM (
+      -- users
+      SELECT
+      projects.kee AS project,
+      users.login  AS login,
+      NULL  AS permission_group,
+      user_roles.role as permission_role
+      FROM projects
+      INNER JOIN user_roles ON user_roles.resource_id = projects.id AND user_roles.role = #{permission}
+      INNER JOIN users ON users.id = user_roles.user_id
+      WHERE
+      projects.authorization_updated_at &gt;= #{date}
+      UNION
+      -- groups without Anyone
+      SELECT
+      projects.kee AS project,
+      NULL  AS login,
+      groups.name  AS permission_group,
+      group_roles.role as permission_role
+      FROM projects
+      INNER JOIN group_roles ON group_roles.resource_id = projects.id AND group_roles.role = #{permission}
+      INNER JOIN groups ON groups.id = group_roles.group_id
+      WHERE
+      projects.authorization_updated_at &gt;= #{date}
+      AND group_id IS NOT NULL
+      UNION
+      -- Anyone groups
+      SELECT
+      projects.kee AS project,
+      NULL         AS login,
+      'anyone'     AS permission_group,
+      group_roles.role as permission_role
+      FROM projects
+      INNER JOIN group_roles ON group_roles.resource_id = projects.id AND group_roles.role = #{permission}
+      WHERE
+      projects.authorization_updated_at &gt;= #{date}
+      AND group_roles.group_id IS NULL
+    ) AS project_authorization
   </select>
 
 </mapper>