From: Julien Lancelot Date: Mon, 15 Sep 2014 11:47:56 +0000 (+0200) Subject: SONAR-5614 Create project permissions and synchronize project issues X-Git-Tag: 5.0-RC1~994 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=3512475d7d4f437403b482f43bbf4790b8736cca;p=sonarqube.git SONAR-5614 Create project permissions and synchronize project issues --- diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/BatchWs.java b/server/sonar-server/src/main/java/org/sonar/server/batch/BatchWs.java index 99fa1ac21e0..ec85d3495b1 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/batch/BatchWs.java +++ b/server/sonar-server/src/main/java/org/sonar/server/batch/BatchWs.java @@ -30,6 +30,8 @@ import java.io.IOException; public class BatchWs implements WebService { + public static final String API_ENDPOINT = "batch"; + private final BatchIndex batchIndex; private final GlobalReferentialsAction globalReferentialsAction; private final ProjectReferentialsAction projectReferentialsAction; @@ -45,7 +47,7 @@ public class BatchWs implements WebService { @Override public void define(Context context) { - NewController controller = context.createController("batch") + NewController controller = context.createController(API_ENDPOINT) .setSince("4.4") .setDescription("Get JAR files and referentials for batch"); diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/UploadReportAction.java b/server/sonar-server/src/main/java/org/sonar/server/batch/UploadReportAction.java index 32846ef36e9..e2b2ccf7917 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/batch/UploadReportAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/batch/UploadReportAction.java @@ -20,27 +20,40 @@ package org.sonar.server.batch; +import com.google.common.collect.ImmutableMap; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.RequestHandler; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; +import org.sonar.core.component.AuthorizedComponentDto; +import org.sonar.core.permission.GlobalPermissions; import org.sonar.core.persistence.DbSession; import org.sonar.core.persistence.MyBatis; import org.sonar.server.db.DbClient; +import org.sonar.server.issue.index.IssueIndex; +import org.sonar.server.permission.InternalPermissionService; +import org.sonar.server.search.IndexClient; +import org.sonar.server.user.UserSession; public class UploadReportAction implements RequestHandler { - private static final String PARAM_PROJECT = "project"; - private static final String PARAM_FIRST_ANALYSIS = "firstAnalysis"; + public static final String UPLOAD_REPORT_ACTION = "upload_report"; + + static final String PARAM_PROJECT = "project"; + static final String PARAM_FIRST_ANALYSIS = "firstAnalysis"; private final DbClient dbClient; + private final IndexClient index; + private final InternalPermissionService permissionService; - public UploadReportAction(DbClient dbClient) { + public UploadReportAction(DbClient dbClient, IndexClient index, InternalPermissionService permissionService) { this.dbClient = dbClient; + this.index = index; + this.permissionService = permissionService; } void define(WebService.NewController controller) { - WebService.NewAction action = controller.createAction("upload_report") + WebService.NewAction action = controller.createAction(UPLOAD_REPORT_ACTION) .setDescription("Update analysis report") .setSince("5.0") .setPost(true) @@ -64,7 +77,24 @@ public class UploadReportAction implements RequestHandler { public void handle(Request request, Response response) throws Exception { DbSession session = dbClient.openSession(false); try { - // TODO + String projectKey = request.mandatoryParam(PARAM_PROJECT); + AuthorizedComponentDto project = dbClient.componentDao().getAuthorizedComponentByKey(projectKey, session); + + // Create permission on project + boolean isFirstAnalysis = request.mandatoryParamAsBoolean(PARAM_FIRST_ANALYSIS); + if (isFirstAnalysis) { + permissionService.applyDefaultPermissionTemplate(session, project); + session.commit(); + } + + UserSession.get().checkGlobalPermission(GlobalPermissions.SCAN_EXECUTION); + + // Index project's issues + dbClient.issueDao().synchronizeAfter(session, + index.get(IssueIndex.class).getLastSynchronization(), + ImmutableMap.of("project", projectKey)); + session.commit(); + } finally { MyBatis.closeQuietly(session); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/db/BaseDao.java b/server/sonar-server/src/main/java/org/sonar/server/db/BaseDao.java index bb42fa775c1..08d9f0f2153 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/db/BaseDao.java +++ b/server/sonar-server/src/main/java/org/sonar/server/db/BaseDao.java @@ -299,9 +299,14 @@ public abstract class BaseDao, KEY extends Serializ } } + @VisibleForTesting + public List findAfterDate(final DbSession session, Date date, Map params) { + return session.selectList(getSynchronizeStatementFQN(), getSynchronizationParams(date, params)); + } + @VisibleForTesting public List findAfterDate(final DbSession session, Date date) { - return session.selectList(getSynchronizeStatementFQN(), getSynchronizationParams(date)); + return findAfterDate(session, date, Collections.emptyMap()); } // Synchronization methods diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/db/IssueDao.java b/server/sonar-server/src/main/java/org/sonar/server/issue/db/IssueDao.java index e37624bdf6b..86cef1b1eff 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/db/IssueDao.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/db/IssueDao.java @@ -29,8 +29,13 @@ import org.sonar.core.persistence.DbSession; import org.sonar.server.db.BaseDao; import org.sonar.server.search.IndexDefinition; +import java.util.Date; +import java.util.Map; + public class IssueDao extends BaseDao implements DaoComponent { + public static final String PROJECT_KEY = "project"; + public IssueDao() { this(System2.INSTANCE); } @@ -59,9 +64,15 @@ public class IssueDao extends BaseDao implements return issue; } - @Override protected String getSynchronizationStatementName() { return "selectAfterDate"; } + + @Override + protected Map getSynchronizationParams(Date date, Map params) { + Map finalParams = super.getSynchronizationParams(date, params); + finalParams.put(PROJECT_KEY, params.get(PROJECT_KEY)); + return finalParams; + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/InternalPermissionService.java b/server/sonar-server/src/main/java/org/sonar/server/permission/InternalPermissionService.java index 012a77cb269..22a34d2f865 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/InternalPermissionService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/InternalPermissionService.java @@ -116,14 +116,18 @@ public class InternalPermissionService implements ServerComponent { UserSession.get().checkGlobalPermission(GlobalPermissions.PROVISIONING); } - permissionFacade.grantDefaultRoles(session, component.getId(), component.qualifier()); - synchronizePermissions(session, componentKey); + applyDefaultPermissionTemplate(session, component); session.commit(); } finally { session.close(); } } + public void applyDefaultPermissionTemplate(DbSession session, AuthorizedComponentDto component) { + permissionFacade.grantDefaultRoles(session, component.getId(), component.qualifier()); + synchronizePermissions(session, component.key()); + } + public void applyPermissionTemplate(Map params) { UserSession.get().checkLoggedIn(); @@ -272,8 +276,8 @@ public class InternalPermissionService implements ServerComponent { } private void synchronizePermissions(DbSession session, String projectKey) { - dbClient.issueAuthorizationDao().synchronizeAfter(session, - index.get(IssueAuthorizationIndex.class).getLastSynchronization(), - ImmutableMap.of(IssueAuthorizationDao.PROJECT_KEY, projectKey)); + dbClient.issueAuthorizationDao().synchronizeAfter(session, + index.get(IssueAuthorizationIndex.class).getLastSynchronization(), + ImmutableMap.of(IssueAuthorizationDao.PROJECT_KEY, projectKey)); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/InternalPermissionTemplateService.java b/server/sonar-server/src/main/java/org/sonar/server/permission/InternalPermissionTemplateService.java index 97b1798ada7..e089b2abd39 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/InternalPermissionTemplateService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/InternalPermissionTemplateService.java @@ -23,13 +23,16 @@ package org.sonar.server.permission; import com.google.common.collect.Lists; import org.apache.commons.lang.StringUtils; import org.sonar.api.ServerComponent; +import org.sonar.api.resources.Qualifiers; import org.sonar.core.permission.GlobalPermissions; import org.sonar.core.permission.PermissionTemplateDao; import org.sonar.core.permission.PermissionTemplateDto; import org.sonar.core.persistence.DbSession; import org.sonar.core.persistence.MyBatis; +import org.sonar.core.properties.PropertyDto; import org.sonar.core.user.GroupDto; import org.sonar.core.user.UserDao; +import org.sonar.server.db.DbClient; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.user.UserSession; @@ -47,12 +50,15 @@ import java.util.regex.PatternSyntaxException; */ public class InternalPermissionTemplateService implements ServerComponent { + private final DbClient db; + private final MyBatis myBatis; private final PermissionTemplateDao permissionTemplateDao; private final UserDao userDao; private final PermissionFinder finder; - public InternalPermissionTemplateService(MyBatis myBatis, PermissionTemplateDao permissionTemplateDao, UserDao userDao, PermissionFinder finder) { + public InternalPermissionTemplateService(DbClient db, MyBatis myBatis, PermissionTemplateDao permissionTemplateDao, UserDao userDao, PermissionFinder finder) { + this.db = db; this.myBatis = myBatis; this.permissionTemplateDao = permissionTemplateDao; this.userDao = userDao; @@ -110,6 +116,20 @@ public class InternalPermissionTemplateService implements ServerComponent { permissionTemplateDao.deletePermissionTemplate(templateId); } + public void updateDefaultTemplate(String permissionTemplateKey, String qualifier){ + if (Qualifiers.PROJECT.equals(qualifier)) { + saveProperty("sonar.permission.template.default", permissionTemplateKey); + } + saveProperty("sonar.permission." + qualifier + ".default", permissionTemplateKey); + } + + private void saveProperty(String propertyKey, String value){ + PropertyDto property = new PropertyDto() + .setKey(propertyKey) + .setValue(value); + db.propertiesDao().setProperty(property); + } + public void addUserPermission(String templateKey, String permission, String userLogin) { PermissionTemplateUpdater updater = new PermissionTemplateUpdater(templateKey, permission, userLogin, permissionTemplateDao, userDao) { @Override diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/BatchWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/BatchWsTest.java index 1373d8468a6..faecc1be4ee 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/batch/BatchWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/batch/BatchWsTest.java @@ -31,9 +31,11 @@ import org.mockito.runners.MockitoJUnitRunner; import org.sonar.api.resources.Languages; import org.sonar.core.properties.PropertiesDao; import org.sonar.server.db.DbClient; +import org.sonar.server.permission.InternalPermissionService; import org.sonar.server.qualityprofile.QProfileFactory; import org.sonar.server.qualityprofile.QProfileLoader; import org.sonar.server.rule.RuleService; +import org.sonar.server.search.IndexClient; import org.sonar.server.ws.WsTester; import java.io.File; @@ -63,7 +65,7 @@ public class BatchWsTest { new GlobalReferentialsAction(mock(DbClient.class), mock(PropertiesDao.class)), new ProjectReferentialsAction(mock(DbClient.class), mock(PropertiesDao.class), mock(QProfileFactory.class), mock(QProfileLoader.class), mock(RuleService.class), mock(Languages.class)), - new UploadReportAction(mock(DbClient.class)))); + new UploadReportAction(mock(DbClient.class), mock(IndexClient.class), mock(InternalPermissionService.class)))); } @Test diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/UploadReportActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/UploadReportActionMediumTest.java new file mode 100644 index 00000000000..f88a3c8f734 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/batch/UploadReportActionMediumTest.java @@ -0,0 +1,190 @@ +/* + * 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.batch; + +import org.elasticsearch.index.query.QueryBuilders; +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.sonar.api.server.ws.WebService; +import org.sonar.api.utils.DateUtils; +import org.sonar.api.web.UserRole; +import org.sonar.core.component.ComponentDto; +import org.sonar.core.issue.db.IssueDto; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.core.permission.PermissionQuery; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.rule.RuleDto; +import org.sonar.server.component.SnapshotTesting; +import org.sonar.server.db.DbClient; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.issue.index.IssueAuthorizationIndex; +import org.sonar.server.issue.index.IssueIndex; +import org.sonar.server.permission.PermissionFinder; +import org.sonar.server.platform.Platform; +import org.sonar.server.rule.RuleTesting; +import org.sonar.server.rule.db.RuleDao; +import org.sonar.server.search.IndexDefinition; +import org.sonar.server.search.SearchClient; +import org.sonar.server.tester.ServerTester; +import org.sonar.server.user.MockUserSession; +import org.sonar.server.ws.WsTester; + +import static org.fest.assertions.Assertions.assertThat; + +public class UploadReportActionMediumTest { + + @ClassRule + public static ServerTester tester = new ServerTester(); + + DbClient db; + DbSession session; + + WsTester wsTester; + BatchWs ws; + WebService.Controller controller; + + @Before + public void setUp() throws Exception { + tester.clearDbAndIndexes(); + + db = tester.get(DbClient.class); + session = db.openSession(false); + + ws = tester.get(BatchWs.class); + wsTester = tester.get(WsTester.class); + controller = wsTester.controller(BatchWs.API_ENDPOINT); + } + + @After + public void after() { + session.close(); + } + + @Test + public void define() throws Exception { + WebService.Action restoreProfiles = controller.action(UploadReportAction.UPLOAD_REPORT_ACTION); + assertThat(restoreProfiles).isNotNull(); + assertThat(restoreProfiles.params()).hasSize(2); + } + + @Test + public void create_project_permission_on_first_analysis() throws Exception { + // Execute startup task to create default permission template + tester.get(Platform.class).executeStartupTasks(); + + ComponentDto project = new ComponentDto() + .setId(1L) + .setKey("MyProject") + .setProjectId(1L); + db.componentDao().insert(session, project); + session.commit(); + + MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); + + // Project has no user permission + assertThat(tester.get(PermissionFinder.class).findGroupsWithPermission(PermissionQuery.builder().component(project.key()).permission(UserRole.USER).build()).groups().get(0).hasPermission()).isFalse(); + + WsTester.TestRequest request = wsTester.newGetRequest(BatchWs.API_ENDPOINT, UploadReportAction.UPLOAD_REPORT_ACTION); + request.setParam(UploadReportAction.PARAM_PROJECT, project.key()); + request.setParam(UploadReportAction.PARAM_FIRST_ANALYSIS, "true"); + request.execute(); + + // Check that user permission group have been affected to the project + assertThat(tester.get(PermissionFinder.class).findGroupsWithPermission(PermissionQuery.builder().component(project.key()).permission(UserRole.USER).build()).groups()).hasSize(1); + assertThat(tester.get(PermissionFinder.class).findGroupsWithPermission(PermissionQuery.builder().component(project.key()).permission(UserRole.USER).build()).groups().get(0).hasPermission()).isTrue(); + + // Check that issue authorization index has been created + assertThat(tester.get(IssueAuthorizationIndex.class).getByKey(project.getKey())).isNotNull(); + } + + @Test(expected = ForbiddenException.class) + public void fail_without_global_scan_permission() throws Exception { + ComponentDto project = new ComponentDto() + .setId(1L) + .setKey("MyProject") + .setProjectId(1L); + db.componentDao().insert(session, project); + session.commit(); + + MockUserSession.set().setLogin("john").addProjectPermissions(UserRole.USER, project.key()); + + WsTester.TestRequest request = wsTester.newGetRequest(BatchWs.API_ENDPOINT, UploadReportAction.UPLOAD_REPORT_ACTION); + request.setParam(UploadReportAction.PARAM_PROJECT, project.key()); + request.execute(); + } + + @Test + public void index_project_issues() throws Exception { + ComponentDto project = new ComponentDto() + .setId(1L) + .setKey("MyProject") + .setProjectId(1L); + db.componentDao().insert(session, project); + + ComponentDto resource = new ComponentDto() + .setProjectId(1L) + .setKey("MyComponent") + .setId(2L); + db.componentDao().insert(session, resource); + db.snapshotDao().insert(session, SnapshotTesting.createForComponent(resource)); + + RuleDto rule = RuleTesting.newXooX1(); + tester.get(RuleDao.class).insert(session, rule); + + IssueDto issue = new IssueDto() + .setIssueCreationDate(DateUtils.parseDate("2014-09-04")) + .setIssueUpdateDate(DateUtils.parseDate("2014-12-04")) + .setRule(rule) + .setDebt(10L) + .setRootComponent(project) + .setComponent(resource) + .setStatus("OPEN").setResolution("OPEN") + .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") + .setSeverity("MAJOR"); + db.issueDao().insert(session, issue); + + session.commit(); + + // Clear issue index to simulate that the issue has been inserted by the batch, so that it's not yet index in E/S + clearIssueIndex(); + assertThat(db.issueDao().getByKey(session, issue.getKey())).isNotNull(); + assertThat(tester.get(IssueIndex.class).getByKey(issue.getKey())).isNull(); + + MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); + + WsTester.TestRequest request = wsTester.newGetRequest(BatchWs.API_ENDPOINT, UploadReportAction.UPLOAD_REPORT_ACTION); + request.setParam(UploadReportAction.PARAM_PROJECT, project.key()); + request.execute(); + + // Check that the issue has well be indexed in E/S + assertThat(tester.get(IssueIndex.class).getByKey(issue.getKey())).isNotNull(); + } + + private void clearIssueIndex(){ + tester.get(SearchClient.class).prepareDeleteByQuery(tester.get(SearchClient.class).admin().cluster().prepareState().get() + .getState().getMetaData().concreteIndices(new String[]{IndexDefinition.ISSUES.getIndexName()})) + .setQuery(QueryBuilders.matchAllQuery()) + .get(); + } + +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueDaoTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueDaoTest.java index 66e3c2ed6b4..44d4efb6b31 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueDaoTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueDaoTest.java @@ -19,6 +19,7 @@ */ package org.sonar.server.issue.db; +import com.google.common.collect.ImmutableMap; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -60,4 +61,11 @@ public class IssueDaoTest extends AbstractDaoTestCase { Date t2014 = DateUtils.parseDate("2014-01-01"); assertThat(dao.findAfterDate(session, t2014)).hasSize(1); } + + @Test + public void find_after_dates_with_project() throws Exception { + setupData("shared", "find_after_dates_with_project"); + + assertThat(dao.findAfterDate(session, DateUtils.parseDate("2014-01-01"), ImmutableMap.of("project", "struts"))).hasSize(1); + } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/IssuesWsMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/IssuesWsMediumTest.java index fe69a4619ee..fb8d9428188 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/IssuesWsMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/IssuesWsMediumTest.java @@ -73,11 +73,7 @@ public class IssuesWsMediumTest { @Test public void define() throws Exception { - - WebService.Context context = new WebService.Context(); - ws.define(context); - - WebService.Controller controller = context.controller(IssuesWs.API_ENDPOINT); + WebService.Controller controller = wsTester.controller(IssuesWs.API_ENDPOINT); assertThat(controller).isNotNull(); assertThat(controller.actions()).hasSize(14); diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/InternalPermissionServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/InternalPermissionServiceTest.java index 03a3b769f8d..1f176312171 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/InternalPermissionServiceTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/InternalPermissionServiceTest.java @@ -542,11 +542,9 @@ public class InternalPermissionServiceTest { final long componentId = 1234l; final String qualifier = Qualifiers.PROJECT; - ComponentDto mockComponent = mock(ComponentDto.class); - when(mockComponent.getId()).thenReturn(componentId); - when(mockComponent.qualifier()).thenReturn(qualifier); + ComponentDto project = new ComponentDto().setId(componentId).setKey(componentKey).setQualifier(qualifier); - when(componentDao.getAuthorizedComponentByKey(componentKey, session)).thenReturn(mockComponent); + when(componentDao.getAuthorizedComponentByKey(componentKey, session)).thenReturn(project); when(resourceDao.selectProvisionedProject(session, componentKey)).thenReturn(mock(ResourceDto.class)); service.applyDefaultPermissionTemplate(componentKey); diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/InternalPermissionTemplateServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/InternalPermissionTemplateServiceTest.java index c50acc61604..661fe9aeb9a 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/InternalPermissionTemplateServiceTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/InternalPermissionTemplateServiceTest.java @@ -36,6 +36,7 @@ import org.sonar.core.persistence.MyBatis; import org.sonar.core.user.GroupDto; import org.sonar.core.user.UserDao; import org.sonar.core.user.UserDto; +import org.sonar.server.db.DbClient; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.user.MockUserSession; @@ -66,6 +67,9 @@ public class InternalPermissionTemplateServiceTest { @Mock DbSession session; + @Mock + DbClient db; + InternalPermissionTemplateService service; @Rule @@ -77,7 +81,7 @@ public class InternalPermissionTemplateServiceTest { MyBatis myBatis = mock(MyBatis.class); when(myBatis.openSession(false)).thenReturn(session); - service = new InternalPermissionTemplateService(myBatis, permissionTemplateDao, userDao, finder); + service = new InternalPermissionTemplateService(db, myBatis, permissionTemplateDao, userDao, finder); } @Test diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueDaoTest/find_after_dates_with_project.xml b/server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueDaoTest/find_after_dates_with_project.xml new file mode 100644 index 00000000000..b8ffad1a1c0 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueDaoTest/find_after_dates_with_project.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + diff --git a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueMapper.java b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueMapper.java index d89868867c7..e09a68c1669 100644 --- a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueMapper.java +++ b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueMapper.java @@ -59,5 +59,5 @@ public interface IssueMapper { int updateIfBeforeSelectedDate(IssueDto issue); - List selectAfterDate(Timestamp timestamp); + List selectAfterDate(@Param("date") Timestamp timestamp, @Nullable @Param("project") String project); } diff --git a/sonar-core/src/main/java/org/sonar/core/permission/PermissionFacade.java b/sonar-core/src/main/java/org/sonar/core/permission/PermissionFacade.java index b2552d5043e..6bf273c5176 100644 --- a/sonar-core/src/main/java/org/sonar/core/permission/PermissionFacade.java +++ b/sonar-core/src/main/java/org/sonar/core/permission/PermissionFacade.java @@ -183,11 +183,11 @@ public class PermissionFacade implements TaskComponent, ServerComponent { roleDao.deleteUserRolesByResourceId(resourceId, session); } - public List selectGroupPermissions(DbSession session, String group, Long componentId) { + public List selectGroupPermissions(DbSession session, String group, @Nullable Long componentId) { return roleDao.selectGroupPermissions(session, group, componentId); } - public List selectUserPermissions(DbSession session, String user, Long componentId) { + public List selectUserPermissions(DbSession session, String user, @Nullable Long componentId) { return roleDao.selectUserPermissions(session, user, componentId); } diff --git a/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueMapper.xml b/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueMapper.xml index 9d22edf886e..76fb97eaadf 100644 --- a/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueMapper.xml +++ b/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueMapper.xml @@ -139,13 +139,17 @@ fetchSize="2000" statementType="PREPARED" resultSetType="FORWARD_ONLY"> - select - + 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.updated_at IS NULL or i.updated_at >= #{date} + + i.updated_at IS NULL or i.updated_at >= #{date} + + and root.kee = #{project} + +