From: Simon Brandhof Date: Thu, 5 Jul 2012 14:40:16 +0000 (+0200) Subject: SONAR-3618 Support custom default permissions for non-project resources X-Git-Tag: 3.2~223 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=cba251c929936768308e59365bc44f532bb16756;p=sonarqube.git SONAR-3618 Support custom default permissions for non-project resources --- diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java index 86cb29c81a7..cad94d72a16 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java @@ -20,12 +20,7 @@ package org.sonar.plugins.core; import com.google.common.collect.ImmutableList; -import org.sonar.api.CoreProperties; -import org.sonar.api.Extension; -import org.sonar.api.Properties; -import org.sonar.api.Property; -import org.sonar.api.PropertyType; -import org.sonar.api.SonarPlugin; +import org.sonar.api.*; import org.sonar.api.checks.NoSonarFilter; import org.sonar.api.resources.Java; import org.sonar.plugins.core.batch.ExcludedResourceFilter; @@ -36,79 +31,19 @@ import org.sonar.plugins.core.charts.DistributionAreaChart; import org.sonar.plugins.core.charts.DistributionBarChart; import org.sonar.plugins.core.charts.XradarChart; import org.sonar.plugins.core.colorizers.JavaColorizerFormat; -import org.sonar.plugins.core.dashboards.DefaultDashboard; -import org.sonar.plugins.core.dashboards.HotspotsDashboard; -import org.sonar.plugins.core.dashboards.MyFavouritesDashboard; -import org.sonar.plugins.core.dashboards.ProjectsDashboard; -import org.sonar.plugins.core.dashboards.ReviewsDashboard; -import org.sonar.plugins.core.dashboards.TimeMachineDashboard; -import org.sonar.plugins.core.dashboards.TreemapDashboard; +import org.sonar.plugins.core.dashboards.*; import org.sonar.plugins.core.filters.MyFavouritesFilter; 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.sensors.BranchCoverageDecorator; -import org.sonar.plugins.core.sensors.CheckAlertThresholds; -import org.sonar.plugins.core.sensors.CommentDensityDecorator; -import org.sonar.plugins.core.sensors.CoverageDecorator; -import org.sonar.plugins.core.sensors.DirectoriesDecorator; -import org.sonar.plugins.core.sensors.FilesDecorator; -import org.sonar.plugins.core.sensors.GenerateAlertEvents; -import org.sonar.plugins.core.sensors.ItBranchCoverageDecorator; -import org.sonar.plugins.core.sensors.ItCoverageDecorator; -import org.sonar.plugins.core.sensors.ItLineCoverageDecorator; -import org.sonar.plugins.core.sensors.LineCoverageDecorator; -import org.sonar.plugins.core.sensors.ManualMeasureDecorator; -import org.sonar.plugins.core.sensors.ManualViolationInjector; -import org.sonar.plugins.core.sensors.ProfileEventsSensor; -import org.sonar.plugins.core.sensors.ProfileSensor; -import org.sonar.plugins.core.sensors.ProjectLinksSensor; -import org.sonar.plugins.core.sensors.ReviewNotifications; -import org.sonar.plugins.core.sensors.ReviewWorkflowDecorator; -import org.sonar.plugins.core.sensors.ReviewsMeasuresDecorator; -import org.sonar.plugins.core.sensors.UnitTestDecorator; -import org.sonar.plugins.core.sensors.VersionEventsSensor; -import org.sonar.plugins.core.sensors.ViolationSeverityUpdater; -import org.sonar.plugins.core.sensors.ViolationsDecorator; -import org.sonar.plugins.core.sensors.ViolationsDensityDecorator; -import org.sonar.plugins.core.sensors.WeightedViolationsDecorator; +import org.sonar.plugins.core.security.DefaultResourcePermissioning; +import org.sonar.plugins.core.sensors.*; import org.sonar.plugins.core.testdetailsviewer.TestsViewerDefinition; -import org.sonar.plugins.core.timemachine.NewCoverageAggregator; -import org.sonar.plugins.core.timemachine.NewCoverageFileAnalyzer; -import org.sonar.plugins.core.timemachine.NewItCoverageFileAnalyzer; -import org.sonar.plugins.core.timemachine.NewViolationsDecorator; -import org.sonar.plugins.core.timemachine.ReferenceAnalysis; -import org.sonar.plugins.core.timemachine.TendencyDecorator; -import org.sonar.plugins.core.timemachine.TimeMachineConfigurationPersister; -import org.sonar.plugins.core.timemachine.VariationDecorator; -import org.sonar.plugins.core.timemachine.ViolationPersisterDecorator; -import org.sonar.plugins.core.timemachine.ViolationTrackingDecorator; +import org.sonar.plugins.core.timemachine.*; import org.sonar.plugins.core.web.Lcom4Viewer; -import org.sonar.plugins.core.widgets.AlertsWidget; -import org.sonar.plugins.core.widgets.CommentsDuplicationsWidget; -import org.sonar.plugins.core.widgets.ComplexityWidget; -import org.sonar.plugins.core.widgets.CoverageWidget; -import org.sonar.plugins.core.widgets.CustomMeasuresWidget; -import org.sonar.plugins.core.widgets.DescriptionWidget; -import org.sonar.plugins.core.widgets.EventsWidget; -import org.sonar.plugins.core.widgets.FilterWidget; -import org.sonar.plugins.core.widgets.HotspotMetricWidget; -import org.sonar.plugins.core.widgets.HotspotMostViolatedResourcesWidget; -import org.sonar.plugins.core.widgets.HotspotMostViolatedRulesWidget; -import org.sonar.plugins.core.widgets.ItCoverageWidget; -import org.sonar.plugins.core.widgets.RulesWidget; -import org.sonar.plugins.core.widgets.SizeWidget; -import org.sonar.plugins.core.widgets.TimeMachineWidget; -import org.sonar.plugins.core.widgets.TimelineWidget; -import org.sonar.plugins.core.widgets.TreemapWidget; +import org.sonar.plugins.core.widgets.*; import org.sonar.plugins.core.widgets.actionPlans.ActionPlansWidget; -import org.sonar.plugins.core.widgets.reviews.FalsePositiveReviewsWidget; -import org.sonar.plugins.core.widgets.reviews.MyReviewsWidget; -import org.sonar.plugins.core.widgets.reviews.PlannedReviewsWidget; -import org.sonar.plugins.core.widgets.reviews.ProjectReviewsWidget; -import org.sonar.plugins.core.widgets.reviews.ReviewsMetricsWidget; -import org.sonar.plugins.core.widgets.reviews.ReviewsPerDeveloperWidget; -import org.sonar.plugins.core.widgets.reviews.UnplannedReviewsWidget; +import org.sonar.plugins.core.widgets.reviews.*; import java.util.List; @@ -291,110 +226,111 @@ public final class CorePlugin extends SonarPlugin { @SuppressWarnings("unchecked") public List> getExtensions() { return ImmutableList.of( - DefaultResourceTypes.class, - UserManagedMetrics.class, - ProjectFileSystemLogger.class, + DefaultResourceTypes.class, + UserManagedMetrics.class, + ProjectFileSystemLogger.class, - // maven - MavenInitializer.class, + // maven + MavenInitializer.class, - // languages - Java.class, + // languages + Java.class, - // pages - TestsViewerDefinition.class, - Lcom4Viewer.class, + // pages + TestsViewerDefinition.class, + Lcom4Viewer.class, - // filters - ProjectFilter.class, - TreeMapFilter.class, - MyFavouritesFilter.class, + // filters + ProjectFilter.class, + TreeMapFilter.class, + MyFavouritesFilter.class, - // widgets - AlertsWidget.class, - CoverageWidget.class, - ItCoverageWidget.class, - CommentsDuplicationsWidget.class, - DescriptionWidget.class, - ComplexityWidget.class, - RulesWidget.class, - SizeWidget.class, - EventsWidget.class, - CustomMeasuresWidget.class, - TimelineWidget.class, - TimeMachineWidget.class, - HotspotMetricWidget.class, - HotspotMostViolatedResourcesWidget.class, - HotspotMostViolatedRulesWidget.class, - MyReviewsWidget.class, - ProjectReviewsWidget.class, - FalsePositiveReviewsWidget.class, - ReviewsPerDeveloperWidget.class, - PlannedReviewsWidget.class, - UnplannedReviewsWidget.class, - ActionPlansWidget.class, - ReviewsMetricsWidget.class, - TreemapWidget.class, - FilterWidget.class, + // widgets + AlertsWidget.class, + CoverageWidget.class, + ItCoverageWidget.class, + CommentsDuplicationsWidget.class, + DescriptionWidget.class, + ComplexityWidget.class, + RulesWidget.class, + SizeWidget.class, + EventsWidget.class, + CustomMeasuresWidget.class, + TimelineWidget.class, + TimeMachineWidget.class, + HotspotMetricWidget.class, + HotspotMostViolatedResourcesWidget.class, + HotspotMostViolatedRulesWidget.class, + MyReviewsWidget.class, + ProjectReviewsWidget.class, + FalsePositiveReviewsWidget.class, + ReviewsPerDeveloperWidget.class, + PlannedReviewsWidget.class, + UnplannedReviewsWidget.class, + ActionPlansWidget.class, + ReviewsMetricsWidget.class, + TreemapWidget.class, + FilterWidget.class, - // dashboards - DefaultDashboard.class, - HotspotsDashboard.class, - ReviewsDashboard.class, - TimeMachineDashboard.class, - ProjectsDashboard.class, - TreemapDashboard.class, - MyFavouritesDashboard.class, + // dashboards + DefaultDashboard.class, + HotspotsDashboard.class, + ReviewsDashboard.class, + TimeMachineDashboard.class, + ProjectsDashboard.class, + TreemapDashboard.class, + MyFavouritesDashboard.class, - // chart - XradarChart.class, - DistributionBarChart.class, - DistributionAreaChart.class, + // chart + XradarChart.class, + DistributionBarChart.class, + DistributionAreaChart.class, - // colorizers - JavaColorizerFormat.class, + // colorizers + JavaColorizerFormat.class, - // batch - ProfileSensor.class, - ProfileEventsSensor.class, - ProjectLinksSensor.class, - UnitTestDecorator.class, - VersionEventsSensor.class, - CheckAlertThresholds.class, - GenerateAlertEvents.class, - ViolationsDecorator.class, - WeightedViolationsDecorator.class, - ViolationsDensityDecorator.class, - LineCoverageDecorator.class, - CoverageDecorator.class, - BranchCoverageDecorator.class, - ItLineCoverageDecorator.class, - ItCoverageDecorator.class, - ItBranchCoverageDecorator.class, - ApplyProjectRolesDecorator.class, - ExcludedResourceFilter.class, - CommentDensityDecorator.class, - NoSonarFilter.class, - DirectoriesDecorator.class, - FilesDecorator.class, - ReviewNotifications.class, - ReviewWorkflowDecorator.class, - ReferenceAnalysis.class, - ManualMeasureDecorator.class, - ManualViolationInjector.class, - ViolationSeverityUpdater.class, - IndexProjectPostJob.class, - ReviewsMeasuresDecorator.class, + // batch + ProfileSensor.class, + ProfileEventsSensor.class, + ProjectLinksSensor.class, + UnitTestDecorator.class, + VersionEventsSensor.class, + CheckAlertThresholds.class, + GenerateAlertEvents.class, + ViolationsDecorator.class, + WeightedViolationsDecorator.class, + ViolationsDensityDecorator.class, + LineCoverageDecorator.class, + CoverageDecorator.class, + BranchCoverageDecorator.class, + ItLineCoverageDecorator.class, + ItCoverageDecorator.class, + ItBranchCoverageDecorator.class, + DefaultResourcePermissioning.class, + ApplyProjectRolesDecorator.class, + ExcludedResourceFilter.class, + CommentDensityDecorator.class, + NoSonarFilter.class, + DirectoriesDecorator.class, + FilesDecorator.class, + ReviewNotifications.class, + ReviewWorkflowDecorator.class, + ReferenceAnalysis.class, + ManualMeasureDecorator.class, + ManualViolationInjector.class, + ViolationSeverityUpdater.class, + IndexProjectPostJob.class, + ReviewsMeasuresDecorator.class, - // time machine - TendencyDecorator.class, - VariationDecorator.class, - ViolationTrackingDecorator.class, - ViolationPersisterDecorator.class, - NewViolationsDecorator.class, - TimeMachineConfigurationPersister.class, - NewCoverageFileAnalyzer.class, - NewItCoverageFileAnalyzer.class, - NewCoverageAggregator.class); + // time machine + TendencyDecorator.class, + VariationDecorator.class, + ViolationTrackingDecorator.class, + ViolationPersisterDecorator.class, + NewViolationsDecorator.class, + TimeMachineConfigurationPersister.class, + NewCoverageFileAnalyzer.class, + NewItCoverageFileAnalyzer.class, + NewCoverageAggregator.class); } } diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/security/ApplyProjectRolesDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/security/ApplyProjectRolesDecorator.java index b6fdab34637..ba0e975295e 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/security/ApplyProjectRolesDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/security/ApplyProjectRolesDecorator.java @@ -21,21 +21,17 @@ package org.sonar.plugins.core.security; import org.sonar.api.batch.Decorator; import org.sonar.api.batch.DecoratorContext; -import org.sonar.api.database.DatabaseSession; import org.sonar.api.resources.Project; import org.sonar.api.resources.Qualifiers; import org.sonar.api.resources.Resource; +import org.sonar.api.security.ResourcePermissioning; public class ApplyProjectRolesDecorator implements Decorator { - private RoleManager roleManager; + private final ResourcePermissioning resourcePermissioning; - ApplyProjectRolesDecorator(RoleManager roleManager) { - this.roleManager = roleManager; - } - - public ApplyProjectRolesDecorator(DatabaseSession session) { - this.roleManager = new RoleManager(session); + public ApplyProjectRolesDecorator(ResourcePermissioning resourcePermissioning) { + this.resourcePermissioning = resourcePermissioning; } public boolean shouldExecuteOnProject(Project project) { @@ -44,29 +40,15 @@ public class ApplyProjectRolesDecorator implements Decorator { public void decorate(Resource resource, DecoratorContext context) { if (shouldDecorateResource(resource)) { - Project project = (Project) resource; - roleManager.affectDefaultRolesToResource(project.getId()); + resourcePermissioning.grantDefaultPermissions(resource); } } private boolean shouldDecorateResource(Resource resource) { - if (isProject(resource)) { - Project project = (Project) resource; - return project.getId() != null && countRoles(project.getId()) == 0; - } - return false; + return resource.getId() != null && isProject(resource) && !resourcePermissioning.hasPermissions(resource); } private boolean isProject(Resource resource) { - if (Qualifiers.PROJECT.equals(resource.getQualifier()) || - Qualifiers.VIEW.equals(resource.getQualifier()) || - Qualifiers.SUBVIEW.equals(resource.getQualifier())) { - return resource instanceof Project; - } - return false; - } - - private int countRoles(int resourceId) { - return roleManager.getUserRoles(resourceId).size() + roleManager.getGroupRoles(resourceId).size(); + return Qualifiers.PROJECT.equals(resource.getQualifier()) || Qualifiers.VIEW.equals(resource.getQualifier()); } } diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/security/DefaultResourcePermissioning.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/security/DefaultResourcePermissioning.java new file mode 100644 index 00000000000..db88d0643a2 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/security/DefaultResourcePermissioning.java @@ -0,0 +1,167 @@ +/* + * 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.Properties; +import org.sonar.api.Property; +import org.sonar.api.config.Settings; +import org.sonar.api.resources.Resource; +import org.sonar.api.security.DefaultGroups; +import org.sonar.api.security.ResourcePermissioning; +import org.sonar.api.web.UserRole; +import org.sonar.core.persistence.MyBatis; +import org.sonar.core.user.*; + +/** + * @since 3.2 + */ +@Properties({ + @Property(key = "sonar.role." + UserRole.ADMIN + ".TRK.defaultGroups", + name = "Default groups for project administrators", + defaultValue = DefaultGroups.ADMINISTRATORS, + global = false, + project = false), + @Property(key = "sonar.role." + UserRole.USER + ".TRK.defaultGroups", + name = "Default groups for project users", + defaultValue = DefaultGroups.USERS + "," + DefaultGroups.ANYONE, + global = false, + project = false), + @Property(key = "sonar.role." + UserRole.CODEVIEWER + ".TRK.defaultGroups", + name = "Default groups for project code viewers", + defaultValue = DefaultGroups.USERS + "," + DefaultGroups.ANYONE, + global = false, + project = false) +}) +public class DefaultResourcePermissioning implements ResourcePermissioning, BatchExtension { + + private final Settings settings; + private final MyBatis myBatis; + + public DefaultResourcePermissioning(Settings settings, MyBatis myBatis) { + this.settings = settings; + this.myBatis = myBatis; + } + + public boolean hasPermissions(Resource resource) { + if (resource.getId() != null) { + SqlSession session = myBatis.openSession(); + try { + RoleMapper roleMapper = session.getMapper(RoleMapper.class); + Long resourceId = new Long(resource.getId()); + return roleMapper.countGroupRoles(resourceId) + roleMapper.countUserRoles(resourceId) > 0; + + } finally { + MyBatis.closeQuietly(session); + } + } + return false; + } + + public void addUserPermissions(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(new Long(resource.getId())); + session.getMapper(RoleMapper.class).insertUserRole(userRole); + session.commit(); + } + } finally { + MyBatis.closeQuietly(session); + } + } + } + + public void addGroupPermissions(Resource resource, String groupName, String role) { + if (resource.getId() != null) { + SqlSession session = myBatis.openSession(); + try { + GroupRoleDto groupRole = new GroupRoleDto() + .setRole(role) + .setResourceId(new Long(resource.getId())); + if (DefaultGroups.isAnyone(groupName)) { + session.getMapper(RoleMapper.class).insertGroupRole(groupRole); + session.commit(); + } else { + GroupDto group = session.getMapper(UserMapper.class).selectGroupByName(groupName); + if (group != null) { + session.getMapper(RoleMapper.class).insertGroupRole(groupRole.setGroupId(group.getId())); + session.commit(); + } + } + } finally { + MyBatis.closeQuietly(session); + } + } + } + + public void grantDefaultPermissions(Resource resource) { + if (resource.getId() != null) { + SqlSession session = myBatis.openSession(); + try { + removePermissions(resource, session); + grantDefaultPermissions(resource, UserRole.ADMIN, session); + grantDefaultPermissions(resource, UserRole.USER, session); + grantDefaultPermissions(resource, UserRole.CODEVIEWER, session); + session.commit(); + } finally { + MyBatis.closeQuietly(session); + } + } + } + + private void removePermissions(Resource resource, SqlSession session) { + Long resourceId = new Long(resource.getId()); + RoleMapper mapper = session.getMapper(RoleMapper.class); + mapper.deleteGroupRolesByResourceId(resourceId); + mapper.deleteUserRolesByResourceId(resourceId); + } + + private void grantDefaultPermissions(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(new Long(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(new Long(resource.getId()))); + } + } + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/security/RoleManager.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/security/RoleManager.java deleted file mode 100644 index d8e4f7a4192..00000000000 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/security/RoleManager.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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.commons.lang.StringUtils; -import org.sonar.api.database.DatabaseSession; -import org.sonar.api.security.GroupRole; -import org.sonar.api.security.UserRole; - -import javax.persistence.Query; -import java.util.List; - -/** - * @since 1.12 - */ -public class RoleManager { - - protected static final String DEFAULT_ROLE_PREFIX = "default-"; - private DatabaseSession session; - - public RoleManager(DatabaseSession session) { - this.session = session; - } - - public void affectDefaultRolesToResource(int resourceId) { - for (UserRole defaultRole : getDefaultUserRoles()) { - session.save(createResourceRoleFromDefault(defaultRole, resourceId)); - } - for (GroupRole defaultRole : getDefaultGroupRoles()) { - session.save(createResourceRoleFromDefault(defaultRole, resourceId)); - } - session.commit(); - } - - public List getUserRoles(int resourceId) { - return session.getResults(UserRole.class, "resourceId", resourceId); - } - - public List getGroupRoles(int resourceId) { - return session.getResults(GroupRole.class, "resourceId", resourceId); - } - - protected List getDefaultUserRoles() { - final Query query = session.createQuery("from " + UserRole.class.getSimpleName() + " ur where ur.resourceId is null and ur.role like '" + DEFAULT_ROLE_PREFIX + "%'"); - return query.getResultList(); - } - - protected List getDefaultGroupRoles() { - final Query query = session.createQuery("from " + GroupRole.class.getSimpleName() + " gr where gr.resourceId is null and gr.role like '" + DEFAULT_ROLE_PREFIX + "%'"); - return query.getResultList(); - } - - protected UserRole createResourceRoleFromDefault(UserRole defaultUserRole, int resourceId) { - final UserRole result = new UserRole(); - result.setRole(convertDefaultRoleName(defaultUserRole.getRole())); - result.setResourceId(resourceId); - result.setUserId(defaultUserRole.getUserId()); - return result; - } - - protected GroupRole createResourceRoleFromDefault(GroupRole defaultUserRole, int resourceId) { - final GroupRole result = new GroupRole(); - result.setRole(convertDefaultRoleName(defaultUserRole.getRole())); - result.setResourceId(resourceId); - result.setGroupId(defaultUserRole.getGroupId()); - return result; - } - - protected static String convertDefaultRoleName(String defaultRoleName) { - return StringUtils.substringAfter(defaultRoleName, DEFAULT_ROLE_PREFIX); - } -} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/security/ApplyProjectRolesDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/security/ApplyProjectRolesDecoratorTest.java index 4a703632d52..cd212425246 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/security/ApplyProjectRolesDecoratorTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/security/ApplyProjectRolesDecoratorTest.java @@ -22,33 +22,30 @@ package org.sonar.plugins.core.security; import org.junit.Before; import org.junit.Test; import org.sonar.api.resources.Project; -import org.sonar.api.security.GroupRole; - -import java.util.ArrayList; -import java.util.Arrays; +import org.sonar.api.security.ResourcePermissioning; import static org.mockito.Mockito.*; public class ApplyProjectRolesDecoratorTest { - private RoleManager roleManager; + private ResourcePermissioning resourcePermissioning; private ApplyProjectRolesDecorator decorator; @Before public void before() { - roleManager = mock(RoleManager.class); - decorator = new ApplyProjectRolesDecorator(roleManager); + resourcePermissioning = mock(ResourcePermissioning.class); + decorator = new ApplyProjectRolesDecorator(resourcePermissioning); } @Test - public void doNotApplySecurityWhenExistingRoles() { + public void doNotApplySecurityWhenExistingPermissions() { Project project = new Project("project"); project.setId(10); - when(roleManager.getGroupRoles(10)).thenReturn(Arrays.asList(new GroupRole())); + when(resourcePermissioning.hasPermissions(project)).thenReturn(true); decorator.decorate(project, null); - verify(roleManager, never()).affectDefaultRolesToResource(anyInt()); + verify(resourcePermissioning, never()).grantDefaultPermissions(project); } @Test @@ -56,23 +53,22 @@ public class ApplyProjectRolesDecoratorTest { Project project = new Project("project"); Project module = new Project("module").setParent(project); module.setId(10); - - when(roleManager.getGroupRoles(10)).thenReturn(Arrays.asList()); + when(resourcePermissioning.hasPermissions(project)).thenReturn(false); decorator.decorate(module, null); - verify(roleManager, never()).affectDefaultRolesToResource(anyInt()); + verify(resourcePermissioning, never()).grantDefaultPermissions(module); } @Test - public void applySecurityWhenNoRoles() { + public void applySecurityWhenNoPermissions() { Project project = new Project("project"); project.setId(10); - when(roleManager.getGroupRoles(10)).thenReturn(new ArrayList()); + when(resourcePermissioning.hasPermissions(project)).thenReturn(false); decorator.decorate(project, null); - verify(roleManager).affectDefaultRolesToResource(10); + verify(resourcePermissioning).grantDefaultPermissions(project); } } diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/security/DefaultResourcePermissioningTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/security/DefaultResourcePermissioningTest.java new file mode 100644 index 00000000000..6c0d86cd088 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/security/DefaultResourcePermissioningTest.java @@ -0,0 +1,132 @@ +/* + * 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.PropertyDefinitions; +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 DefaultResourcePermissioningTest extends AbstractDaoTestCase { + + private Resource project = new Project("project").setId(123); + + @Test + public void addGroupPermissions() { + setupData("addGroupPermissions"); + + DefaultResourcePermissioning permissioning = new DefaultResourcePermissioning(new Settings(), getMyBatis()); + permissioning.addGroupPermissions(project, "sonar-administrators", "admin"); + + checkTables("addGroupPermissions", "group_roles"); + } + + @Test + public void addGroupPermissions_anyone() { + setupData("addGroupPermissions_anyone"); + + DefaultResourcePermissioning permissioning = new DefaultResourcePermissioning(new Settings(), getMyBatis()); + permissioning.addGroupPermissions(project, DefaultGroups.ANYONE, "admin"); + + checkTables("addGroupPermissions_anyone", "group_roles"); + } + + @Test + public void addGroupPermissions_ignore_if_group_not_found() { + setupData("addGroupPermissions_ignore_if_group_not_found"); + + DefaultResourcePermissioning permissioning = new DefaultResourcePermissioning(new Settings(), getMyBatis()); + permissioning.addGroupPermissions(project, "not_found", "admin"); + + checkTables("addGroupPermissions_ignore_if_group_not_found", "group_roles"); + } + + @Test + public void addGroupPermissions_ignore_if_not_persisted() { + setupData("addGroupPermissions_ignore_if_not_persisted"); + + DefaultResourcePermissioning permissioning = new DefaultResourcePermissioning(new Settings(), getMyBatis()); + Project resourceWithoutId = new Project(""); + permissioning.addGroupPermissions(resourceWithoutId, "sonar-users", "admin"); + + checkTables("addGroupPermissions_ignore_if_not_persisted", "group_roles"); + } + + @Test + public void grantDefaultPermissions() { + setupData("grantDefaultPermissions"); + + Settings settings = new Settings(new PropertyDefinitions(DefaultResourcePermissioning.class)); + DefaultResourcePermissioning permissioning = new DefaultResourcePermissioning(settings, getMyBatis()); + permissioning.grantDefaultPermissions(project); + + checkTables("grantDefaultPermissions", "user_roles", "group_roles"); + } + + @Test + public void grantDefaultPermissions_unknown_group() { + setupData("grantDefaultPermissions_unknown_group"); + + Settings settings = new Settings(); + settings.setProperty("sonar.role.admin.TRK.defaultGroups", "sonar-administrators,unknown"); + DefaultResourcePermissioning permissioning = new DefaultResourcePermissioning(settings, getMyBatis()); + permissioning.grantDefaultPermissions(project); + + checkTables("grantDefaultPermissions_unknown_group", "group_roles"); + } + + @Test + public void grantDefaultPermissions_users() { + setupData("grantDefaultPermissions_users"); + + Settings settings = new Settings(); + settings.setProperty("sonar.role.admin.TRK.defaultUsers", "marius,disabled,notfound"); + DefaultResourcePermissioning permissioning = new DefaultResourcePermissioning(settings, getMyBatis()); + permissioning.grantDefaultPermissions(project); + + checkTables("grantDefaultPermissions_users", "user_roles"); + } + + @Test + public void hasPermissions() { + setupData("hasPermissions"); + DefaultResourcePermissioning permissioning = new DefaultResourcePermissioning(new Settings(), getMyBatis()); + + // no groups and at least one user + assertThat(permissioning.hasPermissions(new Project("only_users").setId(1))).isTrue(); + + // no users and at least one group + assertThat(permissioning.hasPermissions(new Project("only_groups").setId(2))).isTrue(); + + // groups and users + assertThat(permissioning.hasPermissions(new Project("groups_and_users").setId(3))).isTrue(); + + // no groups, no users + assertThat(permissioning.hasPermissions(new Project("no_groups_no_users").setId(4))).isFalse(); + + // does not exist + assertThat(permissioning.hasPermissions(new Project("not_found"))).isFalse(); + } +} \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/security/RoleManagerTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/security/RoleManagerTest.java deleted file mode 100644 index 0a361240201..00000000000 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/security/RoleManagerTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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.jpa.test.AbstractDbUnitTestCase; - -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -public class RoleManagerTest extends AbstractDbUnitTestCase { - - @Test - public void affectDefaultRolesToResource() { - setupData("affectDefaultRolesToResource"); - new RoleManager(getSession()).affectDefaultRolesToResource(10); - checkTables("affectDefaultRolesToResource", "user_roles", "group_roles"); - } - - @Test - public void affectZeroDefaultRolesToResource() { - setupData("affectZeroDefaultRolesToResource"); - new RoleManager(getSession()).affectDefaultRolesToResource(10); - checkTables("affectZeroDefaultRolesToResource", "user_roles", "group_roles"); - } - - @Test - public void affectAnyoneDefaultRoleToResource() { - setupData("affectAnyoneDefaultRoleToResource"); - new RoleManager(getSession()).affectDefaultRolesToResource(10); - checkTables("affectAnyoneDefaultRoleToResource", "group_roles"); - } - - @Test - public void convertDefaultRoleName() { - assertThat(RoleManager.convertDefaultRoleName(RoleManager.DEFAULT_ROLE_PREFIX + "admin"), is("admin")); - } -} diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/addGroupPermissions-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/addGroupPermissions-result.xml new file mode 100644 index 00000000000..db7b21199a5 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/addGroupPermissions-result.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/addGroupPermissions.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/addGroupPermissions.xml new file mode 100644 index 00000000000..6a4d9c92410 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/addGroupPermissions.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/addGroupPermissions_anyone-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/addGroupPermissions_anyone-result.xml new file mode 100644 index 00000000000..4b48bf9e59a --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/addGroupPermissions_anyone-result.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/addGroupPermissions_anyone.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/addGroupPermissions_anyone.xml new file mode 100644 index 00000000000..6a4d9c92410 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/addGroupPermissions_anyone.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/addGroupPermissions_ignore_if_group_not_found-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/addGroupPermissions_ignore_if_group_not_found-result.xml new file mode 100644 index 00000000000..78695dd52b2 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/addGroupPermissions_ignore_if_group_not_found-result.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/addGroupPermissions_ignore_if_group_not_found.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/addGroupPermissions_ignore_if_group_not_found.xml new file mode 100644 index 00000000000..78695dd52b2 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/addGroupPermissions_ignore_if_group_not_found.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/addGroupPermissions_ignore_if_not_persisted-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/addGroupPermissions_ignore_if_not_persisted-result.xml new file mode 100644 index 00000000000..78695dd52b2 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/addGroupPermissions_ignore_if_not_persisted-result.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/addGroupPermissions_ignore_if_not_persisted.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/addGroupPermissions_ignore_if_not_persisted.xml new file mode 100644 index 00000000000..78695dd52b2 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/addGroupPermissions_ignore_if_not_persisted.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/grantDefaultPermissions-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/grantDefaultPermissions-result.xml new file mode 100644 index 00000000000..23b0c67e69c --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/grantDefaultPermissions-result.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/grantDefaultPermissions.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/grantDefaultPermissions.xml new file mode 100644 index 00000000000..21a4dda2ccf --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/grantDefaultPermissions.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/grantDefaultPermissions_unknown_group-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/grantDefaultPermissions_unknown_group-result.xml new file mode 100644 index 00000000000..ef56a12934c --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/grantDefaultPermissions_unknown_group-result.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/grantDefaultPermissions_unknown_group.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/grantDefaultPermissions_unknown_group.xml new file mode 100644 index 00000000000..21a4dda2ccf --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/grantDefaultPermissions_unknown_group.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/grantDefaultPermissions_users-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/grantDefaultPermissions_users-result.xml new file mode 100644 index 00000000000..caff65f9e21 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/grantDefaultPermissions_users-result.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/grantDefaultPermissions_users.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/grantDefaultPermissions_users.xml new file mode 100644 index 00000000000..7c5f6c5d347 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/grantDefaultPermissions_users.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/hasPermissions.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/hasPermissions.xml new file mode 100644 index 00000000000..3d5f9a5ecf2 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/DefaultResourcePermissioningTest/hasPermissions.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectAnyoneDefaultRoleToResource-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectAnyoneDefaultRoleToResource-result.xml deleted file mode 100644 index 28a4c30bb5c..00000000000 --- a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectAnyoneDefaultRoleToResource-result.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectAnyoneDefaultRoleToResource.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectAnyoneDefaultRoleToResource.xml deleted file mode 100644 index 59af13b6b19..00000000000 --- a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectAnyoneDefaultRoleToResource.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectDefaultRolesToResource-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectDefaultRolesToResource-result.xml deleted file mode 100644 index ecb82d497a1..00000000000 --- a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectDefaultRolesToResource-result.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectDefaultRolesToResource.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectDefaultRolesToResource.xml deleted file mode 100644 index a6565eeea01..00000000000 --- a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectDefaultRolesToResource.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectZeroDefaultRolesToResource-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectZeroDefaultRolesToResource-result.xml deleted file mode 100644 index 30ce5f48597..00000000000 --- a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectZeroDefaultRolesToResource-result.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectZeroDefaultRolesToResource.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectZeroDefaultRolesToResource.xml deleted file mode 100644 index 66f2aa19f2b..00000000000 --- a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectZeroDefaultRolesToResource.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/sharedFixture.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/sharedFixture.xml deleted file mode 100644 index 861917acf7c..00000000000 --- a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/sharedFixture.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - \ No newline at end of file diff --git a/plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties b/plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties index c0ff95b6f0a..2633daf30ee 100644 --- a/plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties +++ b/plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties @@ -306,12 +306,12 @@ duplications.page=Duplications email_configuration.page=Email Settings event_categories.page=Event Categories filters.page=Filters -global_roles.page=Global Roles +system_administrators.page=System Administrators manual_metrics.page=Manual Metrics manual_measures.page=Manual Measures manual_rules.page=Manual Rules my_profile.page=My Profile -project_roles.page=Project Roles +roles.page=Roles project_settings.page=Settings project_links.page=Links project_exclusions.page=Exclusions @@ -328,7 +328,6 @@ violations.page=Violations violations_drilldown.page=Violations Drilldown update_center.page=Update Center lcom4_viewer.page=LCOM4 -dependencies.page=Dependencies resource_deletion.page={0} Deletion update_key.page=Update Key project_quality_profile.page=Quality Profile diff --git a/pom.xml b/pom.xml index a59a5682301..243e8912258 100644 --- a/pom.xml +++ b/pom.xml @@ -497,6 +497,7 @@ random -Xmx256m -Djava.awt.headless=true + true ${project.build.directory} diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java b/sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java index 67cbc72d58b..fd00b5e92df 100644 --- a/sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java +++ b/sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java @@ -34,7 +34,6 @@ import org.sonar.core.review.ReviewDao; import org.sonar.core.rule.RuleDao; import org.sonar.core.template.LoadedTemplateDao; import org.sonar.core.user.AuthorDao; -import org.sonar.core.user.RoleDao; import org.sonar.core.user.UserDao; import java.util.List; @@ -60,7 +59,6 @@ public final class DaoUtils { ResourceKeyUpdaterDao.class, ReviewCommentDao.class, ReviewDao.class, - RoleDao.class, RuleDao.class, UserDao.class); } diff --git a/sonar-core/src/main/java/org/sonar/core/user/RoleDao.java b/sonar-core/src/main/java/org/sonar/core/user/RoleDao.java deleted file mode 100644 index 164a72e3913..00000000000 --- a/sonar-core/src/main/java/org/sonar/core/user/RoleDao.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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.user; - -import org.apache.ibatis.session.SqlSession; -import org.sonar.core.persistence.MyBatis; - -import java.util.Collection; - -/** - * @since 3.2 - */ -public class RoleDao { - private final MyBatis mybatis; - - public RoleDao(MyBatis mybatis) { - this.mybatis = mybatis; - } - - public RoleDao insertGroupRoles(Collection groupRoles) { - SqlSession session = mybatis.openBatchSession(); - try { - RoleMapper mapper = session.getMapper(RoleMapper.class); - for (GroupRoleDto groupRole : groupRoles) { - mapper.insertGroupRole(groupRole); - } - session.commit(); - } finally { - MyBatis.closeQuietly(session); - } - return this; - } - - public RoleDao insertUserRoles(Collection userRoles) { - SqlSession session = mybatis.openBatchSession(); - try { - RoleMapper mapper = session.getMapper(RoleMapper.class); - for (UserRoleDto userRole : userRoles) { - mapper.insertUserRole(userRole); - } - session.commit(); - } finally { - MyBatis.closeQuietly(session); - } - return this; - } -} diff --git a/sonar-core/src/main/java/org/sonar/core/user/RoleMapper.java b/sonar-core/src/main/java/org/sonar/core/user/RoleMapper.java index bd2b45ff9eb..79e83c766be 100644 --- a/sonar-core/src/main/java/org/sonar/core/user/RoleMapper.java +++ b/sonar-core/src/main/java/org/sonar/core/user/RoleMapper.java @@ -28,4 +28,11 @@ public interface RoleMapper { void insertUserRole(UserRoleDto userRole); + void deleteGroupRolesByResourceId(Long resourceId); + + void deleteUserRolesByResourceId(Long resourceId); + + int countGroupRoles(Long resourceId); + + int countUserRoles(Long resourceId); } diff --git a/sonar-core/src/main/resources/META-INF/persistence.xml b/sonar-core/src/main/resources/META-INF/persistence.xml index 357801c27b9..c8ac4392caf 100644 --- a/sonar-core/src/main/resources/META-INF/persistence.xml +++ b/sonar-core/src/main/resources/META-INF/persistence.xml @@ -21,8 +21,6 @@ org.sonar.api.database.model.ResourceModel org.sonar.api.database.model.SnapshotSource org.sonar.api.database.model.RuleFailureModel - org.sonar.api.security.UserRole - org.sonar.api.security.GroupRole org.sonar.api.rules.Rule org.sonar.api.rules.RuleParam org.sonar.api.resources.ProjectLink diff --git a/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql b/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql index 2493292440f..804f1f830a0 100644 --- a/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql +++ b/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql @@ -7,11 +7,6 @@ ALTER TABLE GROUPS ALTER COLUMN ID RESTART WITH 3; INSERT INTO GROUP_ROLES(ID, GROUP_ID, RESOURCE_ID, ROLE) VALUES (1, 1, null, 'admin'); ALTER TABLE GROUP_ROLES ALTER COLUMN ID RESTART WITH 2; -INSERT INTO PROPERTIES(ID, PROP_KEY, RESOURCE_ID, TEXT_VALUE, USER_ID) VALUES (1, 'sonar.role.admin.project.defaultGroups', null, 'sonar-administrators', null); -INSERT INTO PROPERTIES(ID, PROP_KEY, RESOURCE_ID, TEXT_VALUE, USER_ID) VALUES (2, 'sonar.role.user.project.defaultGroups', null, 'sonar-users,Anyone', null); -INSERT INTO PROPERTIES(ID, PROP_KEY, RESOURCE_ID, TEXT_VALUE, USER_ID) VALUES (3, 'sonar.role.codeviewer.project.defaultGroups', null, 'sonar-users,Anyone', null); -ALTER TABLE PROPERTIES ALTER COLUMN ID RESTART WITH 4; - INSERT INTO GROUPS_USERS(USER_ID, GROUP_ID) VALUES (1, 1); INSERT INTO GROUPS_USERS(USER_ID, GROUP_ID) VALUES (1, 2); diff --git a/sonar-core/src/main/resources/org/sonar/core/user/RoleMapper.xml b/sonar-core/src/main/resources/org/sonar/core/user/RoleMapper.xml index 753f13ea520..be2fad12465 100644 --- a/sonar-core/src/main/resources/org/sonar/core/user/RoleMapper.xml +++ b/sonar-core/src/main/resources/org/sonar/core/user/RoleMapper.xml @@ -12,4 +12,22 @@ INSERT INTO user_roles (user_id, resource_id, role) VALUES (#{userId, jdbcType=INTEGER}, #{resourceId, jdbcType=INTEGER}, #{role, jdbcType=VARCHAR}) + + + delete from group_roles where resource_id=#{id} + + + + delete from user_roles where resource_id=#{id} + + + + + diff --git a/sonar-core/src/test/java/org/sonar/core/user/RoleDaoTest.java b/sonar-core/src/test/java/org/sonar/core/user/RoleDaoTest.java deleted file mode 100644 index 939046d9abc..00000000000 --- a/sonar-core/src/test/java/org/sonar/core/user/RoleDaoTest.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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.user; - -import org.junit.Before; -import org.junit.Test; -import org.sonar.core.persistence.DaoTestCase; - -import java.util.Arrays; -import java.util.Collection; - - -public class RoleDaoTest extends DaoTestCase { - - private RoleDao dao; - - @Before - public void setUp() { - dao = new RoleDao(getMyBatis()); - } - - @Test - public void insertGroupRoles() { - setupData("insertGroupRoles"); - - Collection groupRoles = Arrays.asList( - new GroupRoleDto().setGroupId(100L).setResourceId(200L).setRole("admin"), - - // no group id => Anyone - new GroupRoleDto().setResourceId(200L).setRole("user") - ); - dao.insertGroupRoles(groupRoles); - - checkTables("insertGroupRoles", "group_roles"); - } - - @Test - public void insertUserRoles() { - setupData("insertUserRoles"); - - Collection userRoles = Arrays.asList( - new UserRoleDto().setUserId(100L).setResourceId(200L).setRole("admin"), - new UserRoleDto().setUserId(101L).setResourceId(200L).setRole("user") - ); - dao.insertUserRoles(userRoles); - - checkTables("insertUserRoles", "user_roles"); - } -} diff --git a/sonar-core/src/test/java/org/sonar/core/user/UserDaoTest.java b/sonar-core/src/test/java/org/sonar/core/user/UserDaoTest.java index 6015f5ee196..8fd2516aa29 100644 --- a/sonar-core/src/test/java/org/sonar/core/user/UserDaoTest.java +++ b/sonar-core/src/test/java/org/sonar/core/user/UserDaoTest.java @@ -21,12 +21,12 @@ package org.sonar.core.user; import org.junit.Before; import org.junit.Test; -import org.sonar.core.persistence.DaoTestCase; +import org.sonar.core.persistence.AbstractDaoTestCase; import static org.fest.assertions.Assertions.assertThat; -public class UserDaoTest extends DaoTestCase { +public class UserDaoTest extends AbstractDaoTestCase { private UserDao dao; diff --git a/sonar-core/src/test/resources/org/sonar/core/user/RoleDaoTest/insertGroupRoles-result.xml b/sonar-core/src/test/resources/org/sonar/core/user/RoleDaoTest/insertGroupRoles-result.xml deleted file mode 100644 index 72fd8e47bdf..00000000000 --- a/sonar-core/src/test/resources/org/sonar/core/user/RoleDaoTest/insertGroupRoles-result.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/core/user/RoleDaoTest/insertGroupRoles.xml b/sonar-core/src/test/resources/org/sonar/core/user/RoleDaoTest/insertGroupRoles.xml deleted file mode 100644 index a3306c70d7b..00000000000 --- a/sonar-core/src/test/resources/org/sonar/core/user/RoleDaoTest/insertGroupRoles.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/core/user/RoleDaoTest/insertUserRoles-result.xml b/sonar-core/src/test/resources/org/sonar/core/user/RoleDaoTest/insertUserRoles-result.xml deleted file mode 100644 index 253a46b3faf..00000000000 --- a/sonar-core/src/test/resources/org/sonar/core/user/RoleDaoTest/insertUserRoles-result.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/core/user/RoleDaoTest/insertUserRoles.xml b/sonar-core/src/test/resources/org/sonar/core/user/RoleDaoTest/insertUserRoles.xml deleted file mode 100644 index a3306c70d7b..00000000000 --- a/sonar-core/src/test/resources/org/sonar/core/user/RoleDaoTest/insertUserRoles.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/security/DefaultGroups.java b/sonar-plugin-api/src/main/java/org/sonar/api/security/DefaultGroups.java new file mode 100644 index 00000000000..aa426029645 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/security/DefaultGroups.java @@ -0,0 +1,38 @@ +/* + * 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.api.security; + +/** + * Name of the default user groups + * + * @since 3.2 + */ +public final class DefaultGroups { + private DefaultGroups() { + } + + public static final String ANYONE = "Anyone"; + public static final String ADMINISTRATORS = "sonar-administrators"; + public static final String USERS = "sonar-users"; + + public static boolean isAnyone(String groupName) { + return ANYONE.equalsIgnoreCase(groupName); + } +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/security/GroupRole.java b/sonar-plugin-api/src/main/java/org/sonar/api/security/GroupRole.java deleted file mode 100644 index 70e17ecbe95..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/security/GroupRole.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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.api.security; - -import org.apache.commons.lang.builder.ReflectionToStringBuilder; -import org.apache.commons.lang.builder.ToStringStyle; -import org.sonar.api.database.BaseIdentifiable; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; - -/** - * @since 1.12 - */ -@Entity -@Table(name = "group_roles") -public class GroupRole extends BaseIdentifiable { - - public static final Integer ANYONE_GROUP_ID = null; - - @Column(name = "group_id") - private Integer groupId; - - @Column(name = "role") - private String role; - - @Column(name = "resource_id") - private Integer resourceId; - - public static GroupRole buildGlobalRole(Integer groupId, String role) { - return new GroupRole().setGroupId(groupId).setRole(role); - } - - public static GroupRole buildResourceRole(Integer groupId, String role, Integer resourceId) { - return new GroupRole().setGroupId(groupId).setRole(role).setResourceId(resourceId); - } - - public Integer getGroupId() { - return groupId; - } - - public GroupRole setGroupId(Integer groupId) { - this.groupId = groupId; - return this; - } - - public String getRole() { - return role; - } - - public GroupRole setRole(String role) { - this.role = role; - return this; - } - - public Integer getResourceId() { - return resourceId; - } - - public GroupRole setResourceId(Integer resourceId) { - this.resourceId = resourceId; - return this; - } - - public boolean isAnyone() { - return groupId == null; - } - - @Override - public String toString() { - return new ReflectionToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).toString(); - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/security/ResourcePermissioning.java b/sonar-plugin-api/src/main/java/org/sonar/api/security/ResourcePermissioning.java new file mode 100644 index 00000000000..d40e8b7ca29 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/security/ResourcePermissioning.java @@ -0,0 +1,41 @@ +/* + * 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.api.security; + +import org.sonar.api.BatchComponent; +import org.sonar.api.resources.Resource; + +/** + * Grant access to newly created projects. + * + *

This component is not supposed to be called by standard plugins.

+ * + * @since 3.2 + */ +public interface ResourcePermissioning extends BatchComponent { + + boolean hasPermissions(Resource resource); + + void grantDefaultPermissions(Resource resource); + + void addUserPermissions(Resource resource, String login, String role); + + void addGroupPermissions(Resource resource, String groupName, String role); +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/security/UserRole.java b/sonar-plugin-api/src/main/java/org/sonar/api/security/UserRole.java deleted file mode 100644 index 2e9c474fe65..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/security/UserRole.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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.api.security; - -import org.apache.commons.lang.builder.ToStringBuilder; -import org.apache.commons.lang.builder.ToStringStyle; -import org.sonar.api.database.BaseIdentifiable; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; - -/** - * This JPA model maps the table user_roles - * - * @since 1.12 - */ -@Entity -@Table(name = "user_roles") -public class UserRole extends BaseIdentifiable { - - @Column(name = "user_id") - private Integer userId; - - @Column(name = "role") - private String role; - - @Column(name = "resource_id") - private Integer resourceId; - - public UserRole(Integer userId, String role, Integer resourceId) { - this.userId = userId; - this.role = role; - this.resourceId = resourceId; - } - - public UserRole() { - } - - public Integer getUserId() { - return userId; - } - - public UserRole setUserId(Integer userId) { - this.userId = userId; - return this; - } - - public String getRole() { - return role; - } - - public UserRole setRole(String role) { - this.role = role; - return this; - } - - public Integer getResourceId() { - return resourceId; - } - - public UserRole setResourceId(Integer resourceId) { - this.resourceId = resourceId; - return this; - } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/security/DefaultGroupsTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/security/DefaultGroupsTest.java new file mode 100644 index 00000000000..2f1823332d5 --- /dev/null +++ b/sonar-plugin-api/src/test/java/org/sonar/api/security/DefaultGroupsTest.java @@ -0,0 +1,35 @@ +/* + * 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.api.security; + +import org.junit.Test; + +import static org.fest.assertions.Assertions.assertThat; + +public class DefaultGroupsTest { + @Test + public void isAnyone_is_not_case_sensitive() { + assertThat(DefaultGroups.isAnyone("ANYONE")).isTrue(); + assertThat(DefaultGroups.isAnyone("anyone")).isTrue(); + assertThat(DefaultGroups.isAnyone(DefaultGroups.ANYONE)).isTrue(); + + assertThat(DefaultGroups.isAnyone(DefaultGroups.ADMINISTRATORS)).isFalse(); + } +} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/security/GroupRoleTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/security/GroupRoleTest.java deleted file mode 100644 index 57bb695f975..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/security/GroupRoleTest.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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.api.security; - -import org.junit.Test; - -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -public class GroupRoleTest { - - @Test - public void isAnyone() { - GroupRole gr = GroupRole.buildGlobalRole(GroupRole.ANYONE_GROUP_ID, "admin"); - assertThat(gr.isAnyone(), is(true)); - - gr = GroupRole.buildGlobalRole(3, "admin"); - assertThat(gr.isAnyone(), is(false)); - } -} diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/roles_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/roles_controller.rb index 0703ecec5ce..3b879f7448c 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/roles_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/roles_controller.rb @@ -24,7 +24,10 @@ class RolesController < ApplicationController PER_PAGE = 2 before_filter :admin_required - verify :method => :post, :only => [:grant_users, :grant_groups], :redirect_to => {:action => 'global'} + verify :method => :post, :only => [:set_users, :set_groups, :set_default_project_groups, :set_default_project_users], :redirect_to => {:action => 'global'} + + + # GET REQUESTS def global end @@ -38,44 +41,72 @@ class RolesController < ApplicationController end @qualifier = params[:qualifier] || 'TRK' + conditions_sql = 'projects.enabled=:enabled and projects.qualifier=:qualifier and projects.copy_resource_id is null' conditions_values = {:enabled => true, :qualifier => @qualifier} - + joins = nil if params[:q].present? - conditions_sql += ' and projects.id in (select ri.resource_id from resource_index ri where ri.qualifier=:qualifier and ri.kee like :search)' - conditions_values[:search]="#{params[:q].downcase}%" + joins = "INNER JOIN resource_index on resource_index.resource_id=projects.id and resource_index.qualifier=#{ActiveRecord::Base::sanitize(@qualifier)} and resource_index.kee like #{ActiveRecord::Base::sanitize(params[:q] + '%')}" end @pagination = Api::Pagination.new(params) @projects=Project.find(:all, - :include => %w(user_roles group_roles index), + :joins => joins, :conditions => [conditions_sql, conditions_values], - :order => 'resource_index.kee', + :order => 'projects.name', :offset => @pagination.offset, :limit => @pagination.limit) - @pagination.count=Project.count(:conditions => [conditions_sql, conditions_values]) + @pagination.count=Project.count(:joins => joins, :conditions => [conditions_sql, conditions_values]) end def edit_users - @project=Project.by_key(params[:resource]) if !params[:resource].blank? + @project=Project.by_key(params[:resource]) if params[:resource].present? @role = params[:role] end def edit_groups - @project=Project.by_key(params[:resource]) if !params[:resource].blank? + @project=Project.by_key(params[:resource]) if params[:resource].present? @role = params[:role] end - def grant_users + def edit_default_project_groups + bad_request('Missing role') if params[:role].blank? + bad_request('Missing qualifier') if params[:qualifier].blank? + end + + def edit_default_project_users + bad_request('Missing role') if params[:role].blank? + bad_request('Missing qualifier') if params[:qualifier].blank? + end + + # POST REQUESTS + + def set_users + bad_request('Missing role') if params[:role].blank? UserRole.grant_users(params[:users], params[:role], params[:resource]) redirect end - def grant_groups + def set_groups + bad_request('Missing role') if params[:role].blank? GroupRole.grant_groups(params[:groups], params[:role], params[:resource]) redirect end + def set_default_project_groups + bad_request('Missing role') if params[:role].blank? + bad_request('Missing qualifier') if params[:qualifier].blank? + Property.set("sonar.role.#{params[:role]}.#{params[:qualifier]}.defaultGroups", params[:groups].join(',')) + redirect + end + + def set_default_project_users + bad_request('Missing role') if params[:role].blank? + bad_request('Missing qualifier') if params[:qualifier].blank? + Property.set("sonar.role.#{params[:role]}.#{params[:qualifier]}.defaultUsers", params[:users].join(',')) + redirect + end + private def redirect redirect_to(:action => params['redirect'] || 'global', :q => params[:q], :qualifier => params[:qualifier], :page => params[:page]) diff --git a/sonar-server/src/main/webapp/WEB-INF/app/helpers/roles_helper.rb b/sonar-server/src/main/webapp/WEB-INF/app/helpers/roles_helper.rb index f714d49b910..b0750b80f09 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/helpers/roles_helper.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/helpers/roles_helper.rb @@ -18,43 +18,54 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 # module RolesHelper - + def users(role, resource_id=nil) resource_id=(resource_id.blank? ? nil : resource_id.to_i) user_roles=UserRole.find(:all, :include => 'user', :conditions => {:role => role, :resource_id => resource_id}) users = user_roles.map { |ur| ur.user } - Api::Utils.insensitive_sort(users) {|user| user.name} + Api::Utils.insensitive_sort(users) { |user| user.name } end def all_users users = User.find(:all, :conditions => ["active=?", true]) - Api::Utils.insensitive_sort(users) {|user| user.name} + Api::Utils.insensitive_sort(users) { |user| user.name } end def groups(role, resource_id=nil) resource_id=(resource_id.blank? ? nil : resource_id.to_i) group_roles=GroupRole.find(:all, :include => 'group', :conditions => {:role => role, :resource_id => resource_id}) - groups = group_roles.map{|ur| ur.group} - Api::Utils.insensitive_sort(groups) {|group| group ? group.name : ''} + groups = group_roles.map { |ur| ur.group } + Api::Utils.insensitive_sort(groups) { |group| group ? group.name : '' } end def all_groups - [nil].concat(Api::Utils.insensitive_sort(Group.all) {|group| group.name}) + [nil].concat(Api::Utils.insensitive_sort(Group.all) { |group| group.name }) end def group_name(group) group ? group.name : 'Anyone' end + def default_project_groups(role, qualifier) + property_value=(controller.java_facade.getConfigurationValue("sonar.role.#{role}.#{qualifier}.defaultGroups")||'') + Api::Utils.insensitive_sort(property_value.split(',')) + end + + def default_project_users(role, qualifier) + property_value=(controller.java_facade.getConfigurationValue("sonar.role.#{role}.#{qualifier}.defaultUsers") || '') + Api::Utils.insensitive_sort(property_value.split(',')) + end + def role_name(role) - case(role.to_s) - when 'admin' then 'Administrators' - when 'default-admin' then 'Administrators' - when 'user' then 'Users' - when 'default-user' then 'Users' - when 'codeviewer' then 'Code viewers' - when 'default-codeviewer' then 'Code viewers' - else role.to_s + case (role.to_s) + when 'admin' then + 'Administrators' + when 'user' then + 'Users' + when 'codeviewer' then + 'Code viewers' + else + role.to_s end end end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb index 989ec8f92ca..345fb8176b9 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb @@ -99,7 +99,7 @@ <% end %> <% if (@project.project? || @project.view? || @project.subview?) %>
  • - <%= message('project_roles.page') -%>
  • + <%= message('roles.page') -%> <% end %> <% # NOTE: we keep "@project.view? || @project.subview?" in the test for backward compatibility with the Views plugin @@ -149,9 +149,9 @@
  • <%= message('user_groups.page') -%>
  • - <%= message('global_roles.page') -%>
  • + <%= message('system_administrators.page') -%>
  • - <%= message('project_roles.page') -%>
  • + <%= message('roles.page') -%>
  • <%= message('sidebar.system') -%>
  • diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/roles/edit_default_project_groups.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/roles/edit_default_project_groups.html.erb new file mode 100644 index 00000000000..8c688773fe7 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/roles/edit_default_project_groups.html.erb @@ -0,0 +1,54 @@ +<% + granted_groups=default_project_groups(params[:role], params[:qualifier]) + all_groups = ['Anyone'].concat(Api::Utils.insensitive_sort(Group.all.map{|group| group.name})) + ungranted_groups=all_groups - granted_groups +%> +
    » Back
    +

    TO BE DEFINED

    +
    +
    +
    + + + + + + + + + + + + + +
    +

    Ungranted groups

    + +
    +
    +

    +
    + +
    +

    Role: <%= role_name(params[:role]) -%>

    + +
    + +
    + +
    +
    +
    + +
    diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/roles/edit_default_project_users.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/roles/edit_default_project_users.html.erb new file mode 100644 index 00000000000..e69de29bb2d diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/roles/edit_groups.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/roles/edit_groups.html.erb index d62f6f7dd34..45d0213e677 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/roles/edit_groups.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/roles/edit_groups.html.erb @@ -3,17 +3,15 @@ ungranted_groups=all_groups - granted_groups if @project title=h(@project.name) - elsif @role.starts_with?('default-') - title="Default project #{role_name(@role)}" else - title="Global #{role_name(@role)}" + title='System administrators' end %>
    » Back

    <%= title %>


    -
    + diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/roles/edit_users.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/roles/edit_users.html.erb index 295a56ec59e..7782d580f1c 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/roles/edit_users.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/roles/edit_users.html.erb @@ -13,7 +13,7 @@

    <%= title %>


    - + diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/roles/global.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/roles/global.html.erb index 7a97d24d756..6f01618570e 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/roles/global.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/roles/global.html.erb @@ -1,4 +1,4 @@ -

    Global Roles

    +

    <%= message 'system_administrators.page' -%>

    @@ -10,7 +10,7 @@ - +
    Administrators
    Ability to perform all administration functions for the instance: global configuration, personalization of Time Machine and homepage.
    Administrators
    Ability to perform all administration functions for the instance: global configuration and personalization of default dashboards.
    <%= users('admin').map(&:login).join(', ') %> (<%= link_to "select", {:action => 'edit_users', :role => 'admin', :redirect => 'global'}, :class => 'link-action' %>) diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/roles/projects.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/roles/projects.html.erb index 71c871d11fc..cfe4f174958 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/roles/projects.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/roles/projects.html.erb @@ -1,67 +1,66 @@ -

    Default Roles for New <%= @qualifiers.map { |q| message("qualifiers.#{q}") }.join(', ') -%>

    +

    <%= message('roles.page') -%>

    + +<% if @qualifiers.size>1 %> +
      + <% @qualifiers.each do |q| + css_class = (q==@qualifier ? 'selected' : '') + %> +
    • + <%= link_to message("qualifiers.#{q}"), {:action => 'projects', :qualifier => q}, {:class => css_class} -%> +
    • + <% end %> +
    +<% end %> - + - + - + - +
    RoleDefault Permissions For New <%= message("qualifiers.#{@qualifier}") -%> Users Groups
    Administrators
    Ability to perform administration functions for a project by accessing its settings.
    Role: Administrators
    Ability to perform administration functions for a project by accessing its settings.
    - <%= users('default-admin').map(&:login).join(', ') %> - (<%= link_to "select", {:action => 'edit_users', :role => 'default-admin', :redirect => 'projects'}, :class => 'link-action' %>) + <%= default_project_users('admin', @qualifier).join(', ') -%> + (<%= link_to "select", {:action => 'edit_default_project_users', :role => 'admin', :redirect => 'projects', :qualifier => @qualifier}, :class => 'link-action' %>)
    - <%= groups('default-admin').map { |g| group_name(g) }.join(', ') %> - (<%= link_to "select", {:action => 'edit_groups', :role => 'default-admin', :redirect => 'projects'}, :class => 'link-action' %>) + <%= default_project_groups('admin', @qualifier).join(', ') -%> + (<%= link_to "select", {:action => 'edit_default_project_groups', :role => 'admin', :redirect => 'projects', :qualifier => @qualifier}, :class => 'link-action' %>)
    Users
    Ability to navigate through every service of a project, except viewing source code and settings.
    Role: Users
    Ability to navigate through every service of a project, except viewing source code and settings.
    - <%= users('default-user').map(&:login).join(', ') %> - (<%= link_to "select", {:action => 'edit_users', :role => 'default-user', :redirect => 'projects'}, :class => 'link-action' %>) + <%= default_project_users('user', @qualifier).join(', ') -%> + (<%= link_to "select", {:action => 'edit_default_project_users', :role => 'user', :redirect => 'projects', :qualifier => @qualifier}, :class => 'link-action' %>) - <%= groups('default-user').map { |g| group_name(g) }.join(', ') %> - (<%= link_to "select", {:action => 'edit_groups', :role => 'default-user', :redirect => 'projects'}, :class => 'link-action' %>) + <%= default_project_groups('user', @qualifier).join(', ') -%> + (<%= link_to "select", {:action => 'edit_default_project_groups', :role => 'user', :redirect => 'projects', :qualifier => @qualifier}, :class => 'link-action' %>)
    Code viewers
    Ability to view source code of a project.
    Role: Code viewers
    Ability to view source code of a project.
    - <%= users('default-codeviewer').map(&:login).join(', ') %> - (<%= link_to "select", {:action => 'edit_users', :role => 'default-codeviewer', :redirect => 'projects'}, :class => 'link-action' %>) + <%= default_project_users('codeviewer', @qualifier).join(', ') -%> + (<%= link_to "select", {:action => 'edit_default_project_users', :role => 'codeviewer', :redirect => 'projects', :qualifier => @qualifier}, :class => 'link-action' %>) - <%= groups('default-codeviewer').map { |g| group_name(g) }.join(', ') %> - (<%= link_to "select", {:action => 'edit_groups', :role => 'default-codeviewer', :redirect => 'projects'}, :class => 'link-action' %>) + <%= default_project_groups('codeviewer', @qualifier).join(', ') -%> + (<%= link_to "select", {:action => 'edit_default_project_groups', :role => 'codeviewer', :redirect => 'projects', :qualifier => @qualifier}, :class => 'link-action' %>)
    -

    -<% if @qualifiers.size>1 %> -
      - <% @qualifiers.each do |q| - css_class = (q==@qualifier ? 'selected' : '') - %> -
    • - <%= link_to message("qualifiers.#{q}"), {:action => 'projects', :qualifier => q}, {:class => css_class} -%> -
    • - <% end %> -
    -<% else %> -

    <%= message("qualifiers.#{@qualifiers[0]}") -%>

    -<% end %> +

    diff --git a/sonar-server/src/main/webapp/WEB-INF/db/migrate/320_move_default_roles.rb b/sonar-server/src/main/webapp/WEB-INF/db/migrate/320_move_default_roles.rb index a69922188d7..df56495a5f4 100644 --- a/sonar-server/src/main/webapp/WEB-INF/db/migrate/320_move_default_roles.rb +++ b/sonar-server/src/main/webapp/WEB-INF/db/migrate/320_move_default_roles.rb @@ -39,13 +39,13 @@ class MoveDefaultRoles < ActiveRecord::Migration end def self.up - if GroupRole.count==0 - # fresh install - Property.delete_all(['prop_key like ?', 'sonar.role.%']) - Property.create(:prop_key => 'sonar.role.admin.project.defaultGroups', :text_value => 'sonar-administrators') - Property.create(:prop_key => 'sonar.role.user.project.defaultGroups', :text_value => 'sonar-users,Anyone') - Property.create(:prop_key => 'sonar.role.codeviewer.project.defaultGroups', :text_value => 'sonar-users,Anyone') - else + Group.reset_column_information + GroupRole.reset_column_information + User.reset_column_information + UserRole.reset_column_information + Property.reset_column_information + + if GroupRole.count(:conditions => ['role like ?', 'default-%'])>0 # upgrade from version < 3.2. move_groups move_users @@ -74,10 +74,10 @@ class MoveDefaultRoles < ActiveRecord::Migration end groups_per_role.each_pair do |role, groups| - Property.create(:prop_key => "sonar.role.#{role}.project.defaultGroups", :text_value => groups.join(',')) + Property.create(:prop_key => "sonar.role.#{role}.TRK.defaultGroups", :text_value => groups.join(',')) end - #GroupRole.delete_all ['role like ?', 'default-%'] + GroupRole.delete_all ['role like ?', 'default-%'] end def self.move_users @@ -94,9 +94,9 @@ class MoveDefaultRoles < ActiveRecord::Migration end users_per_role.each_pair do |role, users| - Property.create(:prop_key => "sonar.role.#{role}.project.defaultUsers", :text_value => users.join(',')) + Property.create(:prop_key => "sonar.role.#{role}.TRK.defaultUsers", :text_value => users.join(',')) end - #UserRole.delete_all ['role like ?', 'default-%'] + UserRole.delete_all ['role like ?', 'default-%'] end end