import org.sonar.api.ServerComponent;
import org.sonar.api.utils.System2;
+import org.sonar.core.component.AuthorizedComponentDto;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.component.db.ComponentMapper;
import org.sonar.core.persistence.DaoComponent;
}
public ComponentDto getById(Long id, DbSession session) {
+ ComponentDto componentDto = getNullableById(id, session);
+ if (componentDto == null) {
+ throw new NotFoundException(String.format("Project with id '%s' not found", id));
+ }
+ return componentDto;
+ }
+
+ @CheckForNull
+ public ComponentDto getNullableById(Long id, DbSession session) {
return mapper(session).selectById(id);
}
return mapper(session).findModulesByProject(projectKey);
}
+ @CheckForNull
+ public AuthorizedComponentDto getNullableAuthorizedComponentById(Long id, DbSession session) {
+ return mapper(session).selectAuthorizedComponentById(id);
+ }
+
+ public AuthorizedComponentDto getAuthorizedComponentById(Long id, DbSession session) {
+ AuthorizedComponentDto componentDto = getNullableAuthorizedComponentById(id, session);
+ if (componentDto == null) {
+ throw new NotFoundException(String.format("Project with id '%s' not found", id));
+ }
+ return componentDto;
+ }
+
@Override
+ @CheckForNull
protected ComponentDto doGetNullableByKey(DbSession session, String key) {
return mapper(session).selectByKey(key);
}
private ComponentDto getProject(@Nullable Long projectId, Map<Long, ComponentDto> projectsById, DbSession session) {
ComponentDto project = projectsById.get(projectId);
if (project == null && projectId != null) {
- project = componentDao.getById(projectId, session);
+ project = componentDao.getNullableById(projectId, session);
if (project != null) {
projectsById.put(project.getId(), project);
}
import org.sonar.api.measures.Metric;
import org.sonar.api.measures.Metric.ValueType;
import org.sonar.api.measures.MetricFinder;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.component.AuthorizedComponentDto;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
}
public void associateProject(Long qGateId, Long projectId) {
- checkPermission(UserSession.get());
-
DbSession session = myBatis.openSession(false);
try {
getNonNullQgate(qGateId);
- checkNonNullProject(projectId, session);
+ checkPermission(UserSession.get(), projectId, session);
propertiesDao.setProperty(new PropertyDto().setKey(SONAR_QUALITYGATE_PROPERTY).setResourceId(projectId).setValue(qGateId.toString()));
} finally {
MyBatis.closeQuietly(session);
}
public void dissociateProject(Long qGateId, Long projectId) {
- checkPermission(UserSession.get());
-
DbSession session = myBatis.openSession(false);
try {
getNonNullQgate(qGateId);
- checkNonNullProject(projectId, session);
+ checkPermission(UserSession.get(), projectId, session);
propertiesDao.deleteProjectProperty(SONAR_QUALITYGATE_PROPERTY, projectId);
} finally {
MyBatis.closeQuietly(session);
return condition;
}
- private void checkNonNullProject(long projectId, DbSession session) {
- if (!componentDao.existsById(projectId, session)) {
- throw new NotFoundException("There is no project with id=" + projectId);
- }
- }
-
private void validateQualityGate(@Nullable Long updatingQgateId, @Nullable String name) {
Errors errors = new Errors();
if (Strings.isNullOrEmpty(name)) {
private void checkPermission(UserSession userSession) {
userSession.checkGlobalPermission(GlobalPermissions.QUALITY_PROFILE_ADMIN);
}
+
+ private void checkPermission(UserSession userSession, Long projectId, DbSession session) {
+ AuthorizedComponentDto project = componentDao.getAuthorizedComponentById(projectId, session);
+ if (!userSession.hasGlobalPermission(GlobalPermissions.QUALITY_PROFILE_ADMIN) && !userSession.hasProjectPermission(UserRole.ADMIN, project.key())) {
+ throw new ForbiddenException("Insufficient privileges");
+ }
+ }
}
package org.sonar.server.qualityprofile;
import org.sonar.api.ServerComponent;
-import org.sonar.api.component.Component;
-import org.sonar.core.component.ComponentDto;
+import org.sonar.api.web.UserRole;
+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.core.properties.PropertyDto;
import org.sonar.core.qualityprofile.db.QualityProfileDto;
import org.sonar.server.db.DbClient;
-import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.user.UserSession;
+/**
+ * Should be refactored in order to use project key. Mabye should it be move to {@link QProfileFactory}
+ * Permission checks should also be done in the upper service.
+ */
public class QProfileProjectOperations implements ServerComponent {
private final DbClient db;
}
public void addProject(int profileId, long projectId, UserSession userSession) {
- checkPermission(userSession);
DbSession session = db.openSession(false);
try {
addProject(profileId, projectId, userSession, session);
}
void addProject(int profileId, long projectId, UserSession userSession, DbSession session) {
- checkPermission(userSession);
- ComponentDto project = (ComponentDto) findProjectNotNull(projectId, session);
+ AuthorizedComponentDto project = db.componentDao().getAuthorizedComponentById(projectId, session);
+ checkPermission(userSession, project.key());
QualityProfileDto qualityProfile = findNotNull(profileId, session);
db.propertiesDao().setProperty(new PropertyDto().setKey(
}
public void removeProject(int profileId, long projectId, UserSession userSession) {
- checkPermission(userSession);
DbSession session = db.openSession(false);
try {
- ComponentDto project = (ComponentDto) findProjectNotNull(projectId, session);
+ AuthorizedComponentDto project = db.componentDao().getAuthorizedComponentById(projectId, session);
+ checkPermission(userSession, project.key());
QualityProfileDto qualityProfile = findNotNull(profileId, session);
db.propertiesDao().deleteProjectProperty(QProfileProjectLookup.PROFILE_PROPERTY_PREFIX + qualityProfile.getLanguage(), project.getId(), session);
}
public void removeProject(String language, long projectId, UserSession userSession) {
- checkPermission(userSession);
DbSession session = db.openSession(false);
try {
- ComponentDto project = (ComponentDto) findProjectNotNull(projectId, session);
+ AuthorizedComponentDto project = db.componentDao().getAuthorizedComponentById(projectId, session);
+ checkPermission(userSession, project.key());
db.propertiesDao().deleteProjectProperty(QProfileProjectLookup.PROFILE_PROPERTY_PREFIX + language, project.getId(), session);
session.commit();
return qualityProfile;
}
- private Component findProjectNotNull(long projectId, DbSession session) {
- Component component = db.resourceDao().findById(projectId, session);
- if (component == null) {
- throw new NotFoundException("This project does not exist");
- }
- return component;
- }
-
private void checkPermission(UserSession userSession) {
userSession.checkGlobalPermission(GlobalPermissions.QUALITY_PROFILE_ADMIN);
}
+ private void checkPermission(UserSession userSession, String projectKey) {
+ if (!userSession.hasGlobalPermission(GlobalPermissions.QUALITY_PROFILE_ADMIN) && !userSession.hasProjectPermission(UserRole.ADMIN, projectKey)) {
+ throw new ForbiddenException("Insufficient privileges");
+ }
+ }
+
}
/**
* Used in /api/profiles and in /profiles/export
- * @param language
- * @return
*/
@CheckForNull
public QualityProfileDto getDefault(String language) {
import org.junit.Test;
import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.System2;
+import org.sonar.core.component.AuthorizedComponentDto;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.persistence.AbstractDaoTestCase;
import org.sonar.core.persistence.DbSession;
setupData("shared");
assertThat(dao.getById(4L, session)).isNotNull();
- assertThat(dao.getById(111L, session)).isNull();
+ }
+
+ @Test(expected = NotFoundException.class)
+ public void fail_to_get_by_id_when_project_not_found() {
+ setupData("shared");
+
+ dao.getById(111L, session);
+ }
+
+ @Test
+ public void get_nullable_by_id() {
+ setupData("shared");
+
+ assertThat(dao.getNullableById(4L, session)).isNotNull();
+ assertThat(dao.getNullableById(111L, session)).isNull();
}
@Test
assertThat(dao.getParentModuleByKey("unknown", session)).isNull();
}
+ @Test
+ public void get_nullable_authorized_component_by_id() {
+ setupData("shared");
+
+ AuthorizedComponentDto result = dao.getNullableAuthorizedComponentById(4L, session);
+ assertThat(result).isNotNull();
+ assertThat(result.key()).isEqualTo("org.struts:struts-core:src/org/struts/RequestContext.java");
+
+ assertThat(dao.getNullableAuthorizedComponentById(111L, session)).isNull();
+ }
+
+ @Test
+ public void get_authorized_component_by_id() {
+ setupData("shared");
+
+ assertThat(dao.getAuthorizedComponentById(4L, session)).isNotNull();
+ }
+
+ @Test(expected = NotFoundException.class)
+ public void fail_to_get_authorized_component_by_id_when_project_not_found() {
+ setupData("shared");
+
+ dao.getAuthorizedComponentById(111L, session);
+ }
+
@Test
public void insert() {
when(system2.now()).thenReturn(DateUtils.parseDate("2014-06-18").getTime());
when(componentDao.getNullableByKey(session, key1)).thenReturn(file1);
when(componentDao.getNullableByKey(session, key2)).thenReturn(file2);
- when(componentDao.getById(1L, session)).thenReturn(new ComponentDto().setId(1L).setKey("org.codehaus.sonar:sonar").setLongName("SonarQube"));
- when(componentDao.getById(5L, session)).thenReturn(new ComponentDto().setId(5L).setKey("org.codehaus.sonar:sonar-ws-client").setLongName("SonarQube :: Web Service Client"));
+ when(componentDao.getNullableById(1L, session)).thenReturn(new ComponentDto().setId(1L).setKey("org.codehaus.sonar:sonar").setLongName("SonarQube"));
+ when(componentDao.getNullableById(5L, session)).thenReturn(new ComponentDto().setId(5L).setKey("org.codehaus.sonar:sonar-ws-client").setLongName("SonarQube :: Web Service Client"));
List<DuplicationsParser.Block> blocks = newArrayList();
blocks.add(new DuplicationsParser.Block(newArrayList(
verify(componentDao, times(2)).getNullableByKey(eq(session), anyString());
// Verify call to dao is cached when searching for project / sub project
- verify(componentDao, times(1)).getById(eq(1L), eq(session));
- verify(componentDao, times(1)).getById(eq(5L), eq(session));
+ verify(componentDao, times(1)).getNullableById(eq(1L), eq(session));
+ verify(componentDao, times(1)).getNullableById(eq(5L), eq(session));
}
@Test
when(componentDao.getNullableByKey(session, key1)).thenReturn(file1);
when(componentDao.getNullableByKey(session, key2)).thenReturn(file2);
- when(componentDao.getById(1L, session)).thenReturn(new ComponentDto().setId(1L).setKey("org.codehaus.sonar:sonar").setLongName("SonarQube"));
+ when(componentDao.getNullableById(1L, session)).thenReturn(new ComponentDto().setId(1L).setKey("org.codehaus.sonar:sonar").setLongName("SonarQube"));
List<DuplicationsParser.Block> blocks = newArrayList();
blocks.add(new DuplicationsParser.Block(newArrayList(
ComponentDto file1 = new ComponentDto().setId(10L).setQualifier("FIL").setKey(key1).setLongName("PropertyDeleteQuery").setProjectId(1L);
when(componentDao.getNullableByKey(session, key1)).thenReturn(file1);
- when(componentDao.getById(1L, session)).thenReturn(new ComponentDto().setId(1L).setKey("org.codehaus.sonar:sonar").setLongName("SonarQube"));
+ when(componentDao.getNullableById(1L, session)).thenReturn(new ComponentDto().setId(1L).setKey("org.codehaus.sonar:sonar").setLongName("SonarQube"));
List<DuplicationsParser.Block> blocks = newArrayList();
import org.sonar.api.measures.Metric;
import org.sonar.api.measures.Metric.ValueType;
import org.sonar.api.measures.MetricFinder;
+import org.sonar.api.web.UserRole;
+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 static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class QualityGatesTest {
QualityGates qGates;
- UserSession authorizedUserSession = MockUserSession.create().setLogin("gaudol").setName("Olivier").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN);
- UserSession unauthenticatedUserSession = MockUserSession.create();
+ static final String PROJECT_KEY = "SonarQube";
+
+ UserSession authorizedProfileAdminUserSession = MockUserSession.create().setLogin("gaudol").setName("Olivier").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN);
+ UserSession authorizedProjectAdminUserSession = MockUserSession.create().setLogin("gaudol").setName("Olivier").addProjectPermissions(UserRole.ADMIN, PROJECT_KEY);
UserSession unauthorizedUserSession = MockUserSession.create().setLogin("polop").setName("Polop");
+ UserSession unauthenticatedUserSession = MockUserSession.create();
@Before
public void initialize() {
+ when(componentDao.getAuthorizedComponentById(anyLong(), eq(session))).thenReturn(new AuthorizedComponentDto().setId(1L).setKey(PROJECT_KEY));
+
when(myBatis.openSession(false)).thenReturn(session);
qGates = new QualityGates(dao, conditionDao, metricFinder, propertiesDao, componentDao, myBatis);
- UserSessionTestUtils.setUserSession(authorizedUserSession);
+ UserSessionTestUtils.setUserSession(authorizedProfileAdminUserSession);
}
@Test
public void should_select_default_qgate() throws Exception {
long defaultId = 42L;
String defaultName = "Default Name";
- when(dao.selectById(defaultId)).thenReturn(new QualityGateDto().setId(defaultId).setName(defaultName ));
+ when(dao.selectById(defaultId)).thenReturn(new QualityGateDto().setId(defaultId).setName(defaultName));
qGates.setDefault(defaultId);
verify(dao).selectById(defaultId);
ArgumentCaptor<PropertyDto> propertyCaptor = ArgumentCaptor.forClass(PropertyDto.class);
QualityGateConditionDto cond1 = new QualityGateConditionDto().setMetricId(metric1Id);
QualityGateConditionDto cond2 = new QualityGateConditionDto().setMetricId(metric2Id);
Collection<QualityGateConditionDto> conditions = ImmutableList.of(cond1, cond2);
- when(conditionDao.selectForQualityGate(qGateId)).thenReturn(conditions );
+ when(conditionDao.selectForQualityGate(qGateId)).thenReturn(conditions);
Metric metric1 = mock(Metric.class);
when(metric1.getKey()).thenReturn(metric1Key);
when(metricFinder.findById((int) metric1Id)).thenReturn(metric1);
QualityGateConditionDto cond1 = new QualityGateConditionDto().setMetricId(metric1Id);
QualityGateConditionDto cond2 = new QualityGateConditionDto().setMetricId(metric2Id);
Collection<QualityGateConditionDto> conditions = ImmutableList.of(cond1, cond2);
- when(conditionDao.selectForQualityGate(qGateId)).thenReturn(conditions );
+ when(conditionDao.selectForQualityGate(qGateId)).thenReturn(conditions);
Metric metric1 = mock(Metric.class);
when(metric1.getKey()).thenReturn(metric1Key);
when(metricFinder.findById((int) metric1Id)).thenReturn(metric1);
Long qGateId = 42L;
Long projectId = 24L;
when(dao.selectById(qGateId)).thenReturn(new QualityGateDto().setId(qGateId));
- when(componentDao.existsById(projectId, session)).thenReturn(true);
qGates.associateProject(qGateId, projectId);
verify(dao).selectById(qGateId);
ArgumentCaptor<PropertyDto> propertyCaptor = ArgumentCaptor.forClass(PropertyDto.class);
assertThat(property.getValue()).isEqualTo("42");
}
- @Test(expected = NotFoundException.class)
- public void should_fail_associate_project_on_not_existing_project() {
+ @Test
+ public void associate_project_with_project_admin_permission() {
+ UserSessionTestUtils.setUserSession(authorizedProjectAdminUserSession);
+
Long qGateId = 42L;
Long projectId = 24L;
when(dao.selectById(qGateId)).thenReturn(new QualityGateDto().setId(qGateId));
- qGates.associateProject(qGateId , projectId);
+ qGates.associateProject(qGateId, projectId);
+ verify(dao).selectById(qGateId);
+ ArgumentCaptor<PropertyDto> propertyCaptor = ArgumentCaptor.forClass(PropertyDto.class);
+ verify(propertiesDao).setProperty(propertyCaptor.capture());
+ PropertyDto property = propertyCaptor.getValue();
+ assertThat(property.getKey()).isEqualTo("sonar.qualitygate");
+ assertThat(property.getResourceId()).isEqualTo(projectId);
+ assertThat(property.getValue()).isEqualTo("42");
}
@Test
Long qGateId = 42L;
Long projectId = 24L;
when(dao.selectById(qGateId)).thenReturn(new QualityGateDto().setId(qGateId));
- when(componentDao.existsById(projectId, session)).thenReturn(true);
+ qGates.dissociateProject(qGateId, projectId);
+ verify(dao).selectById(qGateId);
+ verify(propertiesDao).deleteProjectProperty("sonar.qualitygate", projectId);
+ }
+
+ @Test
+ public void dissociate_project_with_project_admin_permission() {
+ UserSessionTestUtils.setUserSession(authorizedProjectAdminUserSession);
+
+ Long qGateId = 42L;
+ Long projectId = 24L;
+ when(dao.selectById(qGateId)).thenReturn(new QualityGateDto().setId(qGateId));
qGates.dissociateProject(qGateId, projectId);
verify(dao).selectById(qGateId);
verify(propertiesDao).deleteProjectProperty("sonar.qualitygate", projectId);
--- /dev/null
+/*
+ * 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.qualityprofile;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.component.ComponentDto;
+import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.core.permission.PermissionFacade;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.qualityprofile.db.QualityProfileDto;
+import org.sonar.core.user.UserDto;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.search.IndexClient;
+import org.sonar.server.tester.ServerTester;
+import org.sonar.server.user.MockUserSession;
+import org.sonar.server.user.UserSession;
+
+import java.util.Date;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class QProfileProjectOperationsMediumTest {
+
+ @ClassRule
+ public static ServerTester tester = new ServerTester();
+
+ DbClient db;
+ DbSession dbSession;
+ IndexClient index;
+ QProfileFactory factory;
+ QProfileProjectOperations projectOperations;
+
+ ComponentDto project;
+ QualityProfileDto profile;
+ static final String PROJECT_KEY = "SonarQube";
+
+ UserSession authorizedProfileAdminUserSession = MockUserSession.create().setLogin("john").setName("John").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN);
+ UserSession authorizedProjectAdminUserSession = MockUserSession.create().setLogin("john").setName("John").addProjectPermissions(UserRole.ADMIN, PROJECT_KEY);
+
+ @Before
+ public void before() {
+ tester.clearDbAndIndexes();
+ db = tester.get(DbClient.class);
+ dbSession = db.openSession(false);
+ index = tester.get(IndexClient.class);
+ factory = tester.get(QProfileFactory.class);
+ projectOperations = tester.get(QProfileProjectOperations.class);
+
+ project = new ComponentDto()
+ .setKey(PROJECT_KEY)
+ .setName("SonarQube")
+ .setLongName("SonarQube")
+ .setQualifier("TRK")
+ .setScope("PRJ")
+ .setEnabled(true);
+ db.componentDao().insert(dbSession, project);
+
+ profile = QProfileTesting.newXooP1();
+ db.qualityProfileDao().insert(dbSession, profile);
+
+ dbSession.commit();
+ }
+
+ @After
+ public void after() throws Exception {
+ dbSession.close();
+ }
+
+ @Test
+ public void add_project() throws Exception {
+ projectOperations.addProject(profile.getId(), project.getId(), authorizedProfileAdminUserSession);
+
+ assertThat(factory.getByProjectAndLanguage(PROJECT_KEY, profile.getLanguage())).isNotNull();
+ }
+
+ @Test
+ public void add_project_with_only_project_admin_permission() throws Exception {
+ projectOperations.addProject(profile.getId(), project.getId(), authorizedProjectAdminUserSession);
+
+ assertThat(factory.getByProjectAndLanguage(PROJECT_KEY, profile.getLanguage())).isNotNull();
+ }
+
+ @Test
+ public void remove_project_from_project_id() throws Exception {
+ projectOperations.addProject(profile.getId(), project.getId(), authorizedProfileAdminUserSession);
+ assertThat(factory.getByProjectAndLanguage(PROJECT_KEY, profile.getLanguage())).isNotNull();
+
+ projectOperations.removeProject(profile.getId(), project.getId(), authorizedProfileAdminUserSession);
+ assertThat(factory.getByProjectAndLanguage(PROJECT_KEY, profile.getLanguage())).isNull();
+ }
+
+ @Test
+ public void remove_project_from_language() throws Exception {
+ projectOperations.addProject(profile.getId(), project.getId(), authorizedProfileAdminUserSession);
+ assertThat(factory.getByProjectAndLanguage(PROJECT_KEY, profile.getLanguage())).isNotNull();
+
+ projectOperations.removeProject(profile.getLanguage(), project.getId(), authorizedProfileAdminUserSession);
+ assertThat(factory.getByProjectAndLanguage(PROJECT_KEY, profile.getLanguage())).isNull();
+ }
+
+ @Test
+ public void remove_all_projects() throws Exception {
+ ComponentDto project1 = new ComponentDto()
+ .setKey("project1")
+ .setName("project1")
+ .setLongName("project1")
+ .setQualifier("TRK")
+ .setScope("PRJ")
+ .setEnabled(true);
+ ComponentDto project2 = new ComponentDto()
+ .setKey("project2")
+ .setName("project2")
+ .setLongName("project2")
+ .setQualifier("TRK")
+ .setScope("PRJ")
+ .setEnabled(true);
+ db.componentDao().insert(dbSession, project1);
+ db.componentDao().insert(dbSession, project2);
+
+ // Create a user having user permission on the two projects and the global quality profile admin permission
+ UserDto user = new UserDto().setLogin("john").setName("John").setEmail("jo@hn.com").setCreatedAt(new Date()).setUpdatedAt(new Date());
+ db.userDao().insert(dbSession, user);
+ tester.get(PermissionFacade.class).insertUserPermission(project1.getId(), user.getId(), UserRole.USER, dbSession);
+ tester.get(PermissionFacade.class).insertUserPermission(project2.getId(), user.getId(), UserRole.USER, dbSession);
+ UserSession userSession = MockUserSession.set().setUserId(user.getId().intValue()).setLogin("john").setName("John")
+ .setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN);
+
+ dbSession.commit();
+
+ projectOperations.addProject(profile.getId(), project1.getId(), userSession);
+ projectOperations.addProject(profile.getId(), project2.getId(), userSession);
+ assertThat(tester.get(QProfileProjectLookup.class).projects(profile.getId())).hasSize(2);
+
+ projectOperations.removeAllProjects(profile.getId(), userSession);
+ assertThat(tester.get(QProfileProjectLookup.class).projects(profile.getId())).isEmpty();
+ }
+}
--- /dev/null
+/*
+ * 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.core.component;
+
+import org.sonar.core.persistence.Dto;
+
+/**
+ * Used to check that a project exists. Can return provisionned projects and projects from analysis.
+ * Warning, this component should not be retrieve from db using a join on snapshots, otherwise provisionned projects will not be returned anymore.
+ */
+public class AuthorizedComponentDto extends Dto<String> {
+
+ private Long id;
+ private String kee;
+
+ public Long getId() {
+ return id;
+ }
+
+ public AuthorizedComponentDto setId(Long id) {
+ this.id = id;
+ return this;
+ }
+
+ public String key() {
+ return kee;
+ }
+
+ public AuthorizedComponentDto setKey(String key) {
+ this.kee = key;
+ return this;
+ }
+
+ @Override
+ public String getKey() {
+ return kee;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ AuthorizedComponentDto that = (AuthorizedComponentDto) o;
+
+ if (!id.equals(that.id)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return id.hashCode();
+ }
+
+}
package org.sonar.core.component;
import org.sonar.api.component.Component;
-import org.sonar.core.persistence.Dto;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
-public class ComponentDto extends Dto<String> implements Component {
+public class ComponentDto extends AuthorizedComponentDto implements Component {
- private Long id;
- private String kee;
private String path;
private String name;
private String longName;
private Long subProjectId;
private boolean enabled = true;
- public Long getId() {
- return id;
- }
-
public ComponentDto setId(Long id) {
- this.id = id;
+ super.setId(id);
return this;
}
- @Override
- public String key() {
- return kee;
- }
-
public ComponentDto setKey(String key) {
- this.kee = key;
+ super.setKey(key);
return this;
}
return this;
}
- @Override
- public String getKey() {
- return kee;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- ComponentDto that = (ComponentDto) o;
-
- if (!id.equals(that.id)) {
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return id.hashCode();
- }
-
}
package org.sonar.core.component.db;
import org.apache.ibatis.annotations.Param;
+import org.sonar.core.component.AuthorizedComponentDto;
import org.sonar.core.component.ComponentDto;
+import javax.annotation.CheckForNull;
+
import java.util.List;
/**
*/
public interface ComponentMapper {
+ @CheckForNull
ComponentDto selectByKey(String key);
+ @CheckForNull
ComponentDto selectById(long id);
+ @CheckForNull
ComponentDto selectRootProjectByKey(String key);
+ @CheckForNull
ComponentDto selectParentModuleByKey(String key);
/**
long countById(long id);
+ @CheckForNull
+ AuthorizedComponentDto selectAuthorizedComponentById(long id);
+
void insert(ComponentDto rule);
}
import org.sonar.core.activity.db.ActivityDto;
import org.sonar.core.activity.db.ActivityMapper;
import org.sonar.core.cluster.WorkQueue;
+import org.sonar.core.component.AuthorizedComponentDto;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.component.db.ComponentMapper;
import org.sonar.core.config.Logback;
loadAlias(conf, "ActiveDashboard", ActiveDashboardDto.class);
loadAlias(conf, "Author", AuthorDto.class);
loadAlias(conf, "Component", ComponentDto.class);
+ loadAlias(conf, "AuthorizedComponent", AuthorizedComponentDto.class);
loadAlias(conf, "Dashboard", DashboardDto.class);
loadAlias(conf, "Dependency", DependencyDto.class);
loadAlias(conf, "DuplicationUnit", DuplicationUnitDto.class);
}
}
- @CheckForNull
public UserDto insert(SqlSession session, UserDto dto) {
session.getMapper(UserMapper.class).insert(dto);
return dto;
p.path as path
</sql>
+ <sql id="authorizedComponentColumns">
+ p.id,
+ p.kee as kee
+ </sql>
+
<select id="selectByKey" parameterType="String" resultType="Component">
SELECT <include refid="componentColumns"/>
FROM projects p
</where>
</select>
+ <select id="selectAuthorizedComponentById" parameterType="long" resultType="AuthorizedComponent">
+ SELECT <include refid="authorizedComponentColumns"/>
+ FROM projects p
+ <where>
+ AND p.enabled=${_true}
+ AND p.id=#{id}
+ </where>
+ </select>
+
<sql id="insertColumns">
(kee, name, long_name, qualifier, scope, language, root_id, path, created_at)
</sql>