mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
Merge remote-tracking branch 'origin/devel' into feat/CB-2339-enable-users
This commit is contained in:
@@ -20,6 +20,7 @@ import io.cloudbeaver.model.rm.RMUtils;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry;
|
||||
import org.jkiss.dbeaver.model.auth.SMSessionContext;
|
||||
import org.jkiss.dbeaver.model.rm.RMProject;
|
||||
import org.jkiss.dbeaver.registry.BaseProjectImpl;
|
||||
@@ -93,7 +94,7 @@ public class VirtualProjectImpl extends BaseProjectImpl {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected DataSourceRegistry createDataSourceRegistry() {
|
||||
return new WebDataSourceRegistryProxy(super.createDataSourceRegistry(), dataSourceFilter);
|
||||
protected DBPDataSourceRegistry createDataSourceRegistry() {
|
||||
return new WebDataSourceRegistryProxy(new DataSourceRegistry(this), dataSourceFilter);
|
||||
}
|
||||
}
|
||||
|
||||
+246
-13
@@ -7,30 +7,40 @@ import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.model.*;
|
||||
import org.jkiss.dbeaver.model.access.DBAAuthProfile;
|
||||
import org.jkiss.dbeaver.model.access.DBACredentialsProvider;
|
||||
import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry;
|
||||
import org.jkiss.dbeaver.model.app.DBPProject;
|
||||
import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDriver;
|
||||
import org.jkiss.dbeaver.model.net.DBWNetworkProfile;
|
||||
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
|
||||
import org.jkiss.dbeaver.model.struct.DBSObjectFilter;
|
||||
import org.jkiss.dbeaver.registry.DataSourceDescriptor;
|
||||
import org.jkiss.dbeaver.registry.DataSourceFolder;
|
||||
import org.jkiss.dbeaver.registry.DataSourceConfigurationManager;
|
||||
import org.jkiss.dbeaver.registry.DataSourcePersistentRegistry;
|
||||
import org.jkiss.dbeaver.registry.DataSourceRegistry;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class WebDataSourceRegistryProxy extends DataSourceRegistry {
|
||||
public class WebDataSourceRegistryProxy implements DBPDataSourceRegistry, DataSourcePersistentRegistry {
|
||||
private final DataSourceFilter dataSourceFilter;
|
||||
private final DataSourceRegistry dataSourceRegistry;
|
||||
|
||||
public WebDataSourceRegistryProxy(DataSourceRegistry dataSourceRegistry, DataSourceFilter filter) {
|
||||
super(dataSourceRegistry.getProject());
|
||||
this.dataSourceRegistry = dataSourceRegistry;
|
||||
this.dataSourceFilter = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DBPProject getProject() {
|
||||
return dataSourceRegistry.getProject();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public DataSourceDescriptor getDataSource(String id) {
|
||||
DataSourceDescriptor dataSource = super.getDataSource(id);
|
||||
public DBPDataSourceContainer getDataSource(String id) {
|
||||
DBPDataSourceContainer dataSource = dataSourceRegistry.getDataSource(id);
|
||||
if (dataSourceFilter != null && !dataSourceFilter.filter(dataSource)) {
|
||||
return null;
|
||||
}
|
||||
@@ -39,17 +49,17 @@ public class WebDataSourceRegistryProxy extends DataSourceRegistry {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public DataSourceDescriptor getDataSource(DBPDataSource dataSource) {
|
||||
public DBPDataSourceContainer getDataSource(DBPDataSource dataSource) {
|
||||
if (dataSourceFilter != null && !dataSourceFilter.filter(dataSource.getContainer())) {
|
||||
return null;
|
||||
}
|
||||
return super.getDataSource(dataSource);
|
||||
return dataSourceRegistry.getDataSource(dataSource);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public DataSourceDescriptor findDataSourceByName(String name) {
|
||||
var dataSource = super.findDataSourceByName(name);
|
||||
public DBPDataSourceContainer findDataSourceByName(String name) {
|
||||
var dataSource = dataSourceRegistry.findDataSourceByName(name);
|
||||
if (dataSource != null) {
|
||||
if (dataSourceFilter == null || dataSourceFilter.filter(dataSource)) {
|
||||
return dataSource;
|
||||
@@ -61,7 +71,7 @@ public class WebDataSourceRegistryProxy extends DataSourceRegistry {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<? extends DBPDataSourceContainer> getDataSourcesByProfile(@NotNull DBWNetworkProfile profile) {
|
||||
return super.getDataSourcesByProfile(profile)
|
||||
return dataSourceRegistry.getDataSourcesByProfile(profile)
|
||||
.stream()
|
||||
.filter(dataSourceFilter::filter)
|
||||
.collect(Collectors.toList());
|
||||
@@ -69,10 +79,233 @@ public class WebDataSourceRegistryProxy extends DataSourceRegistry {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<DataSourceDescriptor> getDataSources() {
|
||||
return super.getDataSources()
|
||||
public List<DBPDataSourceContainer> getDataSources() {
|
||||
return dataSourceRegistry.getDataSources()
|
||||
.stream()
|
||||
.filter(dataSourceFilter::filter)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DBPDataSourceContainer createDataSource(DBPDriver driver, DBPConnectionConfiguration connConfig) {
|
||||
return dataSourceRegistry.createDataSource(driver, connConfig);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DBPDataSourceContainer createDataSource(DBPDataSourceContainer source) {
|
||||
return dataSourceRegistry.createDataSource(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDataSourceListener(@NotNull DBPEventListener listener) {
|
||||
dataSourceRegistry.addDataSourceListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeDataSourceListener(@NotNull DBPEventListener listener) {
|
||||
return dataSourceRegistry.removeDataSourceListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDataSource(@NotNull DBPDataSourceContainer dataSource) {
|
||||
dataSourceRegistry.addDataSource(dataSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDataSource(@NotNull DBPDataSourceContainer dataSource) {
|
||||
dataSourceRegistry.removeDataSource(dataSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDataSource(@NotNull DBPDataSourceContainer dataSource) {
|
||||
dataSourceRegistry.updateDataSource(dataSource);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<? extends DBPDataSourceFolder> getAllFolders() {
|
||||
return dataSourceRegistry.getAllFolders();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<? extends DBPDataSourceFolder> getRootFolders() {
|
||||
return dataSourceRegistry.getRootFolders();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DBPDataSourceFolder getFolder(String path) {
|
||||
return dataSourceRegistry.getFolder(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DBPDataSourceFolder addFolder(DBPDataSourceFolder parent, String name) {
|
||||
return dataSourceRegistry.addFolder(parent, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeFolder(DBPDataSourceFolder folder, boolean dropContents) {
|
||||
dataSourceRegistry.removeFolder(folder, dropContents);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public DBSObjectFilter getSavedFilter(String name) {
|
||||
return dataSourceRegistry.getSavedFilter(name);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<DBSObjectFilter> getSavedFilters() {
|
||||
return dataSourceRegistry.getSavedFilters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSavedFilter(DBSObjectFilter filter) {
|
||||
dataSourceRegistry.updateSavedFilter(filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSavedFilter(String filterName) {
|
||||
dataSourceRegistry.removeSavedFilter(filterName);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public DBWNetworkProfile getNetworkProfile(String name) {
|
||||
return dataSourceRegistry.getNetworkProfile(name);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<DBWNetworkProfile> getNetworkProfiles() {
|
||||
return dataSourceRegistry.getNetworkProfiles();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNetworkProfile(DBWNetworkProfile profile) {
|
||||
dataSourceRegistry.updateNetworkProfile(profile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNetworkProfile(DBWNetworkProfile profile) {
|
||||
dataSourceRegistry.removeNetworkProfile(profile);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public DBAAuthProfile getAuthProfile(String id) {
|
||||
return dataSourceRegistry.getAuthProfile(id);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<DBAAuthProfile> getAllAuthProfiles() {
|
||||
return dataSourceRegistry.getAllAuthProfiles();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<DBAAuthProfile> getApplicableAuthProfiles(@Nullable DBPDriver driver) {
|
||||
return dataSourceRegistry.getApplicableAuthProfiles(driver);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAuthProfile(DBAAuthProfile profile) {
|
||||
dataSourceRegistry.updateAuthProfile(profile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAuthProfile(DBAAuthProfile profile) {
|
||||
dataSourceRegistry.removeAuthProfile(profile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flushConfig() {
|
||||
dataSourceRegistry.flushConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshConfig() {
|
||||
dataSourceRegistry.refreshConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Throwable getLastError() {
|
||||
return dataSourceRegistry.getLastError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasError() {
|
||||
return dataSourceRegistry.hasError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkForErrors() throws DBException {
|
||||
dataSourceRegistry.checkForErrors();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyDataSourceListeners(DBPEvent event) {
|
||||
dataSourceRegistry.notifyDataSourceListeners(event);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ISecurePreferences getSecurePreferences() {
|
||||
return dataSourceRegistry.getSecurePreferences();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public DBACredentialsProvider getAuthCredentialsProvider() {
|
||||
return dataSourceRegistry.getAuthCredentialsProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
dataSourceRegistry.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAuthCredentialsProvider(DBACredentialsProvider authCredentialsProvider) {
|
||||
dataSourceRegistry.setAuthCredentialsProvider(authCredentialsProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<DBPDataSourceFolder> getTemporaryFolders() {
|
||||
return dataSourceRegistry.getTemporaryFolders();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadDataSources(
|
||||
@NotNull List<DBPDataSourceConfigurationStorage> storages,
|
||||
@NotNull DataSourceConfigurationManager manager,
|
||||
boolean refresh,
|
||||
boolean purgeUntouched
|
||||
) {
|
||||
dataSourceRegistry.loadDataSources(storages, manager, refresh, purgeUntouched);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveDataSources() {
|
||||
dataSourceRegistry.saveDataSources();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSourceConfigurationManager getConfigurationManager() {
|
||||
return dataSourceRegistry.getConfigurationManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveConfigurationToManager(
|
||||
@NotNull DBRProgressMonitor monitor,
|
||||
@NotNull DataSourceConfigurationManager configurationManager,
|
||||
@Nullable Predicate<DBPDataSourceContainer> filter
|
||||
) {
|
||||
dataSourceRegistry.saveConfigurationToManager(monitor, configurationManager, filter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+7
@@ -22,6 +22,7 @@ import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.model.app.DBPProject;
|
||||
import org.jkiss.dbeaver.model.auth.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class AbstractSessionFederated implements SMSessionFederated {
|
||||
@@ -56,6 +57,12 @@ public abstract class AbstractSessionFederated implements SMSessionFederated {
|
||||
return parentSession.getSessionPrincipal();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public LocalDateTime getSessionStart() {
|
||||
return parentSession.getSessionStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicationSession() {
|
||||
return false;
|
||||
|
||||
+7
-6
@@ -27,6 +27,7 @@ import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.DBPDataSourceConfigurationStorage;
|
||||
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
|
||||
import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry;
|
||||
import org.jkiss.dbeaver.model.app.DBPProject;
|
||||
import org.jkiss.dbeaver.model.auth.SMCredentials;
|
||||
@@ -259,7 +260,7 @@ public class LocalResourceController implements RMController {
|
||||
DBPDataSourceRegistry registry = projectMetadata.getDataSourceRegistry();
|
||||
registry.checkForErrors();
|
||||
DataSourceConfigurationManagerBuffer buffer = new DataSourceConfigurationManagerBuffer();
|
||||
((DataSourceRegistry)registry).saveConfigurationToManager(new VoidProgressMonitor(), buffer, null);
|
||||
((DataSourcePersistentRegistry) registry).saveConfigurationToManager(new VoidProgressMonitor(), buffer, null);
|
||||
registry.checkForErrors();
|
||||
return new String(buffer.getData(), StandardCharsets.UTF_8);
|
||||
}
|
||||
@@ -267,22 +268,22 @@ public class LocalResourceController implements RMController {
|
||||
@Override
|
||||
public void saveProjectDataSources(@NotNull String projectId, @NotNull String configuration) throws DBException {
|
||||
final DBPProject project = getProjectMetadata(projectId);
|
||||
final DataSourceRegistry registry = (DataSourceRegistry) project.getDataSourceRegistry();
|
||||
final DBPDataSourceRegistry registry = project.getDataSourceRegistry();
|
||||
final DBPDataSourceConfigurationStorage storage = new DataSourceMemoryStorage(configuration.getBytes(StandardCharsets.UTF_8));
|
||||
final DataSourceConfigurationManager manager = new DataSourceConfigurationManagerBuffer();
|
||||
registry.loadDataSources(List.of(storage), manager, true, false);
|
||||
((DataSourcePersistentRegistry) registry).loadDataSources(List.of(storage), manager, true, false);
|
||||
registry.checkForErrors();
|
||||
registry.saveDataSources();
|
||||
((DataSourcePersistentRegistry) registry).saveDataSources();
|
||||
registry.checkForErrors();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteProjectDataSources(@NotNull String projectId, @NotNull String[] dataSourceIds) throws DBException {
|
||||
final DBPProject project = getProjectMetadata(projectId);
|
||||
final DataSourceRegistry registry = (DataSourceRegistry) project.getDataSourceRegistry();
|
||||
final DBPDataSourceRegistry registry = project.getDataSourceRegistry();
|
||||
|
||||
for (String dataSourceId : dataSourceIds) {
|
||||
final DataSourceDescriptor dataSource = registry.getDataSource(dataSourceId);
|
||||
final DBPDataSourceContainer dataSource = registry.getDataSource(dataSourceId);
|
||||
|
||||
if (dataSource != null) {
|
||||
registry.removeDataSource(dataSource);
|
||||
|
||||
+11
-5
@@ -16,10 +16,7 @@
|
||||
*/
|
||||
package io.cloudbeaver.model.session;
|
||||
|
||||
import io.cloudbeaver.DBWConstants;
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.DataSourceFilter;
|
||||
import io.cloudbeaver.VirtualProjectImpl;
|
||||
import io.cloudbeaver.*;
|
||||
import io.cloudbeaver.model.WebAsyncTaskInfo;
|
||||
import io.cloudbeaver.model.WebConnectionInfo;
|
||||
import io.cloudbeaver.model.WebServerMessage;
|
||||
@@ -70,6 +67,9 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Function;
|
||||
@@ -160,6 +160,12 @@ public class WebSession extends AbstractSessionPersistent implements SMSession,
|
||||
return id;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public LocalDateTime getSessionStart() {
|
||||
return LocalDateTime.ofInstant(Instant.ofEpochMilli(createTime), ZoneId.systemDefault());
|
||||
}
|
||||
|
||||
public WebApplication getApplication() {
|
||||
return application;
|
||||
}
|
||||
@@ -357,7 +363,7 @@ public class WebSession extends AbstractSessionPersistent implements SMSession,
|
||||
this,
|
||||
filter);
|
||||
DBPDataSourceRegistry dataSourceRegistry = sessionProject.getDataSourceRegistry();
|
||||
((DataSourceRegistry) dataSourceRegistry).setAuthCredentialsProvider(this);
|
||||
dataSourceRegistry.setAuthCredentialsProvider(this);
|
||||
addSessionProject(sessionProject);
|
||||
if (!project.isShared() || application.isConfigurationMode()) {
|
||||
this.defaultProject = sessionProject;
|
||||
|
||||
@@ -29,6 +29,7 @@ import java.net.http.HttpResponse;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class WebTestUtils {
|
||||
@@ -42,12 +43,24 @@ public class WebTestUtils {
|
||||
|
||||
|
||||
public static Map<String, Object> doPost(String apiUrl, String input, HttpClient client) throws Exception {
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
return doPostWithHeaders(apiUrl, input, client, List.of());
|
||||
}
|
||||
|
||||
public static Map<String, Object> doPostWithHeaders(
|
||||
String apiUrl,
|
||||
String input,
|
||||
HttpClient client,
|
||||
List<String> headers
|
||||
) throws Exception {
|
||||
HttpRequest.Builder requestBuilder = HttpRequest.newBuilder()
|
||||
.uri(URI.create(apiUrl))
|
||||
.POST(HttpRequest.BodyPublishers.ofString(input))
|
||||
.header("Content-Type", "application/json")
|
||||
.build();
|
||||
.header("Content-Type", "application/json");
|
||||
|
||||
if (!headers.isEmpty()) {
|
||||
requestBuilder.headers(headers.toArray(String[]::new));
|
||||
}
|
||||
HttpRequest request = requestBuilder.build();
|
||||
HttpResponse<String> response = client.send(request,
|
||||
HttpResponse.BodyHandlers.ofString());
|
||||
|
||||
|
||||
@@ -198,6 +198,7 @@ type DriverInfo {
|
||||
embedded: Boolean
|
||||
enabled: Boolean!
|
||||
requiresServerName: Boolean
|
||||
requiresDatabaseName: Boolean
|
||||
|
||||
licenseRequired: Boolean
|
||||
license: String
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.jkiss.dbeaver.model.DBPDataSourceContainer;
|
||||
import org.jkiss.dbeaver.model.DBPDataSourceFolder;
|
||||
import org.jkiss.dbeaver.model.access.DBAAuthCredentials;
|
||||
import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry;
|
||||
import org.jkiss.dbeaver.model.app.DBPProject;
|
||||
import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDriver;
|
||||
import org.jkiss.dbeaver.model.impl.auth.AuthModelDatabaseNativeCredentials;
|
||||
@@ -42,7 +43,6 @@ import org.jkiss.dbeaver.model.navigator.DBNModel;
|
||||
import org.jkiss.dbeaver.model.navigator.DBNProject;
|
||||
import org.jkiss.dbeaver.model.net.DBWHandlerConfiguration;
|
||||
import org.jkiss.dbeaver.model.net.ssh.SSHConstants;
|
||||
import org.jkiss.dbeaver.model.rm.RMProject;
|
||||
import org.jkiss.dbeaver.registry.DataSourceDescriptor;
|
||||
import org.jkiss.dbeaver.registry.DataSourceNavigatorSettings;
|
||||
import org.jkiss.dbeaver.registry.DataSourceProviderDescriptor;
|
||||
@@ -169,7 +169,6 @@ public class WebServiceUtils extends WebCommonUtils {
|
||||
if (config.getServerName() != null) {
|
||||
dsConfig.setServerName(config.getServerName());
|
||||
}
|
||||
dsConfig.setUrl(driver.getConnectionURL(dsConfig));
|
||||
}
|
||||
if (config.getProperties() != null) {
|
||||
Map<String, String> newProps = new LinkedHashMap<>();
|
||||
@@ -197,6 +196,9 @@ public class WebServiceUtils extends WebCommonUtils {
|
||||
if (config.getConfigurationType() != null) {
|
||||
dsConfig.setConfigurationType(config.getConfigurationType());
|
||||
}
|
||||
if (CommonUtils.isEmpty(config.getUrl())) {
|
||||
dsConfig.setUrl(driver.getConnectionURL(dsConfig));
|
||||
}
|
||||
// Save network handlers
|
||||
if (config.getNetworkHandlersConfig() != null) {
|
||||
for (WebNetworkHandlerConfigInput nhc : config.getNetworkHandlersConfig()) {
|
||||
@@ -340,6 +342,9 @@ public class WebServiceUtils extends WebCommonUtils {
|
||||
DBNModel.updateConfigAndRefreshDatabases(projectNode.getDatabases());
|
||||
}
|
||||
|
||||
public static boolean isGlobalProject(DBPProject project) {
|
||||
return CommonUtils.equalObjects(CBApplication.getInstance().getDefaultProjectName(), project.getName());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+10
@@ -44,6 +44,7 @@ import java.util.Map;
|
||||
public class WebDatabaseDriverConfig {
|
||||
|
||||
public static final String URL_SERVER_FIELD = "{server}";
|
||||
public static final String URL_DATABASE_FIELD = ".*(?:\\{(?:database|file|folder)}).*";
|
||||
private final WebSession webSession;
|
||||
private final DBPDriver driver;
|
||||
private String id;
|
||||
@@ -249,4 +250,13 @@ public class WebDatabaseDriverConfig {
|
||||
public DBPDriverConfigurationType[] getConfigurationTypes() {
|
||||
return driver.getSupportedConfigurationTypes().toArray(DBPDriverConfigurationType[]::new);
|
||||
}
|
||||
|
||||
|
||||
@Property
|
||||
public boolean getRequiresDatabaseName() {
|
||||
if (driver.getSampleURL() == null) {
|
||||
return false;
|
||||
}
|
||||
return driver.getSampleURL().matches(URL_DATABASE_FIELD);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,9 @@ import java.util.Map;
|
||||
* Application configuration
|
||||
*/
|
||||
public class CBAppConfig extends BaseAuthWebAppConfiguration implements WebAuthConfiguration {
|
||||
public static final DataSourceNavigatorSettings DEFAULT_VIEW_SETTINGS = DataSourceNavigatorSettings.PRESET_FULL.getSettings();
|
||||
public static final DataSourceNavigatorSettings.Preset PRESET_WEB = new DataSourceNavigatorSettings.Preset("web", "Web", "Default view");
|
||||
|
||||
public static final DataSourceNavigatorSettings DEFAULT_VIEW_SETTINGS = PRESET_WEB.getSettings();
|
||||
|
||||
private boolean supportsCustomConnections;
|
||||
private boolean supportsConnectionBrowser;
|
||||
|
||||
+11
-6
@@ -21,17 +21,14 @@ import io.cloudbeaver.DBWConstants;
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.WebServiceUtils;
|
||||
import io.cloudbeaver.model.*;
|
||||
import io.cloudbeaver.model.app.BaseWebApplication;
|
||||
import io.cloudbeaver.model.app.WebAppConfiguration;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import io.cloudbeaver.registry.WebHandlerRegistry;
|
||||
import io.cloudbeaver.registry.WebSessionHandlerDescriptor;
|
||||
import io.cloudbeaver.server.CBAppConfig;
|
||||
import io.cloudbeaver.server.CBApplication;
|
||||
import io.cloudbeaver.server.CBPlatform;
|
||||
import io.cloudbeaver.service.core.DBWServiceCore;
|
||||
import io.cloudbeaver.utils.WebDataSourceUtils;
|
||||
import io.cloudbeaver.utils.WebConnectionFolderUtils;
|
||||
import io.cloudbeaver.utils.WebDataSourceUtils;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
@@ -55,7 +52,6 @@ import org.jkiss.dbeaver.registry.DataSourceDescriptor;
|
||||
import org.jkiss.dbeaver.registry.DataSourceProviderRegistry;
|
||||
import org.jkiss.dbeaver.registry.network.NetworkHandlerDescriptor;
|
||||
import org.jkiss.dbeaver.registry.network.NetworkHandlerRegistry;
|
||||
import org.jkiss.dbeaver.runtime.DBWorkbench;
|
||||
import org.jkiss.dbeaver.runtime.jobs.ConnectionTestJob;
|
||||
import org.jkiss.dbeaver.utils.RuntimeUtils;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
@@ -294,6 +290,8 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
connectionInfo.clearSavedCredentials();
|
||||
}
|
||||
// Mark all specified network configs as saved
|
||||
boolean[] saveConfig = new boolean[1];
|
||||
|
||||
if (networkCredentials != null) {
|
||||
networkCredentials.forEach(c -> {
|
||||
if (CommonUtils.toBoolean(c.isSavePassword()) && !CommonUtils.isEmpty(c.getUserName())) {
|
||||
@@ -302,7 +300,7 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
handlerCfg.setUserName(c.getUserName());
|
||||
handlerCfg.setPassword(c.getPassword());
|
||||
handlerCfg.setSavePassword(true);
|
||||
dataSourceContainer.persistConfiguration();
|
||||
saveConfig[0] = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -316,6 +314,13 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
true);
|
||||
|
||||
WebDataSourceUtils.saveCredentialsInDataSource(connectionInfo, dataSourceContainer, dataSourceContainer.getConnectionConfiguration());
|
||||
saveConfig[0] = true;
|
||||
}
|
||||
if (WebServiceUtils.isGlobalProject(dataSourceContainer.getProject())) {
|
||||
// Do not flush config for global project (only admin can do it - CB-2415)
|
||||
saveConfig[0] = false;
|
||||
}
|
||||
if (saveConfig[0]) {
|
||||
dataSourceContainer.persistConfiguration();
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -160,7 +160,7 @@ public class WebNavigatorNodeInfo {
|
||||
} else if (node instanceof DBNLocalFolder) {
|
||||
DataSourceFolder folder = (DataSourceFolder) ((DBNLocalFolder) node).getFolder();
|
||||
String projectName = folder.getDataSourceRegistry().getProject().getName();
|
||||
Set<DBPDataSourceFolder> tempFolders = ((DataSourceRegistry) folder.getDataSourceRegistry()).getTemporaryFolders();
|
||||
Set<DBPDataSourceFolder> tempFolders = folder.getDataSourceRegistry().getTemporaryFolders();
|
||||
isShared = !projectName.equals(session.getUserId()) || tempFolders.contains(folder);
|
||||
}
|
||||
if (isShared) {
|
||||
|
||||
+2
-2
@@ -660,7 +660,7 @@ public class WebServiceAdmin implements DBWServiceAdmin {
|
||||
String connectionId
|
||||
) throws DBWebException {
|
||||
DBPProject globalProject = webSession.getProjectById(projectId);
|
||||
if (!CommonUtils.equalObjects(globalProject.getName(), CBApplication.getInstance().getDefaultProjectName())) {
|
||||
if (!WebServiceUtils.isGlobalProject(globalProject)) {
|
||||
throw new DBWebException("Project '" + projectId + "'is not global");
|
||||
}
|
||||
try {
|
||||
@@ -685,7 +685,7 @@ public class WebServiceAdmin implements DBWServiceAdmin {
|
||||
@NotNull List<String> subjects
|
||||
) throws DBWebException {
|
||||
DBPProject globalProject = webSession.getProjectById(projectId);
|
||||
if (!CommonUtils.equalObjects(globalProject.getName(), CBApplication.getInstance().getDefaultProjectName())) {
|
||||
if (!WebServiceUtils.isGlobalProject(globalProject)) {
|
||||
throw new DBWebException("Project '" + projectId + "'is not global");
|
||||
}
|
||||
DBPDataSourceContainer dataSource = getGlobalRegistry(webSession).getDataSource(connectionId);
|
||||
|
||||
+4
-31
@@ -16,31 +16,26 @@
|
||||
*/
|
||||
package io.cloudbeaver.service.auth;
|
||||
|
||||
import io.cloudbeaver.DBWUserIdentity;
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.auth.SMAuthProviderExternal;
|
||||
import io.cloudbeaver.auth.provider.rp.RPAuthProvider;
|
||||
import io.cloudbeaver.model.session.WebAuthInfo;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import io.cloudbeaver.model.user.WebUser;
|
||||
import io.cloudbeaver.model.session.WebSessionAuthProcessor;
|
||||
import io.cloudbeaver.server.CBApplication;
|
||||
import io.cloudbeaver.service.DBWSessionHandler;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.auth.SMAuthInfo;
|
||||
import org.jkiss.dbeaver.model.auth.SMSession;
|
||||
import org.jkiss.dbeaver.model.security.SMConstants;
|
||||
import org.jkiss.dbeaver.model.security.SMController;
|
||||
import org.jkiss.dbeaver.model.security.exception.SMException;
|
||||
import org.jkiss.dbeaver.registry.auth.AuthProviderDescriptor;
|
||||
import org.jkiss.dbeaver.registry.auth.AuthProviderRegistry;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -70,7 +65,6 @@ public class RPSessionHandler implements DBWSessionHandler {
|
||||
String userName = request.getHeader(RPAuthProvider.X_USER);
|
||||
String roles = request.getHeader(RPAuthProvider.X_ROLE);
|
||||
List<String> userRoles = roles == null ? Collections.emptyList() : List.of(roles.split("\\|"));
|
||||
SMSession authSession;
|
||||
if (userName != null) {
|
||||
try {
|
||||
Map<String, Object> credentials = new HashMap<>();
|
||||
@@ -79,39 +73,18 @@ public class RPSessionHandler implements DBWSessionHandler {
|
||||
sessionParameters.put(SMConstants.SESSION_PARAM_TRUSTED_USER_ROLES, userRoles);
|
||||
Map<String, Object> userCredentials = authProviderExternal.authExternalUser(
|
||||
webSession.getProgressMonitor(), sessionParameters, credentials);
|
||||
String currentSmSessionId = webSession.getUser() == null ? null : webSession.getUserContext().getSmSessionId();
|
||||
try {
|
||||
SMAuthInfo smAuthInfo = securityController.authenticate(
|
||||
webSession.getSessionId(),
|
||||
webSession.getUserContext().getSmSessionId(),
|
||||
currentSmSessionId,
|
||||
sessionParameters,
|
||||
WebSession.CB_SESSION_TYPE, authProvider.getId(), null, userCredentials);
|
||||
webSession.updateSMAuthInfo(smAuthInfo);
|
||||
new WebSessionAuthProcessor(webSession, smAuthInfo, false).authenticateSession();
|
||||
} catch (SMException e) {
|
||||
log.debug("Error during user authentication", e);
|
||||
throw e;
|
||||
}
|
||||
WebUser user = webSession.getUser();
|
||||
DBWUserIdentity userIdentity = authProviderExternal.getUserIdentity(
|
||||
webSession.getProgressMonitor(), sessionParameters, credentials);
|
||||
|
||||
if (CommonUtils.isEmpty(user.getDisplayName())) {
|
||||
user.setDisplayName(userIdentity.getDisplayName());
|
||||
}
|
||||
authSession = authProviderExternal.openSession(
|
||||
webSession.getProgressMonitor(),
|
||||
webSession,
|
||||
sessionParameters,
|
||||
userCredentials);
|
||||
|
||||
WebAuthInfo authInfo = new WebAuthInfo(
|
||||
webSession,
|
||||
user,
|
||||
authProvider,
|
||||
userIdentity,
|
||||
authSession,
|
||||
OffsetDateTime.now());
|
||||
authInfo.setMessage("Authenticated with " + authProvider.getLabel() + " provider");
|
||||
webSession.addAuthInfo(authInfo);
|
||||
} catch (Exception e) {
|
||||
throw new DBWebException("Error", e);
|
||||
}
|
||||
|
||||
+8
@@ -24,6 +24,8 @@ import org.jkiss.dbeaver.model.auth.SMSession;
|
||||
import org.jkiss.dbeaver.model.auth.SMSessionContext;
|
||||
import org.jkiss.dbeaver.model.auth.SMSessionPrincipal;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* Local auth provider
|
||||
*/
|
||||
@@ -65,6 +67,12 @@ public class LocalAuthSession implements SMSession {
|
||||
return webSession.getSessionId();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public LocalDateTime getSessionStart() {
|
||||
return webSession.getSessionStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicationSession() {
|
||||
return false;
|
||||
|
||||
+42
@@ -1,15 +1,23 @@
|
||||
package io.cloudbeaver.test.platform;
|
||||
|
||||
import io.cloudbeaver.auth.provider.rp.RPAuthProvider;
|
||||
import io.cloudbeaver.utils.WebTestUtils;
|
||||
import org.jkiss.dbeaver.model.auth.SMAuthStatus;
|
||||
import org.jkiss.dbeaver.model.data.json.JSONUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class AuthenticationTest {
|
||||
public static final String GQL_TEMPLATE_OPEN_SESSION = "openSession.json";
|
||||
public static final String GQL_TEMPLATE_ACTIVE_USER = "activeUser.json";
|
||||
public static final String REVERSE_PROXY_TEST_USER = "reverseProxyTestUser";
|
||||
|
||||
@Test
|
||||
public void testLoginUser() throws Exception {
|
||||
@@ -18,4 +26,38 @@ public class AuthenticationTest {
|
||||
client, CEServerTestSuite.getScriptsPath(), CEServerTestSuite.GQL_API_URL);
|
||||
Assert.assertEquals(SMAuthStatus.SUCCESS.name(), JSONUtils.getString(authInfo, "authStatus"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReverseProxyAnonymousModeLogin() throws Exception {
|
||||
HttpClient client = CEServerTestSuite.getClient();
|
||||
Map<String, Object> sessionInfo = openSession(client);
|
||||
Assert.assertTrue(JSONUtils.getBoolean(sessionInfo, "valid"));
|
||||
Map<String, Object> activeUser = getActiveUser(client);
|
||||
Assert.assertEquals(REVERSE_PROXY_TEST_USER, JSONUtils.getString(activeUser, "userId"));
|
||||
}
|
||||
|
||||
private Map<String, Object> openSession(HttpClient client) throws Exception {
|
||||
Map<String, Object> data = doPostQuery(client, GQL_TEMPLATE_OPEN_SESSION);
|
||||
if (data != null) {
|
||||
return JSONUtils.getObject(data, "session");
|
||||
}
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
private Map<String, Object> getActiveUser(HttpClient client) throws Exception {
|
||||
Map<String, Object> data = doPostQuery(client, GQL_TEMPLATE_ACTIVE_USER);
|
||||
if (data != null) {
|
||||
return JSONUtils.getObject(data, "user");
|
||||
}
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
private Map<String, Object> doPostQuery(HttpClient client, String gqlScript) throws Exception {
|
||||
String input = WebTestUtils.readScriptTemplate(gqlScript, CEServerTestSuite.getScriptsPath());
|
||||
List<String> headers = List.of(RPAuthProvider.X_USER, REVERSE_PROXY_TEST_USER, RPAuthProvider.X_ROLE, "user");
|
||||
Map<String, Object> map = WebTestUtils.doPostWithHeaders(CEServerTestSuite.GQL_API_URL, input, client, headers);
|
||||
return JSONUtils.getObjectOrNull(map, "data");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
server: {
|
||||
serverPort: "${CLOUDBEAVER_TEST_PORT:18978}",
|
||||
serverName: "CloudBeaver CE Test Server",
|
||||
|
||||
workspaceLocation: "workspace",
|
||||
contentRoot: "workspace/web",
|
||||
@@ -36,8 +37,10 @@
|
||||
anonymousAccessEnabled: true,
|
||||
anonymousUserRole: "user",
|
||||
supportsCustomConnections: true,
|
||||
enableReverseProxyAuth: true,
|
||||
enabledAuthProviders: [
|
||||
"local"
|
||||
"local",
|
||||
"reverseProxy"
|
||||
],
|
||||
enabledFeatures: [
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"query": "\n query activeUser {\n user: activeUser {\n userId\n }\n}\n ",
|
||||
"operationName": "activeUser"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"query": "\n mutation openSession($defaultLocale: String) {\n session: openSession(defaultLocale: $defaultLocale) {\n valid\n }\n}\n ",
|
||||
"variables": {
|
||||
"defaultLocale": "en"
|
||||
},
|
||||
"operationName": "openSession"
|
||||
}
|
||||
@@ -90,7 +90,7 @@ const styles = css`
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Icon {
|
||||
@@ -112,12 +112,12 @@ const styles = css`
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-left: 12px;
|
||||
|
||||
|
||||
& IconOrImage {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
|
||||
&:not(:empty) + input {
|
||||
padding-left: 34px !important;
|
||||
}
|
||||
@@ -131,8 +131,8 @@ type BaseProps<TKey, TValue> = Omit<React.InputHTMLAttributes<HTMLInputElement>,
|
||||
searchable?: boolean;
|
||||
defaultValue?: TKey;
|
||||
loading?: boolean;
|
||||
keySelector: (item: TValue, index: number) => TKey;
|
||||
valueSelector: (item: TValue) => string;
|
||||
keySelector?: (item: TValue, index: number) => TKey;
|
||||
valueSelector?: (item: TValue) => string;
|
||||
titleSelector?: (item: TValue) => string | undefined;
|
||||
iconSelector?: (item: TValue) => string | React.ReactElement | undefined;
|
||||
isDisabled?: (item: TValue) => boolean;
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import styled, { css } from 'reshadow';
|
||||
|
||||
import { Combobox } from '@cloudbeaver/core-blocks';
|
||||
|
||||
import type { CrsKey } from './LeafletMap';
|
||||
|
||||
const styles = css`
|
||||
root {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
label {
|
||||
margin-right: 4px;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
|
||||
Combobox {
|
||||
width: 120px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
`;
|
||||
|
||||
interface Props {
|
||||
value: CrsKey;
|
||||
onChange: (value: CrsKey) => void;
|
||||
}
|
||||
|
||||
const items: CrsKey[] = [
|
||||
'Simple',
|
||||
'EPSG3395',
|
||||
'EPSG3857',
|
||||
'EPSG4326',
|
||||
'EPSG900913',
|
||||
];
|
||||
|
||||
export function CrsInput(props: Props) {
|
||||
return styled(styles)(
|
||||
<root>
|
||||
<label>CRS:</label>
|
||||
<Combobox
|
||||
items={items}
|
||||
value={props.value}
|
||||
onSelect={props.onChange}
|
||||
/>
|
||||
</root>
|
||||
);
|
||||
}
|
||||
@@ -5,18 +5,51 @@
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import styled, { css } from 'reshadow';
|
||||
import wellknown from 'wellknown';
|
||||
|
||||
import { TextPlaceholder } from '@cloudbeaver/core-blocks';
|
||||
import { useTranslate } from '@cloudbeaver/core-localization';
|
||||
import { IDatabaseResultSet, ResultSetSelectAction, IResultSetElementKey, IDatabaseDataModel, ResultSetViewAction, ResultSetDataKeysUtils } from '@cloudbeaver/plugin-data-viewer';
|
||||
|
||||
import { IGeoJSONFeature, IAssociatedValue, LeafletMap } from './LeafletMap';
|
||||
import { CrsInput } from './CrsInput';
|
||||
import { IGeoJSONFeature, IAssociatedValue, LeafletMap, CrsKey } from './LeafletMap';
|
||||
import { ResultSetGISAction } from './ResultSetGISAction';
|
||||
|
||||
function getCrsKey(feature?: IGeoJSONFeature): CrsKey {
|
||||
switch (feature?.properties.srid) {
|
||||
case 3857:
|
||||
return 'EPSG3857';
|
||||
case 4326:
|
||||
return 'EPSG4326';
|
||||
case 3395:
|
||||
return 'EPSG3395';
|
||||
case 900913:
|
||||
return 'EPSG900913';
|
||||
default:
|
||||
return 'EPSG3857';
|
||||
}
|
||||
}
|
||||
|
||||
const styles = css`
|
||||
root {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
map {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
toolbar {
|
||||
margin-top: 8px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
`;
|
||||
|
||||
interface Props {
|
||||
model: IDatabaseDataModel<any, IDatabaseResultSet>;
|
||||
resultIndex: number;
|
||||
@@ -87,11 +120,25 @@ export const GISValuePresentation = observer<Props>(function GISValuePresentatio
|
||||
return values;
|
||||
}, [view]);
|
||||
|
||||
|
||||
const defaultCrsKey = getCrsKey(parsedGISData[0]);
|
||||
const [crsKey, setCrsKey] = useState(defaultCrsKey);
|
||||
|
||||
if (!parsedGISData.length) {
|
||||
return <TextPlaceholder>{translate('gis_presentation_placeholder')}</TextPlaceholder>;
|
||||
}
|
||||
|
||||
return (
|
||||
<LeafletMap geoJSON={parsedGISData} getAssociatedValues={getAssociatedValues} />
|
||||
return styled(styles)(
|
||||
<root>
|
||||
<map>
|
||||
<LeafletMap key={crsKey} geoJSON={parsedGISData} crsKey={crsKey} getAssociatedValues={getAssociatedValues} />
|
||||
</map>
|
||||
<toolbar>
|
||||
<CrsInput
|
||||
value={crsKey}
|
||||
onChange={setCrsKey}
|
||||
/>
|
||||
</toolbar>
|
||||
</root>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -42,8 +42,11 @@ interface IBaseTile extends TileLayerProps {
|
||||
checked?: boolean;
|
||||
}
|
||||
|
||||
export type CrsKey = 'Simple' | 'EPSG3857' | 'EPSG4326' | 'EPSG3395' | 'EPSG900913';
|
||||
|
||||
interface Props {
|
||||
geoJSON: IGeoJSONFeature[];
|
||||
crsKey: CrsKey;
|
||||
getAssociatedValues: (cell: IResultSetElementKey) => IAssociatedValue[];
|
||||
}
|
||||
|
||||
@@ -87,17 +90,17 @@ function polyStyle() {
|
||||
};
|
||||
}
|
||||
|
||||
function getCRS(feature?: IGeoJSONFeature): leaflet.CRS {
|
||||
switch (feature?.properties.srid) {
|
||||
case 0:
|
||||
function getCRS(crsKey: CrsKey): leaflet.CRS {
|
||||
switch (crsKey) {
|
||||
case 'Simple':
|
||||
return leaflet.CRS.Simple;
|
||||
case 3857:
|
||||
case 'EPSG3857':
|
||||
return leaflet.CRS.EPSG3857;
|
||||
case 4326:
|
||||
case 'EPSG4326':
|
||||
return leaflet.CRS.EPSG4326;
|
||||
case 3395:
|
||||
case 'EPSG3395':
|
||||
return leaflet.CRS.EPSG3395;
|
||||
case 900913:
|
||||
case 'EPSG900913':
|
||||
return leaflet.CRS.EPSG900913;
|
||||
default:
|
||||
return leaflet.CRS.EPSG3857;
|
||||
@@ -111,14 +114,14 @@ const styles = css`
|
||||
}
|
||||
`;
|
||||
|
||||
export const LeafletMap: React.FC<Props> = function LeafletMap({ geoJSON, getAssociatedValues }) {
|
||||
export const LeafletMap: React.FC<Props> = function LeafletMap({ geoJSON, crsKey, getAssociatedValues }) {
|
||||
const splitContext = useSplit();
|
||||
const translate = useTranslate();
|
||||
|
||||
const [mapRef, setMapRef] = useState<leaflet.Map | null>(null);
|
||||
const [geoJSONLayerRef, setGeoJSONLayerRef] = useState<leaflet.GeoJSON | null>(null);
|
||||
|
||||
const crs = getCRS(geoJSON[0]);
|
||||
const crs = getCRS(crsKey);
|
||||
|
||||
const onEachFeature = useCallback((feature: IGeoJSONFeature, layer: leaflet.Layer) => {
|
||||
const associatedValues = getAssociatedValues(feature.properties.associatedCell);
|
||||
|
||||
Reference in New Issue
Block a user