@@ -29,6 +29,7 @@ import java.util.Set; | |||
import java.util.function.Predicate; | |||
import java.util.stream.Collectors; | |||
import javax.annotation.Nullable; | |||
import org.sonar.api.config.Configuration; | |||
import org.sonar.api.resources.Qualifiers; | |||
import org.sonar.api.resources.ResourceType; | |||
import org.sonar.api.resources.ResourceTypes; | |||
@@ -60,6 +61,8 @@ import org.sonar.server.ui.PageRepository; | |||
import org.sonar.server.user.UserSession; | |||
import static java.util.Collections.emptySortedSet; | |||
import static org.sonar.api.CoreProperties.CORE_ALLOW_PERMISSION_MANAGEMENT_FOR_PROJECT_ADMINS_DEFAULT_VALUE; | |||
import static org.sonar.api.CoreProperties.CORE_ALLOW_PERMISSION_MANAGEMENT_FOR_PROJECT_ADMINS_PROPERTY; | |||
import static org.sonar.api.measures.CoreMetrics.QUALITY_PROFILES_KEY; | |||
import static org.sonar.api.utils.DateUtils.formatDateTime; | |||
import static org.sonar.api.web.UserRole.ADMIN; | |||
@@ -94,15 +97,17 @@ public class ComponentAction implements NavigationWsAction { | |||
private final UserSession userSession; | |||
private final ComponentFinder componentFinder; | |||
private final QualityGateFinder qualityGateFinder; | |||
private final Configuration config; | |||
public ComponentAction(DbClient dbClient, PageRepository pageRepository, ResourceTypes resourceTypes, UserSession userSession, | |||
ComponentFinder componentFinder, QualityGateFinder qualityGateFinder) { | |||
ComponentFinder componentFinder, QualityGateFinder qualityGateFinder, Configuration config) { | |||
this.dbClient = dbClient; | |||
this.pageRepository = pageRepository; | |||
this.resourceTypes = resourceTypes; | |||
this.userSession = userSession; | |||
this.componentFinder = componentFinder; | |||
this.qualityGateFinder = qualityGateFinder; | |||
this.config = config; | |||
} | |||
@Override | |||
@@ -287,13 +292,16 @@ public class ComponentAction implements NavigationWsAction { | |||
boolean isQualityGateAdmin = userSession.hasPermission(GlobalPermission.ADMINISTER_QUALITY_GATES); | |||
boolean isGlobalAdmin = userSession.hasPermission(GlobalPermission.ADMINISTER); | |||
boolean canBrowseProject = userSession.hasComponentPermission(USER, component); | |||
boolean allowChangingPermissionsByProjectAdmins = config.getBoolean(CORE_ALLOW_PERMISSION_MANAGEMENT_FOR_PROJECT_ADMINS_PROPERTY) | |||
.orElse(CORE_ALLOW_PERMISSION_MANAGEMENT_FOR_PROJECT_ADMINS_DEFAULT_VALUE); | |||
json.prop("showSettings", isProjectAdmin && componentTypeHasProperty(component, PROPERTY_CONFIGURABLE)); | |||
json.prop("showQualityProfiles", isProject && (isProjectAdmin || isQualityProfileAdmin)); | |||
json.prop("showQualityGates", isProject && (isProjectAdmin || isQualityGateAdmin)); | |||
json.prop("showManualMeasures", showManualMeasures); | |||
json.prop("showLinks", isProjectAdmin && isProject); | |||
json.prop("showPermissions", isProjectAdmin && componentTypeHasProperty(component, PROPERTY_HAS_ROLE_POLICY)); | |||
json.prop("showPermissions", isProjectAdmin && componentTypeHasProperty(component, PROPERTY_HAS_ROLE_POLICY) | |||
&& (isGlobalAdmin || allowChangingPermissionsByProjectAdmins)); | |||
json.prop("showHistory", isProjectAdmin && componentTypeHasProperty(component, PROPERTY_MODIFIABLE_HISTORY)); | |||
json.prop("showUpdateKey", isProjectAdmin && componentTypeHasProperty(component, PROPERTY_UPDATABLE_KEY)); | |||
json.prop("showBackgroundTasks", showBackgroundTasks); |
@@ -25,6 +25,7 @@ import java.util.Date; | |||
import java.util.List; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.sonar.api.config.Configuration; | |||
import org.sonar.api.resources.ResourceType; | |||
import org.sonar.api.resources.ResourceTypes; | |||
import org.sonar.api.server.ws.Change; | |||
@@ -98,6 +99,7 @@ public class ComponentActionTest { | |||
private final ComponentDbTester componentDbTester = db.components(); | |||
private final PropertyDbTester propertyDbTester = new PropertyDbTester(db); | |||
private final ResourceTypes resourceTypes = mock(ResourceTypes.class); | |||
private final Configuration config = mock(Configuration.class); | |||
private WsActionTester ws; | |||
@@ -652,7 +654,7 @@ public class ComponentActionTest { | |||
when(pluginRepository.getPluginInfo(any())).thenReturn(new PluginInfo("unused").setVersion(Version.create("1.0"))); | |||
CoreExtensionRepository coreExtensionRepository = mock(CoreExtensionRepository.class); | |||
when(coreExtensionRepository.isInstalled(any())).thenReturn(false); | |||
PageRepository pageRepository = new PageRepository(pluginRepository, coreExtensionRepository, new PageDefinition[] {context -> { | |||
PageRepository pageRepository = new PageRepository(pluginRepository, coreExtensionRepository, new PageDefinition[]{context -> { | |||
for (Page page : pages) { | |||
context.addPage(page); | |||
} | |||
@@ -660,7 +662,7 @@ public class ComponentActionTest { | |||
pageRepository.start(); | |||
ws = new WsActionTester( | |||
new ComponentAction(dbClient, pageRepository, resourceTypes, userSession, new ComponentFinder(dbClient, resourceTypes), | |||
new QualityGateFinder(dbClient))); | |||
new QualityGateFinder(dbClient), config)); | |||
} | |||
private String execute(String componentKey) { | |||
@@ -702,7 +704,7 @@ public class ComponentActionTest { | |||
.setAdmin(true) | |||
.build(); | |||
return new Page[] {page1, page2, adminPage}; | |||
return new Page[]{page1, page2, adminPage}; | |||
} | |||
private void verifySuccess(String componentKey) { |
@@ -24,7 +24,7 @@ import org.sonar.api.CoreProperties; | |||
import org.sonar.api.PropertyType; | |||
import org.sonar.api.config.PropertyDefinition; | |||
import static java.util.Collections.singletonList; | |||
import static java.util.Arrays.asList; | |||
class SecurityProperties { | |||
@@ -33,7 +33,7 @@ class SecurityProperties { | |||
} | |||
static List<PropertyDefinition> all() { | |||
return singletonList( | |||
return asList( | |||
PropertyDefinition.builder(CoreProperties.CORE_FORCE_AUTHENTICATION_PROPERTY) | |||
.defaultValue(Boolean.toString(CoreProperties.CORE_FORCE_AUTHENTICATION_DEFAULT_VALUE)) | |||
.name("Force user authentication") | |||
@@ -43,7 +43,17 @@ class SecurityProperties { | |||
+ "<br><strong>Disabling this setting can expose the instance to security risks.</strong>") | |||
.type(PropertyType.BOOLEAN) | |||
.category(CoreProperties.CATEGORY_SECURITY) | |||
.build()); | |||
.build(), | |||
PropertyDefinition.builder(CoreProperties.CORE_ALLOW_PERMISSION_MANAGEMENT_FOR_PROJECT_ADMINS_PROPERTY) | |||
.defaultValue(Boolean.toString(CoreProperties.CORE_ALLOW_PERMISSION_MANAGEMENT_FOR_PROJECT_ADMINS_DEFAULT_VALUE)) | |||
.name("Enable permission management for project administrators") | |||
.description( | |||
"Set if users with 'Administer' role in a project should be allowed to change project permissions. By default users with 'Administer' " + | |||
"role are allowed to change both project configuration and project permissions.") | |||
.type(PropertyType.BOOLEAN) | |||
.category(CoreProperties.CATEGORY_SECURITY) | |||
.build() | |||
); | |||
} | |||
} |
@@ -30,7 +30,7 @@ public class CorePropertyDefinitionsTest { | |||
@Test | |||
public void all() { | |||
List<PropertyDefinition> defs = CorePropertyDefinitions.all(); | |||
assertThat(defs).hasSize(54); | |||
assertThat(defs).hasSize(55); | |||
} | |||
@Test |
@@ -198,6 +198,8 @@ public interface CoreProperties { | |||
String CORE_FORCE_AUTHENTICATION_PROPERTY = "sonar.forceAuthentication"; | |||
boolean CORE_FORCE_AUTHENTICATION_DEFAULT_VALUE = true; | |||
String CORE_ALLOW_PERMISSION_MANAGEMENT_FOR_PROJECT_ADMINS_PROPERTY = "sonar.allowPermissionManagementForProjectAdmins"; | |||
boolean CORE_ALLOW_PERMISSION_MANAGEMENT_FOR_PROJECT_ADMINS_DEFAULT_VALUE = true; | |||
/** | |||
* @deprecated since 2.14. See http://jira.sonarsource.com/browse/SONAR-3153. Replaced by {@link #CORE_AUTHENTICATOR_REALM}. |