diff options
author | Julien Lancelot <julien.lancelot@gmail.com> | 2013-06-04 12:29:23 +0200 |
---|---|---|
committer | Julien Lancelot <julien.lancelot@gmail.com> | 2013-06-04 12:29:23 +0200 |
commit | ea08bd15fb9a1267264bb7f00b1e924f44889f5a (patch) | |
tree | de2068bd49145b8840506d59aa66680208dcae1c /sonar-server/src | |
parent | d223b2da0748ccc99862c0b39676edca07579725 (diff) | |
download | sonarqube-ea08bd15fb9a1267264bb7f00b1e924f44889f5a.tar.gz sonarqube-ea08bd15fb9a1267264bb7f00b1e924f44889f5a.zip |
SONAR-3755 Add security on action plan
Diffstat (limited to 'sonar-server/src')
10 files changed, 191 insertions, 98 deletions
diff --git a/sonar-server/src/main/java/org/sonar/server/issue/ActionPlanService.java b/sonar-server/src/main/java/org/sonar/server/issue/ActionPlanService.java index ee024f6bb58..8e8331096e1 100644 --- a/sonar-server/src/main/java/org/sonar/server/issue/ActionPlanService.java +++ b/sonar-server/src/main/java/org/sonar/server/issue/ActionPlanService.java @@ -24,6 +24,7 @@ import com.google.common.base.Function; import com.google.common.collect.Iterables; import org.sonar.api.ServerComponent; import org.sonar.api.issue.ActionPlan; +import org.sonar.api.web.UserRole; import org.sonar.core.issue.ActionPlanDeadlineComparator; import org.sonar.core.issue.ActionPlanStats; import org.sonar.core.issue.db.ActionPlanDao; @@ -33,6 +34,8 @@ import org.sonar.core.issue.db.ActionPlanStatsDto; import org.sonar.core.resource.ResourceDao; import org.sonar.core.resource.ResourceDto; import org.sonar.core.resource.ResourceQuery; +import org.sonar.core.user.AuthorizationDao; +import org.sonar.server.user.UserSession; import javax.annotation.CheckForNull; @@ -51,32 +54,38 @@ public class ActionPlanService implements ServerComponent { private final ActionPlanDao actionPlanDao; private final ActionPlanStatsDao actionPlanStatsDao; private final ResourceDao resourceDao; + private final AuthorizationDao authorizationDao; - public ActionPlanService(ActionPlanDao actionPlanDao, ActionPlanStatsDao actionPlanStatsDao, ResourceDao resourceDao) { + public ActionPlanService(ActionPlanDao actionPlanDao, ActionPlanStatsDao actionPlanStatsDao, ResourceDao resourceDao, AuthorizationDao authorizationDao) { this.actionPlanDao = actionPlanDao; this.actionPlanStatsDao = actionPlanStatsDao; this.resourceDao = resourceDao; + this.authorizationDao = authorizationDao; } - public ActionPlan create(ActionPlan actionPlan){ - actionPlanDao.save(ActionPlanDto.toActionDto(actionPlan, findComponent(actionPlan.projectKey()).getId())); + public ActionPlan create(ActionPlan actionPlan, UserSession userSession) { + ResourceDto project = findProject(actionPlan.projectKey()); + checkAuthorization(userSession, project, UserRole.ADMIN); + actionPlanDao.save(ActionPlanDto.toActionDto(actionPlan, project.getId())); return actionPlan; } - public ActionPlan update(ActionPlan actionPlan){ - actionPlanDao.update(ActionPlanDto.toActionDto(actionPlan, findComponent(actionPlan.projectKey()).getId())); + public ActionPlan update(ActionPlan actionPlan, UserSession userSession) { + ResourceDto project = findProject(actionPlan.projectKey()); + checkAuthorization(userSession, project, UserRole.ADMIN); + actionPlanDao.update(ActionPlanDto.toActionDto(actionPlan, project.getId())); return actionPlan; } - public void delete(String key){ - actionPlanDao.delete(key); + public void delete(String actionPlanKey, UserSession userSession) { + checkAuthorization(userSession, findActionPlanDto(actionPlanKey).getProjectKey(), UserRole.ADMIN); + actionPlanDao.delete(actionPlanKey); } - public ActionPlan setStatus(String key, String status){ - ActionPlanDto actionPlanDto = actionPlanDao.findByKey(key); - if (actionPlanDto == null) { - throw new IllegalArgumentException("Action plan " + key + " has not been found."); - } + public ActionPlan setStatus(String actionPlanKey, String status, UserSession userSession) { + ActionPlanDto actionPlanDto = findActionPlanDto(actionPlanKey); + checkAuthorization(userSession, actionPlanDto.getProjectKey(), UserRole.ADMIN); + actionPlanDto.setStatus(status); actionPlanDto.setCreatedAt(new Date()); actionPlanDao.update(actionPlanDto); @@ -84,11 +93,12 @@ public class ActionPlanService implements ServerComponent { } @CheckForNull - public ActionPlan findByKey(String key) { + public ActionPlan findByKey(String key, UserSession userSession) { ActionPlanDto actionPlanDto = actionPlanDao.findByKey(key); if (actionPlanDto == null) { return null; } + checkAuthorization(userSession, actionPlanDto.getProjectKey(), UserRole.USER); return actionPlanDto.toActionPlan(); } @@ -97,15 +107,21 @@ public class ActionPlanService implements ServerComponent { return toActionPlans(actionPlanDtos); } - public Collection<ActionPlan> findOpenByComponentKey(String componentKey) { - List<ActionPlanDto> dtos = actionPlanDao.findOpenByProjectId(findRootProject(componentKey).getId()); + public Collection<ActionPlan> findOpenByProjectKey(String projectKey, UserSession userSession) { + ResourceDto project = findProject(projectKey); + checkAuthorization(userSession, project, UserRole.USER); + + List<ActionPlanDto> dtos = actionPlanDao.findOpenByProjectId(project.getId()); List<ActionPlan> plans = toActionPlans(dtos); Collections.sort(plans, new ActionPlanDeadlineComparator()); return plans; } - public List<ActionPlanStats> findActionPlanStats(String projectKey) { - List<ActionPlanStatsDto> actionPlanStatsDtos = actionPlanStatsDao.findByProjectId(findComponent(projectKey).getId()); + public List<ActionPlanStats> findActionPlanStats(String projectKey, UserSession userSession) { + ResourceDto project = findProject(projectKey); + checkAuthorization(userSession, project, UserRole.USER); + + List<ActionPlanStatsDto> actionPlanStatsDtos = actionPlanStatsDao.findByProjectId(project.getId()); List<ActionPlanStats> actionPlanStats = newArrayList(Iterables.transform(actionPlanStatsDtos, new Function<ActionPlanStatsDto, ActionPlanStats>() { @Override public ActionPlanStats apply(ActionPlanStatsDto actionPlanStatsDto) { @@ -117,7 +133,7 @@ public class ActionPlanService implements ServerComponent { } public boolean isNameAlreadyUsedForProject(String name, String projectKey) { - return !actionPlanDao.findByNameAndProjectId(name, findComponent(projectKey).getId()).isEmpty(); + return !actionPlanDao.findByNameAndProjectId(name, findProject(projectKey).getId()).isEmpty(); } private List<ActionPlan> toActionPlans(List<ActionPlanDto> actionPlanDtos) { @@ -129,19 +145,34 @@ public class ActionPlanService implements ServerComponent { })); } - private ResourceDto findComponent(String componentKey){ - ResourceDto resourceDto = resourceDao.getResource(ResourceQuery.create().setKey(componentKey)); - if (resourceDto == null) { - throw new IllegalArgumentException("Component " + componentKey + " does not exists."); + private ActionPlanDto findActionPlanDto(String actionPlanKey) { + ActionPlanDto actionPlanDto = actionPlanDao.findByKey(actionPlanKey); + if (actionPlanDto == null) { + throw new IllegalArgumentException("Action plan " + actionPlanKey + " has not been found."); } - return resourceDto; + return actionPlanDto; } - private ResourceDto findRootProject(String componentKey){ - ResourceDto resourceDto = resourceDao.getRootProjectByComponentKey(componentKey); + private ResourceDto findProject(String projectKey) { + ResourceDto resourceDto = resourceDao.getResource(ResourceQuery.create().setKey(projectKey)); if (resourceDto == null) { - throw new IllegalArgumentException("Component " + componentKey + " does not exists."); + throw new IllegalArgumentException("Project " + projectKey + " does not exists."); } return resourceDto; } + + private void checkAuthorization(UserSession userSession, String projectKey, String requiredRole) { + checkAuthorization(userSession, findProject(projectKey), requiredRole); + } + + private void checkAuthorization(UserSession userSession, ResourceDto project, String requiredRole) { + if (!userSession.isLoggedIn()) { + // must be logged + throw new IllegalStateException("User is not logged in"); + } + if (!authorizationDao.isAuthorizedComponentId(project.getId(), userSession.userId(), requiredRole)) { + throw new IllegalStateException("User does not have the required role to access the project: " + project.getKey()); + } + } + } diff --git a/sonar-server/src/main/java/org/sonar/server/issue/DefaultIssueFinder.java b/sonar-server/src/main/java/org/sonar/server/issue/DefaultIssueFinder.java index b3bcd0f6885..5fdd5b54e04 100644 --- a/sonar-server/src/main/java/org/sonar/server/issue/DefaultIssueFinder.java +++ b/sonar-server/src/main/java/org/sonar/server/issue/DefaultIssueFinder.java @@ -88,7 +88,7 @@ public class DefaultIssueFinder implements IssueFinder { throw new IllegalStateException("Unknown issue: " + issueKey); } if (!authorizationDao.isAuthorizedComponentId(dto.getComponentId(), UserSession.get().userId(), requiredRole)) { - throw new IllegalStateException("User does not have the role " + requiredRole + " required to change the issue: " + issueKey); + throw new IllegalStateException("User does not have the required role required to change the issue: " + issueKey); } return dto.toDefaultIssue(); } @@ -115,8 +115,8 @@ public class DefaultIssueFinder implements IssueFinder { Map<String, DefaultIssue> issuesByKey = newHashMap(); List<Issue> issues = newArrayList(); Set<Integer> ruleIds = Sets.newHashSet(); - Set<Integer> componentIds = Sets.newHashSet(); - Set<Integer> projectIds = Sets.newHashSet(); + Set<Long> componentIds = Sets.newHashSet(); + Set<Long> projectIds = Sets.newHashSet(); Set<String> actionPlanKeys = Sets.newHashSet(); Set<String> users = Sets.newHashSet(); for (IssueDto dto : pagedSortedIssues) { @@ -185,11 +185,11 @@ public class DefaultIssueFinder implements IssueFinder { return userFinder.findByLogins(Lists.newArrayList(logins)); } - private Collection<Component> findComponents(Set<Integer> componentIds) { + private Collection<Component> findComponents(Set<Long> componentIds) { return resourceDao.findByIds(componentIds); } - private Collection<Component> findProjects(Set<Integer> projectIds) { + private Collection<Component> findProjects(Set<Long> projectIds) { return resourceDao.findByIds(projectIds); } diff --git a/sonar-server/src/main/java/org/sonar/server/issue/InternalRubyIssueService.java b/sonar-server/src/main/java/org/sonar/server/issue/InternalRubyIssueService.java index 8a7e3231c8c..24e5f67f0f3 100644 --- a/sonar-server/src/main/java/org/sonar/server/issue/InternalRubyIssueService.java +++ b/sonar-server/src/main/java/org/sonar/server/issue/InternalRubyIssueService.java @@ -201,32 +201,28 @@ public class InternalRubyIssueService implements ServerComponent { return result; } - public Collection<ActionPlan> findOpenActionPlansForComponent(String componentKey) { - return actionPlanService.findOpenByComponentKey(componentKey); + public Collection<ActionPlan> findOpenActionPlans(String projectKey) { + return actionPlanService.findOpenByProjectKey(projectKey, UserSession.get()); } public ActionPlan findActionPlan(String actionPlanKey) { - return actionPlanService.findByKey(actionPlanKey); + return actionPlanService.findByKey(actionPlanKey, UserSession.get()); } public List<ActionPlanStats> findActionPlanStats(String projectKey) { - return actionPlanService.findActionPlanStats(projectKey); + return actionPlanService.findActionPlanStats(projectKey, UserSession.get()); } public Result<ActionPlan> createActionPlan(Map<String, String> parameters) { - // TODO verify authorization - Result<ActionPlan> result = createActionPlanResult(parameters); if (result.ok()) { - result.set(actionPlanService.create(result.get())); + result.set(actionPlanService.create(result.get(), UserSession.get())); } return result; } public Result<ActionPlan> updateActionPlan(String key, Map<String, String> parameters) { - // TODO verify authorization - - DefaultActionPlan existingActionPlan = (DefaultActionPlan) actionPlanService.findByKey(key); + DefaultActionPlan existingActionPlan = (DefaultActionPlan) actionPlanService.findByKey(key, UserSession.get()); if (existingActionPlan == null) { Result<ActionPlan> result = Result.of(); result.addError(Result.Message.ofL10n("action_plans.errors.action_plan_does_not_exist", key)); @@ -237,35 +233,32 @@ public class InternalRubyIssueService implements ServerComponent { DefaultActionPlan actionPlan = (DefaultActionPlan) result.get(); actionPlan.setKey(existingActionPlan.key()); actionPlan.setUserLogin(existingActionPlan.userLogin()); - result.set(actionPlanService.update(actionPlan)); + result.set(actionPlanService.update(actionPlan, UserSession.get())); } return result; } } public Result<ActionPlan> closeActionPlan(String actionPlanKey) { - // TODO verify authorization Result<ActionPlan> result = createResultForExistingActionPlan(actionPlanKey); if (result.ok()) { - result.set(actionPlanService.setStatus(actionPlanKey, ActionPlan.STATUS_CLOSED)); + result.set(actionPlanService.setStatus(actionPlanKey, ActionPlan.STATUS_CLOSED, UserSession.get())); } return result; } public Result<ActionPlan> openActionPlan(String actionPlanKey) { - // TODO verify authorization Result<ActionPlan> result = createResultForExistingActionPlan(actionPlanKey); if (result.ok()) { - result.set(actionPlanService.setStatus(actionPlanKey, ActionPlan.STATUS_OPEN)); + result.set(actionPlanService.setStatus(actionPlanKey, ActionPlan.STATUS_OPEN, UserSession.get())); } return result; } public Result<ActionPlan> deleteActionPlan(String actionPlanKey) { - // TODO verify authorization Result<ActionPlan> result = createResultForExistingActionPlan(actionPlanKey); if (result.ok()) { - actionPlanService.delete(actionPlanKey); + actionPlanService.delete(actionPlanKey, UserSession.get()); } return result; } diff --git a/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java b/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java index ee8e177b9f1..5a146420b9a 100644 --- a/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java +++ b/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java @@ -120,7 +120,7 @@ public class IssueService implements ServerComponent { } public Issue plan(String issueKey, @Nullable String actionPlanKey, UserSession userSession) { - if (!Strings.isNullOrEmpty(actionPlanKey) && actionPlanService.findByKey(actionPlanKey) == null) { + if (!Strings.isNullOrEmpty(actionPlanKey) && actionPlanService.findByKey(actionPlanKey, userSession) == null) { throw new IllegalStateException("Unknown action plan: " + actionPlanKey); } diff --git a/sonar-server/src/main/java/org/sonar/server/issue/ServerIssueStorage.java b/sonar-server/src/main/java/org/sonar/server/issue/ServerIssueStorage.java index 447a62a9d19..ad1fce39df3 100644 --- a/sonar-server/src/main/java/org/sonar/server/issue/ServerIssueStorage.java +++ b/sonar-server/src/main/java/org/sonar/server/issue/ServerIssueStorage.java @@ -38,20 +38,20 @@ public class ServerIssueStorage extends IssueStorage implements ServerComponent } @Override - protected int componentId(DefaultIssue issue) { + protected long componentId(DefaultIssue issue) { ResourceDto resourceDto = resourceDao.getResource(ResourceQuery.create().setKey(issue.componentKey())); if (resourceDto == null) { throw new IllegalStateException("Unknown component: " + issue.componentKey()); } - return resourceDto.getId().intValue(); + return resourceDto.getId(); } @Override - protected int projectId(DefaultIssue issue) { + protected long projectId(DefaultIssue issue) { ResourceDto resourceDto = resourceDao.getRootProjectByComponentKey(issue.componentKey()); if (resourceDto == null) { throw new IllegalStateException("Unknown component: " + issue.componentKey()); } - return resourceDto.getId().intValue(); + return resourceDto.getId(); } } diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/issue/_plan_form.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/issue/_plan_form.html.erb index 9bb65fc8048..894eb63edd6 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/issue/_plan_form.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/issue/_plan_form.html.erb @@ -1,13 +1,13 @@ <% plans_select_box_id = "plans-#{params[:issue]}" - plans = Internal.issues.findOpenActionPlansForComponent(@issue.componentKey()) + plans = Internal.issues.findOpenActionPlans(@issue.componentKey()) if plans.empty? %> <% if is_admin? %> <span class="error"><%= message('issue.plan.error.plan_must_be_created_first_for_admin', - :params => ApplicationController.root_context + '/action_plans/index/' + @issue.projectKey()) -%></span> + :params => ApplicationController.root_context + '/action_plans/index/' + @issue_result.project(@issue).key()) -%></span> <% else %> <span class="error"><%= message('issue.plan.error.plan_must_be_created_first_for_other') -%></span> <% end %> diff --git a/sonar-server/src/test/java/org/sonar/server/issue/ActionPlanServiceTest.java b/sonar-server/src/test/java/org/sonar/server/issue/ActionPlanServiceTest.java index f44aa68d721..67f5bf86917 100644 --- a/sonar-server/src/test/java/org/sonar/server/issue/ActionPlanServiceTest.java +++ b/sonar-server/src/test/java/org/sonar/server/issue/ActionPlanServiceTest.java @@ -23,6 +23,7 @@ package org.sonar.server.issue; import org.junit.Before; import org.junit.Test; import org.sonar.api.issue.ActionPlan; +import org.sonar.api.web.UserRole; import org.sonar.core.issue.ActionPlanStats; import org.sonar.core.issue.DefaultActionPlan; import org.sonar.core.issue.db.ActionPlanDao; @@ -32,6 +33,8 @@ import org.sonar.core.issue.db.ActionPlanStatsDto; import org.sonar.core.resource.ResourceDao; import org.sonar.core.resource.ResourceDto; import org.sonar.core.resource.ResourceQuery; +import org.sonar.core.user.AuthorizationDao; +import org.sonar.server.user.UserSession; import java.util.Collection; @@ -45,11 +48,18 @@ public class ActionPlanServiceTest { private ActionPlanDao actionPlanDao = mock(ActionPlanDao.class); private ActionPlanStatsDao actionPlanStatsDao = mock(ActionPlanStatsDao.class); private ResourceDao resourceDao = mock(ResourceDao.class); + private AuthorizationDao authorizationDao = mock(AuthorizationDao.class); + private UserSession userSession = mock(UserSession.class); + private ActionPlanService actionPlanService; @Before public void before() { - actionPlanService = new ActionPlanService(actionPlanDao, actionPlanStatsDao, resourceDao); + when(userSession.isLoggedIn()).thenReturn(true); + when(userSession.userId()).thenReturn(10); + when(authorizationDao.isAuthorizedComponentId(anyLong(), eq(10), anyString())).thenReturn(true); + + actionPlanService = new ActionPlanService(actionPlanDao, actionPlanStatsDao, resourceDao, authorizationDao); } @Test @@ -57,15 +67,45 @@ public class ActionPlanServiceTest { when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey("org.sonar.Sample").setId(1l)); ActionPlan actionPlan = DefaultActionPlan.create("Long term"); - actionPlanService.create(actionPlan); + actionPlanService.create(actionPlan, userSession); verify(actionPlanDao).save(any(ActionPlanDto.class)); } @Test + public void should_create_required_logged_user() { + when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey("org.sonar.Sample").setId(1l)); + ActionPlan actionPlan = DefaultActionPlan.create("Long term"); + when(userSession.isLoggedIn()).thenReturn(false); + + try { + actionPlanService.create(actionPlan, userSession); + } catch (Exception e){ + assertThat(e).isInstanceOf(IllegalStateException.class).hasMessage("User is not logged in"); + } + verifyZeroInteractions(actionPlanDao); + } + + @Test + public void should_create_required_admin_role() { + when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey("org.sonar.Sample").setId(1l)); + ActionPlan actionPlan = DefaultActionPlan.create("Long term"); + when(authorizationDao.isAuthorizedComponentId(anyLong(), eq(10), anyString())).thenReturn(false); + + try { + actionPlanService.create(actionPlan, userSession); + } catch (Exception e){ + assertThat(e).isInstanceOf(IllegalStateException.class).hasMessage("User does not have the required role to access the project: org.sonar.Sample"); + } + verify(authorizationDao).isAuthorizedComponentId(eq(1l), eq(10), eq(UserRole.ADMIN)); + verifyZeroInteractions(actionPlanDao); + } + + @Test public void should_set_status() { when(actionPlanDao.findByKey("ABCD")).thenReturn(new ActionPlanDto().setKey("ABCD")); + when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey("org.sonar.Sample").setId(1l)); - ActionPlan result = actionPlanService.setStatus("ABCD", "CLOSED"); + ActionPlan result = actionPlanService.setStatus("ABCD", "CLOSED", userSession); verify(actionPlanDao).update(any(ActionPlanDto.class)); assertThat(result).isNotNull(); @@ -73,15 +113,28 @@ public class ActionPlanServiceTest { } @Test + public void should_update() { + when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey("org.sonar.Sample").setId(1l)); + ActionPlan actionPlan = DefaultActionPlan.create("Long term"); + + actionPlanService.update(actionPlan, userSession); + verify(actionPlanDao).update(any(ActionPlanDto.class)); + } + + @Test public void should_delete() { - actionPlanService.delete("ABCD"); + when(actionPlanDao.findByKey("ABCD")).thenReturn(new ActionPlanDto().setKey("ABCD")); + when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey("org.sonar.Sample").setId(1l)); + actionPlanService.delete("ABCD", userSession); verify(actionPlanDao).delete("ABCD"); } @Test public void should_find_by_key() { when(actionPlanDao.findByKey("ABCD")).thenReturn(new ActionPlanDto().setKey("ABCD")); - ActionPlan result = actionPlanService.findByKey("ABCD"); + when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey("org.sonar.Sample").setId(1l)); + + ActionPlan result = actionPlanService.findByKey("ABCD", userSession); assertThat(result).isNotNull(); assertThat(result.key()).isEqualTo("ABCD"); } @@ -89,7 +142,7 @@ public class ActionPlanServiceTest { @Test public void should_return_null_if_no_action_plan_when_find_by_key() { when(actionPlanDao.findByKey("ABCD")).thenReturn(null); - assertThat(actionPlanService.findByKey("ABCD")).isNull(); + assertThat(actionPlanService.findByKey("ABCD", userSession)).isNull(); } @Test @@ -102,17 +155,32 @@ public class ActionPlanServiceTest { @Test public void should_find_open_by_project_key() { - when(resourceDao.getRootProjectByComponentKey("org.sonar.Sample")).thenReturn(new ResourceDto().setKey("org.sonar.Sample").setId(1l)); + when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey("org.sonar.Sample").setId(1l)); when(actionPlanDao.findOpenByProjectId(1l)).thenReturn(newArrayList(new ActionPlanDto().setKey("ABCD"))); - Collection<ActionPlan> results = actionPlanService.findOpenByComponentKey("org.sonar.Sample"); + Collection<ActionPlan> results = actionPlanService.findOpenByProjectKey("org.sonar.Sample", userSession); assertThat(results).hasSize(1); assertThat(results.iterator().next().key()).isEqualTo("ABCD"); } + @Test + public void should_find_open_by_project_key_required_user_role() { + when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey("org.sonar.Sample").setId(1l)); + when(actionPlanDao.findOpenByProjectId(1l)).thenReturn(newArrayList(new ActionPlanDto().setKey("ABCD"))); + when(authorizationDao.isAuthorizedComponentId(anyLong(), eq(10), anyString())).thenReturn(false); + + try { + actionPlanService.findOpenByProjectKey("org.sonar.Sample", userSession); + } catch (Exception e){ + assertThat(e).isInstanceOf(IllegalStateException.class).hasMessage("User does not have the required role to access the project: org.sonar.Sample"); + } + verify(authorizationDao).isAuthorizedComponentId(eq(1l), eq(10), eq(UserRole.USER)); + verifyZeroInteractions(actionPlanDao); + } + @Test(expected = IllegalArgumentException.class) public void should_throw_exception_if_project_not_found_when_find_open_by_project_key() { - when(resourceDao.getRootProjectByComponentKey(anyString())).thenReturn(null); - actionPlanService.findOpenByComponentKey("<Unkown>"); + when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(null); + actionPlanService.findOpenByProjectKey("<Unkown>", userSession); } @Test @@ -120,7 +188,7 @@ public class ActionPlanServiceTest { when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setId(1L).setKey("org.sonar.Sample")); when(actionPlanStatsDao.findByProjectId(1L)).thenReturn(newArrayList(new ActionPlanStatsDto())); - Collection<ActionPlanStats> results = actionPlanService.findActionPlanStats("org.sonar.Sample"); + Collection<ActionPlanStats> results = actionPlanService.findActionPlanStats("org.sonar.Sample", userSession); assertThat(results).hasSize(1); } @@ -128,7 +196,7 @@ public class ActionPlanServiceTest { public void should_throw_exception_if_project_not_found_when_find_open_action_plan_stats(){ when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(null); - actionPlanService.findActionPlanStats("org.sonar.Sample"); + actionPlanService.findActionPlanStats("org.sonar.Sample", userSession); } } diff --git a/sonar-server/src/test/java/org/sonar/server/issue/DefaultIssueFinderTest.java b/sonar-server/src/test/java/org/sonar/server/issue/DefaultIssueFinderTest.java index cd6ad711e0a..af2689bc7ce 100644 --- a/sonar-server/src/test/java/org/sonar/server/issue/DefaultIssueFinderTest.java +++ b/sonar-server/src/test/java/org/sonar/server/issue/DefaultIssueFinderTest.java @@ -71,12 +71,12 @@ public class DefaultIssueFinderTest { public void should_find_issues() { IssueQuery query = IssueQuery.builder().build(); - IssueDto issue1 = new IssueDto().setId(1L).setRuleId(50).setComponentId(123).setRootComponentId(100) + IssueDto issue1 = new IssueDto().setId(1L).setRuleId(50).setComponentId(123l).setRootComponentId(100l) .setComponentKey_unit_test_only("Action.java") .setRootComponentKey_unit_test_only("struts") .setRuleKey_unit_test_only("squid", "AvoidCycle") .setStatus("OPEN").setResolution("OPEN"); - IssueDto issue2 = new IssueDto().setId(2L).setRuleId(50).setComponentId(123).setRootComponentId(100) + IssueDto issue2 = new IssueDto().setId(2L).setRuleId(50).setComponentId(123l).setRootComponentId(100l) .setComponentKey_unit_test_only("Action.java") .setRootComponentKey_unit_test_only("struts") .setRuleKey_unit_test_only("squid", "AvoidCycle") @@ -98,12 +98,12 @@ public class DefaultIssueFinderTest { public void should_find_paginate_result() { IssueQuery query = IssueQuery.builder().pageSize(1).pageIndex(1).build(); - IssueDto issue1 = new IssueDto().setId(1L).setRuleId(50).setComponentId(123).setRootComponentId(100) + IssueDto issue1 = new IssueDto().setId(1L).setRuleId(50).setComponentId(123l).setRootComponentId(100l) .setComponentKey_unit_test_only("Action.java") .setRootComponentKey_unit_test_only("struts") .setRuleKey_unit_test_only("squid", "AvoidCycle") .setStatus("OPEN").setResolution("OPEN"); - IssueDto issue2 = new IssueDto().setId(2L).setRuleId(50).setComponentId(135).setRootComponentId(100) + IssueDto issue2 = new IssueDto().setId(2L).setRuleId(50).setComponentId(135l).setRootComponentId(100l) .setComponentKey_unit_test_only("Phases.java") .setRootComponentKey_unit_test_only("struts") .setRuleKey_unit_test_only("squid", "AvoidCycle") @@ -123,7 +123,7 @@ public class DefaultIssueFinderTest { @Test public void should_find_by_key() { - IssueDto issueDto = new IssueDto().setId(1L).setRuleId(1).setComponentId(1).setRootComponentId(100) + IssueDto issueDto = new IssueDto().setId(1L).setRuleId(1).setComponentId(1l).setRootComponentId(100l) .setComponentKey_unit_test_only("Action.java") .setRootComponentKey_unit_test_only("struts") .setRuleKey_unit_test_only("squid", "AvoidCycle") @@ -143,12 +143,12 @@ public class DefaultIssueFinderTest { IssueQuery query = IssueQuery.builder().build(); - IssueDto issue1 = new IssueDto().setId(1L).setRuleId(50).setComponentId(123).setRootComponentId(100) + IssueDto issue1 = new IssueDto().setId(1L).setRuleId(50).setComponentId(123l).setRootComponentId(100l) .setComponentKey_unit_test_only("Action.java") .setRootComponentKey_unit_test_only("struts") .setRuleKey_unit_test_only("squid", "AvoidCycle") .setStatus("OPEN").setResolution("OPEN"); - IssueDto issue2 = new IssueDto().setId(2L).setRuleId(50).setComponentId(123).setRootComponentId(100) + IssueDto issue2 = new IssueDto().setId(2L).setRuleId(50).setComponentId(123l).setRootComponentId(100l) .setComponentKey_unit_test_only("Action.java") .setRootComponentKey_unit_test_only("struts") .setRuleKey_unit_test_only("squid", "AvoidCycle") @@ -171,12 +171,12 @@ public class DefaultIssueFinderTest { IssueQuery query = IssueQuery.builder().build(); - IssueDto issue1 = new IssueDto().setId(1L).setRuleId(50).setComponentId(123).setRootComponentId(100) + IssueDto issue1 = new IssueDto().setId(1L).setRuleId(50).setComponentId(123l).setRootComponentId(100l) .setComponentKey_unit_test_only("Action.java") .setRootComponentKey_unit_test_only("struts") .setRuleKey_unit_test_only("squid", "AvoidCycle") .setStatus("OPEN").setResolution("OPEN"); - IssueDto issue2 = new IssueDto().setId(2L).setRuleId(50).setComponentId(123).setRootComponentId(100) + IssueDto issue2 = new IssueDto().setId(2L).setRuleId(50).setComponentId(123l).setRootComponentId(100l) .setComponentKey_unit_test_only("Action.java") .setRootComponentKey_unit_test_only("struts") .setRuleKey_unit_test_only("squid", "AvoidCycle") @@ -198,12 +198,12 @@ public class DefaultIssueFinderTest { IssueQuery query = IssueQuery.builder().build(); - IssueDto issue1 = new IssueDto().setId(1L).setRuleId(50).setComponentId(123).setRootComponentId(100) + IssueDto issue1 = new IssueDto().setId(1L).setRuleId(50).setComponentId(123l).setRootComponentId(100l) .setComponentKey_unit_test_only("Action.java") .setRootComponentKey_unit_test_only("struts") .setRuleKey_unit_test_only("squid", "AvoidCycle") .setStatus("OPEN").setResolution("OPEN"); - IssueDto issue2 = new IssueDto().setId(2L).setRuleId(50).setComponentId(123).setRootComponentId(100) + IssueDto issue2 = new IssueDto().setId(2L).setRuleId(50).setComponentId(123l).setRootComponentId(100l) .setComponentKey_unit_test_only("Action.java") .setRootComponentKey_unit_test_only("struts") .setRuleKey_unit_test_only("squid", "AvoidCycle") @@ -225,12 +225,12 @@ public class DefaultIssueFinderTest { IssueQuery query = IssueQuery.builder().build(); - IssueDto issue1 = new IssueDto().setId(1L).setRuleId(50).setComponentId(123).setRootComponentId(100).setKee("ABC").setActionPlanKey("A") + IssueDto issue1 = new IssueDto().setId(1L).setRuleId(50).setComponentId(123l).setRootComponentId(100l).setKee("ABC").setActionPlanKey("A") .setComponentKey_unit_test_only("Action.java") .setRootComponentKey_unit_test_only("struts") .setRuleKey_unit_test_only("squid", "AvoidCycle") .setStatus("OPEN").setResolution("OPEN"); - IssueDto issue2 = new IssueDto().setId(2L).setRuleId(50).setComponentId(123).setRootComponentId(100).setKee("DEF").setActionPlanKey("B") + IssueDto issue2 = new IssueDto().setId(2L).setRuleId(50).setComponentId(123l).setRootComponentId(100l).setKee("DEF").setActionPlanKey("B") .setComponentKey_unit_test_only("Action.java") .setRootComponentKey_unit_test_only("struts") .setRuleKey_unit_test_only("squid", "AvoidCycle") @@ -255,10 +255,10 @@ public class DefaultIssueFinderTest { IssueQuery query = IssueQuery.builder().build(); - IssueDto issue1 = new IssueDto().setId(1L).setRuleId(50).setComponentId(123).setRootComponentId(100).setKee("ABC").setAssignee("perceval") + IssueDto issue1 = new IssueDto().setId(1L).setRuleId(50).setComponentId(123l).setRootComponentId(100l).setKee("ABC").setAssignee("perceval") .setRuleKey_unit_test_only("squid", "AvoidCycle") .setStatus("OPEN").setResolution("OPEN"); - IssueDto issue2 = new IssueDto().setId(2L).setRuleId(50).setComponentId(123).setRootComponentId(100).setKee("DEF").setReporter("arthur") + IssueDto issue2 = new IssueDto().setId(2L).setRuleId(50).setComponentId(123l).setRootComponentId(100l).setKee("DEF").setReporter("arthur") .setRuleKey_unit_test_only("squid", "AvoidCycle") .setStatus("OPEN").setResolution("OPEN"); List<IssueDto> dtoList = newArrayList(issue1, issue2); diff --git a/sonar-server/src/test/java/org/sonar/server/issue/InternalRubyIssueServiceTest.java b/sonar-server/src/test/java/org/sonar/server/issue/InternalRubyIssueServiceTest.java index 512cc97413e..0a82a2335cd 100644 --- a/sonar-server/src/test/java/org/sonar/server/issue/InternalRubyIssueServiceTest.java +++ b/sonar-server/src/test/java/org/sonar/server/issue/InternalRubyIssueServiceTest.java @@ -28,6 +28,7 @@ import org.sonar.core.issue.DefaultActionPlan; import org.sonar.core.resource.ResourceDao; import org.sonar.core.resource.ResourceDto; import org.sonar.core.resource.ResourceQuery; +import org.sonar.server.user.UserSession; import java.util.Map; @@ -65,7 +66,7 @@ public class InternalRubyIssueServiceTest { Result result = internalRubyIssueService.createActionPlan(parameters); assertThat(result.ok()).isTrue(); - verify(actionPlanService).create(actionPlanCaptor.capture()); + verify(actionPlanService).create(actionPlanCaptor.capture(), any(UserSession.class)); ActionPlan actionPlan = actionPlanCaptor.getValue(); assertThat(actionPlan).isNotNull(); @@ -77,7 +78,7 @@ public class InternalRubyIssueServiceTest { @Test public void should_update_action_plan() { - when(actionPlanService.findByKey("ABCD")).thenReturn(DefaultActionPlan.create("Long term")); + when(actionPlanService.findByKey(eq("ABCD"), any(UserSession.class))).thenReturn(DefaultActionPlan.create("Long term")); Map<String, String> parameters = newHashMap(); parameters.put("name", "New Long term"); @@ -88,7 +89,7 @@ public class InternalRubyIssueServiceTest { Result result = internalRubyIssueService.updateActionPlan("ABCD", parameters); assertThat(result.ok()).isTrue(); - verify(actionPlanService).update(actionPlanCaptor.capture()); + verify(actionPlanService).update(actionPlanCaptor.capture(), any(UserSession.class)); ActionPlan actionPlan = actionPlanCaptor.getValue(); assertThat(actionPlan).isNotNull(); @@ -100,7 +101,7 @@ public class InternalRubyIssueServiceTest { @Test public void should_update_action_plan_with_new_project() { - when(actionPlanService.findByKey("ABCD")).thenReturn(DefaultActionPlan.create("Long term")); + when(actionPlanService.findByKey(eq("ABCD"), any(UserSession.class))).thenReturn(DefaultActionPlan.create("Long term")); Map<String, String> parameters = newHashMap(); parameters.put("name", "New Long term"); @@ -112,7 +113,7 @@ public class InternalRubyIssueServiceTest { Result result = internalRubyIssueService.updateActionPlan("ABCD", parameters); assertThat(result.ok()).isTrue(); - verify(actionPlanService).update(actionPlanCaptor.capture()); + verify(actionPlanService).update(actionPlanCaptor.capture(), any(UserSession.class)); ActionPlan actionPlan = actionPlanCaptor.getValue(); assertThat(actionPlan).isNotNull(); @@ -125,7 +126,7 @@ public class InternalRubyIssueServiceTest { @Test public void should_not_update_action_plan_when_action_plan_is_not_found() { - when(actionPlanService.findByKey("ABCD")).thenReturn(null); + when(actionPlanService.findByKey(eq("ABCD"), any(UserSession.class))).thenReturn(null); Result result = internalRubyIssueService.updateActionPlan("ABCD", null); assertThat(result.ok()).isFalse(); @@ -134,38 +135,38 @@ public class InternalRubyIssueServiceTest { @Test public void should_delete_action_plan() { - when(actionPlanService.findByKey("ABCD")).thenReturn(DefaultActionPlan.create("Long term")); + when(actionPlanService.findByKey(eq("ABCD"), any(UserSession.class))).thenReturn(DefaultActionPlan.create("Long term")); Result result = internalRubyIssueService.deleteActionPlan("ABCD"); - verify(actionPlanService).delete("ABCD"); + verify(actionPlanService).delete(eq("ABCD"), any(UserSession.class)); assertThat(result.ok()).isTrue(); } @Test public void should_not_delete_action_plan_if_action_plan_not_found() { - when(actionPlanService.findByKey("ABCD")).thenReturn(null); + when(actionPlanService.findByKey(eq("ABCD"), any(UserSession.class))).thenReturn(null); Result result = internalRubyIssueService.deleteActionPlan("ABCD"); - verify(actionPlanService, never()).delete("ABCD"); + verify(actionPlanService, never()).delete(eq("ABCD"), any(UserSession.class)); assertThat(result.ok()).isFalse(); assertThat(result.errors()).contains(Result.Message.ofL10n("action_plans.errors.action_plan_does_not_exist", "ABCD")); } @Test public void should_close_action_plan() { - when(actionPlanService.findByKey("ABCD")).thenReturn(DefaultActionPlan.create("Long term")); + when(actionPlanService.findByKey(eq("ABCD"), any(UserSession.class))).thenReturn(DefaultActionPlan.create("Long term")); Result result = internalRubyIssueService.closeActionPlan("ABCD"); - verify(actionPlanService).setStatus(eq("ABCD"), eq("CLOSED")); + verify(actionPlanService).setStatus(eq("ABCD"), eq("CLOSED"), any(UserSession.class)); assertThat(result.ok()).isTrue(); } @Test public void should_open_action_plan() { - when(actionPlanService.findByKey("ABCD")).thenReturn(DefaultActionPlan.create("Long term")); + when(actionPlanService.findByKey(eq("ABCD"), any(UserSession.class))).thenReturn(DefaultActionPlan.create("Long term")); Result result = internalRubyIssueService.openActionPlan("ABCD"); - verify(actionPlanService).setStatus(eq("ABCD"), eq("OPEN")); + verify(actionPlanService).setStatus(eq("ABCD"), eq("OPEN"), any(UserSession.class)); assertThat(result.ok()).isTrue(); } diff --git a/sonar-server/src/test/java/org/sonar/server/issue/ServerIssueStorageTest.java b/sonar-server/src/test/java/org/sonar/server/issue/ServerIssueStorageTest.java index b0b910621ef..5192ae23e22 100644 --- a/sonar-server/src/test/java/org/sonar/server/issue/ServerIssueStorageTest.java +++ b/sonar-server/src/test/java/org/sonar/server/issue/ServerIssueStorageTest.java @@ -41,7 +41,7 @@ public class ServerIssueStorageTest extends AbstractDaoTestCase { setupData("should_load_component_id_from_db"); ServerIssueStorage storage = new ServerIssueStorage(getMyBatis(), new FakeRuleFinder(), new ResourceDao(getMyBatis())); - int componentId = storage.componentId(new DefaultIssue().setComponentKey("struts:Action.java")); + long componentId = storage.componentId(new DefaultIssue().setComponentKey("struts:Action.java")); assertThat(componentId).isEqualTo(123); } @@ -64,7 +64,7 @@ public class ServerIssueStorageTest extends AbstractDaoTestCase { setupData("should_load_project_id_from_db"); ServerIssueStorage storage = new ServerIssueStorage(getMyBatis(), new FakeRuleFinder(), new ResourceDao(getMyBatis())); - int projectId = storage.projectId(new DefaultIssue().setComponentKey("struts:Action.java")); + long projectId = storage.projectId(new DefaultIssue().setComponentKey("struts:Action.java")); assertThat(projectId).isEqualTo(1); } |