db.commit();
}
+ public ComponentDto insertProjectBranch(ComponentDto project, String branchName) {
+ ComponentDto branch = ComponentTesting.newProjectBranch(project, branchName);
+ insertComponent(branch);
+ db.commit();
+ return branch;
+ }
+
}
.setEnabled(true)
.setPrivate(moduleOrProject.isPrivate());
}
+
+ public static ComponentDto newProjectBranch(ComponentDto project, String branchName) {
+ checkArgument(project.qualifier().equals(Qualifiers.PROJECT));
+ String uuid = Uuids.createFast();
+ return new ComponentDto()
+ .setUuid(uuid)
+ .setOrganizationUuid(project.getOrganizationUuid())
+ .setUuidPath(ComponentDto.UUID_PATH_OF_ROOT)
+ .setProjectUuid(uuid)
+ .setModuleUuidPath(UUID_PATH_SEPARATOR + uuid + UUID_PATH_SEPARATOR)
+ .setRootUuid(uuid)
+ .setDbKey(project.getDbKey() + ":BRANCH:" + branchName)
+ .setMainBranchProjectUuid(project.uuid())
+ .setName(project.name())
+ .setLongName(project.longName())
+ .setDescription(project.description())
+ .setScope(project.scope())
+ .setQualifier(project.qualifier())
+ .setPath(null)
+ .setLanguage(null)
+ .setEnabled(true)
+ .setPrivate(project.isPrivate());
+ }
}
checkArgument(!project.isPrivate(), "No permission to group AnyOne can be granted on a private project");
checkArgument(!ProjectPermissions.PUBLIC_PERMISSIONS.contains(permission),
"permission %s can't be granted on a public project", permission);
+ checkArgument(project.getMainBranchProjectUuid()==null, "Permissions can't be granted on branches");
GroupPermissionDto dto = new GroupPermissionDto()
.setOrganizationUuid(project.getOrganizationUuid())
.setGroupId(null)
checkArgument(group.getOrganizationUuid().equals(project.getOrganizationUuid()), "Different organizations");
checkArgument(project.isPrivate() || !ProjectPermissions.PUBLIC_PERMISSIONS.contains(permission),
"%s can't be granted on a public project", permission);
+ checkArgument(project.getMainBranchProjectUuid()==null, "Permissions can't be granted on branches");
GroupPermissionDto dto = new GroupPermissionDto()
.setOrganizationUuid(group.getOrganizationUuid())
.setGroupId(group.getId())
public UserPermissionDto insertProjectPermissionOnUser(UserDto user, String permission, ComponentDto project) {
checkArgument(project.isPrivate() || !ProjectPermissions.PUBLIC_PERMISSIONS.contains(permission),
"%s can't be granted on a public project", permission);
+ checkArgument(project.getMainBranchProjectUuid()==null, "Permissions can't be granted on branches");
UserPermissionDto dto = new UserPermissionDto(project.getOrganizationUuid(), permission, user.getId(), project.getId());
db.getDbClient().userPermissionDao().insert(db.getSession(), dto);
db.commit();
import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.permission.OrganizationPermission;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.UnauthorizedException;
-import org.sonar.db.permission.OrganizationPermission;
+
+import static org.apache.commons.lang.StringUtils.defaultString;
public abstract class AbstractUserSession implements UserSession {
private static final String INSUFFICIENT_PRIVILEGES_MESSAGE = "Insufficient privileges";
@Override
public final boolean hasComponentPermission(String permission, ComponentDto component) {
- return isRoot() || hasProjectUuidPermission(permission, component.projectUuid());
+ if (isRoot()) {
+ return true;
+ }
+ String projectUuid = defaultString(component.getMainBranchProjectUuid(), component.projectUuid());
+ return hasProjectUuidPermission(permission, projectUuid);
}
@Override
import org.sonar.server.organization.OrganizationFlags;
import static com.google.common.collect.Maps.newHashMap;
+import static org.apache.commons.lang.StringUtils.defaultIfEmpty;
/**
* Implementation of {@link UserSession} used in web server
if (!component.isPresent()) {
return Optional.empty();
}
- projectUuid = component.get().projectUuid();
+ // if component is part of a branch, then permissions must be
+ // checked on the project (represented by its main branch)
+ projectUuid = defaultIfEmpty(component.get().getMainBranchProjectUuid(), component.get().projectUuid());
projectUuidByComponentUuid.put(componentUuid, projectUuid);
return Optional.of(projectUuid);
}
package org.sonar.server.user;
import java.util.Arrays;
-import java.util.Random;
import javax.annotation.Nullable;
import org.junit.Before;
import org.junit.Rule;
import org.sonar.server.organization.TestDefaultOrganizationProvider;
import org.sonar.server.organization.TestOrganizationFlags;
+import static com.google.common.base.Preconditions.checkState;
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.component.ComponentTesting.newChildComponent;
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER;
import static org.sonar.db.permission.OrganizationPermission.PROVISION_PROJECTS;
import static org.sonar.db.permission.OrganizationPermission.SCAN;
public class ServerUserSessionTest {
private static final String LOGIN = "marius";
- private static final String PUBLIC_PROJECT_UUID = "public project";
- private static final String PRIVATE_PROJECT_UUID = "private project";
+ private static final String PUBLIC_PROJECT_UUID = "public_project";
+ private static final String PRIVATE_PROJECT_UUID = "private_project";
private static final String FILE_KEY = "com.foo:Bar:BarFile.xoo";
private static final String FILE_UUID = "BCDE";
private static final UserDto ROOT_USER_DTO = new UserDto() {
}
private boolean hasComponentPermissionByDtoOrUuid(UserSession underTest, String permission, ComponentDto component) {
- return new Random().nextBoolean() ? underTest.hasComponentPermission(permission, component) : underTest.hasComponentUuidPermission(permission, component.uuid());
+ boolean b1 = underTest.hasComponentPermission(permission, component);
+ boolean b2 = underTest.hasComponentUuidPermission(permission, component.uuid());
+ checkState(b1 == b2, "Different behaviors");
+ return b1;
}
@Test
session.checkIsSystemAdministrator();
}
+ @Test
+ public void hasComponentPermission_on_branch_checks_permissions_of_its_project() {
+ ComponentDto branch = db.components().insertProjectBranch(privateProject, "feature/foo");
+ ComponentDto fileInBranch = db.components().insertComponent(newChildComponent("fileUuid", branch, branch));
+
+ // permissions are defined on the project, not on the branch
+ db.users().insertProjectPermissionOnUser(user, "p1", privateProject);
+
+ UserSession underTest = newUserSession(user);
+ assertThat(hasComponentPermissionByDtoOrUuid(underTest, "p1", privateProject)).isTrue();
+ assertThat(hasComponentPermissionByDtoOrUuid(underTest, "p1", branch)).isTrue();
+ assertThat(hasComponentPermissionByDtoOrUuid(underTest, "p1", fileInBranch)).isTrue();
+ }
+
private ServerUserSession newUserSession(@Nullable UserDto userDto) {
return new ServerUserSession(dbClient, organizationFlags, defaultOrganizationProvider, userDto);
}