]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8716 drop UserSession#hasComponentPermission(permission, componentKey)
authorSimon Brandhof <simon.brandhof@sonarsource.com>
Tue, 31 Jan 2017 21:29:28 +0000 (22:29 +0100)
committerSimon Brandhof <simon.brandhof@sonarsource.com>
Wed, 1 Feb 2017 16:11:52 +0000 (17:11 +0100)
13 files changed:
server/sonar-ce/src/main/java/org/sonar/ce/user/CeUserSession.java
server/sonar-server/src/main/java/org/sonar/server/permission/PermissionPrivilegeChecker.java
server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java
server/sonar-server/src/main/java/org/sonar/server/project/ws/DeleteAction.java
server/sonar-server/src/main/java/org/sonar/server/user/DoPrivileged.java
server/sonar-server/src/main/java/org/sonar/server/user/ServerUserSession.java
server/sonar-server/src/main/java/org/sonar/server/user/ThreadLocalUserSession.java
server/sonar-server/src/main/java/org/sonar/server/user/UserSession.java
server/sonar-server/src/test/java/org/sonar/server/project/ws/DeleteActionTest.java
server/sonar-server/src/test/java/org/sonar/server/tester/AbstractMockUserSession.java
server/sonar-server/src/test/java/org/sonar/server/tester/UserSessionRule.java
server/sonar-server/src/test/java/org/sonar/server/user/DoPrivilegedTest.java
server/sonar-server/src/test/java/org/sonar/server/user/ServerUserSessionTest.java

index b2ed1cfc86104560e5ca433149003995e67d2240..285b787f83d7310f25ef7ce6eb5f73146b9303f3 100644 (file)
@@ -121,11 +121,6 @@ public class CeUserSession implements UserSession {
     return notImplementedBooleanMethod();
   }
 
-  @Override
-  public boolean hasComponentPermission(String permission, String componentKey) {
-    return notImplementedBooleanMethod();
-  }
-
   @Override
   public boolean hasComponentUuidPermission(String permission, String componentUuid) {
     return notImplementedBooleanMethod();
index db8c4a6fd31f0934383d98bcbd6f950ffd3d3449..5474d58056ccd980a988f80edb37f54daacd262f 100644 (file)
@@ -37,13 +37,9 @@ public class PermissionPrivilegeChecker {
       .checkOrganizationPermission(organizationUuid, SYSTEM_ADMIN);
   }
 
-  /**
-   * @deprecated does not support organizations. Replaced by {@link #checkProjectAdmin(UserSession, String, Optional)}
-   */
-  @Deprecated
-  public static void checkProjectAdminUserByComponentKey(UserSession userSession, @Nullable String componentKey) {
+  public static void checkProjectAdminUserByComponentUuid(UserSession userSession, @Nullable String componentUuid) {
     userSession.checkLoggedIn();
-    if (componentKey == null || !userSession.hasComponentPermission(UserRole.ADMIN, componentKey)) {
+    if (componentUuid == null || !userSession.hasComponentUuidPermission(UserRole.ADMIN, componentUuid)) {
       userSession.checkPermission(SYSTEM_ADMIN);
     }
   }
index cac9319c624f4e076991fce36df2a02f99b18311..398c6c3486b983b79ad28063841887d23d55caf4 100644 (file)
@@ -31,12 +31,10 @@ import org.apache.commons.lang.StringUtils;
 import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.server.ServerSide;
 import org.sonar.core.component.ComponentKeys;
-import org.sonar.core.permission.GlobalPermissions;
 import org.sonar.core.util.stream.Collectors;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.component.ComponentDto;
-import org.sonar.db.component.ResourceDto;
 import org.sonar.db.organization.DefaultTemplates;
 import org.sonar.db.permission.GroupPermissionDto;
 import org.sonar.db.permission.UserPermissionDto;
@@ -54,8 +52,6 @@ import static java.lang.String.format;
 import static java.util.Arrays.asList;
 import static java.util.Collections.singletonList;
 import static org.sonar.api.security.DefaultGroups.isAnyone;
-import static org.sonar.server.permission.PermissionPrivilegeChecker.checkProjectAdminUserByComponentKey;
-import static org.sonar.server.ws.WsUtils.checkFoundWithOptional;
 
 @ServerSide
 public class PermissionTemplateService {
@@ -72,26 +68,7 @@ public class PermissionTemplateService {
     this.userSession = userSession;
     this.defaultTemplatesResolver = defaultTemplatesResolver;
   }
-
-  /**
-   * @deprecated replaced by {@link #applyDefault(DbSession, String, ComponentDto, Long)}, which <b>does not
-   * verify that user is authorized to administrate the component</b>.
-   */
-  @Deprecated
-  public void applyDefaultPermissionTemplate(DbSession session, String organizationUuid, String componentKey) {
-    ComponentDto component = checkFoundWithOptional(dbClient.componentDao().selectByKey(session, componentKey), "Component key '%s' not found", componentKey);
-    ResourceDto provisioned = dbClient.resourceDao().selectProvisionedProject(session, componentKey);
-    if (provisioned == null) {
-      checkProjectAdminUserByComponentKey(userSession, componentKey);
-    } else {
-      userSession.checkPermission(GlobalPermissions.PROVISIONING);
-    }
-
-    Integer currentUserId = userSession.getUserId();
-    Long userId = Qualifiers.PROJECT.equals(component.qualifier()) && currentUserId != null ? currentUserId.longValue() : null;
-    applyDefault(session, organizationUuid, component, userId);
-  }
-
+  
   public boolean wouldUserHavePermissionWithDefaultTemplate(DbSession dbSession,
     String organizationUuid, @Nullable Long userId, String permission, @Nullable String branch, String projectKey,
     String qualifier) {
index 607e13722c86a37cdfd02469230dbb68f31e3f71..989fb51d2ff9fd8063d4ab6064f74caa8fcb6921 100644 (file)
@@ -19,7 +19,6 @@
  */
 package org.sonar.server.project.ws;
 
-import javax.annotation.Nullable;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
@@ -75,30 +74,23 @@ public class DeleteAction implements ProjectsWsAction {
 
   @Override
   public void handle(Request request, Response response) throws Exception {
+    // fail-fast if not logged in
+    userSession.checkLoggedIn();
     String uuid = request.param(PARAM_ID);
     String key = request.param(PARAM_KEY);
-    checkPermissions(uuid, key);
 
     try (DbSession dbSession = dbClient.openSession(false)) {
       ComponentDto project = componentFinder.getByUuidOrKey(dbSession, uuid, key, ID_AND_KEY);
+      checkPermission(project);
       componentCleanerService.delete(dbSession, project);
     }
 
     response.noContent();
   }
 
-  private void checkPermissions(@Nullable String uuid, @Nullable String key) {
-    if (missPermissionsBasedOnUuid(uuid) || missPermissionsBasedOnKey(key)) {
-      userSession.checkLoggedIn().checkPermission(GlobalPermissions.SYSTEM_ADMIN);
+  private void checkPermission(ComponentDto project) {
+    if (!userSession.hasComponentPermission(UserRole.ADMIN, project)) {
+      userSession.checkOrganizationPermission(project.getOrganizationUuid(), GlobalPermissions.SYSTEM_ADMIN);
     }
   }
-
-  private boolean missPermissionsBasedOnKey(@Nullable String key) {
-    return key != null && !userSession.hasComponentPermission(UserRole.ADMIN, key) && !userSession.hasPermission(GlobalPermissions.SYSTEM_ADMIN);
-  }
-
-  private boolean missPermissionsBasedOnUuid(@Nullable String uuid) {
-    return uuid != null && !userSession.hasComponentUuidPermission(UserRole.ADMIN, uuid) && !userSession.hasPermission(GlobalPermissions.SYSTEM_ADMIN);
-  }
-
 }
index d5242f0af6b51f1e0873a216de73593500bf0bcf..a2aac204a78f54fb3088e641f659fa2d11c16c26 100644 (file)
@@ -25,8 +25,8 @@ import java.util.List;
 import java.util.Set;
 import org.sonar.api.security.DefaultGroups;
 import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.db.user.GroupDto;
 import org.sonar.db.component.ComponentDto;
+import org.sonar.db.user.GroupDto;
 
 /**
  * Allow code to be executed with the highest privileges possible, as if executed by a {@link GlobalPermissions#SYSTEM_ADMIN} account.
@@ -124,11 +124,6 @@ public final class DoPrivileged {
         return true;
       }
 
-      @Override
-      public boolean hasComponentPermission(String permission, String componentKey) {
-        return true;
-      }
-
       @Override
       public boolean hasComponentUuidPermission(String permission, String componentUuid) {
         return true;
index 1923dbd19e3a49cdf39d8efad65f6cf60fd97164..bc866fa866f42393b8cd6d54bea1bbce7bf6e5d0 100644 (file)
@@ -49,8 +49,6 @@ import static java.util.Objects.requireNonNull;
  * Implementation of {@link UserSession} used in web server
  */
 public class ServerUserSession extends AbstractUserSession {
-  private Map<String, String> projectKeyByComponentKey = newHashMap();
-
   @CheckForNull
   private final UserDto userDto;
   private final DbClient dbClient;
@@ -61,7 +59,6 @@ public class ServerUserSession extends AbstractUserSession {
   private SetMultimap<String, String> projectUuidByPermission = HashMultimap.create();
   private SetMultimap<String, String> permissionsByOrganizationUuid;
   private Map<String, String> projectUuidByComponentUuid = newHashMap();
-  private List<String> projectPermissionsCheckedByKey = new ArrayList<>();
   private List<String> projectPermissionsCheckedByUuid = new ArrayList<>();
 
   private ServerUserSession(DbClient dbClient, @Nullable UserDto userDto) {
@@ -164,44 +161,6 @@ public class ServerUserSession extends AbstractUserSession {
     return globalPermissions;
   }
 
-  @Override
-  public boolean hasComponentPermission(String permission, String componentKey) {
-    if (isRoot() || hasPermission(permission)) {
-      return true;
-    }
-
-    String projectKey = projectKeyByComponentKey.get(componentKey);
-    if (projectKey == null) {
-      ResourceDto project = resourceDao.getRootProjectByComponentKey(componentKey);
-      if (project == null) {
-        return false;
-      }
-      projectKey = project.getKey();
-    }
-    boolean hasComponentPermission = hasProjectPermission(permission, projectKey);
-    if (hasComponentPermission) {
-      projectKeyByComponentKey.put(componentKey, projectKey);
-      return true;
-    }
-    return false;
-  }
-
-  private boolean hasProjectPermission(String permission, String projectKey) {
-    if (isRoot()) {
-      return true;
-    }
-    if (!projectPermissionsCheckedByKey.contains(permission)) {
-      try (DbSession dbSession = dbClient.openSession(false)) {
-        Collection<String> projectKeys = dbClient.authorizationDao().selectAuthorizedRootProjectsKeys(dbSession, getUserId(), permission);
-        for (String key : projectKeys) {
-          projectKeyByPermission.put(permission, key);
-        }
-        projectPermissionsCheckedByKey.add(permission);
-      }
-    }
-    return projectKeyByPermission.get(permission).contains(projectKey);
-  }
-
   @Override
   public boolean hasComponentUuidPermission(String permission, String componentUuid) {
     if (isRoot() || hasPermission(permission)) {
index 34607091b7554292c776da0cc1da4eb5360b31e0..97761aebe564169600a73c600562d3e3982a88b6 100644 (file)
@@ -137,11 +137,6 @@ public class ThreadLocalUserSession implements UserSession {
     return get().hasComponentPermission(permission, component);
   }
 
-  @Override
-  public boolean hasComponentPermission(String permission, String componentKey) {
-    return get().hasComponentPermission(permission, componentKey);
-  }
-
   @Override
   public boolean hasComponentUuidPermission(String permission, String componentUuid) {
     return get().hasComponentUuidPermission(permission, componentUuid);
index 772293bfe6b5141663c93cfb62d478ce1965fdad..9425b43fbf9b978456e1fbf0452faca3c331525d 100644 (file)
@@ -135,15 +135,6 @@ public interface UserSession {
    */
   boolean hasComponentPermission(String permission, ComponentDto component);
 
-  /**
-   * Does the user have the given permission for a component key ?
-   *
-   * First, check if the user has the global permission (even if the component doesn't exist)
-   * If not, check is the user has the permission on the project of the component
-   * If the component doesn't exist, return false
-   */
-  boolean hasComponentPermission(String permission, String componentKey);
-
   /**
    * Does the user have the given project permission for a component uuid ?
   
index 9f0a8f4500dbb1cf8e1824b3182c5a9f87ebef95..9e95d53f8c6a75e9187255d522e8ff3537ec40fa 100644 (file)
@@ -34,6 +34,7 @@ import org.sonar.db.component.ComponentDto;
 import org.sonar.server.component.ComponentCleanerService;
 import org.sonar.server.component.ComponentFinder;
 import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.exceptions.UnauthorizedException;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.ws.WsTester;
 
@@ -76,7 +77,7 @@ public class DeleteActionTest {
   }
 
   @Test
-  public void global_admin_deletes_project_by_uuid() throws Exception {
+  public void global_admin_deletes_project_by_id() throws Exception {
     ComponentDto project = componentDbTester.insertProject();
 
     userSessionRule.login().setGlobalPermissions(UserRole.ADMIN);
@@ -115,7 +116,7 @@ public class DeleteActionTest {
   @Test
   public void project_administrator_deletes_the_project_by_key() throws Exception {
     ComponentDto project = componentDbTester.insertProject();
-    userSessionRule.login().addProjectPermissions(UserRole.ADMIN, project.key());
+    userSessionRule.login().addProjectUuidPermissions(UserRole.ADMIN, project.uuid());
 
     call(newRequest().setParam(PARAM_KEY, project.key()));
 
@@ -123,11 +124,23 @@ public class DeleteActionTest {
   }
 
   @Test
-  public void fail_if_insufficient_privileges() throws Exception {
-    userSessionRule.login().setGlobalPermissions(UserRole.CODEVIEWER, UserRole.ISSUE_ADMIN, UserRole.USER);
+  public void return_403_if_not_project_admin_nor_org_admin() throws Exception {
+    ComponentDto project = componentDbTester.insertProject();
+
+    userSessionRule.login().addProjectUuidPermissions(project.uuid(), UserRole.CODEVIEWER, UserRole.ISSUE_ADMIN, UserRole.USER);
     expectedException.expect(ForbiddenException.class);
 
-    call(newRequest().setParam(PARAM_ID, "whatever-the-uuid"));
+    call(newRequest().setParam(PARAM_ID, project.uuid()));
+  }
+
+  @Test
+  public void return_401_if_not_logged_in() throws Exception {
+    ComponentDto project = componentDbTester.insertProject();
+
+    userSessionRule.anonymous();
+    expectedException.expect(UnauthorizedException.class);
+
+    call(newRequest().setParam(PARAM_ID, project.uuid()));
   }
 
   private WsTester.TestRequest newRequest() {
index 6d5fcb00e82d6349217e41153b74bd3c68d3138d..e60f4624d408d6727006594afd31cd85df9a215f 100644 (file)
@@ -45,7 +45,6 @@ public abstract class AbstractMockUserSession<T extends AbstractMockUserSession>
   private Map<String, String> projectUuidByComponentUuid = newHashMap();
   private List<String> projectPermissionsCheckedByKey = newArrayList();
   private List<String> projectPermissionsCheckedByUuid = newArrayList();
-  private Map<String, String> projectKeyByComponentKey = newHashMap();
 
   protected AbstractMockUserSession(Class<T> clazz) {
     this.clazz = clazz;
@@ -75,9 +74,6 @@ public abstract class AbstractMockUserSession<T extends AbstractMockUserSession>
   public T addProjectPermissions(String projectPermission, String... projectKeys) {
     this.projectPermissionsCheckedByKey.add(projectPermission);
     this.projectKeyByPermission.putAll(projectPermission, newArrayList(projectKeys));
-    for (String projectKey : projectKeys) {
-      this.projectKeyByComponentKey.put(projectKey, projectKey);
-    }
     return clazz.cast(this);
   }
 
@@ -95,7 +91,6 @@ public abstract class AbstractMockUserSession<T extends AbstractMockUserSession>
    */
   @Deprecated
   public T addComponentPermission(String projectPermission, String projectKey, String componentKey) {
-    this.projectKeyByComponentKey.put(componentKey, projectKey);
     addProjectPermissions(projectPermission, projectKey);
     return clazz.cast(this);
   }
@@ -116,17 +111,7 @@ public abstract class AbstractMockUserSession<T extends AbstractMockUserSession>
     return hasComponentUuidPermission(permission, component.projectUuid());
   }
 
-  @Override
-  public boolean hasComponentPermission(String permission, String componentKey) {
-    String projectKey = projectKeyByComponentKey.get(componentKey);
-    return hasPermission(permission) || (projectKey != null && hasProjectPermission(permission, projectKey));
-  }
-
-  private boolean hasProjectPermission(String permission, String projectKey) {
-    return projectPermissionsCheckedByKey.contains(permission) && projectKeyByPermission.get(permission).contains(projectKey);
-  }
-
-  @Override
+    @Override
   public boolean hasComponentUuidPermission(String permission, String componentUuid) {
     String projectUuid = projectUuidByComponentUuid.get(componentUuid);
     return hasPermission(permission) || (projectUuid != null && hasProjectPermissionByUuid(permission, projectUuid));
index 6a6333bec99e3106b0c1dda2d33051cdae9d156e..f09ad6c98b572f8c80a8f5ec3b6f993fe2b6f456 100644 (file)
@@ -261,11 +261,6 @@ public class UserSessionRule implements TestRule, UserSession {
     return currentUserSession.hasComponentPermission(permission, component);
   }
 
-  @Override
-  public boolean hasComponentPermission(String permission, String componentKey) {
-    return currentUserSession.hasComponentPermission(permission, componentKey);
-  }
-
   @Override
   public boolean hasComponentUuidPermission(String permission, String componentUuid) {
     return currentUserSession.hasComponentUuidPermission(permission, componentUuid);
index 484351094e71b3e0b97b27164556b60f0568650c..907da4fd757505ae1f9a33fee8eb1f2f5395ebe0 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.server.user;
 
 import org.junit.Before;
 import org.junit.Test;
+import org.sonar.db.component.ComponentDto;
 import org.sonar.server.tester.MockUserSession;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -47,14 +48,14 @@ public class DoPrivilegedTest {
     // verify the session used inside Privileged task
     assertThat(catcher.userSession.isLoggedIn()).isFalse();
     assertThat(catcher.userSession.hasPermission("any permission")).isTrue();
-    assertThat(catcher.userSession.hasComponentPermission("any permission", "any project")).isTrue();
+    assertThat(catcher.userSession.hasComponentPermission("any permission", new ComponentDto())).isTrue();
 
     // verify session in place after task is done
     assertThat(threadLocalUserSession.get()).isSameAs(session);
   }
 
   @Test
-  public void should_lose_privileges_on_exception() {
+  public void should_loose_privileges_on_exception() {
     UserSessionCatcherTask catcher = new UserSessionCatcherTask() {
       @Override
       protected void doPrivileged() {
@@ -73,7 +74,7 @@ public class DoPrivilegedTest {
       // verify the session used inside Privileged task
       assertThat(catcher.userSession.isLoggedIn()).isFalse();
       assertThat(catcher.userSession.hasPermission("any permission")).isTrue();
-      assertThat(catcher.userSession.hasComponentPermission("any permission", "any project")).isTrue();
+      assertThat(catcher.userSession.hasComponentPermission("any permission", new ComponentDto())).isTrue();
     }
   }
 
index 963568ff6f6296beb92e191eb477b50c6de92ab5..3055af6d5a370fa30305afd016a5245b6b14f095 100644 (file)
@@ -179,16 +179,6 @@ public class ServerUserSessionTest {
     assertThat(underTest.checkPermission("whatever!")).isSameAs(underTest);
   }
 
-  @Test
-  public void has_component_permission() {
-    addProjectPermissions(project, UserRole.USER);
-    UserSession session = newUserSession(userDto);
-
-    assertThat(session.hasComponentPermission(UserRole.USER, FILE_KEY)).isTrue();
-    assertThat(session.hasComponentPermission(UserRole.CODEVIEWER, FILE_KEY)).isFalse();
-    assertThat(session.hasComponentPermission(UserRole.ADMIN, FILE_KEY)).isFalse();
-  }
-
   @Test
   public void hasComponentUuidPermission_returns_true_if_user_has_project_permission_for_given_uuid_in_db() {
     addProjectPermissions(project, UserRole.USER);
@@ -209,16 +199,6 @@ public class ServerUserSessionTest {
     assertThat(underTest.hasComponentUuidPermission("whatever", "who cares?")).isTrue();
   }
 
-  @Test
-  public void hasComponentPermission_returns_true_if_user_has_global_permission_in_db() {
-    addGlobalPermissions(UserRole.USER);
-    UserSession session = newUserSession(userDto);
-
-    assertThat(session.hasComponentPermission(UserRole.USER, FILE_KEY)).isTrue();
-    assertThat(session.hasComponentPermission(UserRole.CODEVIEWER, FILE_KEY)).isFalse();
-    assertThat(session.hasComponentPermission(UserRole.ADMIN, FILE_KEY)).isFalse();
-  }
-
   @Test
   public void has_component_uuid_permission_with_only_global_permission() {
     addGlobalPermissions(UserRole.USER);
@@ -274,16 +254,6 @@ public class ServerUserSessionTest {
     assertThat(session.hasPermission(GlobalPermissions.QUALITY_GATE_ADMIN)).isFalse();
   }
 
-  @Test
-  public void has_project_permission_for_anonymous() throws Exception {
-    addAnyonePermissions(organization, project, UserRole.USER);
-    UserSession session = newAnonymousSession();
-
-    assertThat(session.hasComponentPermission(UserRole.USER, FILE_KEY)).isTrue();
-    assertThat(session.hasComponentPermission(UserRole.CODEVIEWER, FILE_KEY)).isFalse();
-    assertThat(session.hasComponentPermission(UserRole.ADMIN, FILE_KEY)).isFalse();
-  }
-
   @Test
   public void checkOrganizationPermission_fails_with_ForbiddenException_when_user_has_no_permissions_on_organization() {
     expectInsufficientPrivilegesForbiddenException();