Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2024 DBeaver Corp and others
* Copyright (C) 2010-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -23,6 +23,7 @@
import org.jkiss.dbeaver.model.auth.SMSessionContext;
import org.jkiss.dbeaver.model.impl.app.BaseProjectImpl;
import org.jkiss.dbeaver.model.rm.*;
import org.jkiss.utils.ArrayUtils;

import java.nio.file.Path;

Expand Down Expand Up @@ -109,6 +110,20 @@ public boolean isPrivateProject() {
return RMProjectType.USER.equals(getRMProject().getType());
}

@Override
public boolean hasRealmPermission(@NotNull String permission) {
if (getWorkspace().hasRealmPermission(permission)) {
return true;
}
for (String projectPermissionId : ArrayUtils.safeArray(getRMProject().getProjectPermissions())) {
RMProjectPermission projectPermission = RMProjectPermission.fromPermission(projectPermissionId);
if (projectPermission != null && projectPermission.getAllPermissions().contains(permission)) {
return true;
}
}
return false;
}

@Override
public void updateProject(@Nullable String newName, @Nullable String description) throws DBException {
RMProject rmProject = getResourceController().updateProject(this.getId(), new RMProjectInfo(newName, description));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import org.jkiss.dbeaver.model.connection.DBPDriver;
import org.jkiss.dbeaver.registry.DataSourceDescriptor;
import org.jkiss.dbeaver.registry.DataSourcePreferenceStore;
import org.jkiss.dbeaver.registry.network.NetworkHandlerRegistry;
import org.jkiss.dbeaver.runtime.DBSecurityException;
import org.jkiss.utils.CommonUtils;

public class WebConnectionConfigInputHandler<T extends WebConnectionConfig, C extends DataSourceDescriptor> {
Expand Down Expand Up @@ -67,6 +69,18 @@ public C createDataSourceContainer() throws DBWebException {
}

public void updateDataSource(@NotNull C dataSource) throws DBWebException {
DBPConnectionConfiguration storedConfiguration = new DBPConnectionConfiguration(
dataSource.getConnectionConfiguration()
);
DBPConnectionConfiguration updatedConfiguration = new DBPConnectionConfiguration(storedConfiguration);
WebDataSourceUtils.setConnectionConfiguration(
dataSource.getDriver(),
updatedConfiguration,
input,
registry.getProject()
);
validateHandlerConfigurationUpdate(storedConfiguration, updatedConfiguration);

Comment on lines +72 to +83
dataSource.setId(dataSource.getId());
if (!CommonUtils.isEmpty(input.getName())) {
dataSource.setName(input.getName());
Expand All @@ -81,8 +95,10 @@ public void updateDataSource(@NotNull C dataSource) throws DBWebException {
WebDataSourceUtils.setConnectionConfiguration(
dataSource.getDriver(),
dataSource.getConnectionConfiguration(),
input
input,
registry.getProject()
);
validateHandlerConfigurationUpdate(storedConfiguration, dataSource.getConnectionConfiguration());
WebDataSourceUtils.saveAuthProperties(
webSession.getProgressMonitor(),
dataSource,
Expand All @@ -97,10 +113,25 @@ public void updateDataSource(@NotNull C dataSource) throws DBWebException {
preferenceStore.setProperties(input.getDefaultUserPreferences());
}

private void validateHandlerConfigurationUpdate(
@NotNull DBPConnectionConfiguration storedConfiguration,
@NotNull DBPConnectionConfiguration updatedConfiguration
) throws DBWebException {
try {
NetworkHandlerRegistry.getInstance().validateHandlerConfigurationUpdate(
storedConfiguration,
updatedConfiguration,
registry.getProject()::hasRealmPermission
);
} catch (DBSecurityException e) {
throw new DBWebException(e.getMessage(), e);
}
}

@NotNull
protected C createDataSourceContainerFromInput(@NotNull DBPDriver driver) {
protected C createDataSourceContainerFromInput(@NotNull DBPDriver driver) throws DBWebException {
DBPConnectionConfiguration dsConfig = new DBPConnectionConfiguration();
WebDataSourceUtils.setConnectionConfiguration(driver, dsConfig, input);
WebDataSourceUtils.setConnectionConfiguration(driver, dsConfig, input, registry.getProject());
C newDataSource = registry.createDataSource(driver, dsConfig);

newDataSource.setSavePassword(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@
import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry;
import org.jkiss.dbeaver.model.app.DBPProject;
import org.jkiss.dbeaver.model.app.DBPWorkspace;
import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration;
import org.jkiss.dbeaver.model.fs.lock.LockManager;
import org.jkiss.dbeaver.model.fs.lock.LockOptions;
import org.jkiss.dbeaver.model.fs.lock.LockTarget;
import org.jkiss.dbeaver.model.net.DBWNetworkProfile;
import org.jkiss.dbeaver.model.rm.RMController;
import org.jkiss.dbeaver.model.rm.RMEvent;
import org.jkiss.dbeaver.model.rm.RMEventManager;
Expand All @@ -45,6 +47,7 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;

public abstract class BaseLocalResourceController implements RMController {
Expand Down Expand Up @@ -158,31 +161,68 @@ protected DataSourceParseResults updateProjectDataSourcesConfig(
@Nullable List<String> dataSourceIds
) throws DBException {
try (var ignoredLock = lockController.lock(LockTarget.of(projectId), LockOptions.of("updateProjectDataSources"))) {
DBPProject project = getWebProject(projectId, false);
RMLocalProject project = getWebProject(projectId, false);
Map<String, DBPConnectionConfiguration> storedDataSourceConfigurations =
captureCurrentDataSourceConfigurations(project, dataSourceIds);
Map<String, DBWNetworkProfile> storedNetworkProfiles = captureCurrentNetworkProfiles(project);
return doFileWriteOperation(
projectId, project.getMetadataFolder(false),
() -> {
DBPDataSourceRegistry registry = project.getDataSourceRegistry();
DBPDataSourceConfigurationStorage storage = new DataSourceMemoryStorage(configuration.getBytes(
StandardCharsets.UTF_8));
DataSourceConfigurationManager manager = new DataSourceConfigurationManagerBuffer();
final DataSourceParseResults parseResults = ((DataSourcePersistentRegistry) registry).loadDataSources(
List.of(storage),
manager,
dataSourceIds,
true,
dataSourceIds == null
);
registry.checkForErrors();
log.debug("Save data sources configuration in project '" + projectId + "'");
((DataSourcePersistentRegistry) registry).saveDataSources();
registry.checkForErrors();
return parseResults;
try {
final DataSourceParseResults parseResults = ((DataSourcePersistentRegistry) registry).loadDataSources(
List.of(storage),
manager,
dataSourceIds,
true,
dataSourceIds == null
);
registry.checkForErrors();
processLoadedDataSourceConfigurationUpdate(
project,
projectId,
dataSourceIds,
storedDataSourceConfigurations,
storedNetworkProfiles
);
log.debug("Save data sources configuration in project '" + projectId + "'");
((DataSourcePersistentRegistry) registry).saveDataSources();
registry.checkForErrors();
return parseResults;
} catch (DBException | RuntimeException e) {
registry.refreshConfig();
throw e;
}
}
);
}
}

@NotNull
protected Map<String, DBPConnectionConfiguration> captureCurrentDataSourceConfigurations(
@NotNull RMLocalProject project,
@Nullable List<String> dataSourceIds
) {
return Map.of();
}

@NotNull
protected Map<String, DBWNetworkProfile> captureCurrentNetworkProfiles(@NotNull RMLocalProject project) {
return Map.of();
}

protected void processLoadedDataSourceConfigurationUpdate(
@NotNull RMLocalProject project,
@NotNull String projectId,
@Nullable List<String> dataSourceIds,
@NotNull Map<String, DBPConnectionConfiguration> storedDataSourceConfigurations,
@NotNull Map<String, DBWNetworkProfile> storedNetworkProfiles
) throws DBException {
}

@Override
public void deleteProjectDataSources(
@NotNull String projectId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.jkiss.dbeaver.model.auth.SMCredentials;
import org.jkiss.dbeaver.model.auth.SMCredentialsProvider;
import org.jkiss.dbeaver.model.auth.SMObjectType;
import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration;
import org.jkiss.dbeaver.model.fs.lock.LockManager;
import org.jkiss.dbeaver.model.fs.lock.LockOptions;
import org.jkiss.dbeaver.model.fs.lock.LockTarget;
Expand All @@ -54,6 +55,7 @@
import org.jkiss.dbeaver.registry.DataSourceParseResults;
import org.jkiss.dbeaver.registry.ResourceTypeDescriptor;
import org.jkiss.dbeaver.registry.ResourceTypeRegistry;
import org.jkiss.dbeaver.registry.network.NetworkHandlerRegistry;
import org.jkiss.dbeaver.runtime.DBWorkbench;
import org.jkiss.dbeaver.utils.GeneralUtils;
import org.jkiss.utils.CommonUtils;
Expand All @@ -66,6 +68,7 @@
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Expand Down Expand Up @@ -419,6 +422,79 @@ public boolean updateProjectDataSources(
return parseResults != null;
}

@Override
@NotNull
protected Map<String, DBPConnectionConfiguration> captureCurrentDataSourceConfigurations(
@NotNull RMLocalProject project,
@Nullable List<String> dataSourceIds
) {
return project.getDataSourceRegistry().getDataSources().stream()
.filter(ds -> dataSourceIds == null || dataSourceIds.contains(ds.getId()))
.collect(Collectors.toMap(
DBPDataSourceContainer::getId,
ds -> new DBPConnectionConfiguration(ds.getConnectionConfiguration())
));
}

@Override
@NotNull
protected Map<String, DBWNetworkProfile> captureCurrentNetworkProfiles(@NotNull RMLocalProject project) {
return project.getDataSourceRegistry().getNetworkProfiles().getProfiles().stream()
.collect(Collectors.toMap(
DBWNetworkProfile::getProfileId,
DBWNetworkProfile::new
));
}

@Override
protected void processLoadedDataSourceConfigurationUpdate(
@NotNull RMLocalProject project,
@NotNull String projectId,
@Nullable List<String> dataSourceIds,
@NotNull Map<String, DBPConnectionConfiguration> storedDataSourceConfigurations,
@NotNull Map<String, DBWNetworkProfile> storedNetworkProfiles
) throws DBException {
Set<RMProjectPermission> userProjectPermissions = getProjectPermissions(projectId, project.getProjectType());
Set<String> grantedPermissions = userProjectPermissions.stream()
.filter(Objects::nonNull)
.flatMap(permission -> permission.getAllPermissions().stream())
.collect(Collectors.toSet());
Predicate<String> hasPermission = permission ->
grantedPermissions.contains(permission) ||
credentialsProvider.hasPermission(DBWConstants.PERMISSION_ADMIN) ||
credentialsProvider.hasPermission(permission);

for (DBPDataSourceContainer dataSource : project.getDataSourceRegistry().getDataSources()) {
if (dataSourceIds != null && !dataSourceIds.contains(dataSource.getId())) {
continue;
}

DBPConnectionConfiguration storedConfiguration = storedDataSourceConfigurations.get(dataSource.getId());
NetworkHandlerRegistry.getInstance().validateHandlerConfigurationUpdate(
storedConfiguration,
dataSource.getConnectionConfiguration(),
hasPermission
);
}

Map<String, DBWNetworkProfile> updatedNetworkProfiles = project.getDataSourceRegistry()
.getNetworkProfiles()
.getProfiles()
.stream()
.collect(Collectors.toMap(DBWNetworkProfile::getProfileId, profile -> profile));
Set<String> profileIds = new LinkedHashSet<>(storedNetworkProfiles.keySet());
profileIds.addAll(updatedNetworkProfiles.keySet());
for (String profileId : profileIds) {
DBWNetworkProfile storedProfile = storedNetworkProfiles.get(profileId);
DBWNetworkProfile updatedProfile = updatedNetworkProfiles.get(profileId);
NetworkHandlerRegistry.getInstance().validateHandlerConfigurationUpdate(
storedProfile == null ? List.of() : storedProfile.getConfigurations(),
updatedProfile == null ? List.of() : updatedProfile.getConfigurations(),
hasPermission
);
}
}

@Override
public void deleteProjectDataSources(@NotNull String projectId, @NotNull String[] dataSourceIds) throws DBException {
super.deleteProjectDataSources(projectId, dataSourceIds);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.DBRuntimeException;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.DBConstants;
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
import org.jkiss.dbeaver.model.access.DBAAuthCredentials;
import org.jkiss.dbeaver.model.access.DBAPermissionRealm;
import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry;
import org.jkiss.dbeaver.model.app.DBPProject;
import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration;
Expand Down Expand Up @@ -290,6 +292,24 @@ public static void setConnectionConfiguration(
@NotNull DBPConnectionConfiguration dsConfig,
@NotNull WebConnectionConfig config
) {
try {
setConnectionConfiguration(
driver,
dsConfig,
config,
DBWorkbench.getPlatform().getWorkspace()
);
} catch (DBWebException e) {
throw new DBRuntimeException(e);
}
}

public static void setConnectionConfiguration(
@NotNull DBPDriver driver,
@NotNull DBPConnectionConfiguration dsConfig,
@NotNull WebConnectionConfig config,
@NotNull DBAPermissionRealm permissionRealm
) throws DBWebException {
setMainProperties(dsConfig, config);
if (config.getProperties() != null) {
Map<String, String> newProps = new LinkedHashMap<>();
Expand Down Expand Up @@ -342,10 +362,14 @@ public static void setConnectionConfiguration(
for (WebNetworkHandlerConfigInput nhc : config.getNetworkHandlersConfig()) {
DBWHandlerConfiguration handlerConfig = dsConfig.getHandler(nhc.getId());
if (handlerConfig == null) {
NetworkHandlerDescriptor handlerDescriptor = NetworkHandlerRegistry.getInstance().getDescriptor(nhc.getId());
NetworkHandlerDescriptor handlerDescriptor = NetworkHandlerRegistry.getInstance()
.getDescriptor(nhc.getId(), permissionRealm);
if (handlerDescriptor == null) {
log.warn("Can't find network handler '" + nhc.getId() + "'");
continue;
if (NetworkHandlerRegistry.getInstance().getRawDescriptor(nhc.getId()) == null) {
log.warn("Can't find network handler '" + nhc.getId() + "'");
continue;
}
throw new DBWebException("No permissions to configure network handler '" + nhc.getId() + "'");
} else {
handlerConfig = new DBWHandlerConfiguration(handlerDescriptor, null);
WebDataSourceUtils.updateHandlerConfig(handlerConfig, nhc);
Expand Down
Loading