All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.sonar.server.user.ServerUserSession Maven / Gradle / Ivy
/*
* SonarQube
* Copyright (C) 2009-2018 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.user;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableSet;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.sonar.core.permission.ProjectPermissions;
import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.permission.OrganizationPermission;
import org.sonar.db.user.GroupDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.organization.DefaultOrganizationProvider;
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
*/
public class ServerUserSession extends AbstractUserSession {
@CheckForNull
private final UserDto userDto;
private final DbClient dbClient;
private final OrganizationFlags organizationFlags;
private final DefaultOrganizationProvider defaultOrganizationProvider;
private final Supplier> groups = Suppliers.memoize(this::loadGroups);
private final Supplier isSystemAdministratorSupplier = Suppliers.memoize(this::loadIsSystemAdministrator);
private final Map projectUuidByComponentUuid = newHashMap();
private Map> permissionsByOrganizationUuid;
private Map> permissionsByProjectUuid;
ServerUserSession(DbClient dbClient, OrganizationFlags organizationFlags,
DefaultOrganizationProvider defaultOrganizationProvider, @Nullable UserDto userDto) {
this.dbClient = dbClient;
this.organizationFlags = organizationFlags;
this.defaultOrganizationProvider = defaultOrganizationProvider;
this.userDto = userDto;
}
private Collection loadGroups() {
if (this.userDto == null) {
return Collections.emptyList();
}
try (DbSession dbSession = dbClient.openSession(false)) {
return dbClient.groupDao().selectByUserLogin(dbSession, userDto.getLogin());
}
}
@Override
@CheckForNull
public String getLogin() {
return userDto == null ? null : userDto.getLogin();
}
@Override
@CheckForNull
public String getName() {
return userDto == null ? null : userDto.getName();
}
@Override
@CheckForNull
public Integer getUserId() {
return userDto == null ? null : userDto.getId();
}
@Override
public Collection getGroups() {
return groups.get();
}
@Override
public boolean isLoggedIn() {
return userDto != null;
}
@Override
public boolean isRoot() {
return userDto != null && userDto.isRoot();
}
@Override
protected boolean hasPermissionImpl(OrganizationPermission permission, String organizationUuid) {
if (permissionsByOrganizationUuid == null) {
permissionsByOrganizationUuid = new HashMap<>();
}
Set permissions = permissionsByOrganizationUuid.computeIfAbsent(organizationUuid, this::loadOrganizationPermissions);
return permissions.contains(permission);
}
private Set loadOrganizationPermissions(String organizationUuid) {
Set permissionKeys;
try (DbSession dbSession = dbClient.openSession(false)) {
if (userDto != null && userDto.getId() != null) {
permissionKeys = dbClient.authorizationDao().selectOrganizationPermissions(dbSession, organizationUuid, userDto.getId());
} else {
permissionKeys = dbClient.authorizationDao().selectOrganizationPermissionsOfAnonymous(dbSession, organizationUuid);
}
}
return permissionKeys.stream()
.map(OrganizationPermission::fromKey)
.collect(MoreCollectors.toSet(permissionKeys.size()));
}
@Override
protected Optional componentUuidToProjectUuid(String componentUuid) {
String projectUuid = projectUuidByComponentUuid.get(componentUuid);
if (projectUuid != null) {
return Optional.of(projectUuid);
}
try (DbSession dbSession = dbClient.openSession(false)) {
com.google.common.base.Optional component = dbClient.componentDao().selectByUuid(dbSession, componentUuid);
if (!component.isPresent()) {
return Optional.empty();
}
// 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);
}
}
@Override
protected boolean hasProjectUuidPermission(String permission, String projectUuid) {
if (permissionsByProjectUuid == null) {
permissionsByProjectUuid = new HashMap<>();
}
Set permissions = permissionsByProjectUuid.computeIfAbsent(projectUuid, this::loadProjectPermissions);
return permissions.contains(permission);
}
private Set loadProjectPermissions(String projectUuid) {
try (DbSession dbSession = dbClient.openSession(false)) {
com.google.common.base.Optional component = dbClient.componentDao().selectByUuid(dbSession, projectUuid);
if (!component.isPresent()) {
return Collections.emptySet();
}
if (component.get().isPrivate()) {
return loadDbPermissions(dbSession, projectUuid);
}
ImmutableSet.Builder builder = ImmutableSet.builder();
builder.addAll(ProjectPermissions.PUBLIC_PERMISSIONS);
builder.addAll(loadDbPermissions(dbSession, projectUuid));
return builder.build();
}
}
private Set loadDbPermissions(DbSession dbSession, String projectUuid) {
if (userDto != null && userDto.getId() != null) {
return dbClient.authorizationDao().selectProjectPermissions(dbSession, projectUuid, userDto.getId());
}
return dbClient.authorizationDao().selectProjectPermissionsOfAnonymous(dbSession, projectUuid);
}
@Override
protected List doKeepAuthorizedComponents(String permission, Collection components) {
try (DbSession dbSession = dbClient.openSession(false)) {
Set projectUuids = components.stream()
.map(c -> defaultIfEmpty(c.getMainBranchProjectUuid(), c.projectUuid()))
.collect(MoreCollectors.toSet(components.size()));
Set authorizedProjectUuids = dbClient.authorizationDao().keepAuthorizedProjectUuids(dbSession, projectUuids, getUserId(), permission);
return components.stream()
.filter(c -> authorizedProjectUuids.contains(c.projectUuid()) || authorizedProjectUuids.contains(c.getMainBranchProjectUuid()))
.collect(MoreCollectors.toList(components.size()));
}
}
@Override
public boolean isSystemAdministrator() {
return isSystemAdministratorSupplier.get();
}
private boolean loadIsSystemAdministrator() {
if (isRoot()) {
return true;
}
try (DbSession dbSession = dbClient.openSession(false)) {
if (!organizationFlags.isEnabled(dbSession)) {
String uuidOfDefaultOrg = defaultOrganizationProvider.get().getUuid();
return hasPermission(OrganizationPermission.ADMINISTER, uuidOfDefaultOrg);
}
// organization feature is enabled -> requires to be root
return false;
}
}
}