mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
CB-5570 do not load data sources in web session init (#2887)
* CB-5570 do not load data sources in web session init * CB-5570 extract methods about web connection info from web session * CB-5570 remove accessible connections from web session * CB-5570 add javadoc * CB-5570 Merge conflicts resolve * CB-5570 return emply list for template connections in te * chore: reorganize localization for connections --------- Co-authored-by: serge-rider <serge@dbeaver.com> Co-authored-by: kseniaguzeeva <112612526+kseniaguzeeva@users.noreply.github.com> Co-authored-by: Evgenia Bezborodova <139753579+EvgeniaBzzz@users.noreply.github.com> Co-authored-by: Aleksei Potsetsuev <wrouds@gmail.com> Co-authored-by: mr-anton-t <42037741+mr-anton-t@users.noreply.github.com>
This commit is contained in:
co-authored by
serge-rider
kseniaguzeeva
Evgenia Bezborodova
Aleksei Potsetsuev
mr-anton-t
parent
c3c15bf7cc
commit
eb33e0e895
@@ -38,21 +38,18 @@ public abstract class BaseWebProjectImpl extends BaseProjectImpl implements RMCo
|
||||
@NotNull
|
||||
private final Path path;
|
||||
@NotNull
|
||||
protected final DataSourceFilter dataSourceFilter;
|
||||
private final RMController resourceController;
|
||||
|
||||
public BaseWebProjectImpl(
|
||||
@NotNull DBPWorkspace workspace,
|
||||
@NotNull RMController resourceController,
|
||||
@NotNull SMSessionContext sessionContext,
|
||||
@NotNull RMProject project,
|
||||
@NotNull DataSourceFilter dataSourceFilter
|
||||
@NotNull RMProject project
|
||||
) {
|
||||
super(workspace, sessionContext);
|
||||
this.resourceController = resourceController;
|
||||
this.path = RMUtils.getProjectPath(project);
|
||||
this.project = project;
|
||||
this.dataSourceFilter = dataSourceFilter;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -104,11 +101,6 @@ public abstract class BaseWebProjectImpl extends BaseProjectImpl implements RMCo
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public RMProject getRmProject() {
|
||||
return this.project;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for Bulk Update of resources properties paths
|
||||
*
|
||||
|
||||
@@ -33,16 +33,15 @@ import org.jkiss.dbeaver.runtime.DBWorkbench;
|
||||
public abstract class WebProjectImpl extends BaseWebProjectImpl {
|
||||
private static final Log log = Log.getLog(WebProjectImpl.class);
|
||||
@NotNull
|
||||
private final DBPPreferenceStore preferenceStore;
|
||||
protected final DBPPreferenceStore preferenceStore;
|
||||
public WebProjectImpl(
|
||||
@NotNull DBPWorkspace workspace,
|
||||
@NotNull RMController resourceController,
|
||||
@NotNull SMSessionContext sessionContext,
|
||||
@NotNull RMProject project,
|
||||
@NotNull DataSourceFilter dataSourceFilter,
|
||||
@NotNull DBPPreferenceStore preferenceStore
|
||||
) {
|
||||
super(workspace, resourceController, sessionContext, project, dataSourceFilter);
|
||||
super(workspace, resourceController, sessionContext, project);
|
||||
this.preferenceStore = preferenceStore;
|
||||
}
|
||||
|
||||
@@ -82,8 +81,13 @@ public abstract class WebProjectImpl extends BaseWebProjectImpl {
|
||||
protected DBPDataSourceRegistry createDataSourceRegistry() {
|
||||
return new WebDataSourceRegistryProxy(
|
||||
new DataSourceRegistryRM(this, getResourceController(), preferenceStore),
|
||||
dataSourceFilter
|
||||
getDataSourceFilter()
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DataSourceFilter getDataSourceFilter() {
|
||||
return (ds) -> true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2024 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.cloudbeaver;
|
||||
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
|
||||
import org.jkiss.dbeaver.model.DBPEvent;
|
||||
import org.jkiss.dbeaver.model.rm.RMProject;
|
||||
import org.jkiss.dbeaver.model.security.SMObjectType;
|
||||
import org.jkiss.dbeaver.model.security.user.SMObjectPermissions;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Global project.
|
||||
* Connections there can be not accessible.
|
||||
*/
|
||||
public class WebSessionGlobalProjectImpl extends WebSessionProjectImpl {
|
||||
private static final Log log = Log.getLog(WebSessionGlobalProjectImpl.class);
|
||||
private Set<String> accessibleConnectionIds = Collections.emptySet();
|
||||
|
||||
public WebSessionGlobalProjectImpl(@NotNull WebSession webSession, @NotNull RMProject project) {
|
||||
super(webSession, project);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update info about accessible connections from a database.
|
||||
*/
|
||||
public synchronized void refreshAccessibleConnectionIds() {
|
||||
this.accessibleConnectionIds = readAccessibleConnectionIds();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Set<String> readAccessibleConnectionIds() {
|
||||
try {
|
||||
return webSession.getSecurityController()
|
||||
.getAllAvailableObjectsPermissions(SMObjectType.datasource)
|
||||
.stream()
|
||||
.map(SMObjectPermissions::getObjectId)
|
||||
.collect(Collectors.toSet());
|
||||
} catch (DBException e) {
|
||||
webSession.addSessionError(e);
|
||||
log.error("Error reading connection grants", e);
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if connection is accessible for current user.
|
||||
*/
|
||||
public boolean isDataSourceAccessible(@NotNull DBPDataSourceContainer dataSource) {
|
||||
return dataSource.isExternallyProvided() ||
|
||||
dataSource.isTemporary() ||
|
||||
webSession.hasPermission(DBWConstants.PERMISSION_ADMIN) ||
|
||||
accessibleConnectionIds.contains(dataSource.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a connection if it became accessible.
|
||||
* The method is processed when connection permissions were updated.
|
||||
*/
|
||||
public synchronized void addAccessibleConnectionToCache(@NotNull String dsId) {
|
||||
if (!getRMProject().isGlobal()) {
|
||||
return;
|
||||
}
|
||||
this.accessibleConnectionIds.add(dsId);
|
||||
var registry = getDataSourceRegistry();
|
||||
var dataSource = registry.getDataSource(dsId);
|
||||
if (dataSource != null) {
|
||||
addConnection(dataSource);
|
||||
// reflect changes is navigator model
|
||||
registry.notifyDataSourceListeners(new DBPEvent(DBPEvent.Action.OBJECT_ADD, dataSource, true));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a connection if it became not accessible.
|
||||
* The method is processed when connection permissions were updated.
|
||||
*/
|
||||
public synchronized void removeAccessibleConnectionFromCache(@NotNull String dsId) {
|
||||
if (!getRMProject().isGlobal()) {
|
||||
return;
|
||||
}
|
||||
var registry = getDataSourceRegistry();
|
||||
var dataSource = registry.getDataSource(dsId);
|
||||
if (dataSource != null) {
|
||||
this.accessibleConnectionIds.remove(dsId);
|
||||
removeConnection(dataSource);
|
||||
// reflect changes is navigator model
|
||||
registry.notifyDataSourceListeners(new DBPEvent(DBPEvent.Action.OBJECT_REMOVE, dataSource));
|
||||
dataSource.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DataSourceFilter getDataSourceFilter() {
|
||||
return this::isDataSourceAccessible;
|
||||
}
|
||||
}
|
||||
@@ -16,27 +16,39 @@
|
||||
*/
|
||||
package io.cloudbeaver;
|
||||
|
||||
import io.cloudbeaver.model.WebConnectionInfo;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import io.cloudbeaver.utils.WebDataSourceUtils;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
|
||||
import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry;
|
||||
import org.jkiss.dbeaver.model.app.DBPDataSourceRegistryCache;
|
||||
import org.jkiss.dbeaver.model.navigator.DBNModel;
|
||||
import org.jkiss.dbeaver.model.rm.RMProject;
|
||||
import org.jkiss.dbeaver.model.websocket.event.WSEventType;
|
||||
import org.jkiss.dbeaver.registry.DataSourceDescriptor;
|
||||
import org.jkiss.dbeaver.runtime.jobs.DisconnectJob;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class WebSessionProjectImpl extends WebProjectImpl {
|
||||
|
||||
private final WebSession webSession;
|
||||
private static final Log log = Log.getLog(WebSessionProjectImpl.class);
|
||||
protected final WebSession webSession;
|
||||
private final Map<String, WebConnectionInfo> connections = new HashMap<>();
|
||||
private boolean registryIsLoaded = false;
|
||||
|
||||
public WebSessionProjectImpl(
|
||||
@NotNull WebSession webSession,
|
||||
@NotNull RMProject project,
|
||||
@NotNull DataSourceFilter dataSourceFilter
|
||||
@NotNull RMProject project
|
||||
) {
|
||||
super(
|
||||
webSession.getWorkspace(),
|
||||
webSession.getRmController(),
|
||||
webSession.getSessionContext(),
|
||||
project,
|
||||
dataSourceFilter,
|
||||
webSession.getUserPreferenceStore()
|
||||
);
|
||||
this.webSession = webSession;
|
||||
@@ -47,4 +59,156 @@ public class WebSessionProjectImpl extends WebProjectImpl {
|
||||
public DBNModel getNavigatorModel() {
|
||||
return webSession.getNavigatorModel();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected DBPDataSourceRegistry createDataSourceRegistry() {
|
||||
DBPDataSourceRegistry dataSourceRegistry = super.createDataSourceRegistry();
|
||||
dataSourceRegistry.setAuthCredentialsProvider(webSession);
|
||||
return dataSourceRegistry;
|
||||
}
|
||||
|
||||
private synchronized void addDataSourcesToCache() {
|
||||
if (registryIsLoaded) {
|
||||
return;
|
||||
}
|
||||
getDataSourceRegistry().getDataSources().forEach(this::addConnection);
|
||||
Throwable lastError = getDataSourceRegistry().getLastError();
|
||||
if (lastError != null) {
|
||||
webSession.addSessionError(lastError);
|
||||
log.error("Error refreshing connections from project '" + getId() + "'", lastError);
|
||||
}
|
||||
registryIsLoaded = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
Map<String, WebConnectionInfo> conCopy;
|
||||
synchronized (this.connections) {
|
||||
conCopy = new HashMap<>(this.connections);
|
||||
this.connections.clear();
|
||||
}
|
||||
|
||||
for (WebConnectionInfo connectionInfo : conCopy.values()) {
|
||||
if (connectionInfo.isConnected()) {
|
||||
new DisconnectJob(connectionInfo.getDataSourceContainer()).schedule();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns web connection info from cache (if exists).
|
||||
*/
|
||||
@Nullable
|
||||
public WebConnectionInfo findWebConnectionInfo(@NotNull String connectionId) {
|
||||
synchronized (connections) {
|
||||
return connections.get(connectionId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns web connection info from cache, adds it to cache if not present.
|
||||
* Throws exception if connection is not found.
|
||||
*/
|
||||
@NotNull
|
||||
public WebConnectionInfo getWebConnectionInfo(@NotNull String connectionId) throws DBWebException {
|
||||
WebConnectionInfo connectionInfo = findWebConnectionInfo(connectionId);
|
||||
if (connectionInfo != null) {
|
||||
return connectionInfo;
|
||||
}
|
||||
DBPDataSourceContainer dataSource = getDataSourceRegistry().getDataSource(connectionId);
|
||||
if (dataSource != null) {
|
||||
return addConnection(dataSource);
|
||||
}
|
||||
throw new DBWebException("Connection '%s' not found".formatted(connectionId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds connection to project cache.
|
||||
*/
|
||||
@NotNull
|
||||
public synchronized WebConnectionInfo addConnection(@NotNull DBPDataSourceContainer dataSourceContainer) {
|
||||
WebConnectionInfo connection = new WebConnectionInfo(webSession, dataSourceContainer);
|
||||
synchronized (connections) {
|
||||
connections.put(dataSourceContainer.getId(), connection);
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes connection from project cache.
|
||||
*/
|
||||
public void removeConnection(@NotNull DBPDataSourceContainer dataSourceContainer) {
|
||||
WebConnectionInfo webConnectionInfo = connections.get(dataSourceContainer.getId());
|
||||
if (webConnectionInfo != null) {
|
||||
webConnectionInfo.clearCache();
|
||||
synchronized (connections) {
|
||||
connections.remove(dataSourceContainer.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads connection from registry if they are not loaded.
|
||||
*
|
||||
* @return connections from cache.
|
||||
*/
|
||||
public List<WebConnectionInfo> getConnections() {
|
||||
if (!registryIsLoaded) {
|
||||
addDataSourcesToCache();
|
||||
registryIsLoaded = true;
|
||||
}
|
||||
synchronized (connections) {
|
||||
return new ArrayList<>(connections.values());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* updates data sources based on event in web session
|
||||
*
|
||||
* @param dataSourceIds list of updated connections
|
||||
* @param type type of event
|
||||
*/
|
||||
public synchronized boolean updateProjectDataSources(@NotNull List<String> dataSourceIds, @NotNull WSEventType type) {
|
||||
var sendDataSourceUpdatedEvent = false;
|
||||
DBPDataSourceRegistry registry = getDataSourceRegistry();
|
||||
// save old connections
|
||||
var oldDataSources = dataSourceIds.stream()
|
||||
.map(registry::getDataSource)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(
|
||||
DBPDataSourceContainer::getId,
|
||||
ds -> new DataSourceDescriptor((DataSourceDescriptor) ds, ds.getRegistry())
|
||||
));
|
||||
if (type == WSEventType.DATASOURCE_CREATED || type == WSEventType.DATASOURCE_UPDATED) {
|
||||
registry.refreshConfig(dataSourceIds);
|
||||
}
|
||||
for (String dsId : dataSourceIds) {
|
||||
DataSourceDescriptor ds = (DataSourceDescriptor) registry.getDataSource(dsId);
|
||||
if (ds == null) {
|
||||
continue;
|
||||
}
|
||||
switch (type) {
|
||||
case DATASOURCE_CREATED -> {
|
||||
addConnection(ds);
|
||||
sendDataSourceUpdatedEvent = true;
|
||||
}
|
||||
case DATASOURCE_UPDATED -> // if settings were changed we need to send event
|
||||
sendDataSourceUpdatedEvent |= !ds.equalSettings(oldDataSources.get(dsId));
|
||||
case DATASOURCE_DELETED -> {
|
||||
WebDataSourceUtils.disconnectDataSource(webSession, ds);
|
||||
if (registry instanceof DBPDataSourceRegistryCache dsrc) {
|
||||
dsrc.removeDataSourceFromList(ds);
|
||||
}
|
||||
removeConnection(ds);
|
||||
sendDataSourceUpdatedEvent = true;
|
||||
}
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
return sendDataSourceUpdatedEvent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -445,10 +445,10 @@ public class WebConnectionInfo {
|
||||
|
||||
private boolean hasProjectPermission(RMProjectPermission projectPermission) {
|
||||
DBPProject project = dataSourceContainer.getProject();
|
||||
if (!(project instanceof WebProjectImpl)) {
|
||||
if (!(project instanceof WebProjectImpl webProject)) {
|
||||
return false;
|
||||
}
|
||||
return SMUtils.hasProjectPermission(session, ((WebProjectImpl) project).getRmProject(), projectPermission);
|
||||
return SMUtils.hasProjectPermission(session, webProject.getRMProject(), projectPermission);
|
||||
}
|
||||
|
||||
private boolean canViewReadOnlyConnections() {
|
||||
|
||||
@@ -53,11 +53,13 @@ public class WebProjectInfo {
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isGlobal() { return project.getRmProject().isGlobal(); }
|
||||
public boolean isGlobal() {
|
||||
return project.getRMProject().isGlobal();
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isShared() {
|
||||
return project.getRmProject().isShared();
|
||||
return project.getRMProject().isShared();
|
||||
}
|
||||
|
||||
@Property
|
||||
@@ -72,7 +74,7 @@ public class WebProjectInfo {
|
||||
|
||||
@Property
|
||||
public boolean isCanEditDataSources() {
|
||||
if (project.getRmProject().getType() == RMProjectType.USER && !customPrivateConnectionsEnabled) {
|
||||
if (project.getRMProject().getType() == RMProjectType.USER && !customPrivateConnectionsEnabled) {
|
||||
return false;
|
||||
}
|
||||
return hasDataSourcePermission(RMProjectPermission.DATA_SOURCES_EDIT);
|
||||
@@ -94,12 +96,12 @@ public class WebProjectInfo {
|
||||
}
|
||||
|
||||
private boolean hasDataSourcePermission(RMProjectPermission permission) {
|
||||
return SMUtils.hasProjectPermission(session, project.getRmProject(), permission);
|
||||
return SMUtils.hasProjectPermission(session, project.getRMProject(), permission);
|
||||
}
|
||||
|
||||
@Property
|
||||
public RMResourceType[] getResourceTypes() {
|
||||
RMResourceType[] resourceTypes = project.getRmProject().getResourceTypes();
|
||||
RMResourceType[] resourceTypes = project.getRMProject().getResourceTypes();
|
||||
|
||||
if(resourceTypes == null) {
|
||||
return ArrayUtils.toArray(RMResourceType.class, new ArrayList<>());
|
||||
|
||||
-18
@@ -16,11 +16,7 @@
|
||||
*/
|
||||
package io.cloudbeaver.model.app;
|
||||
|
||||
import io.cloudbeaver.DataSourceFilter;
|
||||
import io.cloudbeaver.WebProjectImpl;
|
||||
import io.cloudbeaver.WebSessionProjectImpl;
|
||||
import io.cloudbeaver.model.log.SLF4JLogHandler;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.equinox.app.IApplicationContext;
|
||||
import org.jkiss.code.NotNull;
|
||||
@@ -36,7 +32,6 @@ import org.jkiss.dbeaver.model.impl.app.ApplicationRegistry;
|
||||
import org.jkiss.dbeaver.model.impl.app.BaseApplicationImpl;
|
||||
import org.jkiss.dbeaver.model.impl.app.BaseWorkspaceImpl;
|
||||
import org.jkiss.dbeaver.model.rm.RMController;
|
||||
import org.jkiss.dbeaver.model.rm.RMProject;
|
||||
import org.jkiss.dbeaver.model.secret.DBSSecretController;
|
||||
import org.jkiss.dbeaver.model.websocket.event.WSEventController;
|
||||
import org.jkiss.dbeaver.runtime.IVariableResolver;
|
||||
@@ -160,19 +155,6 @@ public abstract class BaseWebApplication extends BaseApplicationImpl implements
|
||||
return Files.exists(customConfigPath) ? customConfigPath : configPath.resolve(fileName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebProjectImpl createProjectImpl(
|
||||
@NotNull WebSession webSession,
|
||||
@NotNull RMProject project,
|
||||
@NotNull DataSourceFilter dataSourceFilter
|
||||
) {
|
||||
return new WebSessionProjectImpl(
|
||||
webSession,
|
||||
project,
|
||||
dataSourceFilter
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* There is no secret controller in base web app.
|
||||
* Method returns VoidSecretController instance.
|
||||
|
||||
@@ -16,9 +16,6 @@
|
||||
*/
|
||||
package io.cloudbeaver.model.app;
|
||||
|
||||
import io.cloudbeaver.DataSourceFilter;
|
||||
import io.cloudbeaver.WebProjectImpl;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.model.DBFileController;
|
||||
@@ -27,7 +24,6 @@ import org.jkiss.dbeaver.model.app.DBPWorkspace;
|
||||
import org.jkiss.dbeaver.model.auth.SMCredentialsProvider;
|
||||
import org.jkiss.dbeaver.model.auth.SMSessionContext;
|
||||
import org.jkiss.dbeaver.model.rm.RMController;
|
||||
import org.jkiss.dbeaver.model.rm.RMProject;
|
||||
import org.jkiss.dbeaver.model.secret.DBSSecretController;
|
||||
import org.jkiss.dbeaver.model.security.SMAdminController;
|
||||
import org.jkiss.dbeaver.model.security.SMController;
|
||||
@@ -58,12 +54,6 @@ public interface WebApplication extends DBPApplication {
|
||||
|
||||
boolean isMultiNode();
|
||||
|
||||
WebProjectImpl createProjectImpl(
|
||||
@NotNull WebSession webSession,
|
||||
@NotNull RMProject project,
|
||||
@NotNull DataSourceFilter dataSourceFilter
|
||||
);
|
||||
|
||||
SMController createSecurityController(@NotNull SMCredentialsProvider credentialsProvider) throws DBException;
|
||||
|
||||
SMAdminController getAdminSecurityController(@NotNull SMCredentialsProvider credentialsProvider) throws DBException;
|
||||
|
||||
+1
-2
@@ -1291,8 +1291,7 @@ public class LocalResourceController implements RMController {
|
||||
LocalResourceController.this.workspace,
|
||||
LocalResourceController.this,
|
||||
sessionContext,
|
||||
rmProject,
|
||||
(container) -> true);
|
||||
rmProject);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+1
@@ -72,6 +72,7 @@ public abstract class BaseWebSession extends AbstractSessionPersistent {
|
||||
return new WebUserContext(this.application, this.workspace);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public WebSessionWorkspace getWorkspace() {
|
||||
return workspace;
|
||||
}
|
||||
|
||||
+55
-250
@@ -19,10 +19,8 @@ package io.cloudbeaver.model.session;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.InstanceCreator;
|
||||
import io.cloudbeaver.DBWConstants;
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.DataSourceFilter;
|
||||
import io.cloudbeaver.WebProjectImpl;
|
||||
import com.google.gson.Strictness;
|
||||
import io.cloudbeaver.*;
|
||||
import io.cloudbeaver.model.WebAsyncTaskInfo;
|
||||
import io.cloudbeaver.model.WebConnectionInfo;
|
||||
import io.cloudbeaver.model.WebServerMessage;
|
||||
@@ -32,7 +30,6 @@ import io.cloudbeaver.model.user.WebUser;
|
||||
import io.cloudbeaver.service.DBWSessionHandler;
|
||||
import io.cloudbeaver.service.sql.WebSQLConstants;
|
||||
import io.cloudbeaver.utils.CBModelConstants;
|
||||
import io.cloudbeaver.utils.WebAppUtils;
|
||||
import io.cloudbeaver.utils.WebDataSourceUtils;
|
||||
import org.eclipse.core.runtime.IAdaptable;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
@@ -43,12 +40,8 @@ import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.DBFileController;
|
||||
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
|
||||
import org.jkiss.dbeaver.model.DBPEvent;
|
||||
import org.jkiss.dbeaver.model.access.DBAAuthCredentials;
|
||||
import org.jkiss.dbeaver.model.access.DBACredentialsProvider;
|
||||
import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry;
|
||||
import org.jkiss.dbeaver.model.app.DBPDataSourceRegistryCache;
|
||||
import org.jkiss.dbeaver.model.app.DBPProject;
|
||||
import org.jkiss.dbeaver.model.auth.*;
|
||||
import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration;
|
||||
import org.jkiss.dbeaver.model.exec.DBCException;
|
||||
@@ -68,15 +61,11 @@ import org.jkiss.dbeaver.model.runtime.ProxyProgressMonitor;
|
||||
import org.jkiss.dbeaver.model.security.SMAdminController;
|
||||
import org.jkiss.dbeaver.model.security.SMConstants;
|
||||
import org.jkiss.dbeaver.model.security.SMController;
|
||||
import org.jkiss.dbeaver.model.security.SMObjectType;
|
||||
import org.jkiss.dbeaver.model.security.user.SMObjectPermissions;
|
||||
import org.jkiss.dbeaver.model.sql.DBQuotaException;
|
||||
import org.jkiss.dbeaver.model.websocket.event.MessageType;
|
||||
import org.jkiss.dbeaver.model.websocket.event.WSEventType;
|
||||
import org.jkiss.dbeaver.model.websocket.event.WSSessionLogUpdatedEvent;
|
||||
import org.jkiss.dbeaver.registry.DataSourceDescriptor;
|
||||
import org.jkiss.dbeaver.runtime.DBWorkbench;
|
||||
import org.jkiss.dbeaver.runtime.jobs.DisconnectJob;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@@ -106,12 +95,10 @@ public class WebSession extends BaseWebSession
|
||||
private String lastRemoteAddr;
|
||||
private String lastRemoteUserAgent;
|
||||
|
||||
private Set<String> accessibleConnectionIds = Collections.emptySet();
|
||||
|
||||
private String locale;
|
||||
private boolean cacheExpired;
|
||||
|
||||
private final Map<String, WebConnectionInfo> connections = new HashMap<>();
|
||||
private WebSessionGlobalProjectImpl globalProject;
|
||||
private final List<WebServerMessage> sessionMessages = new ArrayList<>();
|
||||
|
||||
private final Map<String, WebAsyncTaskInfo> asyncTasks = new HashMap<>();
|
||||
@@ -166,8 +153,8 @@ public class WebSession extends BaseWebSession
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DBPProject getSingletonProject() {
|
||||
@Nullable
|
||||
public WebSessionProjectImpl getSingletonProject() {
|
||||
return getWorkspace().getActiveProject();
|
||||
}
|
||||
|
||||
@@ -264,69 +251,6 @@ public class WebSession extends BaseWebSession
|
||||
initNavigatorModel();
|
||||
}
|
||||
|
||||
/**
|
||||
* updates data sources based on event in web session
|
||||
*
|
||||
* @param project project of connection
|
||||
* @param dataSourceIds list of updated connections
|
||||
* @param type type of event
|
||||
*/
|
||||
public synchronized boolean updateProjectDataSources(
|
||||
DBPProject project,
|
||||
List<String> dataSourceIds,
|
||||
WSEventType type
|
||||
) {
|
||||
var sendDataSourceUpdatedEvent = false;
|
||||
DBPDataSourceRegistry registry = project.getDataSourceRegistry();
|
||||
// save old connections
|
||||
var oldDataSources = dataSourceIds.stream()
|
||||
.map(registry::getDataSource)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(
|
||||
DBPDataSourceContainer::getId,
|
||||
ds -> new DataSourceDescriptor((DataSourceDescriptor) ds, ds.getRegistry())
|
||||
));
|
||||
if (type == WSEventType.DATASOURCE_CREATED || type == WSEventType.DATASOURCE_UPDATED) {
|
||||
registry.refreshConfig(dataSourceIds);
|
||||
}
|
||||
for (String dsId : dataSourceIds) {
|
||||
DataSourceDescriptor ds = (DataSourceDescriptor) registry.getDataSource(dsId);
|
||||
if (ds == null) {
|
||||
continue;
|
||||
}
|
||||
switch (type) {
|
||||
case DATASOURCE_CREATED -> {
|
||||
WebConnectionInfo connectionInfo = new WebConnectionInfo(this, ds);
|
||||
this.connections.put(getConnectionId(ds), connectionInfo);
|
||||
sendDataSourceUpdatedEvent = true;
|
||||
}
|
||||
case DATASOURCE_UPDATED -> // if settings were changed we need to send event
|
||||
sendDataSourceUpdatedEvent |= !ds.equalSettings(oldDataSources.get(dsId));
|
||||
case DATASOURCE_DELETED -> {
|
||||
WebDataSourceUtils.disconnectDataSource(this, ds);
|
||||
if (registry instanceof DBPDataSourceRegistryCache dsrc) {
|
||||
dsrc.removeDataSourceFromList(ds);
|
||||
}
|
||||
this.connections.remove(getConnectionId(ds));
|
||||
sendDataSourceUpdatedEvent = true;
|
||||
}
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
return sendDataSourceUpdatedEvent;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String getConnectionId(@NotNull DBPDataSourceContainer container) {
|
||||
return getConnectionId(container.getProject().getId(), container.getId());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String getConnectionId(@NotNull String projectId, @NotNull String dsId) {
|
||||
return projectId + ":" + dsId;
|
||||
}
|
||||
|
||||
// Note: for admin use only
|
||||
public synchronized void resetUserState() throws DBException {
|
||||
clearAuthTokens();
|
||||
@@ -347,7 +271,7 @@ public class WebSession extends BaseWebSession
|
||||
this.navigatorModel.dispose();
|
||||
this.navigatorModel = null;
|
||||
}
|
||||
this.connections.clear();
|
||||
this.globalProject = null;
|
||||
|
||||
loadProjects();
|
||||
|
||||
@@ -367,7 +291,6 @@ public class WebSession extends BaseWebSession
|
||||
// No anonymous mode in distributed apps
|
||||
return;
|
||||
}
|
||||
refreshAccessibleConnectionIds();
|
||||
try {
|
||||
RMController controller = getRmController();
|
||||
RMProject[] rmProjects = controller.listAccessibleProjects();
|
||||
@@ -387,57 +310,30 @@ public class WebSession extends BaseWebSession
|
||||
}
|
||||
}
|
||||
|
||||
public WebProjectImpl createWebProject(RMProject project) {
|
||||
// Do not filter data sources from user project
|
||||
DataSourceFilter filter = project.getType() == RMProjectType.GLOBAL
|
||||
? this::isDataSourceAccessible
|
||||
: x -> true;
|
||||
WebProjectImpl sessionProject = application.createProjectImpl(this, project, filter);
|
||||
private WebSessionProjectImpl createWebProject(RMProject project) {
|
||||
WebSessionProjectImpl sessionProject;
|
||||
if (project.isGlobal()) {
|
||||
sessionProject = createGlobalProject(project);
|
||||
} else {
|
||||
sessionProject = new WebSessionProjectImpl(this, project);
|
||||
}
|
||||
// do not load data sources for anonymous project
|
||||
if (project.getType() == RMProjectType.USER && userContext.getUser() == null) {
|
||||
sessionProject.setInMemory(true);
|
||||
}
|
||||
DBPDataSourceRegistry dataSourceRegistry = sessionProject.getDataSourceRegistry();
|
||||
dataSourceRegistry.setAuthCredentialsProvider(this);
|
||||
addSessionProject(sessionProject);
|
||||
if (!project.isShared() || application.isConfigurationMode()) {
|
||||
getWorkspace().setActiveProject(sessionProject);
|
||||
}
|
||||
for (DBPDataSourceContainer ds : dataSourceRegistry.getDataSources()) {
|
||||
addConnection(new WebConnectionInfo(this, ds));
|
||||
}
|
||||
Throwable lastError = dataSourceRegistry.getLastError();
|
||||
if (lastError != null) {
|
||||
addSessionError(lastError);
|
||||
log.error("Error refreshing connections from project '" + project.getId() + "'", lastError);
|
||||
}
|
||||
return sessionProject;
|
||||
}
|
||||
|
||||
public void filterAccessibleConnections(List<WebConnectionInfo> connections) {
|
||||
connections.removeIf(c -> !isDataSourceAccessible(c.getDataSourceContainer()));
|
||||
}
|
||||
|
||||
private boolean isDataSourceAccessible(DBPDataSourceContainer dataSource) {
|
||||
return dataSource.isExternallyProvided() ||
|
||||
dataSource.isTemporary() ||
|
||||
this.hasPermission(DBWConstants.PERMISSION_ADMIN) ||
|
||||
accessibleConnectionIds.contains(dataSource.getId());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected Set<String> readAccessibleConnectionIds() {
|
||||
try {
|
||||
return getSecurityController()
|
||||
.getAllAvailableObjectsPermissions(SMObjectType.datasource)
|
||||
.stream()
|
||||
.map(SMObjectPermissions::getObjectId)
|
||||
.collect(Collectors.toSet());
|
||||
} catch (DBException e) {
|
||||
addSessionError(e);
|
||||
log.error("Error reading connection grants", e);
|
||||
return Collections.emptySet();
|
||||
}
|
||||
private WebSessionProjectImpl createGlobalProject(RMProject project) {
|
||||
WebSessionProjectImpl sessionProject;
|
||||
this.globalProject = new WebSessionGlobalProjectImpl(this, project);
|
||||
globalProject.refreshAccessibleConnectionIds();
|
||||
sessionProject = globalProject;
|
||||
return sessionProject;
|
||||
}
|
||||
|
||||
private void resetSessionCache() throws DBCException {
|
||||
@@ -455,17 +351,7 @@ public class WebSession extends BaseWebSession
|
||||
}
|
||||
|
||||
private void resetNavigationModel() {
|
||||
Map<String, WebConnectionInfo> conCopy;
|
||||
synchronized (this.connections) {
|
||||
conCopy = new HashMap<>(this.connections);
|
||||
this.connections.clear();
|
||||
}
|
||||
|
||||
for (WebConnectionInfo connectionInfo : conCopy.values()) {
|
||||
if (connectionInfo.isConnected()) {
|
||||
new DisconnectJob(connectionInfo.getDataSourceContainer()).schedule();
|
||||
}
|
||||
}
|
||||
getWorkspace().getProjects().forEach(WebSessionProjectImpl::dispose);
|
||||
|
||||
if (this.navigatorModel != null) {
|
||||
this.navigatorModel.dispose();
|
||||
@@ -479,7 +365,9 @@ public class WebSession extends BaseWebSession
|
||||
authAsAnonymousUser();
|
||||
} else if (getUserId() != null) {
|
||||
userContext.refreshPermissions();
|
||||
refreshAccessibleConnectionIds();
|
||||
if (globalProject != null) {
|
||||
globalProject.refreshAccessibleConnectionIds();
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
@@ -488,32 +376,6 @@ public class WebSession extends BaseWebSession
|
||||
}
|
||||
}
|
||||
|
||||
protected synchronized void refreshAccessibleConnectionIds() {
|
||||
this.accessibleConnectionIds = readAccessibleConnectionIds();
|
||||
}
|
||||
|
||||
public synchronized void addAccessibleConnectionToCache(@NotNull String dsId) {
|
||||
this.accessibleConnectionIds.add(dsId);
|
||||
var registry = getProjectById(WebAppUtils.getGlobalProjectId()).getDataSourceRegistry();
|
||||
var dataSource = registry.getDataSource(dsId);
|
||||
if (dataSource != null) {
|
||||
connections.put(getConnectionId(dataSource), new WebConnectionInfo(this, dataSource));
|
||||
// reflect changes is navigator model
|
||||
registry.notifyDataSourceListeners(new DBPEvent(DBPEvent.Action.OBJECT_ADD, dataSource, true));
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void removeAccessibleConnectionFromCache(@NotNull String dsId) {
|
||||
var registry = getProjectById(WebAppUtils.getGlobalProjectId()).getDataSourceRegistry();
|
||||
var dataSource = registry.getDataSource(dsId);
|
||||
if (dataSource != null) {
|
||||
this.accessibleConnectionIds.remove(dsId);
|
||||
connections.remove(getConnectionId(dataSource));
|
||||
// reflect changes is navigator model
|
||||
registry.notifyDataSourceListeners(new DBPEvent(DBPEvent.Action.OBJECT_REMOVE, dataSource));
|
||||
dataSource.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void authAsAnonymousUser() throws DBException {
|
||||
if (!application.getAppConfiguration().isAnonymousAccessEnabled()) {
|
||||
@@ -578,69 +440,6 @@ public class WebSession extends BaseWebSession
|
||||
this.cacheExpired = false;
|
||||
}
|
||||
|
||||
@Association
|
||||
public List<WebConnectionInfo> getConnections() {
|
||||
synchronized (connections) {
|
||||
return new ArrayList<>(connections.values());
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public WebConnectionInfo getWebConnectionInfo(@Nullable String projectId, String connectionID) throws DBWebException {
|
||||
WebConnectionInfo connectionInfo = null;
|
||||
synchronized (connections) {
|
||||
if (projectId != null) {
|
||||
connectionInfo = connections.get(getConnectionId(projectId, connectionID));
|
||||
} else {
|
||||
addWarningMessage("Project id is not defined in request. Try to find it from connection cache");
|
||||
for (Map.Entry<String, WebConnectionInfo> entry : connections.entrySet()) {
|
||||
String k = entry.getKey();
|
||||
WebConnectionInfo v = entry.getValue();
|
||||
if (k.contains(connectionID)) {
|
||||
connectionInfo = v;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (connectionInfo == null) {
|
||||
WebProjectImpl project = getProjectById(projectId);
|
||||
if (project == null) {
|
||||
throw new DBWebException("Project '" + projectId + "' not found in web workspace");
|
||||
}
|
||||
DBPDataSourceContainer dataSource = project.getDataSourceRegistry().getDataSource(connectionID);
|
||||
if (dataSource != null) {
|
||||
connectionInfo = new WebConnectionInfo(this, dataSource);
|
||||
synchronized (connections) {
|
||||
connections.put(getConnectionId(dataSource), connectionInfo);
|
||||
}
|
||||
} else {
|
||||
throw new DBWebException("Connection '" + connectionID + "' not found");
|
||||
}
|
||||
}
|
||||
return connectionInfo;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public WebConnectionInfo findWebConnectionInfo(String projectId, String connectionId) {
|
||||
synchronized (connections) {
|
||||
return connections.get(getConnectionId(projectId, connectionId));
|
||||
}
|
||||
}
|
||||
|
||||
public void addConnection(WebConnectionInfo connectionInfo) {
|
||||
synchronized (connections) {
|
||||
connections.put(getConnectionId(connectionInfo.getDataSourceContainer()), connectionInfo);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeConnection(WebConnectionInfo connectionInfo) {
|
||||
connectionInfo.clearCache();
|
||||
synchronized (connections) {
|
||||
connections.remove(getConnectionId(connectionInfo.getDataSourceContainer()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
@@ -824,7 +623,7 @@ public class WebSession extends BaseWebSession
|
||||
synchronized (attributes) {
|
||||
Object value = attributes.get(name);
|
||||
if (value instanceof PersistentAttribute persistentAttribute) {
|
||||
value = persistentAttribute.getValue();
|
||||
value = persistentAttribute.value();
|
||||
}
|
||||
return (T) value;
|
||||
}
|
||||
@@ -840,7 +639,7 @@ public class WebSession extends BaseWebSession
|
||||
synchronized (attributes) {
|
||||
Object value = attributes.get(name);
|
||||
if (value instanceof PersistentAttribute persistentAttribute) {
|
||||
value = persistentAttribute.getValue();
|
||||
value = persistentAttribute.value();
|
||||
}
|
||||
if (value == null) {
|
||||
value = creator.apply(null);
|
||||
@@ -983,9 +782,12 @@ public class WebSession extends BaseWebSession
|
||||
}
|
||||
configuration.setRuntimeAttribute(RUNTIME_PARAM_AUTH_INFOS, getAllAuthInfo());
|
||||
|
||||
WebConnectionInfo webConnectionInfo = findWebConnectionInfo(dataSourceContainer.getProject().getId(), dataSourceContainer.getId());
|
||||
if (webConnectionInfo != null) {
|
||||
WebDataSourceUtils.saveCredentialsInDataSource(webConnectionInfo, dataSourceContainer, configuration);
|
||||
WebSessionProjectImpl project = getProjectById(dataSourceContainer.getProject().getId());
|
||||
if (project != null) {
|
||||
WebConnectionInfo webConnectionInfo = project.findWebConnectionInfo(dataSourceContainer.getId());
|
||||
if (webConnectionInfo != null) {
|
||||
WebDataSourceUtils.saveCredentialsInDataSource(webConnectionInfo, dataSourceContainer, configuration);
|
||||
}
|
||||
}
|
||||
|
||||
// uncommented because we had the problem with non-native auth models
|
||||
@@ -994,7 +796,7 @@ public class WebSession extends BaseWebSession
|
||||
|
||||
InstanceCreator<DBAAuthCredentials> credTypeAdapter = type -> credentials;
|
||||
Gson credGson = new GsonBuilder()
|
||||
.setLenient()
|
||||
.setStrictness(Strictness.LENIENT)
|
||||
.registerTypeAdapter(credentials.getClass(), credTypeAdapter)
|
||||
.create();
|
||||
|
||||
@@ -1076,12 +878,17 @@ public class WebSession extends BaseWebSession
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public WebProjectImpl getProjectById(@Nullable String projectId) {
|
||||
public WebSessionProjectImpl getProjectById(@Nullable String projectId) {
|
||||
return getWorkspace().getProjectById(projectId);
|
||||
}
|
||||
|
||||
public WebProjectImpl getAccessibleProjectById(@Nullable String projectId) throws DBWebException {
|
||||
WebProjectImpl project = null;
|
||||
/**
|
||||
* Returns project info from session cache.
|
||||
*
|
||||
* @throws DBWebException if project with provided id is not found.
|
||||
*/
|
||||
public WebSessionProjectImpl getAccessibleProjectById(@Nullable String projectId) throws DBWebException {
|
||||
WebSessionProjectImpl project = null;
|
||||
if (projectId != null) {
|
||||
project = getWorkspace().getProjectById(projectId);
|
||||
}
|
||||
@@ -1091,18 +898,24 @@ public class WebSession extends BaseWebSession
|
||||
return project;
|
||||
}
|
||||
|
||||
public List<WebProjectImpl> getAccessibleProjects() {
|
||||
public List<WebSessionProjectImpl> getAccessibleProjects() {
|
||||
return getWorkspace().getProjects();
|
||||
}
|
||||
|
||||
public void addSessionProject(@NotNull WebProjectImpl project) {
|
||||
/**
|
||||
* Adds project to session cache and navigator tree.
|
||||
*/
|
||||
public void addSessionProject(@NotNull WebSessionProjectImpl project) {
|
||||
getWorkspace().addProject(project);
|
||||
if (navigatorModel != null) {
|
||||
navigatorModel.getRoot().addProject(project, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteSessionProject(@Nullable WebProjectImpl project) {
|
||||
/**
|
||||
* Removes project from session cache and navigator tree.
|
||||
*/
|
||||
public void deleteSessionProject(@Nullable WebSessionProjectImpl project) {
|
||||
if (project != null) {
|
||||
project.dispose();
|
||||
}
|
||||
@@ -1127,10 +940,6 @@ public class WebSession extends BaseWebSession
|
||||
return;
|
||||
}
|
||||
deleteSessionProject(project);
|
||||
var projectConnections = project.getDataSourceRegistry().getDataSources();
|
||||
for (DBPDataSourceContainer c : projectConnections) {
|
||||
removeConnection(new WebConnectionInfo(this, c));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -1147,6 +956,11 @@ public class WebSession extends BaseWebSession
|
||||
return getUserContext().getPreferenceStore();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public WebSessionGlobalProjectImpl getGlobalProject() {
|
||||
return globalProject;
|
||||
}
|
||||
|
||||
private class SessionProgressMonitor extends BaseProgressMonitor {
|
||||
@Override
|
||||
public void beginTask(String name, int totalWork) {
|
||||
@@ -1181,15 +995,6 @@ public class WebSession extends BaseWebSession
|
||||
}
|
||||
}
|
||||
|
||||
private static class PersistentAttribute {
|
||||
private final Object value;
|
||||
|
||||
public PersistentAttribute(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
private record PersistentAttribute(Object value) {
|
||||
}
|
||||
}
|
||||
|
||||
+14
-15
@@ -16,13 +16,12 @@
|
||||
*/
|
||||
package io.cloudbeaver.model.session;
|
||||
|
||||
import io.cloudbeaver.WebProjectImpl;
|
||||
import io.cloudbeaver.WebSessionProjectImpl;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.model.DBPAdaptable;
|
||||
import org.jkiss.dbeaver.model.DBPImage;
|
||||
import org.jkiss.dbeaver.model.app.DBPPlatform;
|
||||
import org.jkiss.dbeaver.model.app.DBPProject;
|
||||
import org.jkiss.dbeaver.model.app.DBPWorkspace;
|
||||
import org.jkiss.dbeaver.model.impl.auth.SessionContextImpl;
|
||||
import org.jkiss.dbeaver.model.rm.RMUtils;
|
||||
@@ -40,8 +39,8 @@ public class WebSessionWorkspace implements DBPWorkspace {
|
||||
|
||||
private final BaseWebSession session;
|
||||
private final SessionContextImpl workspaceAuthContext;
|
||||
private final List<WebProjectImpl> accessibleProjects = new ArrayList<>();
|
||||
private WebProjectImpl activeProject;
|
||||
private final List<WebSessionProjectImpl> accessibleProjects = new ArrayList<>();
|
||||
private WebSessionProjectImpl activeProject;
|
||||
|
||||
public WebSessionWorkspace(BaseWebSession session) {
|
||||
this.session = session;
|
||||
@@ -83,20 +82,20 @@ public class WebSessionWorkspace implements DBPWorkspace {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<WebProjectImpl> getProjects() {
|
||||
public List<WebSessionProjectImpl> getProjects() {
|
||||
return accessibleProjects;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public DBPProject getActiveProject() {
|
||||
public WebSessionProjectImpl getActiveProject() {
|
||||
return activeProject;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public WebProjectImpl getProject(@NotNull String projectName) {
|
||||
for (WebProjectImpl project : accessibleProjects) {
|
||||
public WebSessionProjectImpl getProject(@NotNull String projectName) {
|
||||
for (WebSessionProjectImpl project : accessibleProjects) {
|
||||
if (project.getName().equals(projectName)) {
|
||||
return project;
|
||||
}
|
||||
@@ -106,11 +105,11 @@ public class WebSessionWorkspace implements DBPWorkspace {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public WebProjectImpl getProjectById(@NotNull String projectId) {
|
||||
public WebSessionProjectImpl getProjectById(@NotNull String projectId) {
|
||||
if (projectId == null) {
|
||||
return activeProject;
|
||||
}
|
||||
for (WebProjectImpl project : accessibleProjects) {
|
||||
for (WebSessionProjectImpl project : accessibleProjects) {
|
||||
if (project.getId().equals(projectId)) {
|
||||
return project;
|
||||
}
|
||||
@@ -139,21 +138,21 @@ public class WebSessionWorkspace implements DBPWorkspace {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setActiveProject(DBPProject activeProject) {
|
||||
this.activeProject = (WebProjectImpl) activeProject;
|
||||
public void setActiveProject(WebSessionProjectImpl activeProject) {
|
||||
this.activeProject = activeProject;
|
||||
}
|
||||
|
||||
void addProject(WebProjectImpl project) {
|
||||
void addProject(WebSessionProjectImpl project) {
|
||||
accessibleProjects.add(project);
|
||||
}
|
||||
|
||||
void removeProject(WebProjectImpl project) {
|
||||
void removeProject(WebSessionProjectImpl project) {
|
||||
accessibleProjects.remove(project);
|
||||
}
|
||||
|
||||
void clearProjects() {
|
||||
if (!this.accessibleProjects.isEmpty()) {
|
||||
for (WebProjectImpl project : accessibleProjects) {
|
||||
for (WebSessionProjectImpl project : accessibleProjects) {
|
||||
project.dispose();
|
||||
}
|
||||
this.activeProject = null;
|
||||
|
||||
+34
-6
@@ -18,10 +18,9 @@ package io.cloudbeaver.utils;
|
||||
|
||||
import io.cloudbeaver.DBWConstants;
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.WebProjectImpl;
|
||||
import io.cloudbeaver.WebSessionProjectImpl;
|
||||
import io.cloudbeaver.model.WebConnectionInfo;
|
||||
import io.cloudbeaver.model.WebNetworkHandlerConfigInput;
|
||||
import io.cloudbeaver.model.app.WebApplication;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
@@ -38,6 +37,7 @@ import org.jkiss.utils.CommonUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class WebDataSourceUtils {
|
||||
|
||||
@@ -114,18 +114,22 @@ public class WebDataSourceUtils {
|
||||
|
||||
@Nullable
|
||||
public static DBPDataSourceContainer getLocalOrGlobalDataSource(
|
||||
WebApplication application, WebSession webSession, @Nullable String projectId, String connectionId
|
||||
WebSession webSession, @Nullable String projectId, String connectionId
|
||||
) throws DBWebException {
|
||||
DBPDataSourceContainer dataSource = null;
|
||||
if (!CommonUtils.isEmpty(connectionId)) {
|
||||
WebProjectImpl project = webSession.getProjectById(projectId);
|
||||
WebSessionProjectImpl project = webSession.getProjectById(projectId);
|
||||
if (project == null) {
|
||||
throw new DBWebException("Project '" + projectId + "' not found");
|
||||
}
|
||||
dataSource = project.getDataSourceRegistry().getDataSource(connectionId);
|
||||
if (dataSource == null && (webSession.hasPermission(DBWConstants.PERMISSION_ADMIN) || application.isConfigurationMode())) {
|
||||
if (dataSource == null &&
|
||||
(webSession.hasPermission(DBWConstants.PERMISSION_ADMIN) || webSession.getApplication().isConfigurationMode())) {
|
||||
// If called for new connection in admin mode then this connection may absent in session registry yet
|
||||
dataSource = getGlobalDataSourceRegistry().getDataSource(connectionId);
|
||||
project = webSession.getGlobalProject();
|
||||
if (project != null) {
|
||||
dataSource = project.getDataSourceRegistry().getDataSource(connectionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
return dataSource;
|
||||
@@ -162,4 +166,28 @@ public class WebDataSourceUtils {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The method that seeks for web connection in session cache by connection id.
|
||||
* Mostly used when project id is not defined.
|
||||
*/
|
||||
@NotNull
|
||||
public static WebConnectionInfo getWebConnectionInfo(
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable String projectId,
|
||||
@NotNull String connectionId
|
||||
) throws DBWebException {
|
||||
if (projectId == null) {
|
||||
webSession.addWarningMessage("Project id is not defined in request. Try to find it from connection cache");
|
||||
// try to find connection in all accessible projects
|
||||
Optional<WebConnectionInfo> optional = webSession.getAccessibleProjects().stream()
|
||||
.flatMap(p -> p.getConnections().stream()) // get connection cache from web projects
|
||||
.filter(e -> e.getId().contains(connectionId))
|
||||
.findFirst();
|
||||
if (optional.isPresent()) {
|
||||
return optional.get();
|
||||
}
|
||||
}
|
||||
return webSession.getAccessibleProjectById(projectId).getWebConnectionInfo(connectionId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ import io.cloudbeaver.registry.WebAuthProviderRegistry;
|
||||
import io.cloudbeaver.server.CBApplication;
|
||||
import io.cloudbeaver.server.CBPlatform;
|
||||
import io.cloudbeaver.service.navigator.WebPropertyFilter;
|
||||
import io.cloudbeaver.utils.WebAppUtils;
|
||||
import io.cloudbeaver.utils.WebCommonUtils;
|
||||
import io.cloudbeaver.utils.WebDataSourceUtils;
|
||||
import org.jkiss.code.NotNull;
|
||||
@@ -98,10 +97,6 @@ public class WebServiceUtils extends WebCommonUtils {
|
||||
return WebDataSourceUtils.getGlobalDataSourceRegistry();
|
||||
}
|
||||
|
||||
public static DBPDataSourceRegistry getGlobalRegistry(WebSession session) {
|
||||
return session.getProjectById(WebAppUtils.getGlobalProjectId()).getDataSourceRegistry();
|
||||
}
|
||||
|
||||
public static InputStream openStaticResource(String path) {
|
||||
return WebServiceUtils.class.getClassLoader().getResourceAsStream(path);
|
||||
}
|
||||
|
||||
+4
-6
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
package io.cloudbeaver.server.events;
|
||||
|
||||
import io.cloudbeaver.WebProjectImpl;
|
||||
import io.cloudbeaver.WebSessionProjectImpl;
|
||||
import io.cloudbeaver.model.session.BaseWebSession;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import org.jkiss.code.NotNull;
|
||||
@@ -34,15 +34,13 @@ public class WSDataSourceUpdatedEventHandlerImpl extends WSAbstractProjectEventH
|
||||
@Override
|
||||
protected void updateSessionData(@NotNull BaseWebSession activeUserSession, @NotNull WSDataSourceEvent event) {
|
||||
var sendEvent = true;
|
||||
if (activeUserSession instanceof WebSession) {
|
||||
var webSession = (WebSession) activeUserSession;
|
||||
WebProjectImpl project = webSession.getProjectById(event.getProjectId());
|
||||
if (activeUserSession instanceof WebSession webSession) {
|
||||
WebSessionProjectImpl project = webSession.getProjectById(event.getProjectId());
|
||||
if (project == null) {
|
||||
log.debug("Project " + event.getProjectId() + " is not found in session " + webSession.getSessionId());
|
||||
return;
|
||||
}
|
||||
sendEvent = webSession.updateProjectDataSources(
|
||||
project,
|
||||
sendEvent = project.updateProjectDataSources(
|
||||
event.getDataSourceIds(),
|
||||
WSEventType.valueById(event.getId())
|
||||
);
|
||||
|
||||
+7
-6
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package io.cloudbeaver.server.events;
|
||||
|
||||
import io.cloudbeaver.WebSessionGlobalProjectImpl;
|
||||
import io.cloudbeaver.model.session.BaseWebSession;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import io.cloudbeaver.utils.WebAppUtils;
|
||||
@@ -74,34 +75,34 @@ public class WSObjectPermissionUpdatedEventHandler extends WSDefaultEventHandler
|
||||
var webSession = (WebSession) activeUserSession;
|
||||
var dataSources = List.of(objectId);
|
||||
|
||||
var project = webSession.getProjectById(WebAppUtils.getGlobalProjectId());
|
||||
WebSessionGlobalProjectImpl project = webSession.getGlobalProject();
|
||||
if (project == null) {
|
||||
log.error("Project " + WebAppUtils.getGlobalProjectId() +
|
||||
" is not found in session " + activeUserSession.getSessionId());
|
||||
return;
|
||||
}
|
||||
if (WSEventType.OBJECT_PERMISSIONS_UPDATED.getEventId().equals(event.getId())) {
|
||||
isAccessibleNow = webSession.findWebConnectionInfo(project.getId(), objectId) != null;
|
||||
isAccessibleNow = project.findWebConnectionInfo(objectId) != null;
|
||||
if (isAccessibleNow) {
|
||||
return;
|
||||
}
|
||||
webSession.addAccessibleConnectionToCache(objectId);
|
||||
project.addAccessibleConnectionToCache(objectId);
|
||||
webSession.addSessionEvent(
|
||||
WSDataSourceEvent.create(
|
||||
event.getSessionId(),
|
||||
event.getUserId(),
|
||||
WebAppUtils.getGlobalProjectId(),
|
||||
project.getId(),
|
||||
dataSources,
|
||||
WSDataSourceProperty.CONFIGURATION
|
||||
)
|
||||
);
|
||||
} else if (WSEventType.OBJECT_PERMISSIONS_DELETED.getEventId().equals(event.getId())) {
|
||||
webSession.removeAccessibleConnectionFromCache(objectId);
|
||||
project.removeAccessibleConnectionFromCache(objectId);
|
||||
webSession.addSessionEvent(
|
||||
WSDataSourceEvent.delete(
|
||||
event.getSessionId(),
|
||||
event.getUserId(),
|
||||
WebAppUtils.getGlobalProjectId(),
|
||||
project.getId(),
|
||||
dataSources,
|
||||
WSDataSourceProperty.CONFIGURATION
|
||||
)
|
||||
|
||||
+2
-2
@@ -53,13 +53,13 @@ public class WSRmResourceUpdatedEventHandlerImpl extends WSAbstractProjectEventH
|
||||
if (eventType == WSEventType.RM_RESOURCE_CREATED) {
|
||||
RMEventManager.fireEvent(
|
||||
new RMEvent(RMEvent.Action.RESOURCE_ADD,
|
||||
project.getRmProject(),
|
||||
project.getRMProject(),
|
||||
resourcePath)
|
||||
);
|
||||
} else if (eventType == WSEventType.RM_RESOURCE_DELETED) {
|
||||
RMEventManager.fireEvent(
|
||||
new RMEvent(RMEvent.Action.RESOURCE_DELETE,
|
||||
project.getRmProject(),
|
||||
project.getRMProject(),
|
||||
resourcePath)
|
||||
);
|
||||
}
|
||||
|
||||
+8
-2
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package io.cloudbeaver.server.events;
|
||||
|
||||
import io.cloudbeaver.WebSessionProjectImpl;
|
||||
import io.cloudbeaver.model.session.BaseWebSession;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import org.jkiss.code.NotNull;
|
||||
@@ -36,11 +37,16 @@ public class WSUserSecretEventHandlerImpl extends WSDefaultEventHandler<WSUserSe
|
||||
|
||||
@Override
|
||||
protected void updateSessionData(@NotNull BaseWebSession activeUserSession, @NotNull WSUserSecretEvent event) {
|
||||
if (!(activeUserSession instanceof WebSession)) {
|
||||
if (!(activeUserSession instanceof WebSession webSession)) {
|
||||
activeUserSession.addSessionEvent(event);
|
||||
return;
|
||||
}
|
||||
var connectionInfo = ((WebSession) activeUserSession).findWebConnectionInfo(event.getProjectId(), event.getDataSourceId());
|
||||
WebSessionProjectImpl project = webSession.getProjectById(event.getProjectId());
|
||||
if (project == null) {
|
||||
log.debug("Project " + event.getDataSourceId() + " is not found in session " + webSession.getSessionId());
|
||||
return;
|
||||
}
|
||||
var connectionInfo = project.findWebConnectionInfo(event.getDataSourceId());
|
||||
if (connectionInfo == null) {
|
||||
log.debug("Connection " + event.getDataSourceId() + " is not found in session " + activeUserSession.getSessionId());
|
||||
return;
|
||||
|
||||
+3
-3
@@ -27,7 +27,7 @@ import io.cloudbeaver.server.CBApplication;
|
||||
import io.cloudbeaver.server.CBPlatform;
|
||||
import io.cloudbeaver.server.graphql.GraphQLEndpoint;
|
||||
import io.cloudbeaver.service.security.SMUtils;
|
||||
import io.cloudbeaver.utils.WebAppUtils;
|
||||
import io.cloudbeaver.utils.WebDataSourceUtils;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.jkiss.code.NotNull;
|
||||
@@ -137,7 +137,7 @@ public abstract class WebServiceBindingBase<API_TYPE extends DBWService> impleme
|
||||
|
||||
@NotNull
|
||||
public static WebConnectionInfo getWebConnection(WebSession session, String projectId, String connectionId) throws DBWebException {
|
||||
return session.getWebConnectionInfo(projectId, connectionId);
|
||||
return WebDataSourceUtils.getWebConnectionInfo(session, projectId, connectionId);
|
||||
}
|
||||
|
||||
private class ServiceInvocationHandler implements InvocationHandler {
|
||||
@@ -230,7 +230,7 @@ public abstract class WebServiceBindingBase<API_TYPE extends DBWService> impleme
|
||||
if (project == null) {
|
||||
throw new DBException("Project not found:" + projectId);
|
||||
}
|
||||
RMProject rmProject = project.getRmProject();
|
||||
RMProject rmProject = project.getRMProject();
|
||||
|
||||
for (String reqProjectPermission : requireProjectPermissions) {
|
||||
if (!rmProject.hasProjectPermission(reqProjectPermission)) {
|
||||
|
||||
+40
-36
@@ -17,10 +17,7 @@
|
||||
package io.cloudbeaver.service.core.impl;
|
||||
|
||||
|
||||
import io.cloudbeaver.DBWConstants;
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.WebProjectImpl;
|
||||
import io.cloudbeaver.WebServiceUtils;
|
||||
import io.cloudbeaver.*;
|
||||
import io.cloudbeaver.model.*;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import io.cloudbeaver.registry.WebHandlerRegistry;
|
||||
@@ -117,15 +114,17 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
return Collections.singletonList(connectionInfo);
|
||||
}
|
||||
}
|
||||
var stream = webSession.getConnections().stream();
|
||||
var stream = webSession.getAccessibleProjects().stream();
|
||||
if (projectId != null) {
|
||||
stream = stream.filter(c -> c.getProjectId().equals(projectId));
|
||||
stream = stream.filter(c -> c.getId().equals(projectId));
|
||||
}
|
||||
if (projectIds != null) {
|
||||
stream = stream.filter(c -> projectIds.contains(c.getProjectId()));
|
||||
stream = stream.filter(c -> projectIds.contains(c.getId()));
|
||||
}
|
||||
Set<String> applicableDrivers = WebServiceUtils.getApplicableDriversIds();
|
||||
return stream.filter(c -> applicableDrivers.contains(c.getDataSourceContainer().getDriver().getId()))
|
||||
return stream
|
||||
.flatMap(p -> p.getConnections().stream())
|
||||
.filter(c -> applicableDrivers.contains(c.getDataSourceContainer().getDriver().getId()))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@@ -153,27 +152,30 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
public List<WebConnectionInfo> getTemplateConnections(
|
||||
@NotNull WebSession webSession, @Nullable String projectId
|
||||
) throws DBWebException {
|
||||
if (webSession.getApplication().isDistributed()) {
|
||||
return List.of();
|
||||
}
|
||||
List<WebConnectionInfo> result = new ArrayList<>();
|
||||
if (projectId == null) {
|
||||
for (DBPProject project : webSession.getAccessibleProjects()) {
|
||||
for (WebSessionProjectImpl project : webSession.getAccessibleProjects()) {
|
||||
getTemplateConnectionsFromProject(webSession, project, result);
|
||||
}
|
||||
} else {
|
||||
DBPProject project = getProjectById(webSession, projectId);
|
||||
WebSessionProjectImpl project = getProjectById(webSession, projectId);
|
||||
getTemplateConnectionsFromProject(webSession, project, result);
|
||||
}
|
||||
webSession.filterAccessibleConnections(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void getTemplateConnectionsFromProject(
|
||||
@NotNull WebSession webSession,
|
||||
@NotNull DBPProject project,
|
||||
@NotNull WebSessionProjectImpl project,
|
||||
List<WebConnectionInfo> result
|
||||
) {
|
||||
DBPDataSourceRegistry registry = project.getDataSourceRegistry();
|
||||
for (DBPDataSourceContainer ds : registry.getDataSources()) {
|
||||
if (ds.isTemplate() &&
|
||||
project.getDataSourceFilter().filter(ds) &&
|
||||
CBPlatform.getInstance().getApplicableDrivers().contains(ds.getDriver())) {
|
||||
result.add(new WebConnectionInfo(webSession, ds));
|
||||
}
|
||||
@@ -316,9 +318,11 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
|
||||
@Override
|
||||
public WebConnectionInfo getConnectionState(
|
||||
WebSession webSession, @Nullable String projectId, String connectionId
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable String projectId,
|
||||
@NotNull String connectionId
|
||||
) throws DBWebException {
|
||||
return webSession.getWebConnectionInfo(projectId, connectionId);
|
||||
return WebDataSourceUtils.getWebConnectionInfo(webSession, projectId, connectionId);
|
||||
}
|
||||
|
||||
|
||||
@@ -333,7 +337,7 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
@Nullable Boolean sharedCredentials,
|
||||
@Nullable String selectedSecretId
|
||||
) throws DBWebException {
|
||||
WebConnectionInfo connectionInfo = webSession.getWebConnectionInfo(projectId, connectionId);
|
||||
WebConnectionInfo connectionInfo = WebDataSourceUtils.getWebConnectionInfo(webSession, projectId, connectionId);
|
||||
connectionInfo.setSavedCredentials(authProperties, networkCredentials);
|
||||
|
||||
var dataSourceContainer = (DataSourceDescriptor) connectionInfo.getDataSourceContainer();
|
||||
@@ -429,8 +433,8 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
@Nullable String projectId,
|
||||
@NotNull WebConnectionConfig connectionConfig
|
||||
) throws DBWebException {
|
||||
var project = getProjectById(webSession, projectId);
|
||||
var rmProject = project.getRmProject();
|
||||
WebSessionProjectImpl project = getProjectById(webSession, projectId);
|
||||
var rmProject = project.getRMProject();
|
||||
if (rmProject.getType() == RMProjectType.USER
|
||||
&& !webSession.hasPermission(DBWConstants.PERMISSION_ADMIN)
|
||||
&& !CBApplication.getInstance().getAppConfiguration().isSupportsCustomConnections()
|
||||
@@ -459,8 +463,7 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
throw new DBWebException("Failed to create connection", e);
|
||||
}
|
||||
|
||||
WebConnectionInfo connectionInfo = new WebConnectionInfo(webSession, newDataSource);
|
||||
webSession.addConnection(connectionInfo);
|
||||
WebConnectionInfo connectionInfo = project.addConnection(newDataSource);
|
||||
webSession.addInfoMessage("New connection was created - " + WebServiceUtils.getConnectionContainerInfo(
|
||||
newDataSource));
|
||||
WebEventUtils.addDataSourceUpdatedEvent(
|
||||
@@ -484,9 +487,8 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
// if (!CBApplication.getInstance().getAppConfiguration().isSupportsCustomConnections()) {
|
||||
// throw new DBWebException("Connection edit is restricted by server configuration");
|
||||
// }
|
||||
DBPDataSourceRegistry sessionRegistry = getProjectById(webSession, projectId).getDataSourceRegistry();
|
||||
|
||||
WebConnectionInfo connectionInfo = webSession.getWebConnectionInfo(projectId, config.getConnectionId());
|
||||
WebConnectionInfo connectionInfo = WebDataSourceUtils.getWebConnectionInfo(webSession, projectId, config.getConnectionId());
|
||||
DBPDataSourceContainer dataSource = connectionInfo.getDataSourceContainer();
|
||||
webSession.addInfoMessage("Update connection - " + WebServiceUtils.getConnectionContainerInfo(dataSource));
|
||||
var oldDataSource = new DataSourceDescriptor((DataSourceDescriptor) dataSource, dataSource.getRegistry());
|
||||
@@ -499,6 +501,8 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
dataSource.setDescription(config.getDescription());
|
||||
}
|
||||
|
||||
WebSessionProjectImpl project = getProjectById(webSession, projectId);
|
||||
DBPDataSourceRegistry sessionRegistry = project.getDataSourceRegistry();
|
||||
dataSource.setFolder(config.getFolder() != null ? sessionRegistry.getFolder(config.getFolder()) : null);
|
||||
if (config.isDefaultAutoCommit() != null) {
|
||||
dataSource.setDefaultAutoCommit(config.isDefaultAutoCommit());
|
||||
@@ -575,7 +579,7 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
public boolean deleteConnection(
|
||||
@NotNull WebSession webSession, @Nullable String projectId, @NotNull String connectionId
|
||||
) throws DBWebException {
|
||||
WebConnectionInfo connectionInfo = webSession.getWebConnectionInfo(projectId, connectionId);
|
||||
WebConnectionInfo connectionInfo = WebDataSourceUtils.getWebConnectionInfo(webSession, projectId, connectionId);
|
||||
if (connectionInfo.getDataSourceContainer().getProject() != getProjectById(webSession, projectId)) {
|
||||
throw new DBWebException("Global connection '" + connectionInfo.getName() + "' configuration cannot be deleted");
|
||||
}
|
||||
@@ -599,7 +603,8 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
@NotNull String templateId,
|
||||
@Nullable String connectionName
|
||||
) throws DBWebException {
|
||||
DBPDataSourceRegistry templateRegistry = getProjectById(webSession, projectId).getDataSourceRegistry();
|
||||
WebSessionProjectImpl project = getProjectById(webSession, projectId);
|
||||
DBPDataSourceRegistry templateRegistry = project.getDataSourceRegistry();
|
||||
DBPDataSourceContainer dataSourceTemplate = templateRegistry.getDataSource(templateId);
|
||||
if (dataSourceTemplate == null) {
|
||||
throw new DBWebException("Template data source '" + templateId + "' not found");
|
||||
@@ -622,9 +627,7 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
throw new DBWebException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
WebConnectionInfo connectionInfo = new WebConnectionInfo(webSession, newDataSource);
|
||||
webSession.addConnection(connectionInfo);
|
||||
return connectionInfo;
|
||||
return project.addConnection(newDataSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -636,7 +639,8 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
) throws DBWebException {
|
||||
try {
|
||||
DBNModel navigatorModel = webSession.getNavigatorModel();
|
||||
DBPDataSourceRegistry dataSourceRegistry = getProjectById(webSession, projectId).getDataSourceRegistry();
|
||||
WebSessionProjectImpl project = getProjectById(webSession, projectId);
|
||||
DBPDataSourceRegistry dataSourceRegistry = project.getDataSourceRegistry();
|
||||
|
||||
DBNNode srcNode = navigatorModel.getNodeByPath(webSession.getProgressMonitor(), nodePath);
|
||||
if (srcNode == null) {
|
||||
@@ -662,9 +666,8 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
|
||||
dataSourceRegistry.addDataSource(newDataSource);
|
||||
|
||||
WebConnectionInfo connectionInfo = new WebConnectionInfo(webSession, newDataSource);
|
||||
dataSourceRegistry.checkForErrors();
|
||||
webSession.addConnection(connectionInfo);
|
||||
WebConnectionInfo connectionInfo = project.addConnection(newDataSource);
|
||||
WebEventUtils.addDataSourceUpdatedEvent(
|
||||
webSession.getProjectById(projectId),
|
||||
webSession,
|
||||
@@ -687,7 +690,7 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
connectionConfig.setSaveCredentials(true); // It is used in createConnectionFromConfig
|
||||
|
||||
DataSourceDescriptor dataSource = (DataSourceDescriptor) WebDataSourceUtils.getLocalOrGlobalDataSource(
|
||||
CBApplication.getInstance(), webSession, projectId, connectionId);
|
||||
webSession, projectId, connectionId);
|
||||
|
||||
WebProjectImpl project = getProjectById(webSession, projectId);
|
||||
DBPDataSourceRegistry sessionRegistry = project.getDataSourceRegistry();
|
||||
@@ -823,12 +826,13 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
@NotNull String connectionId,
|
||||
boolean forceDelete
|
||||
) throws DBWebException {
|
||||
WebConnectionInfo connectionInfo = webSession.getWebConnectionInfo(projectId, connectionId);
|
||||
WebSessionProjectImpl project = getProjectById(webSession, projectId);
|
||||
WebConnectionInfo connectionInfo = project.getWebConnectionInfo(connectionId);
|
||||
|
||||
DBPDataSourceContainer dataSourceContainer = connectionInfo.getDataSourceContainer();
|
||||
boolean disconnected = WebDataSourceUtils.disconnectDataSource(webSession, dataSourceContainer);
|
||||
if (forceDelete) {
|
||||
DBPDataSourceRegistry registry = getProjectById(webSession, projectId).getDataSourceRegistry();
|
||||
DBPDataSourceRegistry registry = project.getDataSourceRegistry();
|
||||
registry.removeDataSource(dataSourceContainer);
|
||||
try {
|
||||
registry.checkForErrors();
|
||||
@@ -840,7 +844,7 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
}
|
||||
throw new DBWebException("Failed to delete connection", e);
|
||||
}
|
||||
webSession.removeConnection(connectionInfo);
|
||||
project.removeConnection(dataSourceContainer);
|
||||
} else {
|
||||
// Just reset saved credentials
|
||||
connectionInfo.clearCache();
|
||||
@@ -954,7 +958,7 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
public WebConnectionInfo setConnectionNavigatorSettings(
|
||||
WebSession webSession, @Nullable String projectId, String id, DBNBrowseSettings settings
|
||||
) throws DBWebException {
|
||||
WebConnectionInfo connectionInfo = webSession.getWebConnectionInfo(projectId, id);
|
||||
WebConnectionInfo connectionInfo = WebDataSourceUtils.getWebConnectionInfo(webSession, projectId, id);
|
||||
DataSourceDescriptor dataSourceDescriptor = ((DataSourceDescriptor) connectionInfo.getDataSourceContainer());
|
||||
dataSourceDescriptor.setNavigatorSettings(settings);
|
||||
dataSourceDescriptor.persistConfiguration();
|
||||
@@ -983,8 +987,8 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
return new WebProductSettings(webSession, ProductSettingsRegistry.getInstance().getSettings());
|
||||
}
|
||||
|
||||
private WebProjectImpl getProjectById(WebSession webSession, String projectId) throws DBWebException {
|
||||
WebProjectImpl project = webSession.getProjectById(projectId);
|
||||
private WebSessionProjectImpl getProjectById(WebSession webSession, String projectId) throws DBWebException {
|
||||
WebSessionProjectImpl project = webSession.getProjectById(projectId);
|
||||
if (project == null) {
|
||||
throw new DBWebException("Project '" + projectId + "' not found");
|
||||
}
|
||||
|
||||
+1
-1
@@ -259,7 +259,7 @@ public class WebNavigatorNodeInfo {
|
||||
if (project == null) {
|
||||
return false;
|
||||
}
|
||||
RMProject rmProject = project.getRmProject();
|
||||
RMProject rmProject = project.getRMProject();
|
||||
return SMUtils.hasProjectPermission(session, rmProject, permission);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -230,7 +230,7 @@ public class WebServiceNavigator implements DBWServiceNavigator {
|
||||
filter.setEnabled(true);
|
||||
if (node instanceof DBNDatabaseNode dbNode) {
|
||||
dbNode.setNodeFilter(dbNode.getItemsMeta(), filter, true);
|
||||
if (hasNodeEditPermission(webSession, node, ((WebProjectImpl) node.getOwnerProject()).getRmProject())) {
|
||||
if (hasNodeEditPermission(webSession, node, ((WebProjectImpl) node.getOwnerProject()).getRMProject())) {
|
||||
// Save settings
|
||||
dbNode.getDataSourceContainer().persistConfiguration();
|
||||
}
|
||||
@@ -571,7 +571,7 @@ public class WebServiceNavigator implements DBWServiceNavigator {
|
||||
|
||||
private void checkProjectEditAccess(DBNNode node, WebSession session) throws DBException {
|
||||
BaseWebProjectImpl project = (BaseWebProjectImpl) node.getOwnerProject();
|
||||
if (project == null || !hasNodeEditPermission(session, node, project.getRmProject())) {
|
||||
if (project == null || !hasNodeEditPermission(session, node, project.getRMProject())) {
|
||||
throw new DBException("Access denied");
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -84,7 +84,7 @@ public class WebServiceSQL implements DBWServiceSQL {
|
||||
WebConnectionInfo webConnection = WebServiceBindingBase.getWebConnection(session, projectId, connectionId);
|
||||
conToRead.add(webConnection);
|
||||
} else {
|
||||
conToRead.addAll(session.getConnections());
|
||||
conToRead.addAll(session.getAccessibleProjects().stream().flatMap(p -> p.getConnections().stream()).toList());
|
||||
}
|
||||
|
||||
List<WebSQLContextInfo> contexts = new ArrayList<>();
|
||||
|
||||
+3
-4
@@ -54,10 +54,9 @@ public class LocalSessionHandler extends AbstractActionSessionHandler {
|
||||
String connectionId = action.getParameter(LocalServletHandler.PARAM_CONNECTION_ID);
|
||||
String connectionName = action.getParameter(LocalServletHandler.PARAM_CONNECTION_NAME);
|
||||
String connectionURL = action.getParameter(LocalServletHandler.PARAM_CONNECTION_URL);
|
||||
Stream<WebConnectionInfo> stream = webSession.getConnections().stream();
|
||||
if (projectId != null) {
|
||||
stream = stream.filter(c -> c.getProjectId().equals(projectId));
|
||||
}
|
||||
Stream<WebConnectionInfo> stream = webSession.getAccessibleProjects().stream()
|
||||
.filter(c -> projectId == null || c.getId().equals(projectId))
|
||||
.flatMap(p -> p.getConnections().stream());
|
||||
if (connectionId != null) {
|
||||
stream = stream.filter(c -> c.getId().equals(connectionId));
|
||||
} else if (connectionName != null) {
|
||||
|
||||
+1
-1
@@ -88,7 +88,7 @@ public class WebDataTransferImportServlet extends WebServiceServletBase {
|
||||
throw new IllegalArgumentException("Missing required parameters");
|
||||
}
|
||||
|
||||
WebConnectionInfo webConnectionInfo = session.getWebConnectionInfo(projectId, connectionId);
|
||||
WebConnectionInfo webConnectionInfo = session.getAccessibleProjectById(projectId).getWebConnectionInfo(connectionId);
|
||||
WebSQLProcessor processor = WebServiceBindingSQL.getSQLProcessor(webConnectionInfo);
|
||||
WebSQLContextInfo webSQLContextInfo = processor.getContext(contextId);
|
||||
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ export const DriverSelectorDialog: DialogComponent<null> = observer(function Dri
|
||||
|
||||
return (
|
||||
<CommonDialogWrapper size="large" autofocus={false} fixedSize>
|
||||
<CommonDialogHeader title={translate('basicConnection_connectionDialog_newConnection')} />
|
||||
<CommonDialogHeader title={translate('plugin_connections_new_connection_dialog_title')} />
|
||||
<CommonDialogBody noBodyPadding noOverflow>
|
||||
<DriverSelector className={s(style, { driverSelector: true })} drivers={enabledDrivers} onSelect={dialog.select} />
|
||||
</CommonDialogBody>
|
||||
|
||||
@@ -1,21 +1,8 @@
|
||||
export default [
|
||||
['customConnection_connectionType_custom', 'Parameters'],
|
||||
['customConnection_connectionType_url', 'URL'],
|
||||
['customConnection_main', 'Main'],
|
||||
['customConnection_properties', 'Driver Properties'],
|
||||
['customConnection_custom_name', 'Name'],
|
||||
['customConnection_custom_host', 'Host'],
|
||||
['customConnection_custom_obligatory', '(obligatory)'],
|
||||
['customConnection_custom_port', 'Port'],
|
||||
['customConnection_custom_server_name', 'Server name'],
|
||||
['customConnection_custom_database', 'Database'],
|
||||
['customConnection_custom_server', 'Server'],
|
||||
['customConnection_url_JDBC', 'JDBC URL'],
|
||||
['customConnection_folder', 'Folder'],
|
||||
['customConnection_userName', 'User name'],
|
||||
['customConnection_Password', 'Password'],
|
||||
['customConnection_test', 'Test Connection'],
|
||||
['customConnection_create', 'Create'],
|
||||
['customConnection_create_error', 'Сreate connection error'],
|
||||
['plugin_connection_custom_action_custom_label', 'New Connection'],
|
||||
];
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
export default [['plugin_connection_custom_action_custom_label', 'New Connection']];
|
||||
|
||||
@@ -5,24 +5,4 @@
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
export default [
|
||||
['customConnection_connectionType_custom', 'Paramètres'],
|
||||
['customConnection_connectionType_url', 'URL'],
|
||||
['customConnection_main', 'Principal'],
|
||||
['customConnection_properties', 'Propriétés du pilote'],
|
||||
['customConnection_custom_name', 'Nom'],
|
||||
['customConnection_custom_host', 'Hôte'],
|
||||
['customConnection_custom_obligatory', '(obligatoire)'],
|
||||
['customConnection_custom_port', 'Port'],
|
||||
['customConnection_custom_server_name', 'Nom du serveur'],
|
||||
['customConnection_custom_database', 'Base de données'],
|
||||
['customConnection_custom_server', 'Serveur'],
|
||||
['customConnection_url_JDBC', 'URL JDBC'],
|
||||
['customConnection_folder', 'Dossier'],
|
||||
['customConnection_userName', "Nom d'utilisateur"],
|
||||
['customConnection_Password', 'Mot de passe'],
|
||||
['customConnection_test', 'Tester la connexion'],
|
||||
['customConnection_create', 'Créer'],
|
||||
['customConnection_create_error', 'Erreur de création de la connexion'],
|
||||
['plugin_connection_custom_action_custom_label', 'Nouvelle connexion'],
|
||||
];
|
||||
export default [['plugin_connection_custom_action_custom_label', 'Nouvelle connexion']];
|
||||
|
||||
@@ -1,21 +1,8 @@
|
||||
export default [
|
||||
['customConnection_connectionType_custom', 'Parametri'],
|
||||
['customConnection_connectionType_url', 'URL'],
|
||||
['customConnection_main', 'Main'],
|
||||
['customConnection_properties', 'Proprietà del driver'],
|
||||
['customConnection_custom_name', 'Nome'],
|
||||
['customConnection_custom_host', 'Host'],
|
||||
['customConnection_custom_obligatory', '(obbligatorio)'],
|
||||
['customConnection_custom_port', 'Porta'],
|
||||
['customConnection_custom_server_name', 'Server name'],
|
||||
['customConnection_custom_database', 'Database'],
|
||||
['customConnection_custom_server', 'Server'],
|
||||
['customConnection_url_JDBC', 'JDBC URL'],
|
||||
['customConnection_folder', 'Folder'],
|
||||
['customConnection_userName', 'User name'],
|
||||
['customConnection_Password', 'Password'],
|
||||
['customConnection_test', 'Prova la connessione'],
|
||||
['customConnection_create', 'Crea'],
|
||||
['customConnection_create_error', 'Errore di creazione connessione'],
|
||||
['plugin_connection_custom_action_custom_label', 'New Connection'],
|
||||
];
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
export default [['plugin_connection_custom_action_custom_label', 'New Connection']];
|
||||
|
||||
@@ -1,21 +1,8 @@
|
||||
export default [
|
||||
['customConnection_connectionType_custom', 'Параметры'],
|
||||
['customConnection_connectionType_url', 'URL'],
|
||||
['customConnection_main', 'Главное'],
|
||||
['customConnection_properties', 'Параметры драйвера'],
|
||||
['customConnection_custom_name', 'Имя'],
|
||||
['customConnection_custom_host', 'Хост'],
|
||||
['customConnection_custom_obligatory', '(обязательное)'],
|
||||
['customConnection_custom_port', 'Порт'],
|
||||
['customConnection_custom_server_name', 'Имя сервера'],
|
||||
['customConnection_custom_database', 'База'],
|
||||
['customConnection_custom_server', 'Сервер'],
|
||||
['customConnection_url_JDBC', 'JDBC URL'],
|
||||
['customConnection_folder', 'Папка'],
|
||||
['customConnection_userName', 'Пользователь'],
|
||||
['customConnection_Password', 'Пароль'],
|
||||
['customConnection_test', 'Проверить'],
|
||||
['customConnection_create', 'Создать'],
|
||||
['customConnection_create_error', 'Ошибка при создании подключения'],
|
||||
['plugin_connection_custom_action_custom_label', 'Новое подключение'],
|
||||
];
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
export default [['plugin_connection_custom_action_custom_label', 'Новое подключение']];
|
||||
|
||||
@@ -5,24 +5,4 @@
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
export default [
|
||||
['customConnection_connectionType_custom', '参数'],
|
||||
['customConnection_connectionType_url', 'URL'],
|
||||
['customConnection_main', '主要'],
|
||||
['customConnection_properties', '驱动属性'],
|
||||
['customConnection_custom_name', '名称'],
|
||||
['customConnection_custom_host', '主机'],
|
||||
['customConnection_custom_obligatory', '(强制性的)'],
|
||||
['customConnection_custom_port', '端口'],
|
||||
['customConnection_custom_server_name', '服务器名称'],
|
||||
['customConnection_custom_database', '数据库'],
|
||||
['customConnection_custom_server', '服务器'],
|
||||
['customConnection_url_JDBC', 'JDBC URL'],
|
||||
['customConnection_folder', '文件夹'],
|
||||
['customConnection_userName', '用户名称'],
|
||||
['customConnection_Password', '密码'],
|
||||
['customConnection_test', '测试连接'],
|
||||
['customConnection_create', '创建'],
|
||||
['customConnection_create_error', '创建连接失败'],
|
||||
['plugin_connection_custom_action_custom_label', '新建连接'],
|
||||
];
|
||||
export default [['plugin_connection_custom_action_custom_label', '新建连接']];
|
||||
|
||||
@@ -128,8 +128,8 @@ export class ConnectionSearchService {
|
||||
}
|
||||
|
||||
const result = await this.commonDialogService.open(ConfirmationDialog, {
|
||||
title: 'connections_public_connection_edit_cancel_title',
|
||||
message: 'connections_public_connection_edit_cancel_message',
|
||||
title: 'plugin_connections_connection_edit_cancel_title',
|
||||
message: 'plugin_connections_connection_edit_cancel_message',
|
||||
confirmActionText: 'ui_processing_ok',
|
||||
});
|
||||
|
||||
|
||||
+2
-4
@@ -43,7 +43,7 @@ export const ConnectionDialog: DialogComponent<null, null> = observer(function C
|
||||
return (
|
||||
<CommonDialogWrapper size="large" fixedSize={dialog.step === ConnectionStep.ConnectionTemplateSelect}>
|
||||
<CommonDialogHeader
|
||||
title="basicConnection_connectionDialog_newConnection"
|
||||
title="plugin_connections_new_connection_dialog_title"
|
||||
subTitle={subTitle}
|
||||
icon={dialog.driver?.icon}
|
||||
onReject={rejectDialog}
|
||||
@@ -52,9 +52,7 @@ export const ConnectionDialog: DialogComponent<null, null> = observer(function C
|
||||
{dialog.step === ConnectionStep.ConnectionTemplateSelect && <TemplateConnectionSelector onSelect={dialog.selectTemplate} />}
|
||||
{dialog.step === ConnectionStep.Connection &&
|
||||
(!dialog.authModelId ? (
|
||||
<center className={s(styles, { center: true })}>
|
||||
{dialog.processing && translate('basicConnection_connectionDialog_connecting_message')}
|
||||
</center>
|
||||
<center className={s(styles, { center: true })}>{dialog.processing && translate('plugin_connection_template_connecting_message')}</center>
|
||||
) : (
|
||||
<Form ref={focusedRef} className={s(styles, { submittingForm: true })} onSubmit={dialog.connect}>
|
||||
<ConnectionAuthenticationFormLoader
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ export const ConnectionDialogFooter = observer<Props>(function ConnectionDialogF
|
||||
{translate('ui_stepper_back')}
|
||||
</Button>
|
||||
<Button type="button" mod={['unelevated']} disabled={isConnecting} onClick={onConnect}>
|
||||
{isConnecting ? translate('basicConnection_connectionDialog_connecting') : translate('connections_connection_connect')}
|
||||
{isConnecting ? translate('plugin_connection_template_connecting') : translate('connections_connection_connect')}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
export default [
|
||||
['basicConnection_connectionDialog_newConnection', 'New connection'],
|
||||
['basicConnection_connectionDialog_title', 'Connect to Database'],
|
||||
['basicConnection_connectionDialog_listTitle', 'Database:'],
|
||||
['basicConnection_connectionDialog_username', 'Database Username:'],
|
||||
['basicConnection_connectionDialog_usernamePlaceholder', 'user'],
|
||||
['basicConnection_connectionDialog_password', 'Database User Password:'],
|
||||
['basicConnection_connectionDialog_passwordPlaceholder', 'password'],
|
||||
['basicConnection_connectionDialog_connecting', 'Connecting...'],
|
||||
['basicConnection_connectionDialog_connecting_message', 'Connecting to database...'],
|
||||
['plugin_connection_template_connecting', 'Connecting...'],
|
||||
['plugin_connection_template_connecting_message', 'Connecting to database...'],
|
||||
['plugin_connection_template_connect_success', 'Connection is established'],
|
||||
['plugin_connection_template_action_connection_template_label', 'From a Template'],
|
||||
];
|
||||
|
||||
@@ -6,15 +6,8 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
export default [
|
||||
['basicConnection_connectionDialog_newConnection', 'Nouvelle connexion'],
|
||||
['basicConnection_connectionDialog_title', 'Se connecter à la base de données'],
|
||||
['basicConnection_connectionDialog_listTitle', 'Base de données :'],
|
||||
['basicConnection_connectionDialog_username', "Nom d'utilisateur de la base de données :"],
|
||||
['basicConnection_connectionDialog_usernamePlaceholder', 'utilisateur'],
|
||||
['basicConnection_connectionDialog_password', "Mot de passe de l'utilisateur de la base de données :"],
|
||||
['basicConnection_connectionDialog_passwordPlaceholder', 'mot de passe'],
|
||||
['basicConnection_connectionDialog_connecting', 'Connexion en cours...'],
|
||||
['basicConnection_connectionDialog_connecting_message', 'Connexion à la base de données en cours...'],
|
||||
['plugin_connection_template_connecting', 'Connexion en cours...'],
|
||||
['plugin_connection_template_connecting_message', 'Connexion à la base de données en cours...'],
|
||||
['plugin_connection_template_connect_success', 'Connexion établie'],
|
||||
['plugin_connection_template_action_connection_template_label', "À partir d'un modèle"],
|
||||
];
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
export default [
|
||||
['basicConnection_connectionDialog_newConnection', 'Nuova connessione'],
|
||||
['basicConnection_connectionDialog_title', 'Collegati al database'],
|
||||
['basicConnection_connectionDialog_listTitle', 'Database:'],
|
||||
['basicConnection_connectionDialog_username', 'Database Username:'],
|
||||
['basicConnection_connectionDialog_usernamePlaceholder', 'utente'],
|
||||
['basicConnection_connectionDialog_password', 'Password Utente del Database:'],
|
||||
['basicConnection_connectionDialog_passwordPlaceholder', 'password'],
|
||||
['basicConnection_connectionDialog_connecting', 'Collegamento...'],
|
||||
['basicConnection_connectionDialog_connecting_message', 'Collegamento al database...'],
|
||||
['plugin_connection_template_connecting', 'Collegamento...'],
|
||||
['plugin_connection_template_connecting_message', 'Collegamento al database...'],
|
||||
['plugin_connection_template_connect_success', 'Connection is established'],
|
||||
['plugin_connection_template_action_connection_template_label', 'Dal Template'],
|
||||
];
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
export default [
|
||||
['basicConnection_connectionDialog_newConnection', 'Новое подключение'],
|
||||
['basicConnection_connectionDialog_title', 'Подключение к базе данных'],
|
||||
['basicConnection_connectionDialog_listTitle', 'Базы данных:'],
|
||||
['basicConnection_connectionDialog_username', 'Имя пользователя:'],
|
||||
['basicConnection_connectionDialog_usernamePlaceholder', 'user'],
|
||||
['basicConnection_connectionDialog_password', 'Пароль пользователя:'],
|
||||
['basicConnection_connectionDialog_passwordPlaceholder', 'password'],
|
||||
['basicConnection_connectionDialog_connecting', 'Подключение...'],
|
||||
['basicConnection_connectionDialog_connecting_message', 'Подключение к базе...'],
|
||||
['plugin_connection_template_connecting', 'Подключение...'],
|
||||
['plugin_connection_template_connecting_message', 'Подключение к базе...'],
|
||||
['plugin_connection_template_connect_success', 'Подключение установлено'],
|
||||
['plugin_connection_template_action_connection_template_label', 'Из шаблона'],
|
||||
];
|
||||
|
||||
@@ -6,15 +6,8 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
export default [
|
||||
['basicConnection_connectionDialog_newConnection', '新连接'],
|
||||
['basicConnection_connectionDialog_title', '连接数据库'],
|
||||
['basicConnection_connectionDialog_listTitle', '数据库:'],
|
||||
['basicConnection_connectionDialog_username', '用户库用户名:'],
|
||||
['basicConnection_connectionDialog_usernamePlaceholder', '用户'],
|
||||
['basicConnection_connectionDialog_password', '数据库用户密码:'],
|
||||
['basicConnection_connectionDialog_passwordPlaceholder', '密码'],
|
||||
['basicConnection_connectionDialog_connecting', '连接中...'],
|
||||
['basicConnection_connectionDialog_connecting_message', '连接数据库...'],
|
||||
['plugin_connection_template_connecting', '连接中...'],
|
||||
['plugin_connection_template_connecting_message', '连接数据库...'],
|
||||
['plugin_connection_template_connect_success', '已建立连接'],
|
||||
['plugin_connection_template_action_connection_template_label', '从模板创建'],
|
||||
];
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
export default [
|
||||
['connections_public_connection_edit_menu_item_title', 'Edit Connection'],
|
||||
['connections_public_connection_edit_cancel_title', 'Cancel confirmation'],
|
||||
['connections_public_connection_edit_reconnect_title', 'Connection updated'],
|
||||
['connections_public_connection_edit_reconnect_message', 'Connection has been updated. Do you want to reconnect?'],
|
||||
['connections_public_connection_edit_reconnect_failed', 'Failed to reconnect'],
|
||||
['plugin_connections_connection_edit_menu_item_title', 'Edit Connection'],
|
||||
['plugin_connections_connection_edit_cancel_title', 'Cancel confirmation'],
|
||||
['plugin_connections_connection_edit_reconnect_title', 'Connection updated'],
|
||||
['plugin_connections_connection_edit_reconnect_message', 'Connection has been updated. Do you want to reconnect?'],
|
||||
['plugin_connections_connection_edit_reconnect_failed', 'Failed to reconnect'],
|
||||
|
||||
['connections_administration_deactivate_message', "Your connection's settings will be lost. Do you want to continue?"],
|
||||
[
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
export default [
|
||||
['connections_public_connection_edit_menu_item_title', 'Modifier la connexion'],
|
||||
['connections_public_connection_edit_cancel_title', "Confirmation d'annulation"],
|
||||
['connections_public_connection_edit_reconnect_title', 'Connexion mise à jour'],
|
||||
['connections_public_connection_edit_reconnect_message', 'La connexion a été mise à jour. Voulez-vous vous reconnecter ?'],
|
||||
['connections_public_connection_edit_reconnect_failed', 'Échec de la reconnexion'],
|
||||
['plugin_connections_connection_edit_menu_item_title', 'Modifier la connexion'],
|
||||
['plugin_connections_connection_edit_cancel_title', "Confirmation d'annulation"],
|
||||
['plugin_connections_connection_edit_reconnect_title', 'Connexion mise à jour'],
|
||||
['plugin_connections_connection_edit_reconnect_message', 'La connexion a été mise à jour. Voulez-vous vous reconnecter ?'],
|
||||
['plugin_connections_connection_edit_reconnect_failed', 'Échec de la reconnexion'],
|
||||
|
||||
['connections_administration_deactivate_message', 'Les paramètres de votre connexion seront perdus. Voulez-vous continuer ?'],
|
||||
[
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
export default [
|
||||
['connections_public_connection_edit_menu_item_title', 'Modifica Connessione'],
|
||||
['connections_public_connection_edit_cancel_title', "Conferma l'annullamento"],
|
||||
['plugin_connections_connection_edit_menu_item_title', 'Modifica Connessione'],
|
||||
['plugin_connections_connection_edit_cancel_title', "Conferma l'annullamento"],
|
||||
[
|
||||
'templates_administration_info_message',
|
||||
'The templates enable administrators to define various reusable connection parameters, subsequently allowing users to create multiple connections based on these templates.',
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
export default [
|
||||
['connections_public_connection_edit_menu_item_title', 'Изменить подключение'],
|
||||
['connections_public_connection_edit_cancel_title', 'Отмена редактирования'],
|
||||
['connections_public_connection_edit_reconnect_title', 'Подключение обновлено'],
|
||||
['connections_public_connection_edit_reconnect_message', 'Подключение было обновлено. Вы хотите переподключиться?'],
|
||||
['connections_public_connection_edit_reconnect_failed', 'Не удалось переподключиться'],
|
||||
['plugin_connections_connection_edit_menu_item_title', 'Изменить подключение'],
|
||||
['plugin_connections_connection_edit_cancel_title', 'Отмена редактирования'],
|
||||
['plugin_connections_connection_edit_reconnect_title', 'Подключение обновлено'],
|
||||
['plugin_connections_connection_edit_reconnect_message', 'Подключение было обновлено. Вы хотите переподключиться?'],
|
||||
['plugin_connections_connection_edit_reconnect_failed', 'Не удалось переподключиться'],
|
||||
|
||||
['connections_administration_deactivate_message', 'Настройки вашего подключения будут потеряны. Вы хотите продолжить?'],
|
||||
[
|
||||
|
||||
@@ -6,16 +6,13 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
export default [
|
||||
['connections_public_connection_edit_menu_item_title', '编辑连接'],
|
||||
['connections_public_connection_edit_cancel_title', '取消确认'],
|
||||
['connections_public_connection_edit_reconnect_title', '连接已更新'],
|
||||
['connections_public_connection_edit_reconnect_message', '连接已更新。您想重新连接吗?'],
|
||||
['connections_public_connection_edit_reconnect_failed', '重新连接失败'],
|
||||
['plugin_connections_connection_edit_menu_item_title', '编辑连接'],
|
||||
['plugin_connections_connection_edit_cancel_title', '取消确认'],
|
||||
['plugin_connections_connection_edit_reconnect_title', '连接已更新'],
|
||||
['plugin_connections_connection_edit_reconnect_message', '连接已更新。您想重新连接吗?'],
|
||||
['plugin_connections_connection_edit_reconnect_failed', '重新连接失败'],
|
||||
|
||||
['connections_administration_deactivate_message', '您的连接设置将丢失。您要继续吗?'],
|
||||
[
|
||||
'templates_administration_info_message',
|
||||
'管理员可在数据库连接模板中定义各种可重用的连接参数,之后用户可基于这些模板创建多个数据库连接。',
|
||||
],
|
||||
['templates_administration_info_message', '管理员可在数据库连接模板中定义各种可重用的连接参数,之后用户可基于这些模板创建多个数据库连接。'],
|
||||
['connections_administration_connection_create_error', 'Failed to create connection'],
|
||||
];
|
||||
|
||||
+2
-2
@@ -35,8 +35,8 @@ export class ConnectionDriverPropertiesTabService extends Bootstrap {
|
||||
override register(): void {
|
||||
this.connectionFormService.tabsContainer.add({
|
||||
key: 'driver_properties',
|
||||
name: 'customConnection_properties',
|
||||
title: 'customConnection_properties',
|
||||
name: 'plugin_connections_connection_form_part_properties',
|
||||
title: 'plugin_connections_connection_form_part_properties',
|
||||
order: 2,
|
||||
panel: () => DriverPropertiesLoader,
|
||||
isDisabled: (tabId, props) => {
|
||||
|
||||
+2
-2
@@ -64,7 +64,7 @@ export class ConnectionOptionsTabService extends Bootstrap {
|
||||
override register(): void {
|
||||
this.connectionFormService.tabsContainer.add({
|
||||
key: 'options',
|
||||
name: 'customConnection_main',
|
||||
name: 'plugin_connections_connection_form_part_main',
|
||||
order: 1,
|
||||
panel: () => Options,
|
||||
});
|
||||
@@ -382,7 +382,7 @@ export class ConnectionOptionsTabService extends Bootstrap {
|
||||
|
||||
if (!this.userInfoResource.hasToken(providerId)) {
|
||||
const provider = await this.authProvidersResource.load(providerId);
|
||||
const message = this.localizationService.translate('connections_public_connection_cloud_auth_required', undefined, {
|
||||
const message = this.localizationService.translate('plugin_connections_connection_cloud_auth_required', undefined, {
|
||||
providerLabel: provider.label,
|
||||
});
|
||||
stateContext.setInfo(message);
|
||||
|
||||
@@ -220,7 +220,7 @@ export const Options: TabContainerPanelComponent<IConnectionFormProps> = observe
|
||||
readOnly={readonly}
|
||||
autoComplete={`section-${config.driverId || 'driver'} section-jdbc`}
|
||||
>
|
||||
{translate('customConnection_url_JDBC')}
|
||||
{translate('plugin_connections_connection_form_part_main_url_jdbc')}
|
||||
</InputField>
|
||||
)}
|
||||
|
||||
@@ -269,7 +269,7 @@ export const Options: TabContainerPanelComponent<IConnectionFormProps> = observe
|
||||
tiny
|
||||
fill
|
||||
>
|
||||
{translate('customConnection_folder')}
|
||||
{translate('plugin_connections_connection_form_part_main_folder')}
|
||||
</InputField>
|
||||
)}
|
||||
</Container>
|
||||
|
||||
@@ -27,19 +27,19 @@ export const ParametersForm = observer<Props>(function ParametersForm({ config,
|
||||
{!embedded && (
|
||||
<Container wrap gap>
|
||||
<InputField type="text" name="host" state={config} disabled={disabled} readOnly={readOnly || !originLocal} small required>
|
||||
{translate('customConnection_custom_host')}
|
||||
{translate('plugin_connections_connection_form_part_main_custom_host')}
|
||||
</InputField>
|
||||
<InputField type="number" name="port" state={config} disabled={disabled} readOnly={readOnly || !originLocal} tiny>
|
||||
{translate('customConnection_custom_port')}
|
||||
{translate('plugin_connections_connection_form_part_main_custom_port')}
|
||||
</InputField>
|
||||
</Container>
|
||||
)}
|
||||
<InputField type="text" name="databaseName" state={config} disabled={disabled} readOnly={readOnly}>
|
||||
{translate('customConnection_custom_database')}
|
||||
{translate('plugin_connections_connection_form_part_main_custom_database')}
|
||||
</InputField>
|
||||
{requiresServerName && (
|
||||
<InputField type="text" name="serverName" state={config} disabled={disabled} readOnly={readOnly} required>
|
||||
{translate('customConnection_custom_server_name')}
|
||||
{translate('plugin_connections_connection_form_part_main_custom_server_name')}
|
||||
</InputField>
|
||||
)}
|
||||
</Container>
|
||||
|
||||
@@ -96,7 +96,7 @@ export const OriginInfo: TabContainerPanelComponent<IConnectionFormProps> = obse
|
||||
return (
|
||||
<ColoredContainer className={s(style, { coloredContainer: true })} parent>
|
||||
<TextPlaceholder>
|
||||
{translate('connections_public_connection_cloud_auth_required', undefined, {
|
||||
{translate('plugin_connections_connection_cloud_auth_required', undefined, {
|
||||
providerLabel: providerLoader.data?.label,
|
||||
})}
|
||||
</TextPlaceholder>
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ export class ConnectionSSHTabService extends Bootstrap {
|
||||
override register(): void {
|
||||
this.connectionFormService.tabsContainer.add({
|
||||
key: 'ssh',
|
||||
name: 'customConnection_main',
|
||||
name: 'plugin_connections_connection_form_part_main',
|
||||
order: 3,
|
||||
tab: () => SSHTab,
|
||||
panel: () => SSHPanel,
|
||||
|
||||
@@ -68,7 +68,7 @@ export const SSL: TabContainerPanelComponent<Props> = observer(function SSL({ st
|
||||
mod={['primary']}
|
||||
disabled={disabled || readonly}
|
||||
>
|
||||
{translate('connections_public_connection_ssl_enable')}
|
||||
{translate('plugin_connections_connection_ssl_enable')}
|
||||
</Switch>
|
||||
{isUncategorizedExists && (
|
||||
<ObjectPropertyInfoForm
|
||||
|
||||
+1
-1
@@ -8,5 +8,5 @@
|
||||
import { createAction } from '@cloudbeaver/core-view';
|
||||
|
||||
export const ACTION_CONNECTION_EDIT = createAction('connection-edit', {
|
||||
label: 'connections_public_connection_edit_menu_item_title',
|
||||
label: 'plugin_connections_connection_edit_menu_item_title',
|
||||
});
|
||||
|
||||
@@ -109,7 +109,7 @@ export class ConnectionFoldersBootstrap extends Bootstrap {
|
||||
|
||||
const result = await this.commonDialogService.open(ConfirmationDialogDelete, {
|
||||
title: 'ui_data_delete_confirmation',
|
||||
message: this.localizationService.translate('connections_public_connection_folder_delete_confirmation', undefined, { name: nodes }),
|
||||
message: this.localizationService.translate('plugin_connections_connection_folder_delete_confirmation', undefined, { name: nodes }),
|
||||
confirmActionText: 'ui_delete',
|
||||
});
|
||||
|
||||
@@ -209,8 +209,8 @@ export class ConnectionFoldersBootstrap extends Bootstrap {
|
||||
|
||||
if (folderDuplicates.length > 0) {
|
||||
this.notificationService.logError({
|
||||
title: 'connections_public_connection_folder_move_failed',
|
||||
message: this.localizationService.translate('connections_public_connection_folder_move_duplication', undefined, {
|
||||
title: 'plugin_connections_connection_folder_move_failed',
|
||||
message: this.localizationService.translate('plugin_connections_connection_folder_move_duplication', undefined, {
|
||||
name: folderDuplicates.map(node => `"${node.name}"`).join(', '),
|
||||
}),
|
||||
});
|
||||
@@ -233,7 +233,7 @@ export class ConnectionFoldersBootstrap extends Bootstrap {
|
||||
|
||||
this.connectionInfoResource.markOutdated(resourceKeyList(connections));
|
||||
} catch (exception: any) {
|
||||
this.notificationService.logException(exception, 'connections_public_connection_folder_move_failed');
|
||||
this.notificationService.logException(exception, 'plugin_connections_connection_folder_move_failed');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,8 +41,8 @@ export class PluginConnectionsSettingsService extends Dependency {
|
||||
// access: {
|
||||
// scope: ['server'],
|
||||
// },
|
||||
// name: 'settings_connections_hide_connections_view_name',
|
||||
// description: 'settings_connections_hide_connections_view_description',
|
||||
// name: 'plugin_connections_settings_hide_connections_view_name',
|
||||
// description: 'plugin_connections_settings_hide_connections_view_description',
|
||||
// group: CONNECTIONS_SETTINGS_GROUP,
|
||||
// },
|
||||
// ]);
|
||||
|
||||
+5
-5
@@ -190,8 +190,8 @@ export class PublicConnectionFormService {
|
||||
}
|
||||
|
||||
const result = await this.commonDialogService.open(ConfirmationDialog, {
|
||||
title: 'connections_public_connection_edit_cancel_title',
|
||||
message: 'connections_public_connection_edit_cancel_message',
|
||||
title: 'plugin_connections_connection_edit_cancel_title',
|
||||
message: 'plugin_connections_connection_edit_cancel_message',
|
||||
confirmActionText: 'ui_processing_ok',
|
||||
});
|
||||
|
||||
@@ -200,8 +200,8 @@ export class PublicConnectionFormService {
|
||||
|
||||
private async tryReconnect(connectionKey: IConnectionInfoParams) {
|
||||
const result = await this.commonDialogService.open(ConfirmationDialog, {
|
||||
title: 'connections_public_connection_edit_reconnect_title',
|
||||
message: 'connections_public_connection_edit_reconnect_message',
|
||||
title: 'plugin_connections_connection_edit_reconnect_title',
|
||||
message: 'plugin_connections_connection_edit_reconnect_message',
|
||||
confirmActionText: 'ui_reconnect',
|
||||
});
|
||||
|
||||
@@ -213,7 +213,7 @@ export class PublicConnectionFormService {
|
||||
await this.connectionInfoResource.close(connectionKey);
|
||||
await this.connectionsManagerService.requireConnection(connectionKey);
|
||||
} catch (exception: any) {
|
||||
this.notificationService.logException(exception, 'connections_public_connection_edit_reconnect_failed');
|
||||
this.notificationService.logException(exception, 'plugin_connections_connection_edit_reconnect_failed');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,27 +6,37 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
export default [
|
||||
['connections_public_connection_edit_menu_item_title', 'Edit Connection'],
|
||||
['connections_public_connection_edit_cancel_title', 'Cancel confirmation'],
|
||||
['connections_public_connection_edit_cancel_message', "You're going to cancel connection changes. Unsaved changes will be lost. Are you sure?"],
|
||||
['connections_public_connection_edit_reconnect_title', 'Connection updated'],
|
||||
['connections_public_connection_edit_reconnect_message', 'Connection has been updated. Do you want to reconnect?'],
|
||||
['connections_public_connection_edit_reconnect_failed', 'Failed to reconnect'],
|
||||
['connections_public_connection_folder_move_failed', 'Failed to move to folder'],
|
||||
['connections_public_connection_folder_move_duplication', 'Target folder or selected folders contains folder with the same name ({arg:name})'],
|
||||
['connections_public_connection_cloud_auth_required', 'You need to sign in with "{arg:providerLabel}" credentials to work with this connection.'],
|
||||
['plugin_connections_new_connection_dialog_title', 'New connection'],
|
||||
['plugin_connections_connection_form_part_main', 'Main'],
|
||||
['plugin_connections_connection_form_part_properties', 'Driver Properties'],
|
||||
['plugin_connections_connection_form_part_main_custom_host', 'Host'],
|
||||
['plugin_connections_connection_form_part_main_custom_port', 'Port'],
|
||||
['plugin_connections_connection_form_part_main_custom_server_name', 'Server name'],
|
||||
['plugin_connections_connection_form_part_main_custom_database', 'Database'],
|
||||
['plugin_connections_connection_form_part_main_url_jdbc', 'JDBC URL'],
|
||||
['plugin_connections_connection_form_part_main_folder', 'Folder'],
|
||||
|
||||
['plugin_connections_connection_edit_menu_item_title', 'Edit Connection'],
|
||||
['plugin_connections_connection_edit_cancel_title', 'Cancel confirmation'],
|
||||
['plugin_connections_connection_edit_cancel_message', "You're going to cancel connection changes. Unsaved changes will be lost. Are you sure?"],
|
||||
['plugin_connections_connection_edit_reconnect_title', 'Connection updated'],
|
||||
['plugin_connections_connection_edit_reconnect_message', 'Connection has been updated. Do you want to reconnect?'],
|
||||
['plugin_connections_connection_edit_reconnect_failed', 'Failed to reconnect'],
|
||||
['plugin_connections_connection_folder_move_failed', 'Failed to move to folder'],
|
||||
['plugin_connections_connection_folder_move_duplication', 'Target folder or selected folders contains folder with the same name ({arg:name})'],
|
||||
['plugin_connections_connection_cloud_auth_required', 'You need to sign in with "{arg:providerLabel}" credentials to work with this connection.'],
|
||||
['plugin_connections_connection_form_project_invalid', 'You have no access to create connections in selected project'],
|
||||
['plugin_connections_connection_form_host_configuration_invalid', 'Host configuration is not supported'],
|
||||
['plugin_connections_connection_form_name_invalid', "Field 'Connection name' can't be empty"],
|
||||
['plugin_connections_connection_form_host_invalid', "Field 'Host' can't be empty"],
|
||||
['connections_public_connection_folder_delete_confirmation', 'You\'re going to delete "{arg:name}". Connections won\'t be deleted. Are you sure?'],
|
||||
['plugin_connections_connection_folder_delete_confirmation', 'You\'re going to delete "{arg:name}". Connections won\'t be deleted. Are you sure?'],
|
||||
['plugin_connections_menu_connections_label', 'Connection'],
|
||||
['plugin_connections_action_disconnect_all_label', 'Disconnect All'],
|
||||
['settings_connections', 'Connections'],
|
||||
['settings_connections_hide_connections_view_name', 'Hide connections'],
|
||||
['settings_connections_hide_connections_view_description', 'Connections will be hidden for all users except administrators'],
|
||||
['plugin_connections_settings', 'Connections'],
|
||||
['plugin_connections_settings_hide_connections_view_name', 'Hide connections'],
|
||||
['plugin_connections_settings_hide_connections_view_description', 'Connections will be hidden for all users except administrators'],
|
||||
|
||||
['connections_public_connection_ssl_enable', 'Enable SSL'],
|
||||
['plugin_connections_connection_ssl_enable', 'Enable SSL'],
|
||||
|
||||
['plugin_connections_connection_form_shared_credentials_manage_info', 'You can manage credentials in the '],
|
||||
['plugin_connections_connection_form_shared_credentials_manage_info_tab_link', 'Credentials tab'],
|
||||
|
||||
@@ -6,22 +6,32 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
export default [
|
||||
['connections_public_connection_edit_menu_item_title', 'Modifier la connexion'],
|
||||
['connections_public_connection_edit_cancel_title', "Confirmation d'annulation"],
|
||||
['plugin_connections_connection_form_part_main', 'Principal'],
|
||||
['plugin_connections_connection_form_part_properties', 'Propriétés du pilote'],
|
||||
['plugin_connections_connection_form_part_main_custom_host', 'Hôte'],
|
||||
['plugin_connections_connection_form_part_main_custom_port', 'Port'],
|
||||
['plugin_connections_connection_form_part_main_custom_server_name', 'Nom du serveur'],
|
||||
['plugin_connections_connection_form_part_main_custom_database', 'Base de données'],
|
||||
['plugin_connections_connection_form_part_main_url_jdbc', 'URL JDBC'],
|
||||
['plugin_connections_connection_form_part_main_folder', 'Dossier'],
|
||||
['plugin_connections_new_connection_dialog_title', 'Nouvelle connexion'],
|
||||
|
||||
['plugin_connections_connection_edit_menu_item_title', 'Modifier la connexion'],
|
||||
['plugin_connections_connection_edit_cancel_title', "Confirmation d'annulation"],
|
||||
[
|
||||
'connections_public_connection_edit_cancel_message',
|
||||
'plugin_connections_connection_edit_cancel_message',
|
||||
'Vous allez annuler les modifications de la connexion. Les modifications non enregistrées seront perdues. Êtes-vous sûr ?',
|
||||
],
|
||||
['connections_public_connection_edit_reconnect_title', 'Connexion mise à jour'],
|
||||
['connections_public_connection_edit_reconnect_message', 'La connexion a été mise à jour. Voulez-vous vous reconnecter ?'],
|
||||
['connections_public_connection_edit_reconnect_failed', 'Échec de la reconnexion'],
|
||||
['connections_public_connection_folder_move_failed', 'Échec du déplacement vers le dossier'],
|
||||
['plugin_connections_connection_edit_reconnect_title', 'Connexion mise à jour'],
|
||||
['plugin_connections_connection_edit_reconnect_message', 'La connexion a été mise à jour. Voulez-vous vous reconnecter ?'],
|
||||
['plugin_connections_connection_edit_reconnect_failed', 'Échec de la reconnexion'],
|
||||
['plugin_connections_connection_folder_move_failed', 'Échec du déplacement vers le dossier'],
|
||||
[
|
||||
'connections_public_connection_folder_move_duplication',
|
||||
'plugin_connections_connection_folder_move_duplication',
|
||||
'Le dossier cible ou les dossiers sélectionnés contiennent un dossier portant le même nom ({arg:name})',
|
||||
],
|
||||
[
|
||||
'connections_public_connection_cloud_auth_required',
|
||||
'plugin_connections_connection_cloud_auth_required',
|
||||
'Vous devez vous connecter avec les identifiants "{arg:providerLabel}" pour travailler avec cette connexion.',
|
||||
],
|
||||
['plugin_connections_connection_form_project_invalid', "Vous n'avez pas accès à la création de connexions dans le projet sélectionné"],
|
||||
@@ -29,16 +39,16 @@ export default [
|
||||
['plugin_connections_connection_form_name_invalid', 'Le champ "Nom de la connexion" ne peut pas être vide'],
|
||||
['plugin_connections_connection_form_host_invalid', 'Le champ "Hôte" ne peut pas être vide'],
|
||||
[
|
||||
'connections_public_connection_folder_delete_confirmation',
|
||||
'plugin_connections_connection_folder_delete_confirmation',
|
||||
'Vous allez supprimer "{arg:name}". Les connexions ne seront pas supprimées. Êtes-vous sûr ?',
|
||||
],
|
||||
['plugin_connections_menu_connections_label', 'Connexion'],
|
||||
['plugin_connections_action_disconnect_all_label', 'Déconnecter tout'],
|
||||
['settings_connections', 'Connexions'],
|
||||
['settings_connections_hide_connections_view_name', 'Hide connections'],
|
||||
['settings_connections_hide_connections_view_description', 'Connections will be hidden for all users except administrators'],
|
||||
['plugin_connections_settings', 'Connexions'],
|
||||
['plugin_connections_settings_hide_connections_view_name', 'Hide connections'],
|
||||
['plugin_connections_settings_hide_connections_view_description', 'Connections will be hidden for all users except administrators'],
|
||||
|
||||
['connections_public_connection_ssl_enable', 'Activer SSL'],
|
||||
['plugin_connections_connection_ssl_enable', 'Activer SSL'],
|
||||
|
||||
['plugin_connections_connection_form_shared_credentials_manage_info', "Vous pouvez gérer les identifiants dans l'onglet "],
|
||||
['plugin_connections_connection_form_shared_credentials_manage_info_tab_link', 'Onglet Identifiants'],
|
||||
|
||||
@@ -6,29 +6,39 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
export default [
|
||||
['connections_public_connection_edit_menu_item_title', 'Modifica Connessione'],
|
||||
['connections_public_connection_edit_cancel_title', "Conferma l'annullamento"],
|
||||
['plugin_connections_connection_form_part_main', 'Main'],
|
||||
['plugin_connections_connection_form_part_properties', 'Proprietà del driver'],
|
||||
['plugin_connections_connection_form_part_main_custom_host', 'Host'],
|
||||
['plugin_connections_connection_form_part_main_custom_port', 'Porta'],
|
||||
['plugin_connections_connection_form_part_main_custom_server_name', 'Server name'],
|
||||
['plugin_connections_connection_form_part_main_custom_database', 'Database'],
|
||||
['plugin_connections_connection_form_part_main_url_jdbc', 'JDBC URL'],
|
||||
['plugin_connections_connection_form_part_main_folder', 'Folder'],
|
||||
['plugin_connections_new_connection_dialog_title', 'Nuova connessione'],
|
||||
|
||||
['plugin_connections_connection_edit_menu_item_title', 'Modifica Connessione'],
|
||||
['plugin_connections_connection_edit_cancel_title', "Conferma l'annullamento"],
|
||||
[
|
||||
'connections_public_connection_edit_cancel_message',
|
||||
'plugin_connections_connection_edit_cancel_message',
|
||||
'Stai per annullare le modifiche alla connessione. Modifiche non salvate saranno perse. Sei sicuro?',
|
||||
],
|
||||
['connections_public_connection_edit_reconnect_title', 'Connection updated'],
|
||||
['connections_public_connection_edit_reconnect_message', 'Connection has been updated. Do you want to reconnect?'],
|
||||
['connections_public_connection_edit_reconnect_failed', 'Failed to reconnect'],
|
||||
['connections_public_connection_folder_move_failed', 'Failed to move to folder'],
|
||||
['connections_public_connection_folder_move_duplication', 'Target folder or selected folders contains folder with the same name ({arg:name})'],
|
||||
['plugin_connections_connection_edit_reconnect_title', 'Connection updated'],
|
||||
['plugin_connections_connection_edit_reconnect_message', 'Connection has been updated. Do you want to reconnect?'],
|
||||
['plugin_connections_connection_edit_reconnect_failed', 'Failed to reconnect'],
|
||||
['plugin_connections_connection_folder_move_failed', 'Failed to move to folder'],
|
||||
['plugin_connections_connection_folder_move_duplication', 'Target folder or selected folders contains folder with the same name ({arg:name})'],
|
||||
['plugin_connections_connection_form_project_invalid', 'You have no access to create connections in selected project'],
|
||||
['plugin_connections_connection_form_host_configuration_invalid', 'Host configuration is not supported'],
|
||||
['plugin_connections_connection_form_name_invalid', "Field 'Connection name' can't be empty"],
|
||||
['plugin_connections_connection_form_host_invalid', "Field 'Host' can't be empty"],
|
||||
['connections_public_connection_folder_delete_confirmation', 'You\'re going to delete "{arg:name}". Connections won\'t be deleted. Are you sure?'],
|
||||
['plugin_connections_connection_folder_delete_confirmation', 'You\'re going to delete "{arg:name}". Connections won\'t be deleted. Are you sure?'],
|
||||
['plugin_connections_menu_connections_label', 'Connessione'],
|
||||
['plugin_connections_action_disconnect_all_label', 'Scollegati da tutto'],
|
||||
['settings_connections', 'Connections'],
|
||||
['settings_connections_hide_connections_view_name', 'Hide connections'],
|
||||
['settings_connections_hide_connections_view_description', 'Connections will be hidden for all users except administrators'],
|
||||
['plugin_connections_settings', 'Connections'],
|
||||
['plugin_connections_settings_hide_connections_view_name', 'Hide connections'],
|
||||
['plugin_connections_settings_hide_connections_view_description', 'Connections will be hidden for all users except administrators'],
|
||||
|
||||
['connections_public_connection_ssl_enable', 'Enable SSL'],
|
||||
['plugin_connections_connection_ssl_enable', 'Enable SSL'],
|
||||
|
||||
['plugin_connections_connection_form_shared_credentials_manage_info', 'You can manage credentials in the '],
|
||||
['plugin_connections_connection_form_shared_credentials_manage_info_tab_link', 'Credentials tab'],
|
||||
|
||||
@@ -6,27 +6,37 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
export default [
|
||||
['connections_public_connection_edit_menu_item_title', 'Изменить подключение'],
|
||||
['connections_public_connection_edit_cancel_title', 'Отмена редактирования'],
|
||||
['connections_public_connection_edit_cancel_message', 'Вы собираетесь закрыть редактор, несохраненные изменения не будут применены. Вы уверены?'],
|
||||
['connections_public_connection_edit_reconnect_title', 'Подключение обновлено'],
|
||||
['connections_public_connection_edit_reconnect_message', 'Подключение было обновлено. Вы хотите переподключиться?'],
|
||||
['connections_public_connection_edit_reconnect_failed', 'Не удалось переподключиться'],
|
||||
['connections_public_connection_folder_move_failed', 'Ошибка перемещения в папку'],
|
||||
['connections_public_connection_folder_move_duplication', 'Выбранные папки или папка назначения содержит папки с таким же названием ({arg:name})'],
|
||||
['connections_public_connection_cloud_auth_required', 'Вы должны подключиться через "{arg:providerLabel}", чтобы работать с этим соединением.'],
|
||||
['plugin_connections_connection_form_part_main', 'Главное'],
|
||||
['plugin_connections_connection_form_part_properties', 'Параметры драйвера'],
|
||||
['plugin_connections_connection_form_part_main_custom_host', 'Хост'],
|
||||
['plugin_connections_connection_form_part_main_custom_port', 'Порт'],
|
||||
['plugin_connections_connection_form_part_main_custom_server_name', 'Имя сервера'],
|
||||
['plugin_connections_connection_form_part_main_custom_database', 'База'],
|
||||
['plugin_connections_connection_form_part_main_url_jdbc', 'JDBC URL'],
|
||||
['plugin_connections_connection_form_part_main_folder', 'Папка'],
|
||||
['plugin_connections_new_connection_dialog_title', 'Новое подключение'],
|
||||
|
||||
['plugin_connections_connection_edit_menu_item_title', 'Изменить подключение'],
|
||||
['plugin_connections_connection_edit_cancel_title', 'Отмена редактирования'],
|
||||
['plugin_connections_connection_edit_cancel_message', 'Вы собираетесь закрыть редактор, несохраненные изменения не будут применены. Вы уверены?'],
|
||||
['plugin_connections_connection_edit_reconnect_title', 'Подключение обновлено'],
|
||||
['plugin_connections_connection_edit_reconnect_message', 'Подключение было обновлено. Вы хотите переподключиться?'],
|
||||
['plugin_connections_connection_edit_reconnect_failed', 'Не удалось переподключиться'],
|
||||
['plugin_connections_connection_folder_move_failed', 'Ошибка перемещения в папку'],
|
||||
['plugin_connections_connection_folder_move_duplication', 'Выбранные папки или папка назначения содержит папки с таким же названием ({arg:name})'],
|
||||
['plugin_connections_connection_cloud_auth_required', 'Вы должны подключиться через "{arg:providerLabel}", чтобы работать с этим соединением.'],
|
||||
['plugin_connections_connection_form_project_invalid', 'У вас нет разрешения создавать коннекшены в выбранном проекте'],
|
||||
['plugin_connections_connection_form_host_configuration_invalid', 'Конфигурация хоста не поддерживается'],
|
||||
['plugin_connections_connection_form_name_invalid', "Поле 'Название подключения' не может быть пустым"],
|
||||
['plugin_connections_connection_form_host_invalid', "Поле 'Хост' не может быть пустым"],
|
||||
['connections_public_connection_folder_delete_confirmation', 'Вы удаляете "{arg:name}". Подключения не будут удалены. Вы уверены?'],
|
||||
['plugin_connections_connection_folder_delete_confirmation', 'Вы удаляете "{arg:name}". Подключения не будут удалены. Вы уверены?'],
|
||||
['plugin_connections_menu_connections_label', 'Подключение'],
|
||||
['plugin_connections_action_disconnect_all_label', 'Отключить все'],
|
||||
['settings_connections', 'Подключения'],
|
||||
['settings_connections_hide_connections_view_name', 'Скрыть подключения'],
|
||||
['settings_connections_hide_connections_view_description', 'Подключения будут скрыты для всех пользователей, кроме администраторов'],
|
||||
['plugin_connections_settings', 'Подключения'],
|
||||
['plugin_connections_settings_hide_connections_view_name', 'Скрыть подключения'],
|
||||
['plugin_connections_settings_hide_connections_view_description', 'Подключения будут скрыты для всех пользователей, кроме администраторов'],
|
||||
|
||||
['connections_public_connection_ssl_enable', 'Включить SSL'],
|
||||
['plugin_connections_connection_ssl_enable', 'Включить SSL'],
|
||||
|
||||
['plugin_connections_connection_form_shared_credentials_manage_info', 'Вы можете указать учетные данные в '],
|
||||
['plugin_connections_connection_form_shared_credentials_manage_info_tab_link', 'во вкладке "Учетные данные"'],
|
||||
|
||||
@@ -6,26 +6,36 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
export default [
|
||||
['connections_public_connection_edit_menu_item_title', '编辑连接'],
|
||||
['connections_public_connection_edit_cancel_title', '取消确认'],
|
||||
['connections_public_connection_edit_cancel_message', '您将取消连接更改。未保存的更改将丢失。您确定吗?'],
|
||||
['connections_public_connection_edit_reconnect_title', '连接已更新'],
|
||||
['connections_public_connection_edit_reconnect_message', '连接已更新。您想重新连接吗?'],
|
||||
['connections_public_connection_edit_reconnect_failed', '重新连接失败'],
|
||||
['connections_public_connection_folder_move_failed', '移动到文件夹失败'],
|
||||
['connections_public_connection_folder_move_duplication', '目标文件夹或所选文件夹包含同名文件夹 ({arg:name})'],
|
||||
['plugin_connections_connection_form_part_main', '主要'],
|
||||
['plugin_connections_connection_form_part_properties', '驱动属性'],
|
||||
['plugin_connections_connection_form_part_main_custom_host', '主机'],
|
||||
['plugin_connections_connection_form_part_main_custom_port', '端口'],
|
||||
['plugin_connections_connection_form_part_main_custom_server_name', '服务器名称'],
|
||||
['plugin_connections_connection_form_part_main_custom_database', '数据库'],
|
||||
['plugin_connections_connection_form_part_main_url_jdbc', 'JDBC URL'],
|
||||
['plugin_connections_connection_form_part_main_folder', '文件夹'],
|
||||
['plugin_connections_new_connection_dialog_title', '新连接'],
|
||||
|
||||
['plugin_connections_connection_edit_menu_item_title', '编辑连接'],
|
||||
['plugin_connections_connection_edit_cancel_title', '取消确认'],
|
||||
['plugin_connections_connection_edit_cancel_message', '您将取消连接更改。未保存的更改将丢失。您确定吗?'],
|
||||
['plugin_connections_connection_edit_reconnect_title', '连接已更新'],
|
||||
['plugin_connections_connection_edit_reconnect_message', '连接已更新。您想重新连接吗?'],
|
||||
['plugin_connections_connection_edit_reconnect_failed', '重新连接失败'],
|
||||
['plugin_connections_connection_folder_move_failed', '移动到文件夹失败'],
|
||||
['plugin_connections_connection_folder_move_duplication', '目标文件夹或所选文件夹包含同名文件夹 ({arg:name})'],
|
||||
['plugin_connections_connection_form_project_invalid', '您无权在所选项目中创建连接'],
|
||||
['plugin_connections_connection_form_host_configuration_invalid', '不支持主机配置'],
|
||||
['plugin_connections_connection_form_name_invalid', "字段 '连接名称' 不可为空"],
|
||||
['plugin_connections_connection_form_host_invalid', "字段 '主机' 不可为空"],
|
||||
['connections_public_connection_folder_delete_confirmation', '即将删除 "{arg:name}". 连接并不会删除,是否确定?'],
|
||||
['plugin_connections_connection_folder_delete_confirmation', '即将删除 "{arg:name}". 连接并不会删除,是否确定?'],
|
||||
['plugin_connections_menu_connections_label', '连接'],
|
||||
['plugin_connections_action_disconnect_all_label', '断开所有连接'],
|
||||
['settings_connections', '连接'],
|
||||
['settings_connections_hide_connections_view_name', 'Hide connections'],
|
||||
['settings_connections_hide_connections_view_description', 'Connections will be hidden for all users except administrators'],
|
||||
['plugin_connections_settings', '连接'],
|
||||
['plugin_connections_settings_hide_connections_view_name', 'Hide connections'],
|
||||
['plugin_connections_settings_hide_connections_view_description', 'Connections will be hidden for all users except administrators'],
|
||||
|
||||
['connections_public_connection_ssl_enable', '启用 SSL'],
|
||||
['plugin_connections_connection_ssl_enable', '启用 SSL'],
|
||||
|
||||
['plugin_connections_connection_form_shared_credentials_manage_info', '您可在此管理凭证 '],
|
||||
['plugin_connections_connection_form_shared_credentials_manage_info_tab_link', '凭证页签'],
|
||||
|
||||
@@ -41,8 +41,8 @@ export const UserProfileFormPanel: TabContainerPanelComponent = observer(functio
|
||||
|
||||
if (state.isChanged && !context.force) {
|
||||
const result = await commonDialogService.open(ConfirmationDialog, {
|
||||
title: 'connections_public_connection_edit_cancel_title',
|
||||
message: 'connections_public_connection_edit_cancel_message',
|
||||
title: 'plugin_connections_connection_edit_cancel_title',
|
||||
message: 'plugin_connections_connection_edit_cancel_message',
|
||||
confirmActionText: 'ui_processing_ok',
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user