return notImplementedBooleanMethod();
}
+ @Override
+ public boolean hasOrganizationPermission(String organizationUuid, String permission) {
+ return notImplementedBooleanMethod();
+ }
+
+ @Override
+ public UserSession checkOrganizationPermission(String organizationUuid, String permission) {
+ return notImplemented();
+ }
+
@Override
public boolean hasGlobalPermission(String globalPermission) {
return notImplementedBooleanMethod();
return this;
}
+ @Override
+ public UserSession checkOrganizationPermission(String organizationUuid, String permission) {
+ if (isRoot()) {
+ return this;
+ }
+ if (!hasOrganizationPermission(organizationUuid, permission)) {
+ throw new ForbiddenException(INSUFFICIENT_PRIVILEGES_MESSAGE);
+ }
+ return this;
+ }
+
@Override
public UserSession checkGlobalPermission(String globalPermission) {
return checkPermission(globalPermission);
return true;
}
+ @Override
+ public boolean hasOrganizationPermission(String organizationUuid, String permission) {
+ return true;
+ }
+
@Override
public List<String> globalPermissions() {
return Collections.emptyList();
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.SetMultimap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
private final ResourceDao resourceDao;
private final Set<String> userGroups;
private List<String> globalPermissions = null;
- private HashMultimap<String, String> projectKeyByPermission = HashMultimap.create();
- private HashMultimap<String, String> projectUuidByPermission = HashMultimap.create();
+ private SetMultimap<String, String> projectKeyByPermission = HashMultimap.create();
+ 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<>();
return userDto != null && userDto.isRoot();
}
+ @Override
+ public boolean hasOrganizationPermission(String organizationUuid, String permission) {
+ if (permissionsByOrganizationUuid == null) {
+ permissionsByOrganizationUuid = HashMultimap.create();
+ }
+ Set<String> permissions;
+ if (permissionsByOrganizationUuid.containsKey(organizationUuid)) {
+ permissions = permissionsByOrganizationUuid.get(organizationUuid);
+ } else {
+ permissions = loadOrganizationPermissions(organizationUuid);
+ permissionsByOrganizationUuid.putAll(organizationUuid, permissions);
+ }
+ return permissions.contains(permission);
+ }
+
+ private Set<String> loadOrganizationPermissions(String organizationUuid) {
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ if (userDto != null && userDto.getId() != null) {
+ return dbClient.authorizationDao().selectOrganizationPermissions(dbSession, organizationUuid, userDto.getId());
+ }
+ return dbClient.authorizationDao().selectOrganizationPermissionsOfAnonymous(dbSession, organizationUuid);
+ }
+ }
+
@Override
public List<String> globalPermissions() {
if (globalPermissions == null) {
public boolean hasComponentUuidPermission(String permission, String componentUuid) {
return get().hasComponentUuidPermission(permission, componentUuid);
}
+
+ @Override
+ public UserSession checkOrganizationPermission(String organizationUuid, String permission) {
+ get().checkOrganizationPermission(organizationUuid, permission);
+ return this;
+ }
+
+ @Override
+ public boolean hasOrganizationPermission(String organizationUuid, String permission) {
+ return get().hasOrganizationPermission(organizationUuid, permission);
+ }
}
@CheckForNull
Integer getUserId();
+ /**
+ * @deprecated does not support organizations as group names are not unique
+ */
+ @Deprecated
Set<String> getUserGroups();
boolean isLoggedIn();
*/
boolean hasPermission(String globalPermission);
+ /**
+ * Returns {@code true} if the permission is granted on the organization, else {@code false}.
+ * Root status is not verified, so the method may return {@code false} even for root users.
+ */
+ boolean hasOrganizationPermission(String organizationUuid, String permission);
+
+ /**
+ * Ensures that user implies the specified organization permission,
+ * otherwise throws a {@link org.sonar.server.exceptions.ForbiddenException}.
+ */
+ UserSession checkOrganizationPermission(String organizationUuid, String permission);
+
/**
* @deprecated Only used by Views and the Developer Cockpit plugins.
*/
private List<String> globalPermissions = Collections.emptyList();
private HashMultimap<String, String> projectKeyByPermission = HashMultimap.create();
private HashMultimap<String, String> projectUuidByPermission = HashMultimap.create();
+ private HashMultimap<String, String> permissionsByOrganizationUuid = HashMultimap.create();
private Map<String, String> projectUuidByComponentUuid = newHashMap();
private List<String> projectPermissionsCheckedByKey = newArrayList();
private List<String> projectPermissionsCheckedByUuid = newArrayList();
private boolean hasProjectPermissionByUuid(String permission, String projectUuid) {
return projectPermissionsCheckedByUuid.contains(permission) && projectUuidByPermission.get(permission).contains(projectUuid);
}
+
+ @Override
+ public boolean hasOrganizationPermission(String organizationUuid, String permission) {
+ return permissionsByOrganizationUuid.get(organizationUuid).contains(permission);
+ }
+
+ public T addOrganizationPermission(String organizationUuid, String permission) {
+ permissionsByOrganizationUuid.put(organizationUuid, permission);
+ return clazz.cast(this);
+ }
}
return this;
}
+ public UserSessionRule addOrganizationPermission(String organizationUuid, String permission) {
+ ensureAbstractMockUserSession().addOrganizationPermission(organizationUuid, permission);
+ return this;
+ }
+
public UserSessionRule setUserId(@Nullable Integer userId) {
ensureMockUserSession().setUserId(userId);
return this;
return currentUserSession.hasGlobalPermission(globalPermission);
}
+ @Override
+ public boolean hasOrganizationPermission(String organizationUuid, String permission) {
+ return currentUserSession.hasOrganizationPermission(organizationUuid, permission);
+ }
+
@Override
public UserSession checkComponentPermission(String projectPermission, String componentKey) {
currentUserSession.checkComponentPermission(projectPermission, componentKey);
return this;
}
-
+ @Override
+ public UserSession checkOrganizationPermission(String organizationUuid, String permission) {
+ currentUserSession.checkOrganizationPermission(organizationUuid, permission);
+ return this;
+ }
}
import org.sonar.api.web.UserRole;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
+import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.organization.OrganizationTesting;
import org.sonar.db.user.UserDto;
import org.sonar.server.exceptions.ForbiddenException;
import static org.sonar.core.permission.GlobalPermissions.QUALITY_GATE_ADMIN;
import static org.sonar.core.permission.GlobalPermissions.QUALITY_PROFILE_ADMIN;
import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
+import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto;
import static org.sonar.db.user.UserTesting.newUserDto;
import static org.sonar.server.user.ServerUserSession.createForAnonymous;
import static org.sonar.server.user.ServerUserSession.createForUser;
assertThat(session.hasComponentPermission(UserRole.ADMIN, FILE_KEY)).isFalse();
}
+ @Test
+ public void checkOrganizationPermission_fails_with_ForbiddenException_when_user_has_no_permissions_on_organization() {
+ expectInsufficientPrivilegesForbiddenException();
+
+ newUserSession(NON_ROOT_USER_DTO).checkOrganizationPermission("org-uuid", "perm1");
+ }
+
+ @Test
+ public void hasOrganizationPermission_for_logged_in_user() {
+ OrganizationDto org = OrganizationTesting.insert(db, newOrganizationDto());
+ db.users().insertPermissionOnUser(org, userDto, GlobalPermissions.PROVISIONING);
+
+ 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();
+ }
+
+ @Test
+ public void hasOrganizationPermission_for_anonymous_user() {
+ OrganizationDto org = OrganizationTesting.insert(db, newOrganizationDto());
+ db.users().insertPermissionOnAnyone(org, GlobalPermissions.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();
+ }
+
private ServerUserSession newUserSession(UserDto userDto) {
return createForUser(dbClient, userDto);
}