import org.sonar.plugins.core.filters.ProjectFilter;
import org.sonar.plugins.core.filters.TreeMapFilter;
import org.sonar.plugins.core.security.ApplyProjectRolesDecorator;
-import org.sonar.plugins.core.security.DefaultResourcePermissions;
import org.sonar.plugins.core.sensors.BranchCoverageDecorator;
import org.sonar.plugins.core.sensors.CheckAlertThresholds;
import org.sonar.plugins.core.sensors.CommentDensityDecorator;
OverallLineCoverageDecorator.class,
OverallCoverageDecorator.class,
OverallBranchCoverageDecorator.class,
- DefaultResourcePermissions.class,
ApplyProjectRolesDecorator.class,
ExcludedResourceFilter.class,
CommentDensityDecorator.class,
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar 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.
- *
- * Sonar 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 Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-package org.sonar.plugins.core.security;
-
-import org.apache.ibatis.session.SqlSession;
-import org.sonar.api.BatchExtension;
-import org.sonar.api.ServerExtension;
-import org.sonar.api.config.Settings;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.security.DefaultGroups;
-import org.sonar.api.security.ResourcePermissions;
-import org.sonar.api.web.UserRole;
-import org.sonar.core.persistence.MyBatis;
-import org.sonar.core.user.*;
-
-/**
- * @since 3.2
- */
-public class DefaultResourcePermissions implements ResourcePermissions, BatchExtension, ServerExtension {
-
- private final Settings settings;
- private final MyBatis myBatis;
-
- public DefaultResourcePermissions(Settings settings, MyBatis myBatis) {
- this.settings = settings;
- this.myBatis = myBatis;
- }
-
- public boolean hasRoles(Resource resource) {
- if (resource.getId() != null) {
- SqlSession session = myBatis.openSession();
- try {
- RoleMapper roleMapper = session.getMapper(RoleMapper.class);
- Long resourceId = Long.valueOf(resource.getId());
- return roleMapper.countGroupRoles(resourceId) + roleMapper.countUserRoles(resourceId) > 0;
-
- } finally {
- MyBatis.closeQuietly(session);
- }
- }
- return false;
- }
-
- public void grantUserRole(Resource resource, String login, String role) {
- if (resource.getId() != null) {
- SqlSession session = myBatis.openSession();
- try {
- UserDto user = session.getMapper(UserMapper.class).selectUserByLogin(login);
- if (user != null) {
- UserRoleDto userRole = new UserRoleDto()
- .setRole(role)
- .setUserId(user.getId())
- .setResourceId(Long.valueOf(resource.getId()));
- RoleMapper roleMapper = session.getMapper(RoleMapper.class);
- roleMapper.deleteUserRole(userRole);
- roleMapper.insertUserRole(userRole);
- session.commit();
- }
- } finally {
- MyBatis.closeQuietly(session);
- }
- }
- }
-
- public void grantGroupRole(Resource resource, String groupName, String role) {
- if (resource.getId() != null) {
- SqlSession session = myBatis.openSession();
- try {
- GroupRoleDto groupRole = new GroupRoleDto()
- .setRole(role)
- .setResourceId(Long.valueOf(resource.getId()));
- RoleMapper roleMapper = session.getMapper(RoleMapper.class);
- if (DefaultGroups.isAnyone(groupName)) {
- roleMapper.deleteGroupRole(groupRole);
- roleMapper.insertGroupRole(groupRole);
- session.commit();
- } else {
- GroupDto group = session.getMapper(UserMapper.class).selectGroupByName(groupName);
- if (group != null) {
- groupRole.setGroupId(group.getId());
- roleMapper.deleteGroupRole(groupRole);
- roleMapper.insertGroupRole(groupRole);
- session.commit();
- }
- }
- } finally {
- MyBatis.closeQuietly(session);
- }
- }
- }
-
- public void grantDefaultRoles(Resource resource) {
- if (resource.getId() != null) {
- SqlSession session = myBatis.openSession();
- try {
- removeRoles(resource, session);
- grantDefaultRoles(resource, UserRole.ADMIN, session);
- grantDefaultRoles(resource, UserRole.USER, session);
- grantDefaultRoles(resource, UserRole.CODEVIEWER, session);
- session.commit();
- } finally {
- MyBatis.closeQuietly(session);
- }
- }
- }
-
- private void removeRoles(Resource resource, SqlSession session) {
- Long resourceId = Long.valueOf(resource.getId());
- RoleMapper mapper = session.getMapper(RoleMapper.class);
- mapper.deleteGroupRolesByResourceId(resourceId);
- mapper.deleteUserRolesByResourceId(resourceId);
- }
-
- private void grantDefaultRoles(Resource resource, String role, SqlSession session) {
- UserMapper userMapper = session.getMapper(UserMapper.class);
- RoleMapper roleMapper = session.getMapper(RoleMapper.class);
-
- String[] groupNames = settings.getStringArrayBySeparator("sonar.role." + role + "." + resource.getQualifier() + ".defaultGroups", ",");
- for (String groupName : groupNames) {
- GroupRoleDto groupRole = new GroupRoleDto().setRole(role).setResourceId(Long.valueOf(resource.getId()));
- if (DefaultGroups.isAnyone(groupName)) {
- roleMapper.insertGroupRole(groupRole);
- } else {
- GroupDto group = userMapper.selectGroupByName(groupName);
- if (group != null) {
- roleMapper.insertGroupRole(groupRole.setGroupId(group.getId()));
- }
- }
- }
-
- String[] logins = settings.getStringArrayBySeparator("sonar.role." + role + "." + resource.getQualifier() + ".defaultUsers", ",");
- for (String login : logins) {
- UserDto user = userMapper.selectUserByLogin(login);
- if (user != null) {
- roleMapper.insertUserRole(new UserRoleDto().setRole(role).setUserId(user.getId()).setResourceId(Long.valueOf(resource.getId())));
- }
- }
- }
-}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar 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.
- *
- * Sonar 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 Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-package org.sonar.plugins.core.security;
-
-import org.junit.Test;
-import org.sonar.api.config.Settings;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.security.DefaultGroups;
-import org.sonar.core.persistence.AbstractDaoTestCase;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class DefaultResourcePermissionsTest extends AbstractDaoTestCase {
-
- private Resource project = new Project("project").setId(123);
-
- @Test
- public void grantGroupRole() {
- setupData("grantGroupRole");
-
- DefaultResourcePermissions permissions = new DefaultResourcePermissions(new Settings(), getMyBatis());
- permissions.grantGroupRole(project, "sonar-administrators", "admin");
-
- // do not insert duplicated rows
- permissions.grantGroupRole(project, "sonar-administrators", "admin");
-
- checkTables("grantGroupRole", new String[] {"id"}, "group_roles");
- }
-
- @Test
- public void grantGroupRole_anyone() {
- setupData("grantGroupRole_anyone");
-
- DefaultResourcePermissions permissions = new DefaultResourcePermissions(new Settings(), getMyBatis());
- permissions.grantGroupRole(project, DefaultGroups.ANYONE, "admin");
-
- checkTables("grantGroupRole_anyone", "group_roles");
- }
-
- @Test
- public void grantGroupRole_ignore_if_group_not_found() {
- setupData("grantGroupRole_ignore_if_group_not_found");
-
- DefaultResourcePermissions permissions = new DefaultResourcePermissions(new Settings(), getMyBatis());
- permissions.grantGroupRole(project, "not_found", "admin");
-
- checkTables("grantGroupRole_ignore_if_group_not_found", "group_roles");
- }
-
- @Test
- public void grantGroupRole_ignore_if_not_persisted() {
- setupData("grantGroupRole_ignore_if_not_persisted");
-
- DefaultResourcePermissions permissions = new DefaultResourcePermissions(new Settings(), getMyBatis());
- Project resourceWithoutId = new Project("");
- permissions.grantGroupRole(resourceWithoutId, "sonar-users", "admin");
-
- checkTables("grantGroupRole_ignore_if_not_persisted", "group_roles");
- }
-
- @Test
- public void grantUserRole() {
- setupData("grantUserRole");
-
- DefaultResourcePermissions permissions = new DefaultResourcePermissions(new Settings(), getMyBatis());
- permissions.grantUserRole(project, "marius", "admin");
-
- // do not insert duplicated rows
- permissions.grantUserRole(project, "marius", "admin");
-
- checkTables("grantUserRole", new String[] {"id"}, "user_roles");
- }
-
- @Test
- public void grantDefaultRoles() {
- setupData("grantDefaultRoles");
-
- Settings settings = new Settings();
- settings.setProperty("sonar.role.admin.TRK.defaultGroups", "sonar-administrators");
- settings.setProperty("sonar.role.admin.TRK.defaultUsers", "");
- settings.setProperty("sonar.role.user.TRK.defaultGroups", "Anyone,sonar-users");
- settings.setProperty("sonar.role.user.TRK.defaultUsers", "");
- settings.setProperty("sonar.role.codeviewer.TRK.defaultGroups", "Anyone,sonar-users");
- settings.setProperty("sonar.role.codeviewer.TRK.defaultUsers", "");
- DefaultResourcePermissions permissions = new DefaultResourcePermissions(settings, getMyBatis());
-
- permissions.grantDefaultRoles(project);
-
- checkTables("grantDefaultRoles", "user_roles", "group_roles");
- }
-
- @Test
- public void grantDefaultRoles_unknown_group() {
- setupData("grantDefaultRoles_unknown_group");
-
- Settings settings = new Settings();
- settings.setProperty("sonar.role.admin.TRK.defaultGroups", "sonar-administrators,unknown");
- DefaultResourcePermissions permissions = new DefaultResourcePermissions(settings, getMyBatis());
- permissions.grantDefaultRoles(project);
-
- checkTables("grantDefaultRoles_unknown_group", "group_roles");
- }
-
- @Test
- public void grantDefaultRoles_users() {
- setupData("grantDefaultRoles_users");
-
- Settings settings = new Settings();
- settings.setProperty("sonar.role.admin.TRK.defaultUsers", "marius,disabled,notfound");
- DefaultResourcePermissions permissions = new DefaultResourcePermissions(settings, getMyBatis());
- permissions.grantDefaultRoles(project);
-
- checkTables("grantDefaultRoles_users", "user_roles");
- }
-
- @Test
- public void hasRoles() {
- setupData("hasRoles");
- DefaultResourcePermissions permissions = new DefaultResourcePermissions(new Settings(), getMyBatis());
-
- // no groups and at least one user
- assertThat(permissions.hasRoles(new Project("only_users").setId(1))).isTrue();
-
- // no users and at least one group
- assertThat(permissions.hasRoles(new Project("only_groups").setId(2))).isTrue();
-
- // groups and users
- assertThat(permissions.hasRoles(new Project("groups_and_users").setId(3))).isTrue();
-
- // no groups, no users
- assertThat(permissions.hasRoles(new Project("no_groups_no_users").setId(4))).isFalse();
-
- // does not exist
- assertThat(permissions.hasRoles(new Project("not_found"))).isFalse();
- }
-}
+++ /dev/null
-<dataset>
- <groups id="100" name="sonar-administrators"/>
- <groups id="101" name="sonar-users"/>
- <users id="200" login="marius" name="Marius" email="[null]" active="[true]"/>
-
- <!-- on other resources -->
- <group_roles id="1" group_id="100" resource_id="1" role="admin"/>
- <group_roles id="2" group_id="101" resource_id="1" role="user"/>
- <user_roles id="1" user_id="200" resource_id="1" role="admin"/>
-
- <!--
- new rows : sonar-administrators (admin), sonar-users (user & codeviewer), Anyone (user & codeviewer),
- -->
- <group_roles id="3" group_id="100" resource_id="123" role="admin"/>
- <group_roles id="4" group_id="[null]" resource_id="123" role="user"/>
- <group_roles id="5" group_id="101" resource_id="123" role="user"/>
- <group_roles id="6" group_id="[null]" resource_id="123" role="codeviewer"/>
- <group_roles id="7" group_id="101" resource_id="123" role="codeviewer"/>
-
-</dataset>
\ No newline at end of file
+++ /dev/null
-<dataset>
- <groups id="100" name="sonar-administrators" />
- <groups id="101" name="sonar-users" />
- <users id="200" login="marius" name="Marius" email="[null]" active="[true]" />
-
- <!-- on other resources -->
- <group_roles id="1" group_id="100" resource_id="1" role="admin"/>
- <group_roles id="2" group_id="101" resource_id="1" role="user"/>
- <user_roles id="1" user_id="200" resource_id="1" role="admin"/>
-</dataset>
\ No newline at end of file
+++ /dev/null
-<dataset>
- <groups id="100" name="sonar-administrators"/>
- <groups id="101" name="sonar-users"/>
- <users id="200" login="marius" name="Marius" email="[null]" active="[true]"/>
-
- <!-- on other resources -->
- <group_roles id="1" group_id="100" resource_id="1" role="admin"/>
- <group_roles id="2" group_id="101" resource_id="1" role="user"/>
- <user_roles id="1" user_id="200" resource_id="1" role="admin"/>
-
- <!--
- new rows : sonar-administrators (admin)
- -->
- <group_roles id="3" group_id="100" resource_id="123" role="admin"/>
-
-</dataset>
\ No newline at end of file
+++ /dev/null
-<dataset>
- <groups id="100" name="sonar-administrators" />
- <groups id="101" name="sonar-users" />
- <users id="200" login="marius" name="Marius" email="[null]" active="[true]" />
-
- <!-- on other resources -->
- <group_roles id="1" group_id="100" resource_id="1" role="admin"/>
- <group_roles id="2" group_id="101" resource_id="1" role="user"/>
- <user_roles id="1" user_id="200" resource_id="1" role="admin"/>
-</dataset>
\ No newline at end of file
+++ /dev/null
-<dataset>
- <groups id="100" name="sonar-administrators"/>
- <groups id="101" name="sonar-users"/>
- <users id="200" login="marius" name="Marius" email="[null]" active="[true]"/>
- <users id="201" login="disabled" name="Disabled" email="[null]" active="[false]"/>
-
- <!-- on other resources -->
- <group_roles id="1" group_id="100" resource_id="1" role="admin"/>
- <group_roles id="2" group_id="101" resource_id="1" role="user"/>
- <user_roles id="1" user_id="200" resource_id="1" role="admin"/>
-
- <!--
- new row : marius (admin)
- -->
- <user_roles id="2" user_id="200" resource_id="123" role="admin"/>
-</dataset>
\ No newline at end of file
+++ /dev/null
-<dataset>
- <groups id="100" name="sonar-administrators" />
- <groups id="101" name="sonar-users" />
- <users id="200" login="marius" name="Marius" email="[null]" active="[true]" />
- <users id="201" login="disabled" name="Disabled" email="[null]" active="[false]" />
-
- <!-- on other resources -->
- <group_roles id="1" group_id="100" resource_id="1" role="admin"/>
- <group_roles id="2" group_id="101" resource_id="1" role="user"/>
- <user_roles id="1" user_id="200" resource_id="1" role="admin"/>
-</dataset>
\ No newline at end of file
+++ /dev/null
-<dataset>
- <groups id="100" name="sonar-administrators"/>
- <groups id="101" name="sonar-users"/>
-
- <group_roles group_id="100" resource_id="123" role="admin"/>
-</dataset>
\ No newline at end of file
+++ /dev/null
-<dataset>
- <groups id="100" name="sonar-administrators" />
- <groups id="101" name="sonar-users" />
-</dataset>
\ No newline at end of file
+++ /dev/null
-<dataset>
- <groups id="100" name="sonar-administrators" />
- <groups id="101" name="sonar-users" />
-
- <group_roles id="1" group_id="[null]" resource_id="123" role="admin"/>
-</dataset>
\ No newline at end of file
+++ /dev/null
-<dataset>
- <groups id="100" name="sonar-administrators" />
- <groups id="101" name="sonar-users" />
-</dataset>
\ No newline at end of file
+++ /dev/null
-<dataset>
- <groups id="100" name="sonar-administrators" />
- <groups id="101" name="sonar-users" />
-
- <!-- already existed -->
- <group_roles id="1" group_id="[null]" resource_id="123" role="admin"/>
-</dataset>
\ No newline at end of file
+++ /dev/null
-<dataset>
- <groups id="100" name="sonar-administrators" />
- <groups id="101" name="sonar-users" />
-
- <!-- already existed -->
- <group_roles id="1" group_id="[null]" resource_id="123" role="admin"/>
-</dataset>
\ No newline at end of file
+++ /dev/null
-<dataset>
- <groups id="100" name="sonar-administrators" />
- <groups id="101" name="sonar-users" />
-
- <!-- already existed -->
- <group_roles id="1" group_id="[null]" resource_id="123" role="admin"/>
-</dataset>
\ No newline at end of file
+++ /dev/null
-<dataset>
- <groups id="100" name="sonar-administrators" />
- <groups id="101" name="sonar-users" />
-
- <!-- already existed -->
- <group_roles id="1" group_id="[null]" resource_id="123" role="admin"/>
-</dataset>
\ No newline at end of file
+++ /dev/null
-<dataset>
- <users id="200" login="marius" name="Marius" email="[null]" active="[true]"/>
-
- <user_roles user_id="200" resource_id="123" role="admin"/>
-
-</dataset>
\ No newline at end of file
+++ /dev/null
-<dataset>
- <users id="200" login="marius" name="Marius" email="[null]" active="[true]" />
-</dataset>
\ No newline at end of file
+++ /dev/null
-<dataset>
- <groups id="100" name="sonar-administrators"/>
- <groups id="101" name="sonar-users"/>
- <users id="200" login="marius" name="Marius" email="[null]" active="[true]"/>
-
- <!-- only_users -->
- <user_roles id="1" user_id="200" resource_id="1" role="admin"/>
-
- <!-- only_groups -->
- <group_roles id="1" group_id="100" resource_id="2" role="admin"/>
-
- <!-- groups_and_users -->
- <group_roles id="2" group_id="101" resource_id="3" role="user"/>
- <user_roles id="2" user_id="200" resource_id="3" role="admin"/>
-
-</dataset>
\ No newline at end of file
import org.sonar.core.persistence.DaoUtils;
import org.sonar.core.persistence.DatabaseVersion;
import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.resource.DefaultResourcePermissions;
import org.sonar.core.rule.CacheRuleFinder;
import org.sonar.core.user.DefaultUserFinder;
import org.sonar.jpa.dao.MeasuresDao;
container.addSingleton(LinkPersister.class);
container.addSingleton(MeasurePersister.class);
container.addSingleton(MemoryOptimizer.class);
+ container.addSingleton(DefaultResourcePermissions.class);
container.addSingleton(DefaultResourcePersister.class);
container.addSingleton(SourcePersister.class);
container.addSingleton(MeasuresDao.class);
import org.sonar.api.database.model.ResourceModel;
import org.sonar.api.database.model.Snapshot;
import org.sonar.api.resources.*;
+import org.sonar.api.security.ResourcePermissions;
import org.sonar.api.utils.SonarException;
import javax.persistence.NonUniqueResultException;
private DatabaseSession session;
private Map<Resource, Snapshot> snapshotsByResource = Maps.newHashMap();
+ private ResourcePermissions permissions;
- public DefaultResourcePersister(DatabaseSession session) {
+ public DefaultResourcePersister(DatabaseSession session, ResourcePermissions permissions) {
this.session = session;
+ this.permissions = permissions;
}
public Snapshot saveProject(Project project, Project parent) {
snapshot.setBuildDate(new Date());
snapshot = session.save(snapshot);
session.commit();
+
+ permissions.grantDefaultRoles(project);
+
return snapshot;
}
import org.sonar.api.resources.JavaPackage;
import org.sonar.api.resources.Library;
import org.sonar.api.resources.Project;
+import org.sonar.api.security.ResourcePermissions;
import org.sonar.jpa.test.AbstractDbUnitTestCase;
import java.text.ParseException;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.notNullValue;
+import static org.mockito.Mockito.mock;
public class DefaultResourcePersisterTest extends AbstractDbUnitTestCase {
public void shouldSaveNewProject() {
setupData("shared");
- ResourcePersister persister = new DefaultResourcePersister(getSession());
+ ResourcePersister persister = new DefaultResourcePersister(getSession(), mock(ResourcePermissions.class));
persister.saveProject(singleProject, null);
checkTables("shouldSaveNewProject", new String[] {"build_date", "created_at"}, "projects", "snapshots");
public void shouldSaveNewMultiModulesProject() {
setupData("shared");
- ResourcePersister persister = new DefaultResourcePersister(getSession());
+ ResourcePersister persister = new DefaultResourcePersister(getSession(), mock(ResourcePermissions.class));
persister.saveProject(multiModuleProject, null);
persister.saveProject(moduleA, multiModuleProject);
persister.saveProject(moduleB, multiModuleProject);
public void shouldSaveNewDirectory() {
setupData("shared");
- ResourcePersister persister = new DefaultResourcePersister(getSession());
+ ResourcePersister persister = new DefaultResourcePersister(getSession(), mock(ResourcePermissions.class));
persister.saveProject(singleProject, null);
persister.saveResource(singleProject, new JavaPackage("org.foo").setEffectiveKey("foo:org.foo"));
public void shouldSaveNewLibrary() {
setupData("shared");
- ResourcePersister persister = new DefaultResourcePersister(getSession());
+ ResourcePersister persister = new DefaultResourcePersister(getSession(), mock(ResourcePermissions.class));
persister.saveProject(singleProject, null);
persister.saveResource(singleProject, new Library("junit:junit", "4.8.2").setEffectiveKey("junit:junit"));
persister.saveResource(singleProject, new Library("junit:junit", "4.8.2").setEffectiveKey("junit:junit"));// do nothing, already saved
public void shouldClearResourcesExceptProjects() {
setupData("shared");
- DefaultResourcePersister persister = new DefaultResourcePersister(getSession());
+ DefaultResourcePersister persister = new DefaultResourcePersister(getSession(), mock(ResourcePermissions.class));
persister.saveProject(multiModuleProject, null);
persister.saveProject(moduleA, multiModuleProject);
persister.saveResource(moduleA, new JavaPackage("org.foo").setEffectiveKey("a:org.foo"));
public void shouldUpdateExistingResource() {
setupData("shouldUpdateExistingResource");
- ResourcePersister persister = new DefaultResourcePersister(getSession());
+ ResourcePersister persister = new DefaultResourcePersister(getSession(), mock(ResourcePermissions.class));
singleProject.setName("new name");
singleProject.setDescription("new description");
persister.saveProject(singleProject, null);
public void shouldRemoveRootIndexIfResourceIsProject() {
setupData("shouldRemoveRootIndexIfResourceIsProject");
- ResourcePersister persister = new DefaultResourcePersister(getSession());
+ ResourcePersister persister = new DefaultResourcePersister(getSession(), mock(ResourcePermissions.class));
persister.saveProject(singleProject, null);
checkTables("shouldRemoveRootIndexIfResourceIsProject", new String[] {"build_date", "created_at"}, "projects", "snapshots");
import org.sonar.api.config.Settings;
import org.sonar.api.database.DatabaseSession;
import org.sonar.api.database.model.Snapshot;
+import org.sonar.api.security.ResourcePermissions;
import org.sonar.batch.bootstrap.ServerClient;
import org.sonar.batch.index.DefaultResourcePersister;
import org.sonar.jpa.test.AbstractDbUnitTestCase;
setupData("sharedFixture", fixture);
DatabaseSession session = getSession();
- UpdateStatusJob sensor = new UpdateStatusJob(new Settings(), mock(ServerClient.class), session, new DefaultResourcePersister(session), loadSnapshot(snapshotId));
+ UpdateStatusJob sensor = new UpdateStatusJob(new Settings(), mock(ServerClient.class), session, new DefaultResourcePersister(session, mock(ResourcePermissions.class)), loadSnapshot(snapshotId));
sensor.execute();
checkTables(fixture, "snapshots");
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.core.resource;
+
+import org.apache.ibatis.session.SqlSession;
+import org.sonar.api.BatchExtension;
+import org.sonar.api.ServerExtension;
+import org.sonar.api.config.Settings;
+import org.sonar.api.resources.Resource;
+import org.sonar.api.security.DefaultGroups;
+import org.sonar.api.security.ResourcePermissions;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.user.GroupDto;
+import org.sonar.core.user.GroupRoleDto;
+import org.sonar.core.user.RoleMapper;
+import org.sonar.core.user.UserDto;
+import org.sonar.core.user.UserMapper;
+import org.sonar.core.user.UserRoleDto;
+
+/**
+ * @since 3.2
+ */
+public class DefaultResourcePermissions implements ResourcePermissions, BatchExtension, ServerExtension {
+
+ private final Settings settings;
+ private final MyBatis myBatis;
+
+ public DefaultResourcePermissions(Settings settings, MyBatis myBatis) {
+ this.settings = settings;
+ this.myBatis = myBatis;
+ }
+
+ public boolean hasRoles(Resource resource) {
+ if (resource.getId() != null) {
+ SqlSession session = myBatis.openSession();
+ try {
+ RoleMapper roleMapper = session.getMapper(RoleMapper.class);
+ Long resourceId = Long.valueOf(resource.getId());
+ return roleMapper.countGroupRoles(resourceId) + roleMapper.countUserRoles(resourceId) > 0;
+
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+ return false;
+ }
+
+ public void grantUserRole(Resource resource, String login, String role) {
+ if (resource.getId() != null) {
+ SqlSession session = myBatis.openSession();
+ try {
+ UserDto user = session.getMapper(UserMapper.class).selectUserByLogin(login);
+ if (user != null) {
+ UserRoleDto userRole = new UserRoleDto()
+ .setRole(role)
+ .setUserId(user.getId())
+ .setResourceId(Long.valueOf(resource.getId()));
+ RoleMapper roleMapper = session.getMapper(RoleMapper.class);
+ roleMapper.deleteUserRole(userRole);
+ roleMapper.insertUserRole(userRole);
+ session.commit();
+ }
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+ }
+
+ public void grantGroupRole(Resource resource, String groupName, String role) {
+ if (resource.getId() != null) {
+ SqlSession session = myBatis.openSession();
+ try {
+ GroupRoleDto groupRole = new GroupRoleDto()
+ .setRole(role)
+ .setResourceId(Long.valueOf(resource.getId()));
+ RoleMapper roleMapper = session.getMapper(RoleMapper.class);
+ if (DefaultGroups.isAnyone(groupName)) {
+ roleMapper.deleteGroupRole(groupRole);
+ roleMapper.insertGroupRole(groupRole);
+ session.commit();
+ } else {
+ GroupDto group = session.getMapper(UserMapper.class).selectGroupByName(groupName);
+ if (group != null) {
+ groupRole.setGroupId(group.getId());
+ roleMapper.deleteGroupRole(groupRole);
+ roleMapper.insertGroupRole(groupRole);
+ session.commit();
+ }
+ }
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+ }
+
+ public void grantDefaultRoles(Resource resource) {
+ if (resource.getId() != null) {
+ SqlSession session = myBatis.openSession();
+ try {
+ removeRoles(resource, session);
+ grantDefaultRoles(resource, UserRole.ADMIN, session);
+ grantDefaultRoles(resource, UserRole.USER, session);
+ grantDefaultRoles(resource, UserRole.CODEVIEWER, session);
+ session.commit();
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+ }
+
+ private void removeRoles(Resource resource, SqlSession session) {
+ Long resourceId = Long.valueOf(resource.getId());
+ RoleMapper mapper = session.getMapper(RoleMapper.class);
+ mapper.deleteGroupRolesByResourceId(resourceId);
+ mapper.deleteUserRolesByResourceId(resourceId);
+ }
+
+ private void grantDefaultRoles(Resource resource, String role, SqlSession session) {
+ UserMapper userMapper = session.getMapper(UserMapper.class);
+ RoleMapper roleMapper = session.getMapper(RoleMapper.class);
+
+ String[] groupNames = settings.getStringArrayBySeparator("sonar.role." + role + "." + resource.getQualifier() + ".defaultGroups", ",");
+ for (String groupName : groupNames) {
+ GroupRoleDto groupRole = new GroupRoleDto().setRole(role).setResourceId(Long.valueOf(resource.getId()));
+ if (DefaultGroups.isAnyone(groupName)) {
+ roleMapper.insertGroupRole(groupRole);
+ } else {
+ GroupDto group = userMapper.selectGroupByName(groupName);
+ if (group != null) {
+ roleMapper.insertGroupRole(groupRole.setGroupId(group.getId()));
+ }
+ }
+ }
+
+ String[] logins = settings.getStringArrayBySeparator("sonar.role." + role + "." + resource.getQualifier() + ".defaultUsers", ",");
+ for (String login : logins) {
+ UserDto user = userMapper.selectUserByLogin(login);
+ if (user != null) {
+ roleMapper.insertUserRole(new UserRoleDto().setRole(role).setUserId(user.getId()).setResourceId(Long.valueOf(resource.getId())));
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.core.resource;
+
+import org.junit.Test;
+import org.sonar.api.config.Settings;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Resource;
+import org.sonar.api.security.DefaultGroups;
+import org.sonar.core.persistence.AbstractDaoTestCase;
+import org.sonar.core.resource.DefaultResourcePermissions;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class DefaultResourcePermissionsTest extends AbstractDaoTestCase {
+
+ private Resource project = new Project("project").setId(123);
+
+ @Test
+ public void grantGroupRole() {
+ setupData("grantGroupRole");
+
+ DefaultResourcePermissions permissions = new DefaultResourcePermissions(new Settings(), getMyBatis());
+ permissions.grantGroupRole(project, "sonar-administrators", "admin");
+
+ // do not insert duplicated rows
+ permissions.grantGroupRole(project, "sonar-administrators", "admin");
+
+ checkTables("grantGroupRole", new String[] {"id"}, "group_roles");
+ }
+
+ @Test
+ public void grantGroupRole_anyone() {
+ setupData("grantGroupRole_anyone");
+
+ DefaultResourcePermissions permissions = new DefaultResourcePermissions(new Settings(), getMyBatis());
+ permissions.grantGroupRole(project, DefaultGroups.ANYONE, "admin");
+
+ checkTables("grantGroupRole_anyone", "group_roles");
+ }
+
+ @Test
+ public void grantGroupRole_ignore_if_group_not_found() {
+ setupData("grantGroupRole_ignore_if_group_not_found");
+
+ DefaultResourcePermissions permissions = new DefaultResourcePermissions(new Settings(), getMyBatis());
+ permissions.grantGroupRole(project, "not_found", "admin");
+
+ checkTables("grantGroupRole_ignore_if_group_not_found", "group_roles");
+ }
+
+ @Test
+ public void grantGroupRole_ignore_if_not_persisted() {
+ setupData("grantGroupRole_ignore_if_not_persisted");
+
+ DefaultResourcePermissions permissions = new DefaultResourcePermissions(new Settings(), getMyBatis());
+ Project resourceWithoutId = new Project("");
+ permissions.grantGroupRole(resourceWithoutId, "sonar-users", "admin");
+
+ checkTables("grantGroupRole_ignore_if_not_persisted", "group_roles");
+ }
+
+ @Test
+ public void grantUserRole() {
+ setupData("grantUserRole");
+
+ DefaultResourcePermissions permissions = new DefaultResourcePermissions(new Settings(), getMyBatis());
+ permissions.grantUserRole(project, "marius", "admin");
+
+ // do not insert duplicated rows
+ permissions.grantUserRole(project, "marius", "admin");
+
+ checkTables("grantUserRole", new String[] {"id"}, "user_roles");
+ }
+
+ @Test
+ public void grantDefaultRoles() {
+ setupData("grantDefaultRoles");
+
+ Settings settings = new Settings();
+ settings.setProperty("sonar.role.admin.TRK.defaultGroups", "sonar-administrators");
+ settings.setProperty("sonar.role.admin.TRK.defaultUsers", "");
+ settings.setProperty("sonar.role.user.TRK.defaultGroups", "Anyone,sonar-users");
+ settings.setProperty("sonar.role.user.TRK.defaultUsers", "");
+ settings.setProperty("sonar.role.codeviewer.TRK.defaultGroups", "Anyone,sonar-users");
+ settings.setProperty("sonar.role.codeviewer.TRK.defaultUsers", "");
+ DefaultResourcePermissions permissions = new DefaultResourcePermissions(settings, getMyBatis());
+
+ permissions.grantDefaultRoles(project);
+
+ checkTables("grantDefaultRoles", "user_roles", "group_roles");
+ }
+
+ @Test
+ public void grantDefaultRoles_unknown_group() {
+ setupData("grantDefaultRoles_unknown_group");
+
+ Settings settings = new Settings();
+ settings.setProperty("sonar.role.admin.TRK.defaultGroups", "sonar-administrators,unknown");
+ DefaultResourcePermissions permissions = new DefaultResourcePermissions(settings, getMyBatis());
+ permissions.grantDefaultRoles(project);
+
+ checkTables("grantDefaultRoles_unknown_group", "group_roles");
+ }
+
+ @Test
+ public void grantDefaultRoles_users() {
+ setupData("grantDefaultRoles_users");
+
+ Settings settings = new Settings();
+ settings.setProperty("sonar.role.admin.TRK.defaultUsers", "marius,disabled,notfound");
+ DefaultResourcePermissions permissions = new DefaultResourcePermissions(settings, getMyBatis());
+ permissions.grantDefaultRoles(project);
+
+ checkTables("grantDefaultRoles_users", "user_roles");
+ }
+
+ @Test
+ public void hasRoles() {
+ setupData("hasRoles");
+ DefaultResourcePermissions permissions = new DefaultResourcePermissions(new Settings(), getMyBatis());
+
+ // no groups and at least one user
+ assertThat(permissions.hasRoles(new Project("only_users").setId(1))).isTrue();
+
+ // no users and at least one group
+ assertThat(permissions.hasRoles(new Project("only_groups").setId(2))).isTrue();
+
+ // groups and users
+ assertThat(permissions.hasRoles(new Project("groups_and_users").setId(3))).isTrue();
+
+ // no groups, no users
+ assertThat(permissions.hasRoles(new Project("no_groups_no_users").setId(4))).isFalse();
+
+ // does not exist
+ assertThat(permissions.hasRoles(new Project("not_found"))).isFalse();
+ }
+}
--- /dev/null
+<dataset>
+ <groups id="100" name="sonar-administrators"/>
+ <groups id="101" name="sonar-users"/>
+ <users id="200" login="marius" name="Marius" email="[null]" active="[true]"/>
+
+ <!-- on other resources -->
+ <group_roles id="1" group_id="100" resource_id="1" role="admin"/>
+ <group_roles id="2" group_id="101" resource_id="1" role="user"/>
+ <user_roles id="1" user_id="200" resource_id="1" role="admin"/>
+
+ <!--
+ new rows : sonar-administrators (admin), sonar-users (user & codeviewer), Anyone (user & codeviewer),
+ -->
+ <group_roles id="3" group_id="100" resource_id="123" role="admin"/>
+ <group_roles id="4" group_id="[null]" resource_id="123" role="user"/>
+ <group_roles id="5" group_id="101" resource_id="123" role="user"/>
+ <group_roles id="6" group_id="[null]" resource_id="123" role="codeviewer"/>
+ <group_roles id="7" group_id="101" resource_id="123" role="codeviewer"/>
+
+</dataset>
\ No newline at end of file
--- /dev/null
+<dataset>
+ <groups id="100" name="sonar-administrators" />
+ <groups id="101" name="sonar-users" />
+ <users id="200" login="marius" name="Marius" email="[null]" active="[true]" />
+
+ <!-- on other resources -->
+ <group_roles id="1" group_id="100" resource_id="1" role="admin"/>
+ <group_roles id="2" group_id="101" resource_id="1" role="user"/>
+ <user_roles id="1" user_id="200" resource_id="1" role="admin"/>
+</dataset>
\ No newline at end of file
--- /dev/null
+<dataset>
+ <groups id="100" name="sonar-administrators"/>
+ <groups id="101" name="sonar-users"/>
+ <users id="200" login="marius" name="Marius" email="[null]" active="[true]"/>
+
+ <!-- on other resources -->
+ <group_roles id="1" group_id="100" resource_id="1" role="admin"/>
+ <group_roles id="2" group_id="101" resource_id="1" role="user"/>
+ <user_roles id="1" user_id="200" resource_id="1" role="admin"/>
+
+ <!--
+ new rows : sonar-administrators (admin)
+ -->
+ <group_roles id="3" group_id="100" resource_id="123" role="admin"/>
+
+</dataset>
\ No newline at end of file
--- /dev/null
+<dataset>
+ <groups id="100" name="sonar-administrators" />
+ <groups id="101" name="sonar-users" />
+ <users id="200" login="marius" name="Marius" email="[null]" active="[true]" />
+
+ <!-- on other resources -->
+ <group_roles id="1" group_id="100" resource_id="1" role="admin"/>
+ <group_roles id="2" group_id="101" resource_id="1" role="user"/>
+ <user_roles id="1" user_id="200" resource_id="1" role="admin"/>
+</dataset>
\ No newline at end of file
--- /dev/null
+<dataset>
+ <groups id="100" name="sonar-administrators"/>
+ <groups id="101" name="sonar-users"/>
+ <users id="200" login="marius" name="Marius" email="[null]" active="[true]"/>
+ <users id="201" login="disabled" name="Disabled" email="[null]" active="[false]"/>
+
+ <!-- on other resources -->
+ <group_roles id="1" group_id="100" resource_id="1" role="admin"/>
+ <group_roles id="2" group_id="101" resource_id="1" role="user"/>
+ <user_roles id="1" user_id="200" resource_id="1" role="admin"/>
+
+ <!--
+ new row : marius (admin)
+ -->
+ <user_roles id="2" user_id="200" resource_id="123" role="admin"/>
+</dataset>
\ No newline at end of file
--- /dev/null
+<dataset>
+ <groups id="100" name="sonar-administrators" />
+ <groups id="101" name="sonar-users" />
+ <users id="200" login="marius" name="Marius" email="[null]" active="[true]" />
+ <users id="201" login="disabled" name="Disabled" email="[null]" active="[false]" />
+
+ <!-- on other resources -->
+ <group_roles id="1" group_id="100" resource_id="1" role="admin"/>
+ <group_roles id="2" group_id="101" resource_id="1" role="user"/>
+ <user_roles id="1" user_id="200" resource_id="1" role="admin"/>
+</dataset>
\ No newline at end of file
--- /dev/null
+<dataset>
+ <groups id="100" name="sonar-administrators"/>
+ <groups id="101" name="sonar-users"/>
+
+ <group_roles group_id="100" resource_id="123" role="admin"/>
+</dataset>
\ No newline at end of file
--- /dev/null
+<dataset>
+ <groups id="100" name="sonar-administrators" />
+ <groups id="101" name="sonar-users" />
+</dataset>
\ No newline at end of file
--- /dev/null
+<dataset>
+ <groups id="100" name="sonar-administrators" />
+ <groups id="101" name="sonar-users" />
+
+ <group_roles id="1" group_id="[null]" resource_id="123" role="admin"/>
+</dataset>
\ No newline at end of file
--- /dev/null
+<dataset>
+ <groups id="100" name="sonar-administrators" />
+ <groups id="101" name="sonar-users" />
+</dataset>
\ No newline at end of file
--- /dev/null
+<dataset>
+ <groups id="100" name="sonar-administrators" />
+ <groups id="101" name="sonar-users" />
+
+ <!-- already existed -->
+ <group_roles id="1" group_id="[null]" resource_id="123" role="admin"/>
+</dataset>
\ No newline at end of file
--- /dev/null
+<dataset>
+ <groups id="100" name="sonar-administrators" />
+ <groups id="101" name="sonar-users" />
+
+ <!-- already existed -->
+ <group_roles id="1" group_id="[null]" resource_id="123" role="admin"/>
+</dataset>
\ No newline at end of file
--- /dev/null
+<dataset>
+ <groups id="100" name="sonar-administrators" />
+ <groups id="101" name="sonar-users" />
+
+ <!-- already existed -->
+ <group_roles id="1" group_id="[null]" resource_id="123" role="admin"/>
+</dataset>
\ No newline at end of file
--- /dev/null
+<dataset>
+ <groups id="100" name="sonar-administrators" />
+ <groups id="101" name="sonar-users" />
+
+ <!-- already existed -->
+ <group_roles id="1" group_id="[null]" resource_id="123" role="admin"/>
+</dataset>
\ No newline at end of file
--- /dev/null
+<dataset>
+ <users id="200" login="marius" name="Marius" email="[null]" active="[true]"/>
+
+ <user_roles user_id="200" resource_id="123" role="admin"/>
+
+</dataset>
\ No newline at end of file
--- /dev/null
+<dataset>
+ <users id="200" login="marius" name="Marius" email="[null]" active="[true]" />
+</dataset>
\ No newline at end of file
--- /dev/null
+<dataset>
+ <groups id="100" name="sonar-administrators"/>
+ <groups id="101" name="sonar-users"/>
+ <users id="200" login="marius" name="Marius" email="[null]" active="[true]"/>
+
+ <!-- only_users -->
+ <user_roles id="1" user_id="200" resource_id="1" role="admin"/>
+
+ <!-- only_groups -->
+ <group_roles id="1" group_id="100" resource_id="2" role="admin"/>
+
+ <!-- groups_and_users -->
+ <group_roles id="2" group_id="101" resource_id="3" role="user"/>
+ <user_roles id="2" user_id="200" resource_id="3" role="admin"/>
+
+</dataset>
\ No newline at end of file
import org.sonar.core.persistence.DryRunDatabaseFactory;
import org.sonar.core.persistence.MyBatis;
import org.sonar.core.qualitymodel.DefaultModelFinder;
+import org.sonar.core.resource.DefaultResourcePermissions;
import org.sonar.core.rule.DefaultRuleFinder;
import org.sonar.core.user.DefaultUserFinder;
import org.sonar.core.workflow.ReviewDatabaseStore;
servicesContainer.addSingleton(MeasureFilterExecutor.class);
servicesContainer.addSingleton(MeasureFilterEngine.class);
servicesContainer.addSingleton(DryRunDatabaseFactory.class);
+ servicesContainer.addSingleton(DefaultResourcePermissions.class);
// Notifications
servicesContainer.addSingleton(EmailSettings.class);