aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-webserver-auth/src/main
diff options
context:
space:
mode:
authorklaudio-sinani-sonarsource <92299827+klaudio-sinani-sonarsource@users.noreply.github.com>2022-01-11 12:49:37 +0100
committersonartech <sonartech@sonarsource.com>2022-01-20 20:02:43 +0000
commit110208dd8037b2cbf63df1ae17fb523c057d2046 (patch)
treeb1503539eb1e3cbdf51cf729f29dabcc77be7163 /server/sonar-webserver-auth/src/main
parent5dd324c60877c4445460bde30ab3e3cc25fc7a7f (diff)
downloadsonarqube-110208dd8037b2cbf63df1ae17fb523c057d2046.tar.gz
sonarqube-110208dd8037b2cbf63df1ae17fb523c057d2046.zip
SONAR-15877 Flag portfolios that contain inaccessible components (#5239)
Diffstat (limited to 'server/sonar-webserver-auth/src/main')
-rw-r--r--server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/SafeModeUserSession.java5
-rw-r--r--server/sonar-webserver-auth/src/main/java/org/sonar/server/user/AbstractUserSession.java11
-rw-r--r--server/sonar-webserver-auth/src/main/java/org/sonar/server/user/DoPrivileged.java5
-rw-r--r--server/sonar-webserver-auth/src/main/java/org/sonar/server/user/ServerUserSession.java53
-rw-r--r--server/sonar-webserver-auth/src/main/java/org/sonar/server/user/ThreadLocalUserSession.java5
-rw-r--r--server/sonar-webserver-auth/src/main/java/org/sonar/server/user/UserSession.java2
6 files changed, 81 insertions, 0 deletions
diff --git a/server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/SafeModeUserSession.java b/server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/SafeModeUserSession.java
index 7bc12dd1ef4..c14babcfdc4 100644
--- a/server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/SafeModeUserSession.java
+++ b/server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/SafeModeUserSession.java
@@ -51,6 +51,11 @@ public class SafeModeUserSession extends AbstractUserSession {
return false;
}
+ @Override
+ protected boolean hasPortfolioChildProjectsPermission(String permission, String portfolioUuid) {
+ return false;
+ }
+
@CheckForNull
@Override
public String getLogin() {
diff --git a/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/AbstractUserSession.java b/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/AbstractUserSession.java
index 9fec50125fc..29914eb211f 100644
--- a/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/AbstractUserSession.java
+++ b/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/AbstractUserSession.java
@@ -131,6 +131,15 @@ public abstract class AbstractUserSession implements UserSession {
}
@Override
+ public final boolean hasPortfolioChildProjectsPermission(String permission, ComponentDto portfolio) {
+ if (isRoot()) {
+ return true;
+ }
+
+ return hasPortfolioChildProjectsPermission(permission, portfolio.uuid());
+ }
+
+ @Override
public final boolean hasComponentUuidPermission(String permission, String componentUuid) {
if (isRoot()) {
return true;
@@ -147,6 +156,8 @@ public abstract class AbstractUserSession implements UserSession {
protected abstract boolean hasChildProjectsPermission(String permission, String applicationUuid);
+ protected abstract boolean hasPortfolioChildProjectsPermission(String permission, String portfolioUuid);
+
@Override
public final List<ComponentDto> keepAuthorizedComponents(String permission, Collection<ComponentDto> components) {
if (isRoot()) {
diff --git a/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/DoPrivileged.java b/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/DoPrivileged.java
index ed2770c08c0..c4a504d7a7b 100644
--- a/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/DoPrivileged.java
+++ b/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/DoPrivileged.java
@@ -133,6 +133,11 @@ public final class DoPrivileged {
}
@Override
+ protected boolean hasPortfolioChildProjectsPermission(String permission, String applicationUuid) {
+ return true;
+ }
+
+ @Override
public boolean isSystemAdministrator() {
return true;
}
diff --git a/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/ServerUserSession.java b/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/ServerUserSession.java
index 0131f2ab492..7acb465d77d 100644
--- a/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/ServerUserSession.java
+++ b/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/ServerUserSession.java
@@ -19,6 +19,7 @@
*/
package org.sonar.server.user;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -27,6 +28,7 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
+import java.util.stream.Collectors;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.sonar.api.resources.Qualifiers;
@@ -181,6 +183,22 @@ public class ServerUserSession extends AbstractUserSession {
.allMatch(Boolean::valueOf);
}
+ @Override
+ protected boolean hasPortfolioChildProjectsPermission(String permission, String portfolioUuid) {
+ if (permissionsByProjectUuid == null) {
+ permissionsByProjectUuid = new HashMap<>();
+ }
+
+ Set<ComponentDto> portfolioHierarchyComponents = resolvePortfolioHierarchyComponents(portfolioUuid);
+
+ Set<String> portfolioHierarchyComponentUuids = portfolioHierarchyComponents.stream().map(ComponentDto::getCopyComponentUuid).collect(Collectors.toSet());
+
+ return portfolioHierarchyComponentUuids
+ .stream()
+ .map(uuid -> hasPermission(permission, uuid))
+ .allMatch(Boolean::valueOf);
+ }
+
private boolean hasPermission(String permission, String projectUuid) {
Set<String> projectPermissions = permissionsByProjectUuid.computeIfAbsent(projectUuid, this::loadProjectPermissions);
return projectPermissions.contains(permission);
@@ -219,6 +237,41 @@ public class ServerUserSession extends AbstractUserSession {
}
}
+ private List<ComponentDto> getDirectChildComponents(String portfolioUuid) {
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ return dbClient.componentDao().selectDescendants(dbSession, ComponentTreeQuery.builder()
+ .setBaseUuid(portfolioUuid)
+ .setQualifiers(Arrays.asList(Qualifiers.PROJECT, Qualifiers.SUBVIEW))
+ .setStrategy(Strategy.CHILDREN).build());
+ }
+ }
+
+ private Set<ComponentDto> resolvePortfolioHierarchyComponents(String parentComponentUuid) {
+ Set<ComponentDto> portfolioHierarchyProjects = new HashSet<>();
+
+ resolvePortfolioHierarchyComponents(parentComponentUuid, portfolioHierarchyProjects);
+
+ return portfolioHierarchyProjects;
+ }
+
+ private void resolvePortfolioHierarchyComponents(String parentComponentUuid, Set<ComponentDto> hierarchyChildComponents) {
+ List<ComponentDto> childComponents = getDirectChildComponents(parentComponentUuid);
+
+ if (childComponents.isEmpty()) {
+ return;
+ }
+
+ childComponents.forEach(c -> {
+ if (c.getCopyComponentUuid() != null) {
+ hierarchyChildComponents.add(c);
+ }
+
+ if (Qualifiers.SUBVIEW.equals(c.qualifier())) {
+ resolvePortfolioHierarchyComponents(c.uuid(), hierarchyChildComponents);
+ }
+ });
+ }
+
private Set<GlobalPermission> loadGlobalPermissions() {
Set<String> permissionKeys;
try (DbSession dbSession = dbClient.openSession(false)) {
diff --git a/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/ThreadLocalUserSession.java b/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/ThreadLocalUserSession.java
index 96096ccefe1..3dec0032d96 100644
--- a/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/ThreadLocalUserSession.java
+++ b/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/ThreadLocalUserSession.java
@@ -199,6 +199,11 @@ public class ThreadLocalUserSession implements UserSession {
}
@Override
+ public boolean hasPortfolioChildProjectsPermission(String permission, ComponentDto portfolio) {
+ return get().hasPortfolioChildProjectsPermission(permission, portfolio);
+ }
+
+ @Override
public boolean hasComponentUuidPermission(String permission, String componentUuid) {
return get().hasComponentUuidPermission(permission, componentUuid);
}
diff --git a/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/UserSession.java b/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/UserSession.java
index 61992db77cc..5350e578539 100644
--- a/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/UserSession.java
+++ b/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/UserSession.java
@@ -201,6 +201,8 @@ public interface UserSession {
boolean hasChildProjectsPermission(String permission, ProjectDto component);
+ boolean hasPortfolioChildProjectsPermission(String permission, ComponentDto component);
+
/**
* Using {@link #hasComponentPermission(String, ComponentDto)} is recommended
* because it does not have to load project if the referenced component