*/
package org.sonar.server.user;
+import java.util.Optional;
import org.sonar.db.component.ComponentDto;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.UnauthorizedException;
private static final String AUTHENTICATION_IS_REQUIRED_MESSAGE = "Authentication is required";
@Override
- public UserSession checkLoggedIn() {
+ public final UserSession checkLoggedIn() {
if (!isLoggedIn()) {
throw new UnauthorizedException(AUTHENTICATION_IS_REQUIRED_MESSAGE);
}
return this;
}
-
@Override
- public UserSession checkIsRoot() {
+ public final UserSession checkIsRoot() {
if (!isRoot()) {
throw new ForbiddenException(INSUFFICIENT_PRIVILEGES_MESSAGE);
}
}
@Override
- public UserSession checkOrganizationPermission(String organizationUuid, String permission) {
- if (isRoot()) {
- return this;
- }
+ public final boolean hasOrganizationPermission(String organizationUuid, String permission) {
+ return isRoot() || hasOrganizationPermissionImpl(organizationUuid, permission);
+ }
+
+ protected abstract boolean hasOrganizationPermissionImpl(String organizationUuid, String permission);
+
+ @Override
+ public final UserSession checkOrganizationPermission(String organizationUuid, String permission) {
if (!hasOrganizationPermission(organizationUuid, permission)) {
throw new ForbiddenException(INSUFFICIENT_PRIVILEGES_MESSAGE);
}
}
@Override
- public boolean hasComponentPermission(String permission, ComponentDto component) {
- return hasComponentUuidPermission(permission, component.projectUuid());
+ public final boolean hasComponentPermission(String permission, ComponentDto component) {
+ return isRoot() || hasProjectUuidPermission(permission, component.projectUuid());
}
@Override
- public UserSession checkComponentPermission(String projectPermission, ComponentDto component) {
+ public final boolean hasComponentUuidPermission(String permission, String componentUuid) {
+ if (isRoot()) {
+ return true;
+ }
+ Optional<String> projectUuid = componentUuidToProjectUuid(componentUuid);
+ return projectUuid
+ .map(s -> hasProjectUuidPermission(permission, s))
+ .orElse(false);
+ }
+
+ protected abstract Optional<String> componentUuidToProjectUuid(String componentUuid);
+
+ protected abstract boolean hasProjectUuidPermission(String permission, String projectUuid);
+
+ @Override
+ public final UserSession checkComponentPermission(String projectPermission, ComponentDto component) {
if (!hasComponentPermission(projectPermission, component)) {
throw new ForbiddenException(INSUFFICIENT_PRIVILEGES_MESSAGE);
}
}
@Override
- public UserSession checkComponentUuidPermission(String permission, String componentUuid) {
+ public final UserSession checkComponentUuidPermission(String permission, String componentUuid) {
if (!hasComponentUuidPermission(permission, componentUuid)) {
throw new ForbiddenException(INSUFFICIENT_PRIVILEGES_MESSAGE);
}
import java.util.Collection;
import java.util.Collections;
+import java.util.Optional;
import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.db.component.ComponentDto;
import org.sonar.db.user.GroupDto;
/**
}
@Override
- public boolean hasOrganizationPermission(String organizationUuid, String permission) {
+ protected boolean hasOrganizationPermissionImpl(String organizationUuid, String permission) {
return true;
}
@Override
- public boolean hasComponentPermission(String permission, ComponentDto component) {
- return true;
+ protected Optional<String> componentUuidToProjectUuid(String componentUuid) {
+ // always root so unused
+ throw new UnsupportedOperationException();
}
@Override
- public boolean hasComponentUuidPermission(String permission, String componentUuid) {
+ protected boolean hasProjectUuidPermission(String permission, String projectUuid) {
return true;
}
}
*/
package org.sonar.server.user;
-import com.google.common.base.Optional;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.HashMultimap;
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
}
@Override
- public boolean hasOrganizationPermission(String organizationUuid, String permission) {
+ protected boolean hasOrganizationPermissionImpl(String organizationUuid, String permission) {
if (permissionsByOrganizationUuid == null) {
permissionsByOrganizationUuid = HashMultimap.create();
}
}
@Override
- public boolean hasComponentUuidPermission(String permission, String componentUuid) {
- if (isRoot()) {
- return true;
- }
-
+ protected Optional<String> componentUuidToProjectUuid(String componentUuid) {
String projectUuid = projectUuidByComponentUuid.get(componentUuid);
- if (projectUuid == null) {
- try (DbSession dbSession = dbClient.openSession(false)) {
- Optional<ComponentDto> component = dbClient.componentDao().selectByUuid(dbSession, componentUuid);
- if (!component.isPresent()) {
- return false;
- }
- projectUuid = component.get().projectUuid();
- }
+ if (projectUuid != null) {
+ return Optional.of(projectUuid);
}
- boolean hasComponentPermission = hasProjectPermissionByUuid(permission, projectUuid);
- if (hasComponentPermission) {
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ com.google.common.base.Optional<ComponentDto> component = dbClient.componentDao().selectByUuid(dbSession, componentUuid);
+ if (!component.isPresent()) {
+ return Optional.empty();
+ }
+ projectUuid = component.get().projectUuid();
projectUuidByComponentUuid.put(componentUuid, projectUuid);
- return true;
+ return Optional.of(projectUuid);
}
- return false;
}
- // To keep private
- private boolean hasProjectPermissionByUuid(String permission, String projectUuid) {
+ @Override
+ protected boolean hasProjectUuidPermission(String permission, String projectUuid) {
if (!projectPermissionsCheckedByUuid.contains(permission)) {
try (DbSession dbSession = dbClient.openSession(false)) {
+ // FIXME do not load all the authorized projects. It can be huge.
Collection<String> projectUuids = dbClient.authorizationDao().selectAuthorizedRootProjectsUuids(dbSession, getUserId(), permission);
addProjectPermission(permission, projectUuids);
}
import com.google.common.collect.HashMultimap;
import java.util.List;
import java.util.Map;
-import org.sonar.db.component.ComponentDto;
+import java.util.Optional;
import org.sonar.server.user.AbstractUserSession;
import static com.google.common.collect.Lists.newArrayList;
}
@Override
- public boolean hasComponentPermission(String permission, ComponentDto component) {
- return isRoot() || hasComponentUuidPermission(permission, component.projectUuid());
+ protected boolean hasOrganizationPermissionImpl(String organizationUuid, String permission) {
+ return permissionsByOrganizationUuid.get(organizationUuid).contains(permission);
}
@Override
- public boolean hasComponentUuidPermission(String permission, String componentUuid) {
- if (isRoot()) {
- return true;
- }
- String projectUuid = projectUuidByComponentUuid.get(componentUuid);
- return projectUuid != null && hasProjectPermissionByUuid(permission, projectUuid);
- }
-
- private boolean hasProjectPermissionByUuid(String permission, String projectUuid) {
- return projectPermissionsCheckedByUuid.contains(permission) && projectUuidByPermission.get(permission).contains(projectUuid);
+ protected Optional<String> componentUuidToProjectUuid(String componentUuid) {
+ return Optional.ofNullable(projectUuidByComponentUuid.get(componentUuid));
}
@Override
- public boolean hasOrganizationPermission(String organizationUuid, String permission) {
- return isRoot() || permissionsByOrganizationUuid.get(organizationUuid).contains(permission);
+ protected boolean hasProjectUuidPermission(String permission, String projectUuid) {
+ return projectPermissionsCheckedByUuid.contains(permission) && projectUuidByPermission.get(permission).contains(projectUuid);
}
public T addOrganizationPermission(String organizationUuid, String permission) {
import org.junit.rules.ExpectedException;
import org.sonar.api.utils.System2;
import org.sonar.api.web.UserRole;
-import org.sonar.core.permission.GlobalPermissions;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.server.exceptions.ForbiddenException;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.core.permission.GlobalPermissions.PROVISIONING;
+import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
import static org.sonar.db.user.UserTesting.newUserDto;
import static org.sonar.server.user.ServerUserSession.createForAnonymous;
import static org.sonar.server.user.ServerUserSession.createForUser;
}
@Test
- public void checkOrganizationPermission_fails_with_ForbiddenException_when_user_has_no_permissions_on_organization() {
+ public void checkOrganizationPermission_throws_ForbiddenException_when_user_doesnt_have_the_specified_permission_on_organization() {
+ OrganizationDto org = db.organizations().insert();
+ db.users().insertUser(NON_ROOT_USER_DTO);
+
expectInsufficientPrivilegesForbiddenException();
- newUserSession(NON_ROOT_USER_DTO).checkOrganizationPermission("org-uuid", "perm1");
+ newUserSession(NON_ROOT_USER_DTO).checkOrganizationPermission(org.getUuid(), PROVISIONING);
+ }
+
+ @Test
+ public void checkOrganizationPermission_succeeds_when_user_has_the_specified_permission_on_organization() {
+ OrganizationDto org = db.organizations().insert();
+ db.users().insertUser(NON_ROOT_USER_DTO);
+ db.users().insertPermissionOnUser(org, NON_ROOT_USER_DTO, PROVISIONING);
+
+ newUserSession(NON_ROOT_USER_DTO).checkOrganizationPermission(org.getUuid(), PROVISIONING);
+ }
+
+ @Test
+ public void checkOrganizationPermission_succeeds_when_user_is_root() {
+ OrganizationDto org = db.organizations().insert();
+
+ newUserSession(ROOT_USER_DTO).checkOrganizationPermission(org.getUuid(), PROVISIONING);
}
@Test
public void hasOrganizationPermission_for_logged_in_user() {
OrganizationDto org = db.organizations().insert();
ComponentDto project = db.components().insertProject(org);
- db.users().insertPermissionOnUser(org, userDto, GlobalPermissions.PROVISIONING);
+ db.users().insertPermissionOnUser(org, userDto, PROVISIONING);
db.users().insertProjectPermissionOnUser(userDto, UserRole.ADMIN, project);
UserSession session = newUserSession(userDto);
- assertThat(session.hasOrganizationPermission(org.getUuid(), GlobalPermissions.PROVISIONING)).isTrue();
- assertThat(session.hasOrganizationPermission(org.getUuid(), GlobalPermissions.SYSTEM_ADMIN)).isFalse();
- assertThat(session.hasOrganizationPermission("another-org", GlobalPermissions.PROVISIONING)).isFalse();
+ assertThat(session.hasOrganizationPermission(org.getUuid(), PROVISIONING)).isTrue();
+ assertThat(session.hasOrganizationPermission(org.getUuid(), SYSTEM_ADMIN)).isFalse();
+ assertThat(session.hasOrganizationPermission("another-org", PROVISIONING)).isFalse();
}
@Test
- public void hasOrganizationPermission_for_anonymous_user() {
+ public void test_hasOrganizationPermission_for_anonymous_user() {
OrganizationDto org = db.organizations().insert();
- db.users().insertPermissionOnAnyone(org, GlobalPermissions.PROVISIONING);
+ db.users().insertPermissionOnAnyone(org, PROVISIONING);
UserSession session = newAnonymousSession();
- assertThat(session.hasOrganizationPermission(org.getUuid(), GlobalPermissions.PROVISIONING)).isTrue();
- assertThat(session.hasOrganizationPermission(org.getUuid(), GlobalPermissions.SYSTEM_ADMIN)).isFalse();
- assertThat(session.hasOrganizationPermission("another-org", GlobalPermissions.PROVISIONING)).isFalse();
+ assertThat(session.hasOrganizationPermission(org.getUuid(), PROVISIONING)).isTrue();
+ assertThat(session.hasOrganizationPermission(org.getUuid(), SYSTEM_ADMIN)).isFalse();
+ assertThat(session.hasOrganizationPermission("another-org", PROVISIONING)).isFalse();
}
private ServerUserSession newUserSession(UserDto userDto) {