mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-10-16 14:50:15 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20769431ba | ||
|
|
b7680d35cc |
Vendored
-8
@@ -107,14 +107,6 @@
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/webapp"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Add Custom Plugin",
|
||||
"type": "shell",
|
||||
"command": "yarn run add-plugin",
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/webapp/packages"
|
||||
}
|
||||
}
|
||||
],
|
||||
"inputs": [
|
||||
|
||||
@@ -25,59 +25,67 @@ You can see a live demo of CloudBeaver here: https://demo.cloudbeaver.io
|
||||
|
||||
## Changelog
|
||||
|
||||
### 24.3.3. 2025-01-20
|
||||
- Administration:
|
||||
- Added an ability to match users from LDAP configuration with CloudBeaver users;
|
||||
- New environment variables were introduced for theme styling, SQL editor, and log viewer settings. You can use them for quick setup during the initial Docker configuration stage.
|
||||
### 24.2.4. 2024-11-04
|
||||
- General:
|
||||
- An ability to show metadata object comments was added in the Navigator tree. You can enable it in the database navigator settings panel;
|
||||
- Added transaction log viewing for connections with manual commit mode. This allows users to see all modifying statements before committing;
|
||||
- Added an ability to import data in tables without unique keys;
|
||||
- Added an ability to insert data in tables without unique keys;
|
||||
- Added Ctrl + Shift + S (Cmd + Shift + S on Mac) shortcut for "Save As Script" action.
|
||||
|
||||
### 24.3.2. 2025-01-06
|
||||
- Added an ability to specify a user login as an attribute parameter for LDAP providers;
|
||||
- The collapse of the grouping panel doesn't lead to the full panel cleaning anymore.
|
||||
|
||||
### 24.3.1. 2024-12-23
|
||||
- Added an ability to reconnect for all editors if a connection has been lost;
|
||||
- Added an option to replace line break characters on any custom value when exporting to CSV;
|
||||
- Added an ability to create connections in the Navigation tree not only on the initial level but in folders and sub-folders directly;
|
||||
- Updated list of available shortcuts for MacOS.
|
||||
|
||||
### 24.3.0. 2024-12-02
|
||||
### Changes since 24.2.0:
|
||||
- General:
|
||||
- The connections Templates feature is declared obsolete and will be removed in future releases;
|
||||
- Data export: Added the ability to export JSON values as embedded JSON;
|
||||
- Fixed a proxy issue that excluded the Content-Type header in responses;
|
||||
- Data editor enhancements: Rows with focused cells are specially marked to make it easier to locate a position in large tables;
|
||||
- Keyboard navigation has been enhanced. You can now use the arrow keys to move through navigator tree elements and the tab key to switch between editors' tabs;
|
||||
- Sample SQLite database was removed;
|
||||
- Chinese localization has been improved (thanks to @cashlifei);
|
||||
- Brazilian Portuguese localization was enhanced (thanks to @brlarini).
|
||||
- Brazilian Portuguese localization was enhanced (thanks to [brlarini](https://github.com/brlarini));
|
||||
- Fixed a proxy issue that excluded the Content-Type header in responses.
|
||||
- Administration:
|
||||
- Updated user storage mechanism: New user logins are now stored in lowercase to prevent duplicate entries (e.g., "ADMIN" and "admin"). Note: This update does not affect previously created user logins;
|
||||
- Added an ability to change a user password even if the user is disabled in a system;
|
||||
- Refreshed design for the User and Teams tab in the Administration panel;
|
||||
- A new setting in Global Preferences was added to restrict data import for non-admin users;
|
||||
- A search option was added for preferences in the Administration part;
|
||||
- Added detailed logging of GraphQL queries in the server logs, including all provided variables, for improved debugging and monitoring;
|
||||
- Environment variables configuration has been improved - now you can configure more variables on the initial stage of the Docker setup.
|
||||
- Added an ability to change a user password even if the user is disabled in a system.
|
||||
### 24.2.3. 2024-10-21
|
||||
- Important update:
|
||||
- Connections Templates feature is declared as obsolete and will be removed in future releases.
|
||||
- General:
|
||||
- Data editor enhancements: Rows with focused cells are specially marked to make it easier to locate a position in large tables;
|
||||
- DB2i driver has been updated to version 20.0.7;
|
||||
- The URL mode for PostgreSQL now supports connecting to multiple databases;
|
||||
- The issue with displaying BLOB data types in DuckDB has been resolved.
|
||||
|
||||
### 24.2.2. 2024-10-07
|
||||
- Schemas were added to the SQL autocompletion for PostgreSQL, H2, and SQL Server;
|
||||
- CloudBeaver can now correctly display negative dates for MySQL database;
|
||||
- A search option was added for preferences in the Administration part;
|
||||
- Keyboard navigation has been enhanced. You can now use the arrow keys to move through navigator tree elements and the tab key to switch between editors tabs;
|
||||
- Sample SQLite database was removed.
|
||||
|
||||
### 24.2.1. 2024-09-23
|
||||
- Chinese localization has been improved (thanks to [cashlifei](https://github.com/cashlifei));
|
||||
- Environment variables configuration has been improved - now you can configure more variables on the initial stage of the Docker setup;
|
||||
- SQL Server driver has been updated to version 12.8.0.
|
||||
|
||||
### 24.2.0. 2024-09-02
|
||||
### Changes since 24.1.0:
|
||||
- General:
|
||||
- French language support was added (thanks to [matthieukhl](https://github.com/matthieukhl))
|
||||
- Added the ability to close editor tabs with the middle mouse button
|
||||
- Added right-click support to open the context menu in the Metadata Editor
|
||||
- The list of forbidden characters for naming and renaming resource manager files has been updated, and now it includes the following characters: / : " \ ' <> | ? *
|
||||
- Application cookies security was improved
|
||||
- Authentication:
|
||||
- Improved LDAP authentication: added the ability to filter users via service account parameters and ability to specify custom unique user identifiers
|
||||
- Data Editor:
|
||||
- Added additional notifications about the restricted operations
|
||||
- Enhanced IPv6 and DateTime32 data representation for Clickhouse
|
||||
- Data editing was fixed for DuckDB
|
||||
- SQL Editor:
|
||||
- SQL Editor auto-completion was enhanced to get column, table, and function names faster
|
||||
- Fixed the dollar-quoted string parsing in the SQL Editor for PostgreSQL
|
||||
- Improved display of the long error messages in the SQL Editor and Log viewer
|
||||
- Changed the save script icon to a floppy disk for better recognition
|
||||
- Improved application behavior when closing a connection - open editors won't be closed on disconnect
|
||||
- Administration:
|
||||
- Redesigned administration navigation panel - now it is more compact and clear
|
||||
- Added the ability to change the default commit mode for each connection separately
|
||||
- Added the ability to configure the server property rootURI parameter (thanks to [arioko](https://github.com/arioko))
|
||||
- Databases:
|
||||
- PostgreSQL, Greenplum, CockroachDB: The URL mode now supports connecting to multiple databases;
|
||||
- PostgreSQL, H2, and SQL Server: Schemas were added to the SQL autocompletion;
|
||||
- MySQL: CloudBeaver can now correctly display negative dates;
|
||||
- DuckDB: The issue with displaying BLOB data types has been resolved.
|
||||
- Drivers:
|
||||
- A new LibSQL/Turso driver was added;
|
||||
- SQL Server driver has been updated to version 12.8.0;
|
||||
- DB2i driver has been updated to version 20.0.7.
|
||||
- Added the "Keep alive" setting for Db2 LUW and IMB i, Apache Kyuubi, Clickhouse, Firebird, and Trino
|
||||
- Updated Firebird driver to version 5.0.4
|
||||
- DDL generation for Oracle Tablespaces was added (thanks to [pandya09](https://github.com/pandya09))
|
||||
|
||||
## Contribution
|
||||
As a community-driven open-source project, we warmly welcome contributions through GitHub pull requests.
|
||||
|
||||
[We are happy to reward](https://dbeaver.com/help-dbeaver/) our most active contributors every major sprint.
|
||||
The most significant contribution to our code for the major release 24.3.0 was made by:
|
||||
1. [cashlifei](https://github.com/cashlifei)
|
||||
The most significant contribution to our code for the major release 24.2.0 was made by:
|
||||
1. [matthieukhl](https://github.com/matthieukhl)
|
||||
|
||||
@@ -13,16 +13,16 @@
|
||||
|
||||
productSettings: {
|
||||
# Global properties
|
||||
core.theming.theme: "${CLOUDBEAVER_CORE_THEMING_THEME:light}",
|
||||
core.localization.localization: "${CLOUDBEAVER_CORE_LOCALIZATION:en}",
|
||||
plugin.sql-editor.autoSave: "${CLOUDBEAVER_SQL_EDITOR_AUTOSAVE:true}",
|
||||
plugin.sql-editor.disabled: "${CLOUDBEAVER_SQL_EDITOR_DISABLED:false}",
|
||||
core.theming.theme: 'light',
|
||||
core.localization.localization: 'en',
|
||||
plugin.sql-editor.autoSave: true,
|
||||
plugin.sql-editor.disabled: false,
|
||||
# max size of the file that can be uploaded to the editor (in kilobytes)
|
||||
plugin.sql-editor.maxFileSize: "${CLOUDBEAVER_SQL_EDITOR_MAX_FILE_SIZE:10240}",
|
||||
plugin.log-viewer.disabled: "${CLOUDBEAVER_LOG_VIEWER_DISABLED:false}",
|
||||
plugin.log-viewer.logBatchSize: "${CLOUDBEAVER_LOG_VIEWER_LOG_BATCH_SIZE:1000}",
|
||||
plugin.log-viewer.maxLogRecords: "${CLOUDBEAVER_LOG_VIEWER_MAX_LOG_RECORDS:2000}",
|
||||
sql.proposals.insert.table.alias: "${CLOUDBEAVER_SQL_PROPOSALS_INSERT_TABLE_ALIAS:PLAIN}"
|
||||
plugin.sql-editor.maxFileSize: 10240,
|
||||
plugin.log-viewer.disabled: false,
|
||||
plugin.log-viewer.logBatchSize: 1000,
|
||||
plugin.log-viewer.maxLogRecords: 2000,
|
||||
sql.proposals.insert.table.alias: PLAIN
|
||||
},
|
||||
|
||||
expireSessionAfterPeriod: "${CLOUDBEAVER_EXPIRE_SESSION_AFTER_PERIOD:1800000}",
|
||||
|
||||
@@ -23,7 +23,8 @@ RUN set -eux; \
|
||||
tzdata \
|
||||
# locales ensures proper character encoding and locale-specific behaviors using en_US.UTF-8
|
||||
locales \
|
||||
nano && \
|
||||
nano \
|
||||
; \
|
||||
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen; \
|
||||
locale-gen en_US.UTF-8; \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
@@ -31,7 +32,7 @@ RUN set -eux; \
|
||||
ENV LANG=en_US.UTF-8
|
||||
|
||||
ENV JAVA_HOME=/opt/java/openjdk
|
||||
COPY --from=eclipse-temurin:21 $JAVA_HOME $JAVA_HOME
|
||||
COPY --from=eclipse-temurin:17 $JAVA_HOME $JAVA_HOME
|
||||
ENV PATH="${JAVA_HOME}/bin:${PATH}"
|
||||
|
||||
RUN set -eux; \
|
||||
|
||||
@@ -2,22 +2,12 @@ FROM dbeaver/base-java
|
||||
|
||||
MAINTAINER DBeaver Corp, devops@dbeaver.com
|
||||
|
||||
ENV DBEAVER_GID=8978
|
||||
ENV DBEAVER_UID=8978
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get upgrade -y
|
||||
|
||||
RUN groupadd -g $DBEAVER_GID dbeaver && \
|
||||
useradd -g $DBEAVER_GID -m -u $DBEAVER_UID -s /bin/bash dbeaver
|
||||
|
||||
RUN apt-get update; \
|
||||
apt-get upgrade -y;
|
||||
|
||||
COPY cloudbeaver /opt/cloudbeaver
|
||||
COPY scripts/launch-product.sh /opt/cloudbeaver/launch-product.sh
|
||||
|
||||
EXPOSE 8978
|
||||
RUN find /opt/cloudbeaver -type d -exec chmod 775 {} \;
|
||||
WORKDIR /opt/cloudbeaver/
|
||||
|
||||
RUN chmod +x "run-server.sh" "/opt/cloudbeaver/launch-product.sh"
|
||||
|
||||
ENTRYPOINT ["./launch-product.sh"]
|
||||
ENTRYPOINT ["./run-server.sh"]
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script is needed to change ownership and run the application as user dbeaver during the upgrade from version 24.2.0
|
||||
|
||||
# Change ownership of the WORKDIR to the dbeaver user and group
|
||||
# Variables DBEAVER_<UID|GID> are defined in the Dockerfile and exported to the runtime environment
|
||||
# PWD equals WORKDIR value from product Dockerfile
|
||||
|
||||
if [ "$(id -u)" -eq 0 ]; then
|
||||
TARGET_USER=${TARGET_USER:-dbeaver}
|
||||
TARGET_UID=${TARGET_UID:-$DBEAVER_UID}
|
||||
TARGET_GID=${TARGET_GID:-$DBEAVER_GID}
|
||||
|
||||
chown -R $DBEAVER_UID:$DBEAVER_GID $PWD
|
||||
# Execute run-server.sh as the dbeaver user with the JAVA_HOME and PATH environment variables
|
||||
exec su "$TARGET_USER" -c "JAVA_HOME=$JAVA_HOME PATH=$PATH ./run-server.sh"
|
||||
else
|
||||
exec ./run-server.sh
|
||||
fi
|
||||
+6
-8
@@ -5,16 +5,12 @@ featuresPaths=\
|
||||
bundlesPaths=\
|
||||
dbeaver-common/modules;\
|
||||
dbeaver/plugins;\
|
||||
cloudbeaver/server/bundles;\
|
||||
dbeaver-jdbc-libsql;\
|
||||
cloudbeaver/server/test
|
||||
cloudbeaver/server/bundles;
|
||||
testLibraries=\
|
||||
org.junit;\
|
||||
org.mockito.mockito-core;\
|
||||
junit-jupiter-api;\
|
||||
org.opentest4j;\
|
||||
org.hamcrest.core;\
|
||||
org.hamcrest
|
||||
org.opentest4j
|
||||
repositories=\
|
||||
https://p2.dev.dbeaver.com/eclipse-repo/;\
|
||||
https://download.eclipse.org/releases/${eclipse-version}/;
|
||||
@@ -25,10 +21,12 @@ testBundles=\
|
||||
org.opentest4j
|
||||
productsPaths=\
|
||||
dbeaver/product/community/DBeaver.product;\
|
||||
cloudbeaver/server/product/web-server/CloudbeaverServer.product:../../opt/cloudbeaver;\
|
||||
cloudbeaver/server/product/web-server-test/CloudbeaverServerTest.product:../../opt/cloudbeaver;
|
||||
cloudbeaver/server/product/web-server/CloudbeaverServer.product:../../opt/cloudbeaver;
|
||||
ideaConfigurationFilesPaths=\
|
||||
dbeaver/.ide/.idea;
|
||||
testBundlePaths=\
|
||||
dbeaver/test;\
|
||||
cloudbeaver/server/test;
|
||||
additionalModuleRoots=\
|
||||
opt;
|
||||
optionalFeatureRepositories=\
|
||||
|
||||
@@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2
|
||||
Bundle-Vendor: DBeaver Corp
|
||||
Bundle-Name: Cloudbeaver Web Model
|
||||
Bundle-SymbolicName: io.cloudbeaver.model;singleton:=true
|
||||
Bundle-Version: 1.0.70.qualifier
|
||||
Bundle-Release-Date: 20250203
|
||||
Bundle-Version: 1.0.65.qualifier
|
||||
Bundle-Release-Date: 20241118
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-17
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-ClassPath: .
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
<plugin>
|
||||
<extension-point id="io.cloudbeaver.service" name="Web services" schema="schema/io.cloudbeaver.service.exsd"/>
|
||||
<extension-point id="io.cloudbeaver.feature" name="Web features" schema="schema/io.cloudbeaver.feature.exsd"/>
|
||||
<extension-point id="io.cloudbeaver.server.feature" name="Web server features" schema="schema/io.cloudbeaver.server.feature.exsd"/>
|
||||
<extension-point id="io.cloudbeaver.valueSerializer" name="Web value serializers" schema="schema/io.cloudbeaver.valueSerializer.exsd"/>
|
||||
<extension-point id="org.jkiss.dbeaver.auth.provider" name="%extension-point.org.jkiss.dbeaver.authProvider.name" schema="schema/org.jkiss.dbeaver.authProvider.exsd"/>
|
||||
<extension-point id="io.cloudbeaver.metaParameters" name="Meta parameters" schema="schema/io.cloudbeaver.metaParameters.exsd"/>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.model</artifactId>
|
||||
<version>1.0.70-SNAPSHOT</version>
|
||||
<version>1.0.65-SNAPSHOT</version>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<schema targetNamespace="org.jkiss.dbeaver.core" xmlns="http://www.w3.org/2001/XMLSchema">
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.schema plugin="io.cloudbeaver.model" id="io.cloudbeaver.server.feature" name="Web features"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
Web feature
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<element name="extension">
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.element />
|
||||
</appInfo>
|
||||
</annotation>
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref="feature"/>
|
||||
</sequence>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name="feature">
|
||||
<annotation>
|
||||
<documentation>
|
||||
Web service description
|
||||
</documentation>
|
||||
</annotation>
|
||||
</element>
|
||||
|
||||
|
||||
</schema>
|
||||
@@ -22,6 +22,7 @@ import graphql.GraphQLError;
|
||||
import graphql.language.SourceLocation;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.model.sql.SQLState;
|
||||
import org.jkiss.dbeaver.utils.GeneralUtils;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
@@ -99,7 +100,7 @@ public class DBWebException extends DBException implements GraphQLError {
|
||||
@Override
|
||||
public Map<String, Object> getExtensions() {
|
||||
StringWriter buf = new StringWriter();
|
||||
CommonUtils.getRootCause(this).printStackTrace(new PrintWriter(buf, true));
|
||||
GeneralUtils.getRootCause(this).printStackTrace(new PrintWriter(buf, true));
|
||||
|
||||
Map<String, Object> extensions = new LinkedHashMap<>();
|
||||
String stString = buf.toString();
|
||||
|
||||
+9
-29
@@ -44,12 +44,10 @@ import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class WebDataSourceRegistryProxy implements DBPDataSourceRegistry, DataSourcePersistentRegistry, DBPDataSourceRegistryCache {
|
||||
@NotNull
|
||||
private final DataSourceFilter dataSourceFilter;
|
||||
@NotNull
|
||||
private final DataSourceRegistry<?> dataSourceRegistry;
|
||||
private final DataSourceRegistry dataSourceRegistry;
|
||||
|
||||
public WebDataSourceRegistryProxy(@NotNull DataSourceRegistry<?> dataSourceRegistry, @NotNull DataSourceFilter filter) {
|
||||
public WebDataSourceRegistryProxy(DataSourceRegistry dataSourceRegistry, DataSourceFilter filter) {
|
||||
this.dataSourceRegistry = dataSourceRegistry;
|
||||
this.dataSourceFilter = filter;
|
||||
}
|
||||
@@ -64,7 +62,7 @@ public class WebDataSourceRegistryProxy implements DBPDataSourceRegistry, DataSo
|
||||
@Override
|
||||
public DBPDataSourceContainer getDataSource(@NotNull String id) {
|
||||
DBPDataSourceContainer dataSource = dataSourceRegistry.getDataSource(id);
|
||||
if (dataSource == null || !dataSourceFilter.filter(dataSource)) {
|
||||
if (dataSource == null || dataSourceFilter != null && !dataSourceFilter.filter(dataSource)) {
|
||||
return null;
|
||||
}
|
||||
return dataSource;
|
||||
@@ -73,7 +71,7 @@ public class WebDataSourceRegistryProxy implements DBPDataSourceRegistry, DataSo
|
||||
@Nullable
|
||||
@Override
|
||||
public DBPDataSourceContainer getDataSource(@NotNull DBPDataSource dataSource) {
|
||||
if (!dataSourceFilter.filter(dataSource.getContainer())) {
|
||||
if (dataSourceFilter != null && !dataSourceFilter.filter(dataSource.getContainer())) {
|
||||
return null;
|
||||
}
|
||||
return dataSourceRegistry.getDataSource(dataSource);
|
||||
@@ -83,8 +81,10 @@ public class WebDataSourceRegistryProxy implements DBPDataSourceRegistry, DataSo
|
||||
@Override
|
||||
public DBPDataSourceContainer findDataSourceByName(String name) {
|
||||
var dataSource = dataSourceRegistry.findDataSourceByName(name);
|
||||
if (dataSource != null && dataSourceFilter.filter(dataSource)) {
|
||||
return dataSource;
|
||||
if (dataSource != null) {
|
||||
if (dataSourceFilter == null || dataSourceFilter.filter(dataSource)) {
|
||||
return dataSource;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -113,26 +113,6 @@ public class WebDataSourceRegistryProxy implements DBPDataSourceRegistry, DataSo
|
||||
return dataSourceRegistry.createDataSource(driver, connConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DBPDataSourceContainer createDataSource(
|
||||
@NotNull String id,
|
||||
@NotNull DBPDriver driver,
|
||||
@NotNull DBPConnectionConfiguration connConfig
|
||||
) {
|
||||
return dataSourceRegistry.createDataSource(id, driver, connConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DBPDataSourceContainer createDataSource(
|
||||
@NotNull DBPDataSourceConfigurationStorage dataSourceStorage,
|
||||
@NotNull DBPDataSourceOrigin origin,
|
||||
@NotNull String id,
|
||||
@NotNull DBPDriver driver,
|
||||
@NotNull DBPConnectionConfiguration configuration
|
||||
) {
|
||||
return dataSourceRegistry.createDataSource(dataSourceStorage, origin, id, driver, configuration);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DBPDataSourceContainer createDataSource(@NotNull DBPDataSourceContainer source) {
|
||||
@@ -186,7 +166,7 @@ public class WebDataSourceRegistryProxy implements DBPDataSourceRegistry, DataSo
|
||||
return dataSourceRegistry.getRootFolders();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Nullable
|
||||
@Override
|
||||
public DBPDataSourceFolder getFolder(@NotNull String path) {
|
||||
return dataSourceRegistry.getFolder(path);
|
||||
|
||||
@@ -27,7 +27,6 @@ import org.jkiss.dbeaver.model.preferences.DBPPreferenceStore;
|
||||
import org.jkiss.dbeaver.model.rm.RMController;
|
||||
import org.jkiss.dbeaver.model.rm.RMProject;
|
||||
import org.jkiss.dbeaver.model.task.DBTTaskManager;
|
||||
import org.jkiss.dbeaver.registry.DataSourceRegistry;
|
||||
import org.jkiss.dbeaver.registry.rm.DataSourceRegistryRM;
|
||||
import org.jkiss.dbeaver.runtime.DBWorkbench;
|
||||
|
||||
@@ -84,12 +83,15 @@ public abstract class WebProjectImpl extends BaseWebProjectImpl {
|
||||
@NotNull
|
||||
@Override
|
||||
protected DBPDataSourceRegistry createDataSourceRegistry() {
|
||||
return createRMRegistry();
|
||||
return new WebDataSourceRegistryProxy(
|
||||
new DataSourceRegistryRM(this, getResourceController(), preferenceStore),
|
||||
getDataSourceFilter()
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected DataSourceRegistry<?> createRMRegistry() {
|
||||
return new DataSourceRegistryRM<>(this, getResourceController(), preferenceStore);
|
||||
public DataSourceFilter getDataSourceFilter() {
|
||||
return (ds) -> true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+20
-23
@@ -22,13 +22,13 @@ 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.app.DBPDataSourceRegistry;
|
||||
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.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Global project.
|
||||
@@ -36,39 +36,31 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
*/
|
||||
public class WebSessionGlobalProjectImpl extends WebSessionProjectImpl {
|
||||
private static final Log log = Log.getLog(WebSessionGlobalProjectImpl.class);
|
||||
|
||||
private final Set<String> accessibleConnectionIds = new CopyOnWriteArraySet<>();
|
||||
private Set<String> accessibleConnectionIds = Collections.emptySet();
|
||||
|
||||
public WebSessionGlobalProjectImpl(@NotNull WebSession webSession, @NotNull RMProject project) {
|
||||
super(webSession, project);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates data source registry that can filter data sources that are not accessible for user.
|
||||
*/
|
||||
@NotNull
|
||||
@Override
|
||||
protected DBPDataSourceRegistry createDataSourceRegistry() {
|
||||
return new WebDataSourceRegistryProxy(
|
||||
createRegistryWithCredentialsProvider(),
|
||||
this::isDataSourceAccessible
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update info about accessible connections from a database.
|
||||
*/
|
||||
public void refreshAccessibleConnectionIds() {
|
||||
this.accessibleConnectionIds.clear();
|
||||
public synchronized void refreshAccessibleConnectionIds() {
|
||||
this.accessibleConnectionIds = readAccessibleConnectionIds();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Set<String> readAccessibleConnectionIds() {
|
||||
try {
|
||||
for (SMObjectPermissions smObjectPermissions : webSession.getSecurityController()
|
||||
.getAllAvailableObjectsPermissions(SMObjectType.datasource)) {
|
||||
String objectId = smObjectPermissions.getObjectId();
|
||||
this.accessibleConnectionIds.add(objectId);
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,4 +110,9 @@ public class WebSessionGlobalProjectImpl extends WebSessionProjectImpl {
|
||||
dataSource.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DataSourceFilter getDataSourceFilter() {
|
||||
return this::isDataSourceAccessible;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,14 +28,12 @@ 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.rm.RMUtils;
|
||||
import org.jkiss.dbeaver.model.websocket.event.datasource.WSDataSourceEvent;
|
||||
import org.jkiss.dbeaver.model.websocket.event.WSEventType;
|
||||
import org.jkiss.dbeaver.registry.DataSourceDescriptor;
|
||||
import org.jkiss.dbeaver.registry.DataSourceRegistry;
|
||||
import org.jkiss.dbeaver.runtime.jobs.DisconnectJob;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class WebSessionProjectImpl extends WebProjectImpl {
|
||||
@@ -84,12 +82,7 @@ public class WebSessionProjectImpl extends WebProjectImpl {
|
||||
@NotNull
|
||||
@Override
|
||||
protected DBPDataSourceRegistry createDataSourceRegistry() {
|
||||
return createRegistryWithCredentialsProvider();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected DataSourceRegistry<?> createRegistryWithCredentialsProvider() {
|
||||
DataSourceRegistry<?> dataSourceRegistry = createRMRegistry();
|
||||
DBPDataSourceRegistry dataSourceRegistry = super.createDataSourceRegistry();
|
||||
dataSourceRegistry.setAuthCredentialsProvider(webSession);
|
||||
return dataSourceRegistry;
|
||||
}
|
||||
@@ -195,9 +188,9 @@ public class WebSessionProjectImpl extends WebProjectImpl {
|
||||
* updates data sources based on event in web session
|
||||
*
|
||||
* @param dataSourceIds list of updated connections
|
||||
* @param eventId id of event
|
||||
* @param type type of event
|
||||
*/
|
||||
public synchronized boolean updateProjectDataSources(@NotNull List<String> dataSourceIds, @NotNull String eventId) {
|
||||
public synchronized boolean updateProjectDataSources(@NotNull List<String> dataSourceIds, @NotNull WSEventType type) {
|
||||
var sendDataSourceUpdatedEvent = false;
|
||||
DBPDataSourceRegistry registry = getDataSourceRegistry();
|
||||
// save old connections
|
||||
@@ -206,9 +199,9 @@ public class WebSessionProjectImpl extends WebProjectImpl {
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(
|
||||
DBPDataSourceContainer::getId,
|
||||
Function.identity())
|
||||
);
|
||||
if (WSDataSourceEvent.CREATED.equals(eventId) || WSDataSourceEvent.UPDATED.equals(eventId)) {
|
||||
ds -> new DataSourceDescriptor((DataSourceDescriptor) ds, ds.getRegistry())
|
||||
));
|
||||
if (type == WSEventType.DATASOURCE_CREATED || type == WSEventType.DATASOURCE_UPDATED) {
|
||||
registry.refreshConfig(dataSourceIds);
|
||||
}
|
||||
for (String dsId : dataSourceIds) {
|
||||
@@ -216,14 +209,14 @@ public class WebSessionProjectImpl extends WebProjectImpl {
|
||||
if (ds == null) {
|
||||
continue;
|
||||
}
|
||||
switch (eventId) {
|
||||
case WSDataSourceEvent.CREATED -> {
|
||||
switch (type) {
|
||||
case DATASOURCE_CREATED -> {
|
||||
addConnection(ds);
|
||||
sendDataSourceUpdatedEvent = true;
|
||||
}
|
||||
case WSDataSourceEvent.UPDATED -> // if settings were changed we need to send event
|
||||
case DATASOURCE_UPDATED -> // if settings were changed we need to send event
|
||||
sendDataSourceUpdatedEvent |= !ds.equalSettings(oldDataSources.get(dsId));
|
||||
case WSDataSourceEvent.DELETED -> {
|
||||
case DATASOURCE_DELETED -> {
|
||||
WebDataSourceUtils.disconnectDataSource(webSession, ds);
|
||||
if (registry instanceof DBPDataSourceRegistryCache dsrc) {
|
||||
dsrc.removeDataSourceFromList(ds);
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ import java.util.Map;
|
||||
public interface SMAuthProviderFederated extends SMSignOutLinkProvider {
|
||||
|
||||
@NotNull
|
||||
String getSignInLink(String id) throws DBException;
|
||||
String getSignInLink(String id, @NotNull Map<String, Object> providerConfig) throws DBException;
|
||||
|
||||
@Override
|
||||
default String getUserSignOutLink(
|
||||
|
||||
-1
@@ -21,6 +21,5 @@ package io.cloudbeaver.auth.provider.local;
|
||||
public class LocalAuthProviderConstants {
|
||||
public static final String PROVIDER_ID = "local";
|
||||
public static final String CRED_USER = "user";
|
||||
public static final String CRED_DISPLAY_NAME = "displayName";
|
||||
public static final String CRED_PASSWORD = "password";
|
||||
}
|
||||
|
||||
+13
-10
@@ -16,19 +16,16 @@
|
||||
*/
|
||||
package io.cloudbeaver.model;
|
||||
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.dbeaver.model.runtime.AbstractJob;
|
||||
|
||||
/**
|
||||
* Web async task info
|
||||
* Web connection info
|
||||
*/
|
||||
public class WebAsyncTaskInfo {
|
||||
|
||||
@NotNull
|
||||
private final String id;
|
||||
@NotNull
|
||||
private final String name;
|
||||
private boolean running = false;
|
||||
private String id;
|
||||
private String name;
|
||||
private boolean running;
|
||||
private Object result;
|
||||
private Object extendedResult;
|
||||
private String status;
|
||||
@@ -36,21 +33,27 @@ public class WebAsyncTaskInfo {
|
||||
|
||||
private AbstractJob job;
|
||||
|
||||
public WebAsyncTaskInfo(@NotNull String id, @NotNull String name) {
|
||||
public WebAsyncTaskInfo(String id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
return running;
|
||||
}
|
||||
|
||||
+3
-14
@@ -22,10 +22,9 @@ import io.cloudbeaver.model.session.WebSession;
|
||||
import io.cloudbeaver.service.security.SMUtils;
|
||||
import io.cloudbeaver.service.sql.WebDataFormat;
|
||||
import io.cloudbeaver.utils.CBModelConstants;
|
||||
import io.cloudbeaver.utils.ServletAppUtils;
|
||||
import io.cloudbeaver.utils.WebAppUtils;
|
||||
import io.cloudbeaver.utils.WebCommonUtils;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.*;
|
||||
@@ -77,8 +76,6 @@ public class WebConnectionInfo {
|
||||
private String connectTime;
|
||||
private String serverVersion;
|
||||
private String clientVersion;
|
||||
@Nullable
|
||||
private Boolean credentialsSavedInSession;
|
||||
|
||||
private transient Map<String, Object> savedAuthProperties;
|
||||
private transient List<WebNetworkHandlerConfigInput> savedNetworkCredentials;
|
||||
@@ -198,8 +195,7 @@ public class WebConnectionInfo {
|
||||
|
||||
@Property
|
||||
public boolean isCredentialsSaved() throws DBException {
|
||||
// isCredentialsSaved can be true if credentials were saved during connection init for global project
|
||||
return dataSourceContainer.isCredentialsSaved() && !(credentialsSavedInSession != null && credentialsSavedInSession);
|
||||
return dataSourceContainer.isCredentialsSaved();
|
||||
}
|
||||
|
||||
@Property
|
||||
@@ -469,8 +465,7 @@ public class WebConnectionInfo {
|
||||
if (isCanEdit()) {
|
||||
return true;
|
||||
}
|
||||
BaseWebAppConfiguration appConfig = (BaseWebAppConfiguration) ServletAppUtils.getServletApplication()
|
||||
.getAppConfiguration();
|
||||
BaseWebAppConfiguration appConfig = (BaseWebAppConfiguration) WebAppUtils.getWebApplication().getAppConfiguration();
|
||||
return appConfig.isShowReadOnlyConnectionInfo();
|
||||
|
||||
}
|
||||
@@ -518,10 +513,4 @@ public class WebConnectionInfo {
|
||||
return tools;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates param that checks whether credentials were saved only in session.
|
||||
*/
|
||||
public void setCredentialsSavedInSession(@Nullable Boolean credentialsSavedInSession) {
|
||||
this.credentialsSavedInSession = credentialsSavedInSession;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2025 DBeaver Corp and others
|
||||
* 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.
|
||||
@@ -44,12 +44,6 @@ public class WebPropertyInfo {
|
||||
private DBPPropertySource propertySource;
|
||||
private boolean showProtected;
|
||||
|
||||
private Object[] validValues;
|
||||
|
||||
private String[] supportedConfigurationTypes = new String[0];
|
||||
|
||||
private Object defaultValue;
|
||||
|
||||
public WebPropertyInfo(WebSession session, DBPPropertyDescriptor property, DBPPropertySource propertySource) {
|
||||
this.session = session;
|
||||
this.property = property;
|
||||
@@ -129,7 +123,7 @@ public class WebPropertyInfo {
|
||||
|
||||
@Property
|
||||
public Object getDefaultValue() throws DBException {
|
||||
var defaultValue = property.getDefaultValue() == null ? this.defaultValue : property.getDefaultValue();
|
||||
var defaultValue = property.getDefaultValue();
|
||||
return defaultValue == null ? getValue() : defaultValue;
|
||||
}
|
||||
|
||||
@@ -160,9 +154,9 @@ public class WebPropertyInfo {
|
||||
}
|
||||
return validValues;
|
||||
}
|
||||
return validValues;
|
||||
return null;
|
||||
}
|
||||
return validValues;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Property
|
||||
@@ -178,7 +172,7 @@ public class WebPropertyInfo {
|
||||
.map(DBPDriverConfigurationType::toString)
|
||||
.toArray(String[]::new);
|
||||
}
|
||||
return supportedConfigurationTypes;
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Property
|
||||
@@ -258,20 +252,4 @@ public class WebPropertyInfo {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//TODO: delete after refactoring on front-end
|
||||
public void setDefaultValue(String defaultValue) {
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
//TODO: delete after refactoring on front-end
|
||||
public void setValidValues(Object[] validValues) {
|
||||
this.validValues = validValues;
|
||||
}
|
||||
|
||||
//TODO: delete after refactoring on front-end
|
||||
public void setSupportedConfigurationTypes(String[] supportedConfigurationTypes) {
|
||||
this.supportedConfigurationTypes = supportedConfigurationTypes;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -32,8 +32,8 @@ import java.nio.file.Path;
|
||||
/**
|
||||
* Abstract class that contains methods for loading configuration with gson.
|
||||
*/
|
||||
public abstract class BaseServerConfigurationController<T extends ServletServerConfiguration>
|
||||
implements ServletServerConfigurationController<T> {
|
||||
public abstract class BaseServerConfigurationController<T extends WebServerConfiguration>
|
||||
implements WebServerConfigurationController<T> {
|
||||
private static final Log log = Log.getLog(BaseServerConfigurationController.class);
|
||||
@NotNull
|
||||
private final Path homeDirectory;
|
||||
|
||||
+1
-9
@@ -25,13 +25,12 @@ import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class BaseWebAppConfiguration implements ServletAppConfiguration {
|
||||
public abstract class BaseWebAppConfiguration implements WebAppConfiguration {
|
||||
public static final String DEFAULT_APP_ANONYMOUS_TEAM_NAME = "user";
|
||||
|
||||
protected final Map<String, Object> plugins;
|
||||
protected String defaultUserTeam = DEFAULT_APP_ANONYMOUS_TEAM_NAME;
|
||||
protected boolean resourceManagerEnabled;
|
||||
protected boolean secretManagerEnabled;
|
||||
protected boolean showReadOnlyConnectionInfo;
|
||||
protected String[] enabledFeatures;
|
||||
protected String[] disabledBetaFeatures;
|
||||
@@ -43,7 +42,6 @@ public abstract class BaseWebAppConfiguration implements ServletAppConfiguration
|
||||
this.enabledFeatures = null;
|
||||
this.disabledBetaFeatures = new String[0];
|
||||
this.showReadOnlyConnectionInfo = false;
|
||||
this.secretManagerEnabled = false;
|
||||
}
|
||||
|
||||
public BaseWebAppConfiguration(BaseWebAppConfiguration src) {
|
||||
@@ -53,7 +51,6 @@ public abstract class BaseWebAppConfiguration implements ServletAppConfiguration
|
||||
this.enabledFeatures = src.enabledFeatures;
|
||||
this.disabledBetaFeatures = src.disabledBetaFeatures;
|
||||
this.showReadOnlyConnectionInfo = src.showReadOnlyConnectionInfo;
|
||||
this.secretManagerEnabled = src.secretManagerEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -87,11 +84,6 @@ public abstract class BaseWebAppConfiguration implements ServletAppConfiguration
|
||||
return resourceManagerEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecretManagerEnabled() {
|
||||
return secretManagerEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFeatureEnabled(String id) {
|
||||
return ArrayUtils.contains(getEnabledFeatures(), id);
|
||||
|
||||
+4
-4
@@ -45,16 +45,16 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Servlet application
|
||||
* Web application
|
||||
*/
|
||||
public abstract class BaseServletApplication extends BaseApplicationImpl implements ServletApplication {
|
||||
public abstract class BaseWebApplication extends BaseApplicationImpl implements WebApplication {
|
||||
|
||||
public static final String DEFAULT_CONFIG_FILE_PATH = "/etc/cloudbeaver.conf";
|
||||
public static final String CUSTOM_CONFIG_FOLDER = "custom";
|
||||
public static final String CLI_PARAM_WEB_CONFIG = "-web-config";
|
||||
public static final String LOGBACK_FILE_NAME = "logback.xml";
|
||||
|
||||
private static final Log log = Log.getLog(BaseServletApplication.class);
|
||||
private static final Log log = Log.getLog(BaseWebApplication.class);
|
||||
|
||||
private String instanceId;
|
||||
|
||||
@@ -252,7 +252,7 @@ public abstract class BaseServletApplication extends BaseApplicationImpl impleme
|
||||
return null;
|
||||
}
|
||||
|
||||
public abstract ServletServerConfigurationController getServerConfigurationController();
|
||||
public abstract WebServerConfigurationController getServerConfigurationController();
|
||||
|
||||
@Override
|
||||
public boolean isEnvironmentVariablesAccessible() {
|
||||
-57
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* 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.model.app;
|
||||
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Application configuration
|
||||
*/
|
||||
public interface ServletAppConfiguration {
|
||||
String getAnonymousUserTeam();
|
||||
|
||||
boolean isAnonymousAccessEnabled();
|
||||
|
||||
@Nullable
|
||||
<T> T getResourceQuota(String quotaId);
|
||||
|
||||
String getDefaultUserTeam();
|
||||
|
||||
<T> T getPluginOption(@NotNull String pluginId, @NotNull String option);
|
||||
|
||||
Map<String, Object> getPluginConfig(@NotNull String pluginId, boolean create);
|
||||
|
||||
boolean isResourceManagerEnabled();
|
||||
|
||||
boolean isSecretManagerEnabled();
|
||||
|
||||
boolean isFeaturesEnabled(String[] requiredFeatures);
|
||||
|
||||
boolean isFeatureEnabled(String id);
|
||||
|
||||
@NotNull
|
||||
default String[] getEnabledFeatures() {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
default boolean isSupportsCustomConnections() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+21
-20
@@ -17,38 +17,39 @@
|
||||
package io.cloudbeaver.model.app;
|
||||
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.dbeaver.model.navigator.DBNBrowseSettings;
|
||||
import org.jkiss.dbeaver.registry.DataSourceNavigatorSettings;
|
||||
import org.jkiss.code.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Application configuration
|
||||
*/
|
||||
public interface WebAppConfiguration extends ServletAppConfiguration {
|
||||
DataSourceNavigatorSettings.Preset PRESET_WEB = new DataSourceNavigatorSettings.Preset("web",
|
||||
"Web",
|
||||
"Default view");
|
||||
public interface WebAppConfiguration {
|
||||
String getAnonymousUserTeam();
|
||||
|
||||
DBNBrowseSettings getDefaultNavigatorSettings();
|
||||
boolean isAnonymousAccessEnabled();
|
||||
|
||||
boolean isPublicCredentialsSaveEnabled();
|
||||
@Nullable
|
||||
<T> T getResourceQuota(String quotaId);
|
||||
|
||||
boolean isAdminCredentialsSaveEnabled();
|
||||
String getDefaultUserTeam();
|
||||
|
||||
default String[] getDisabledBetaFeatures() {
|
||||
<T> T getPluginOption(@NotNull String pluginId, @NotNull String option);
|
||||
|
||||
Map<String, Object> getPluginConfig(@NotNull String pluginId, boolean create);
|
||||
|
||||
boolean isResourceManagerEnabled();
|
||||
|
||||
boolean isFeaturesEnabled(String[] requiredFeatures);
|
||||
|
||||
boolean isFeatureEnabled(String id);
|
||||
|
||||
@NotNull
|
||||
default String[] getEnabledFeatures() {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
default String[] getEnabledAuthProviders() {
|
||||
return new String[0];
|
||||
default boolean isSupportsCustomConnections() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
String[] getEnabledDrivers();
|
||||
|
||||
@NotNull
|
||||
String[] getDisabledDrivers();
|
||||
|
||||
Map<String, Object> getResourceQuotas();
|
||||
}
|
||||
|
||||
+6
-6
@@ -35,16 +35,16 @@ import java.util.Map;
|
||||
/**
|
||||
* Base interface for web application
|
||||
*/
|
||||
public interface ServletApplication extends DBPApplication {
|
||||
public interface WebApplication extends DBPApplication {
|
||||
boolean isConfigurationMode();
|
||||
|
||||
default boolean isInitializationMode() {
|
||||
return false;
|
||||
}
|
||||
default boolean isInitializationMode() {
|
||||
return false;
|
||||
}
|
||||
|
||||
ServletAppConfiguration getAppConfiguration();
|
||||
WebAppConfiguration getAppConfiguration();
|
||||
|
||||
ServletServerConfiguration getServerConfiguration();
|
||||
WebServerConfiguration getServerConfiguration();
|
||||
|
||||
Path getDataDirectory(boolean create);
|
||||
|
||||
+4
-2
@@ -20,8 +20,10 @@ package io.cloudbeaver.model.app;
|
||||
import io.cloudbeaver.auth.CBAuthConstants;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
|
||||
public interface ServletAuthApplication extends ServletApplication {
|
||||
ServletAuthConfiguration getAuthConfiguration();
|
||||
import java.util.List;
|
||||
|
||||
public interface WebAuthApplication extends WebApplication {
|
||||
WebAuthConfiguration getAuthConfiguration();
|
||||
|
||||
String getAuthServiceURL();
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ import java.util.Set;
|
||||
/**
|
||||
* Application authentication configuration
|
||||
*/
|
||||
public interface ServletAuthConfiguration {
|
||||
public interface WebAuthConfiguration {
|
||||
|
||||
String getDefaultAuthProvider();
|
||||
|
||||
+2
-1
@@ -25,7 +25,7 @@ import java.util.Map;
|
||||
* Web server configuration.
|
||||
* Contains only server configuration properties.
|
||||
*/
|
||||
public interface ServletServerConfiguration {
|
||||
public interface WebServerConfiguration {
|
||||
boolean isDevelMode();
|
||||
|
||||
default String getRootURI() {
|
||||
@@ -39,4 +39,5 @@ public interface ServletServerConfiguration {
|
||||
default Map<String, Object> getProductSettings() {
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -27,7 +27,7 @@ import java.util.Map;
|
||||
* Server configuration controller.
|
||||
* Works with app server configuration (loads, updates)
|
||||
*/
|
||||
public interface ServletServerConfigurationController<T extends ServletServerConfiguration> {
|
||||
public interface WebServerConfigurationController<T extends WebServerConfiguration> {
|
||||
|
||||
/**
|
||||
* Loads server configuration.
|
||||
+17
-9
@@ -19,8 +19,7 @@ package io.cloudbeaver.model.config;
|
||||
import com.google.gson.annotations.Expose;
|
||||
import io.cloudbeaver.auth.provider.local.LocalAuthProviderConstants;
|
||||
import io.cloudbeaver.model.app.BaseWebAppConfiguration;
|
||||
import io.cloudbeaver.model.app.WebAppConfiguration;
|
||||
import io.cloudbeaver.model.app.ServletAuthConfiguration;
|
||||
import io.cloudbeaver.model.app.WebAuthConfiguration;
|
||||
import io.cloudbeaver.registry.WebAuthProviderDescriptor;
|
||||
import io.cloudbeaver.registry.WebAuthProviderRegistry;
|
||||
import org.jkiss.code.NotNull;
|
||||
@@ -37,8 +36,9 @@ import java.util.*;
|
||||
/**
|
||||
* Application configuration
|
||||
*/
|
||||
public class CBAppConfig extends BaseWebAppConfiguration implements ServletAuthConfiguration, WebAppConfiguration {
|
||||
public class CBAppConfig extends BaseWebAppConfiguration implements WebAuthConfiguration {
|
||||
private static final Log log = Log.getLog(CBAppConfig.class);
|
||||
public static final DataSourceNavigatorSettings.Preset PRESET_WEB = new DataSourceNavigatorSettings.Preset("web", "Web", "Default view");
|
||||
|
||||
public static final DataSourceNavigatorSettings DEFAULT_VIEW_SETTINGS = PRESET_WEB.getSettings();
|
||||
private final Set<SMAuthProviderCustomConfiguration> authConfigurations;
|
||||
@@ -47,6 +47,8 @@ public class CBAppConfig extends BaseWebAppConfiguration implements ServletAuthC
|
||||
private final Map<String, SMAuthProviderCustomConfiguration> authConfiguration;
|
||||
|
||||
private boolean supportsCustomConnections;
|
||||
private boolean supportsConnectionBrowser;
|
||||
private boolean supportsUserWorkspaces;
|
||||
private boolean enableReverseProxyAuth;
|
||||
private boolean forwardProxy;
|
||||
private boolean publicCredentialsSaveEnabled;
|
||||
@@ -78,6 +80,8 @@ public class CBAppConfig extends BaseWebAppConfiguration implements ServletAuthC
|
||||
this.anonymousUserRole = DEFAULT_APP_ANONYMOUS_TEAM_NAME;
|
||||
this.anonymousUserTeam = DEFAULT_APP_ANONYMOUS_TEAM_NAME;
|
||||
this.supportsCustomConnections = true;
|
||||
this.supportsConnectionBrowser = false;
|
||||
this.supportsUserWorkspaces = false;
|
||||
this.publicCredentialsSaveEnabled = true;
|
||||
this.adminCredentialsSaveEnabled = true;
|
||||
this.redirectOnFederatedAuth = false;
|
||||
@@ -102,6 +106,8 @@ public class CBAppConfig extends BaseWebAppConfiguration implements ServletAuthC
|
||||
this.anonymousUserRole = src.anonymousUserRole;
|
||||
this.anonymousUserTeam = src.anonymousUserTeam;
|
||||
this.supportsCustomConnections = src.supportsCustomConnections;
|
||||
this.supportsConnectionBrowser = src.supportsConnectionBrowser;
|
||||
this.supportsUserWorkspaces = src.supportsUserWorkspaces;
|
||||
this.publicCredentialsSaveEnabled = src.publicCredentialsSaveEnabled;
|
||||
this.adminCredentialsSaveEnabled = src.adminCredentialsSaveEnabled;
|
||||
this.redirectOnFederatedAuth = src.redirectOnFederatedAuth;
|
||||
@@ -134,10 +140,6 @@ public class CBAppConfig extends BaseWebAppConfiguration implements ServletAuthC
|
||||
this.resourceManagerEnabled = resourceManagerEnabled;
|
||||
}
|
||||
|
||||
public void setSecretManagerEnabled(boolean secretManagerEnabled) {
|
||||
this.secretManagerEnabled = secretManagerEnabled;
|
||||
}
|
||||
|
||||
public boolean isSupportsCustomConnections() {
|
||||
return supportsCustomConnections;
|
||||
}
|
||||
@@ -146,6 +148,14 @@ public class CBAppConfig extends BaseWebAppConfiguration implements ServletAuthC
|
||||
this.supportsCustomConnections = supportsCustomConnections;
|
||||
}
|
||||
|
||||
public boolean isSupportsConnectionBrowser() {
|
||||
return supportsConnectionBrowser;
|
||||
}
|
||||
|
||||
public boolean isSupportsUserWorkspaces() {
|
||||
return supportsUserWorkspaces;
|
||||
}
|
||||
|
||||
public boolean isPublicCredentialsSaveEnabled() {
|
||||
return publicCredentialsSaveEnabled;
|
||||
}
|
||||
@@ -166,7 +176,6 @@ public class CBAppConfig extends BaseWebAppConfiguration implements ServletAuthC
|
||||
return redirectOnFederatedAuth;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String[] getEnabledDrivers() {
|
||||
return enabledDrivers;
|
||||
}
|
||||
@@ -175,7 +184,6 @@ public class CBAppConfig extends BaseWebAppConfiguration implements ServletAuthC
|
||||
this.enabledDrivers = enabledDrivers;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String[] getDisabledDrivers() {
|
||||
return disabledDrivers;
|
||||
}
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.model.rm;
|
||||
|
||||
import io.cloudbeaver.model.app.WebApplication;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.model.rm.RMController;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class RMControllerInvocationHandler implements InvocationHandler {
|
||||
private final WebApplication webApplication;
|
||||
private final RMController rmController;
|
||||
|
||||
public RMControllerInvocationHandler(RMController rmController, WebApplication webApplication) {
|
||||
this.webApplication = webApplication;
|
||||
this.rmController = rmController;
|
||||
}
|
||||
|
||||
private void checkIsRmEnabled() throws DBException {
|
||||
if (!webApplication.getAppConfiguration().isResourceManagerEnabled()) {
|
||||
throw new DBException("Resource Manager disabled");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
try {
|
||||
checkIsRmEnabled();
|
||||
return method.invoke(rmController, args);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw e.getCause();
|
||||
}
|
||||
}
|
||||
}
|
||||
+25
-37
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2025 DBeaver Corp and others
|
||||
* 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.
|
||||
@@ -18,11 +18,11 @@ package io.cloudbeaver.model.rm.local;
|
||||
|
||||
import io.cloudbeaver.BaseWebProjectImpl;
|
||||
import io.cloudbeaver.DBWConstants;
|
||||
import io.cloudbeaver.model.app.ServletApplication;
|
||||
import io.cloudbeaver.model.app.WebApplication;
|
||||
import io.cloudbeaver.model.rm.lock.RMFileLockController;
|
||||
import io.cloudbeaver.service.security.SMUtils;
|
||||
import io.cloudbeaver.service.sql.WebSQLConstants;
|
||||
import io.cloudbeaver.utils.ServletAppUtils;
|
||||
import io.cloudbeaver.utils.WebAppUtils;
|
||||
import io.cloudbeaver.utils.file.UniversalFileVisitor;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.jkiss.code.NotNull;
|
||||
@@ -39,6 +39,7 @@ import org.jkiss.dbeaver.model.security.SMController;
|
||||
import org.jkiss.dbeaver.model.security.SMObjectType;
|
||||
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.ResourceTypeDescriptor;
|
||||
import org.jkiss.dbeaver.registry.ResourceTypeRegistry;
|
||||
@@ -83,7 +84,7 @@ public class LocalResourceController extends BaseLocalResourceController {
|
||||
Path sharedProjectsPath,
|
||||
Supplier<SMController> smControllerSupplier
|
||||
) throws DBException {
|
||||
super(workspace, new RMFileLockController(ServletAppUtils.getServletApplication()));
|
||||
super(workspace, new RMFileLockController(WebAppUtils.getWebApplication()));
|
||||
this.credentialsProvider = credentialsProvider;
|
||||
this.rootPath = rootPath;
|
||||
this.userProjectsPath = userProjectsPath;
|
||||
@@ -114,22 +115,13 @@ public class LocalResourceController extends BaseLocalResourceController {
|
||||
if (project == null || refresh) {
|
||||
SessionContextImpl sessionContext = new SessionContextImpl(null);
|
||||
RMProject rmProject = makeProjectFromId(projectId, false);
|
||||
project = createWebProjectImpl(projectId, sessionContext, rmProject);
|
||||
project = new InternalWebProjectImpl(sessionContext, rmProject, getProjectPath(projectId));
|
||||
projectRegistries.put(projectId, project);
|
||||
}
|
||||
return project;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected InternalWebProjectImpl createWebProjectImpl(
|
||||
String projectId,
|
||||
SessionContextImpl sessionContext,
|
||||
RMProject rmProject
|
||||
) throws DBException {
|
||||
return new InternalWebProjectImpl(sessionContext, rmProject, getProjectPath(projectId));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public RMProject[] listAccessibleProjects() throws DBException {
|
||||
@@ -153,7 +145,7 @@ public class LocalResourceController extends BaseLocalResourceController {
|
||||
}
|
||||
|
||||
// Checking if private projects are enabled in the configuration and if the user has permission to them
|
||||
var webApp = ServletAppUtils.getServletApplication();
|
||||
var webApp = WebAppUtils.getWebApplication();
|
||||
var userHasPrivateProjectPermission = userHasAccessToPrivateProject(webApp, activeUserCreds);
|
||||
if (webApp.getAppConfiguration().isSupportsCustomConnections() && userHasPrivateProjectPermission) {
|
||||
var userProjectPermission = getProjectPermissions(null, RMProjectType.USER);
|
||||
@@ -162,7 +154,7 @@ public class LocalResourceController extends BaseLocalResourceController {
|
||||
projects.add(0, userProject);
|
||||
}
|
||||
}
|
||||
if (ServletAppUtils.getServletApplication().isMultiNode()) {
|
||||
if (WebAppUtils.getWebApplication().isMultiNode()) {
|
||||
for (RMProject rmProject : projects) {
|
||||
handleProjectOpened(rmProject.getId());
|
||||
}
|
||||
@@ -208,7 +200,7 @@ public class LocalResourceController extends BaseLocalResourceController {
|
||||
}
|
||||
return getRmProjectPermissions(projectId, activeUserCreds);
|
||||
case USER:
|
||||
var webApp = ServletAppUtils.getServletApplication();
|
||||
var webApp = WebAppUtils.getWebApplication();
|
||||
if (userHasAccessToPrivateProject(webApp, activeUserCreds)) {
|
||||
return Set.of(RMProjectPermission.RESOURCE_EDIT, RMProjectPermission.DATA_SOURCES_EDIT);
|
||||
}
|
||||
@@ -217,7 +209,7 @@ public class LocalResourceController extends BaseLocalResourceController {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean userHasAccessToPrivateProject(ServletApplication webApp, @Nullable SMCredentials activeUserCreds) {
|
||||
private boolean userHasAccessToPrivateProject(WebApplication webApp, @Nullable SMCredentials activeUserCreds) {
|
||||
return !webApp.isMultiNode() ||
|
||||
(activeUserCreds != null && activeUserCreds.hasPermission(DBWConstants.PERMISSION_PRIVATE_PROJECT_ACCESS));
|
||||
}
|
||||
@@ -285,7 +277,7 @@ public class LocalResourceController extends BaseLocalResourceController {
|
||||
try {
|
||||
log.debug("Creating project '" + project.getId() + "'");
|
||||
Files.createDirectories(projectPath);
|
||||
if (ServletAppUtils.getServletApplication().isMultiNode()) {
|
||||
if (WebAppUtils.getWebApplication().isMultiNode()) {
|
||||
createResourceTypeFolders(projectPath);
|
||||
}
|
||||
fireRmProjectAddEvent(project);
|
||||
@@ -445,9 +437,6 @@ public class LocalResourceController extends BaseLocalResourceController {
|
||||
if (Files.exists(newTargetPath)) {
|
||||
throw new DBException("Resource with name %s already exists".formatted(newTargetPath.getFileName()));
|
||||
}
|
||||
if (!Files.exists(newTargetPath.getParent())) {
|
||||
throw new DBException("Resource %s doesn't exists".formatted(newTargetPath.getParent().getFileName()));
|
||||
}
|
||||
try {
|
||||
Files.move(oldTargetPath, newTargetPath);
|
||||
} catch (IOException e) {
|
||||
@@ -519,7 +508,7 @@ public class LocalResourceController extends BaseLocalResourceController {
|
||||
log.warn("Failed to remove resources properties", e);
|
||||
}
|
||||
try {
|
||||
if (Files.isDirectory(targetPath)) {
|
||||
if (targetPath.toFile().isDirectory()) {
|
||||
IOUtils.deleteDirectory(targetPath);
|
||||
} else {
|
||||
Files.delete(targetPath);
|
||||
@@ -589,7 +578,7 @@ public class LocalResourceController extends BaseLocalResourceController {
|
||||
) throws DBException {
|
||||
try (var ignoredLock = lockController.lockProject(projectId, "setResourceContents")) {
|
||||
validateResourcePath(resourcePath);
|
||||
Number fileSizeLimit = ServletAppUtils.getServletApplication()
|
||||
Number fileSizeLimit = WebAppUtils.getWebApplication()
|
||||
.getAppConfiguration()
|
||||
.getResourceQuota(WebSQLConstants.QUOTA_PROP_RM_FILE_SIZE_LIMIT);
|
||||
if (fileSizeLimit != null && data.length > fileSizeLimit.longValue()) {
|
||||
@@ -783,8 +772,9 @@ public class LocalResourceController extends BaseLocalResourceController {
|
||||
fileHandler.projectOpened(projectId);
|
||||
} catch (Exception e) {
|
||||
if (credentialsProvider.getActiveUserCredentials() != null) {
|
||||
ServletAppUtils.getServletApplication().getEventController().addEvent(
|
||||
WebAppUtils.getWebApplication().getEventController().addEvent(
|
||||
new WSSessionLogUpdatedEvent(
|
||||
WSEventType.SESSION_LOG_UPDATED,
|
||||
credentialsProvider.getActiveUserCredentials().getSmSessionId(),
|
||||
credentialsProvider.getActiveUserCredentials().getUserId(),
|
||||
MessageType.ERROR,
|
||||
@@ -801,8 +791,9 @@ public class LocalResourceController extends BaseLocalResourceController {
|
||||
fileHandler.beforeFileRead(projectId, file);
|
||||
} catch (Exception e) {
|
||||
if (credentialsProvider.getActiveUserCredentials() != null) {
|
||||
ServletAppUtils.getServletApplication().getEventController().addEvent(
|
||||
WebAppUtils.getWebApplication().getEventController().addEvent(
|
||||
new WSSessionLogUpdatedEvent(
|
||||
WSEventType.SESSION_LOG_UPDATED,
|
||||
credentialsProvider.getActiveUserCredentials().getSmSessionId(),
|
||||
credentialsProvider.getActiveUserCredentials().getUserId(),
|
||||
MessageType.ERROR,
|
||||
@@ -955,19 +946,16 @@ public class LocalResourceController extends BaseLocalResourceController {
|
||||
return "pong (RM)";
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
protected final SMCredentialsProvider credentialsProvider;
|
||||
protected final Supplier<SMController> smController;
|
||||
protected final DBPWorkspace workspace;
|
||||
public static final class Builder {
|
||||
private final SMCredentialsProvider credentialsProvider;
|
||||
private final Supplier<SMController> smController;
|
||||
private final DBPWorkspace workspace;
|
||||
|
||||
protected Path rootPath;
|
||||
protected Path userProjectsPath;
|
||||
protected Path sharedProjectsPath;
|
||||
private Path rootPath;
|
||||
private Path userProjectsPath;
|
||||
private Path sharedProjectsPath;
|
||||
|
||||
protected Builder(
|
||||
DBPWorkspace workspace, SMCredentialsProvider credentialsProvider,
|
||||
Supplier<SMController> smControllerSupplier
|
||||
) {
|
||||
private Builder(DBPWorkspace workspace, SMCredentialsProvider credentialsProvider, Supplier<SMController> smControllerSupplier) {
|
||||
this.workspace = workspace;
|
||||
this.credentialsProvider = credentialsProvider;
|
||||
this.smController = smControllerSupplier;
|
||||
|
||||
+3
-3
@@ -17,7 +17,7 @@
|
||||
package io.cloudbeaver.model.rm.lock;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import io.cloudbeaver.model.app.ServletApplication;
|
||||
import io.cloudbeaver.model.app.WebApplication;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
@@ -50,12 +50,12 @@ public class RMFileLockController {
|
||||
private final int maxLockTime;
|
||||
|
||||
|
||||
public RMFileLockController(ServletApplication application) throws DBException {
|
||||
public RMFileLockController(WebApplication application) throws DBException {
|
||||
this(application, DEFAULT_MAX_LOCK_TIME);
|
||||
}
|
||||
|
||||
// for tests
|
||||
public RMFileLockController(ServletApplication application, int maxLockTime) throws DBException {
|
||||
public RMFileLockController(WebApplication application, int maxLockTime) throws DBException {
|
||||
this.lockFolderPath = application.getWorkspaceDirectory()
|
||||
.resolve(DBPWorkspace.METADATA_FOLDER)
|
||||
.resolve(LOCK_META_FOLDER);
|
||||
|
||||
+6
-6
@@ -17,8 +17,8 @@
|
||||
package io.cloudbeaver.model.session;
|
||||
|
||||
import io.cloudbeaver.model.WebServerMessage;
|
||||
import io.cloudbeaver.model.app.ServletApplication;
|
||||
import io.cloudbeaver.model.app.ServletAuthApplication;
|
||||
import io.cloudbeaver.model.app.WebApplication;
|
||||
import io.cloudbeaver.model.app.WebAuthApplication;
|
||||
import io.cloudbeaver.websocket.CBWebSessionEventHandler;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
@@ -51,14 +51,14 @@ public abstract class BaseWebSession extends AbstractSessionPersistent {
|
||||
@NotNull
|
||||
protected final WebUserContext userContext;
|
||||
@NotNull
|
||||
protected final ServletApplication application;
|
||||
protected final WebApplication application;
|
||||
protected volatile long lastAccessTime;
|
||||
|
||||
private final List<CBWebSessionEventHandler> sessionEventHandlers = new CopyOnWriteArrayList<>();
|
||||
private WebSessionEventsFilter eventsFilter = new WebSessionEventsFilter();
|
||||
private final WebSessionWorkspace workspace;
|
||||
|
||||
public BaseWebSession(@NotNull String id, @NotNull ServletApplication application) throws DBException {
|
||||
public BaseWebSession(@NotNull String id, @NotNull WebApplication application) throws DBException {
|
||||
this.id = id;
|
||||
this.application = application;
|
||||
this.createTime = System.currentTimeMillis();
|
||||
@@ -153,7 +153,7 @@ public abstract class BaseWebSession extends AbstractSessionPersistent {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ServletApplication getApplication() {
|
||||
public WebApplication getApplication() {
|
||||
return application;
|
||||
}
|
||||
|
||||
@@ -238,7 +238,7 @@ public abstract class BaseWebSession extends AbstractSessionPersistent {
|
||||
|
||||
@Property
|
||||
public long getRemainingTime() {
|
||||
if (application instanceof ServletAuthApplication authApplication) {
|
||||
if (application instanceof WebAuthApplication authApplication) {
|
||||
return authApplication.getMaxSessionIdleTime() + lastAccessTime - System.currentTimeMillis();
|
||||
}
|
||||
return Integer.MAX_VALUE;
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@
|
||||
package io.cloudbeaver.model.session;
|
||||
|
||||
import io.cloudbeaver.model.WebServerMessage;
|
||||
import io.cloudbeaver.model.app.ServletAuthApplication;
|
||||
import io.cloudbeaver.model.app.WebAuthApplication;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
@@ -29,7 +29,7 @@ import org.jkiss.dbeaver.model.auth.SMSessionPrincipal;
|
||||
public class WebHeadlessSession extends BaseWebSession {
|
||||
public WebHeadlessSession(
|
||||
@NotNull String id,
|
||||
@NotNull ServletAuthApplication application
|
||||
@NotNull WebAuthApplication application
|
||||
) throws DBException {
|
||||
super(id, application);
|
||||
}
|
||||
|
||||
+3
-17
@@ -17,33 +17,22 @@
|
||||
package io.cloudbeaver.model.session;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.jkiss.code.Nullable;
|
||||
|
||||
public class WebHttpRequestInfo {
|
||||
public static final String USER_AGENT = "User-Agent";
|
||||
|
||||
@Nullable
|
||||
private final String id;
|
||||
@Nullable
|
||||
private final Object locale;
|
||||
@Nullable
|
||||
private final String lastRemoteAddress;
|
||||
@Nullable
|
||||
private final String lastRemoteUserAgent;
|
||||
|
||||
public WebHttpRequestInfo(HttpServletRequest request) {
|
||||
this.id = request.getSession() == null ? null : request.getSession().getId();
|
||||
this.id = request.getSession().getId();
|
||||
this.locale = request.getAttribute("locale");
|
||||
this.lastRemoteAddress = request.getRemoteAddr();
|
||||
this.lastRemoteUserAgent = request.getHeader(USER_AGENT);
|
||||
this.lastRemoteUserAgent = request.getHeader("User-Agent");
|
||||
}
|
||||
|
||||
public WebHttpRequestInfo(
|
||||
@Nullable String id,
|
||||
@Nullable Object locale,
|
||||
@Nullable String lastRemoteAddress,
|
||||
@Nullable String lastRemoteUserAgent
|
||||
) {
|
||||
public WebHttpRequestInfo(String id, Object locale, String lastRemoteAddress, String lastRemoteUserAgent) {
|
||||
this.id = id;
|
||||
this.locale = locale;
|
||||
this.lastRemoteAddress = lastRemoteAddress;
|
||||
@@ -54,17 +43,14 @@ public class WebHttpRequestInfo {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Object getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getLastRemoteAddress() {
|
||||
return lastRemoteAddress;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getLastRemoteUserAgent() {
|
||||
return lastRemoteUserAgent;
|
||||
}
|
||||
|
||||
+34
-17
@@ -24,15 +24,13 @@ import io.cloudbeaver.*;
|
||||
import io.cloudbeaver.model.WebAsyncTaskInfo;
|
||||
import io.cloudbeaver.model.WebConnectionInfo;
|
||||
import io.cloudbeaver.model.WebServerMessage;
|
||||
import io.cloudbeaver.model.app.ServletApplication;
|
||||
import io.cloudbeaver.model.app.ServletAuthApplication;
|
||||
import io.cloudbeaver.model.session.monitor.TaskProgressMonitor;
|
||||
import io.cloudbeaver.model.app.WebApplication;
|
||||
import io.cloudbeaver.model.app.WebAuthApplication;
|
||||
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.WebDataSourceUtils;
|
||||
import io.cloudbeaver.utils.WebEventUtils;
|
||||
import org.eclipse.core.runtime.IAdaptable;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
@@ -59,11 +57,13 @@ import org.jkiss.dbeaver.model.rm.RMUtils;
|
||||
import org.jkiss.dbeaver.model.runtime.AbstractJob;
|
||||
import org.jkiss.dbeaver.model.runtime.BaseProgressMonitor;
|
||||
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
|
||||
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.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.runtime.DBWorkbench;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
@@ -114,7 +114,7 @@ public class WebSession extends BaseWebSession
|
||||
|
||||
public WebSession(
|
||||
@NotNull WebHttpRequestInfo requestInfo,
|
||||
@NotNull ServletAuthApplication application,
|
||||
@NotNull WebAuthApplication application,
|
||||
@NotNull Map<String, DBWSessionHandler> sessionHandlers
|
||||
) throws DBException {
|
||||
this(requestInfo.getId(),
|
||||
@@ -128,7 +128,7 @@ public class WebSession extends BaseWebSession
|
||||
protected WebSession(
|
||||
@NotNull String id,
|
||||
@Nullable String locale,
|
||||
@NotNull ServletApplication application,
|
||||
@NotNull WebApplication application,
|
||||
@NotNull Map<String, DBWSessionHandler> sessionHandlers
|
||||
) throws DBException {
|
||||
super(id, application);
|
||||
@@ -316,7 +316,7 @@ public class WebSession extends BaseWebSession
|
||||
if (project.isGlobal()) {
|
||||
sessionProject = createGlobalProject(project);
|
||||
} else {
|
||||
sessionProject = createSessionProject(project);
|
||||
sessionProject = new WebSessionProjectImpl(this, project, getProjectPath(project));
|
||||
}
|
||||
// do not load data sources for anonymous project
|
||||
if (project.getType() == RMProjectType.USER && userContext.getUser() == null) {
|
||||
@@ -329,10 +329,6 @@ public class WebSession extends BaseWebSession
|
||||
return sessionProject;
|
||||
}
|
||||
|
||||
protected WebSessionProjectImpl createSessionProject(@NotNull RMProject project) throws DBException {
|
||||
return new WebSessionProjectImpl(this, project, getProjectPath(project));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected Path getProjectPath(@NotNull RMProject project) throws DBException {
|
||||
return RMUtils.getProjectPath(project);
|
||||
@@ -511,7 +507,7 @@ public class WebSession extends BaseWebSession
|
||||
///////////////////////////////////////////////////////
|
||||
// Async model
|
||||
|
||||
public WebAsyncTaskInfo getAsyncTask(@NotNull String taskId, @NotNull String taskName, boolean create) {
|
||||
public WebAsyncTaskInfo getAsyncTask(String taskId, String taskName, boolean create) {
|
||||
synchronized (asyncTasks) {
|
||||
WebAsyncTaskInfo taskInfo = asyncTasks.get(taskId);
|
||||
if (taskInfo == null && create) {
|
||||
@@ -528,6 +524,7 @@ public class WebSession extends BaseWebSession
|
||||
if (taskInfo == null) {
|
||||
throw new DBWebException("Task '" + taskId + "' not found");
|
||||
}
|
||||
taskInfo.setRunning(taskInfo.getJob() != null && !taskInfo.getJob().isFinished());
|
||||
if (removeOnFinish && !taskInfo.isRunning()) {
|
||||
asyncTasks.remove(taskId);
|
||||
}
|
||||
@@ -550,7 +547,7 @@ public class WebSession extends BaseWebSession
|
||||
return true;
|
||||
}
|
||||
|
||||
public WebAsyncTaskInfo createAndRunAsyncTask(@NotNull String taskName, @NotNull WebAsyncTaskProcessor<?> runnable) {
|
||||
public WebAsyncTaskInfo createAndRunAsyncTask(String taskName, WebAsyncTaskProcessor<?> runnable) {
|
||||
int taskId = TASK_ID.incrementAndGet();
|
||||
WebAsyncTaskInfo asyncTask = getAsyncTask(String.valueOf(taskId), taskName, true);
|
||||
|
||||
@@ -559,8 +556,7 @@ public class WebSession extends BaseWebSession
|
||||
protected IStatus run(DBRProgressMonitor monitor) {
|
||||
int curTaskCount = taskCount.incrementAndGet();
|
||||
|
||||
DBRProgressMonitor taskMonitor = new TaskProgressMonitor(monitor, WebSession.this, asyncTask);
|
||||
|
||||
TaskProgressMonitor taskMonitor = new TaskProgressMonitor(monitor, asyncTask);
|
||||
try {
|
||||
Number queryLimit = application.getAppConfiguration().getResourceQuota(WebSQLConstants.QUOTA_PROP_QUERY_LIMIT);
|
||||
if (queryLimit != null && curTaskCount > queryLimit.intValue()) {
|
||||
@@ -572,6 +568,7 @@ public class WebSession extends BaseWebSession
|
||||
asyncTask.setResult(runnable.getResult());
|
||||
asyncTask.setExtendedResult(runnable.getExtendedResults());
|
||||
asyncTask.setStatus("Finished");
|
||||
asyncTask.setRunning(false);
|
||||
} catch (InvocationTargetException e) {
|
||||
addSessionError(e.getTargetException());
|
||||
asyncTask.setJobError(e.getTargetException());
|
||||
@@ -579,8 +576,6 @@ public class WebSession extends BaseWebSession
|
||||
asyncTask.setJobError(e);
|
||||
} finally {
|
||||
taskCount.decrementAndGet();
|
||||
asyncTask.setRunning(false);
|
||||
WebEventUtils.sendAsyncTaskEvent(WebSession.this, asyncTask);
|
||||
}
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
@@ -601,6 +596,7 @@ public class WebSession extends BaseWebSession
|
||||
sessionMessages.add(message);
|
||||
}
|
||||
addSessionEvent(new WSSessionLogUpdatedEvent(
|
||||
WSEventType.SESSION_LOG_UPDATED,
|
||||
this.userContext.getSmSessionId(),
|
||||
this.userContext.getUserId(),
|
||||
MessageType.ERROR,
|
||||
@@ -989,6 +985,27 @@ public class WebSession extends BaseWebSession
|
||||
}
|
||||
}
|
||||
|
||||
private static class TaskProgressMonitor extends ProxyProgressMonitor {
|
||||
|
||||
private final WebAsyncTaskInfo asyncTask;
|
||||
|
||||
public TaskProgressMonitor(DBRProgressMonitor original, WebAsyncTaskInfo asyncTask) {
|
||||
super(original);
|
||||
this.asyncTask = asyncTask;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginTask(String name, int totalWork) {
|
||||
super.beginTask(name, totalWork);
|
||||
asyncTask.setStatus(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subTask(String name) {
|
||||
super.subTask(name);
|
||||
asyncTask.setStatus(name);
|
||||
}
|
||||
}
|
||||
|
||||
private record PersistentAttribute(Object value) {
|
||||
}
|
||||
|
||||
+5
-6
@@ -20,11 +20,11 @@ package io.cloudbeaver.model.session;
|
||||
import io.cloudbeaver.DBWUserIdentity;
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.auth.SMAuthProviderExternal;
|
||||
import io.cloudbeaver.model.app.ServletAuthConfiguration;
|
||||
import io.cloudbeaver.model.app.WebAuthConfiguration;
|
||||
import io.cloudbeaver.model.user.WebUser;
|
||||
import io.cloudbeaver.registry.WebAuthProviderDescriptor;
|
||||
import io.cloudbeaver.registry.WebAuthProviderRegistry;
|
||||
import io.cloudbeaver.utils.ServletAppUtils;
|
||||
import io.cloudbeaver.utils.WebAppUtils;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
@@ -82,7 +82,7 @@ public class WebSessionAuthProcessor {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<WebAuthInfo> finishWebSessionAuthorization(SMAuthInfo authInfo) throws DBException {
|
||||
boolean configMode = ServletAppUtils.getServletApplication().isConfigurationMode();
|
||||
boolean configMode = WebAppUtils.getWebApplication().isConfigurationMode();
|
||||
boolean alreadyLoggedIn = webSession.getUser() != null;
|
||||
boolean resetUserStateOnError = !alreadyLoggedIn;
|
||||
|
||||
@@ -127,7 +127,7 @@ public class WebSessionAuthProcessor {
|
||||
|
||||
DBWUserIdentity userIdentity = null;
|
||||
var providerConfigId = authConfiguration.getAuthProviderConfigurationId();
|
||||
var providerConfig = ServletAppUtils.getAuthApplication()
|
||||
var providerConfig = WebAppUtils.getWebAuthApplication()
|
||||
.getAuthConfiguration()
|
||||
.getAuthProviderConfiguration(providerConfigId);
|
||||
if (authProviderExternal != null) {
|
||||
@@ -194,8 +194,7 @@ public class WebSessionAuthProcessor {
|
||||
}
|
||||
|
||||
private boolean isProviderEnabled(@NotNull String providerId) {
|
||||
ServletAuthConfiguration appConfiguration = (ServletAuthConfiguration) ServletAppUtils.getServletApplication()
|
||||
.getAppConfiguration();
|
||||
WebAuthConfiguration appConfiguration = (WebAuthConfiguration) WebAppUtils.getWebApplication().getAppConfiguration();
|
||||
return appConfiguration.isAuthProviderEnabled(providerId);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -17,7 +17,7 @@
|
||||
|
||||
package io.cloudbeaver.model.session;
|
||||
|
||||
import io.cloudbeaver.model.app.ServletApplication;
|
||||
import io.cloudbeaver.model.app.WebApplication;
|
||||
import io.cloudbeaver.model.user.WebUser;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
@@ -50,7 +50,7 @@ import java.util.stream.Collectors;
|
||||
public class WebUserContext implements SMCredentialsProvider {
|
||||
private static final Log log = Log.getLog(WebUserContext.class);
|
||||
|
||||
private final ServletApplication application;
|
||||
private final WebApplication application;
|
||||
private final DBPWorkspace workspace;
|
||||
|
||||
private WebUser user;
|
||||
@@ -67,7 +67,7 @@ public class WebUserContext implements SMCredentialsProvider {
|
||||
private Set<String> accessibleProjectIds = new HashSet<>();
|
||||
private final WebSessionPreferenceStore preferenceStore;
|
||||
|
||||
public WebUserContext(ServletApplication application, DBPWorkspace workspace) throws DBException {
|
||||
public WebUserContext(WebApplication application, DBPWorkspace workspace) throws DBException {
|
||||
this.application = application;
|
||||
this.workspace = workspace;
|
||||
this.securityController = application.createSecurityController(this);
|
||||
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* 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.model.session.monitor;
|
||||
|
||||
import io.cloudbeaver.model.WebAsyncTaskInfo;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import io.cloudbeaver.utils.WebEventUtils;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
|
||||
import org.jkiss.dbeaver.model.runtime.ProxyProgressMonitor;
|
||||
|
||||
/**
|
||||
* Task progress monitor.
|
||||
* Used by async GQL requests.
|
||||
*/
|
||||
public class TaskProgressMonitor extends ProxyProgressMonitor {
|
||||
|
||||
@NotNull
|
||||
private final WebAsyncTaskInfo asyncTask;
|
||||
private final WebSession webSession;
|
||||
|
||||
public TaskProgressMonitor(DBRProgressMonitor original, @NotNull WebSession webSession, @NotNull WebAsyncTaskInfo asyncTask) {
|
||||
super(original);
|
||||
this.webSession = webSession;
|
||||
this.asyncTask = asyncTask;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginTask(String name, int totalWork) {
|
||||
super.beginTask(name, totalWork);
|
||||
asyncTask.setStatus(name);
|
||||
WebEventUtils.sendAsyncTaskEvent(webSession, asyncTask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subTask(String name) {
|
||||
super.subTask(name);
|
||||
asyncTask.setStatus(name);
|
||||
WebEventUtils.sendAsyncTaskEvent(webSession, asyncTask);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -92,7 +92,7 @@ public class WebUserOriginInfo implements WebObjectOrigin {
|
||||
}
|
||||
try {
|
||||
SMAuthProvider<?> authProvider = this.authProviderDescriptor.getInstance();
|
||||
if (authProvider instanceof SMAuthProviderExternal && !authProviderDescriptor.isAuthHidden()) {
|
||||
if (authProvider instanceof SMAuthProviderExternal) {
|
||||
// read user's info from credentials, previously we tried to read data from external service using
|
||||
// SMAuthProviderExternal#getUserDetails
|
||||
var creds = loadCredentials();
|
||||
|
||||
+11
-17
@@ -19,7 +19,7 @@ package io.cloudbeaver.registry;
|
||||
import io.cloudbeaver.auth.CBAuthConstants;
|
||||
import io.cloudbeaver.auth.SMAuthProviderFederated;
|
||||
import io.cloudbeaver.auth.SMSignOutLinkProvider;
|
||||
import io.cloudbeaver.utils.ServletAppUtils;
|
||||
import io.cloudbeaver.utils.WebAppUtils;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.auth.SMAuthProvider;
|
||||
@@ -74,52 +74,46 @@ public class WebAuthProviderConfiguration {
|
||||
@Property
|
||||
public String getSignInLink() throws DBException {
|
||||
SMAuthProvider<?> instance = providerDescriptor.getInstance();
|
||||
return instance instanceof SMAuthProviderFederated smAuthProviderFederated ?
|
||||
buildRedirectUrl(smAuthProviderFederated.getSignInLink(getId()))
|
||||
return instance instanceof SMAuthProviderFederated ?
|
||||
buildRedirectUrl(((SMAuthProviderFederated) instance).getSignInLink(getId(), config.getParameters()))
|
||||
: null;
|
||||
}
|
||||
|
||||
private String buildRedirectUrl(String baseUrl) {
|
||||
return baseUrl + "?" + CBAuthConstants.CB_REDIRECT_URL_REQUEST_PARAM + "=" + ServletAppUtils.getFullServerUrl();
|
||||
return baseUrl + "?" + CBAuthConstants.CB_REDIRECT_URL_REQUEST_PARAM + "=" + WebAppUtils.getFullServerUrl();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getSignOutLink() throws DBException {
|
||||
SMAuthProvider<?> instance = providerDescriptor.getInstance();
|
||||
return instance instanceof SMSignOutLinkProvider smSignOutLinkProvider
|
||||
? smSignOutLinkProvider.getCommonSignOutLink(getId(), config.getParameters())
|
||||
return instance instanceof SMSignOutLinkProvider
|
||||
? ((SMSignOutLinkProvider) instance).getCommonSignOutLink(getId(), config.getParameters())
|
||||
: null;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getRedirectLink() throws DBException {
|
||||
SMAuthProvider<?> instance = providerDescriptor.getInstance();
|
||||
return instance instanceof SMAuthProviderFederated smAuthProviderFederated
|
||||
? smAuthProviderFederated.getRedirectLink(getId(), config.getParameters())
|
||||
: null;
|
||||
return instance instanceof SMAuthProviderFederated ? ((SMAuthProviderFederated) instance).getRedirectLink(getId(), config.getParameters()) : null;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getMetadataLink() throws DBException {
|
||||
SMAuthProvider<?> instance = providerDescriptor.getInstance();
|
||||
return instance instanceof SMAuthProviderFederated smAuthProviderFederated
|
||||
? smAuthProviderFederated.getMetadataLink(getId(), config.getParameters())
|
||||
: null;
|
||||
return instance instanceof SMAuthProviderFederated ? ((SMAuthProviderFederated) instance).getMetadataLink(getId(), config.getParameters()) : null;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getAcsLink() throws DBException {
|
||||
SMAuthProvider<?> instance = providerDescriptor.getInstance();
|
||||
return instance instanceof SMAuthProviderFederated smAuthProviderFederated
|
||||
? smAuthProviderFederated.getAcsLink(getId(), config.getParameters())
|
||||
: null;
|
||||
return instance instanceof SMAuthProviderFederated ? ((SMAuthProviderFederated) instance).getAcsLink(getId(), config.getParameters()) : null;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getEntityIdLink() throws DBException {
|
||||
SMAuthProvider<?> instance = providerDescriptor.getInstance();
|
||||
return instance instanceof SMAuthProviderFederated smAuthProviderFederated
|
||||
? smAuthProviderFederated.getEntityIdLink(getId(), config.getParameters())
|
||||
return instance instanceof SMAuthProviderFederated
|
||||
? ((SMAuthProviderFederated) instance).getEntityIdLink(getId(), config.getParameters())
|
||||
: null;
|
||||
}
|
||||
|
||||
|
||||
+1
-3
@@ -22,8 +22,6 @@ import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.DBPImage;
|
||||
import org.jkiss.dbeaver.model.DBPNamedObjectLocalized;
|
||||
import org.jkiss.dbeaver.model.DBPObjectWithDescriptionLocalized;
|
||||
import org.jkiss.dbeaver.model.auth.AuthPropertyDescriptor;
|
||||
import org.jkiss.dbeaver.model.auth.SMAuthProvider;
|
||||
import org.jkiss.dbeaver.model.impl.AbstractDescriptor;
|
||||
@@ -75,7 +73,7 @@ public class WebAuthProviderDescriptor extends AbstractDescriptor {
|
||||
this.isCaseInsensitive = CommonUtils.toBoolean(cfg.getAttribute("caseInsensitive"));
|
||||
|
||||
for (IConfigurationElement cfgElement : cfg.getChildren("configuration")) {
|
||||
List<WebAuthProviderProperty> properties = WebAuthProviderRegistry.readProperties(cfgElement, getId());
|
||||
List<WebAuthProviderProperty> properties = WebAuthProviderRegistry.readProperties(cfgElement);
|
||||
for (WebAuthProviderProperty property : properties) {
|
||||
configurationParameters.put(CommonUtils.toString(property.getId()), property);
|
||||
}
|
||||
|
||||
+3
-15
@@ -19,18 +19,15 @@ package io.cloudbeaver.registry;
|
||||
import org.eclipse.core.runtime.IConfigurationElement;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.model.impl.LocalizedPropertyDescriptor;
|
||||
import org.jkiss.dbeaver.model.impl.PropertyDescriptor;
|
||||
|
||||
public class WebAuthProviderProperty extends LocalizedPropertyDescriptor {
|
||||
public class WebAuthProviderProperty extends PropertyDescriptor {
|
||||
private final String[] requiredFeatures;
|
||||
@Nullable
|
||||
private final String type;
|
||||
|
||||
private final String authProviderId;
|
||||
|
||||
public WebAuthProviderProperty(String category, IConfigurationElement config, String authProviderId) {
|
||||
public WebAuthProviderProperty(String category, IConfigurationElement config) {
|
||||
super(category, config);
|
||||
this.authProviderId = authProviderId;
|
||||
String featuresAttr = config.getAttribute("requiredFeatures");
|
||||
this.requiredFeatures = featuresAttr == null ? new String[0] : featuresAttr.split(",");
|
||||
this.type = config.getAttribute("type");
|
||||
@@ -45,13 +42,4 @@ public class WebAuthProviderProperty extends LocalizedPropertyDescriptor {
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPropertyId() {
|
||||
if (authProviderId != null) {
|
||||
return "prop.auth.model." + authProviderId + "." + this.getId();
|
||||
} else {
|
||||
return "prop.auth.model." + this.getId();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -81,13 +81,13 @@ public class WebAuthProviderRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
static List<WebAuthProviderProperty> readProperties(IConfigurationElement root, String authProviderId) {
|
||||
static List<WebAuthProviderProperty> readProperties(IConfigurationElement root) {
|
||||
List<WebAuthProviderProperty> properties = new ArrayList<>();
|
||||
for (IConfigurationElement propGroup : ArrayUtils.safeArray(root.getChildren(PropertyDescriptor.TAG_PROPERTY_GROUP))) {
|
||||
String category = propGroup.getAttribute(PropertyDescriptor.ATTR_LABEL);
|
||||
IConfigurationElement[] propElements = propGroup.getChildren(PropertyDescriptor.TAG_PROPERTY);
|
||||
for (IConfigurationElement prop : propElements) {
|
||||
WebAuthProviderProperty propertyDescriptor = new WebAuthProviderProperty(category, prop, authProviderId);
|
||||
WebAuthProviderProperty propertyDescriptor = new WebAuthProviderProperty(category, prop);
|
||||
properties.add(propertyDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ public class WebCommonAuthProviderPropertyDescriptor extends AbstractDescriptor
|
||||
|
||||
public WebCommonAuthProviderPropertyDescriptor(IConfigurationElement cfg) {
|
||||
super(cfg);
|
||||
configurationParameters = WebAuthProviderRegistry.readProperties(cfg, null);
|
||||
configurationParameters = WebAuthProviderRegistry.readProperties(cfg);
|
||||
String supportedCategoriesAttr = cfg.getAttribute("supportedProviderCategories");
|
||||
if (CommonUtils.isNotEmpty(supportedCategoriesAttr)) {
|
||||
supportedProviderCategories.addAll(Arrays.stream(supportedCategoriesAttr.split(",")).toList());
|
||||
|
||||
+2
-52
@@ -19,20 +19,11 @@ package io.cloudbeaver.registry;
|
||||
import org.eclipse.core.runtime.IConfigurationElement;
|
||||
import org.eclipse.core.runtime.IExtensionRegistry;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDataSourceProviderDescriptor;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDriver;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDriverLibrary;
|
||||
import org.jkiss.dbeaver.registry.DataSourceProviderRegistry;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class WebDriverRegistry {
|
||||
|
||||
@@ -51,7 +42,6 @@ public class WebDriverRegistry {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private final List<DBPDriver> applicableDrivers = new ArrayList<>();
|
||||
private final Set<String> webDrivers = new HashSet<>();
|
||||
|
||||
protected WebDriverRegistry() {
|
||||
@@ -69,48 +59,8 @@ public class WebDriverRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
public List<DBPDriver> getApplicableDrivers() {
|
||||
return applicableDrivers;
|
||||
public boolean isDriverEnabled(DBPDriver driver) {
|
||||
return webDrivers.contains(driver.getFullId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates info about applicable drivers (f.e. some changes were made in driver config file).
|
||||
*/
|
||||
public void refreshApplicableDrivers() {
|
||||
this.applicableDrivers.clear();
|
||||
this.applicableDrivers.addAll(
|
||||
DataSourceProviderRegistry.getInstance().getEnabledDataSourceProviders().stream()
|
||||
.map(DBPDataSourceProviderDescriptor::getEnabledDrivers)
|
||||
.flatMap(List::stream)
|
||||
.filter(this::isDriverApplicable)
|
||||
.toList());
|
||||
log.info("Available drivers: " + applicableDrivers.stream().map(DBPDriver::getFullName).collect(Collectors.joining(",")));
|
||||
}
|
||||
|
||||
protected boolean isDriverApplicable(@NotNull DBPDriver driver) {
|
||||
List<? extends DBPDriverLibrary> libraries = driver.getDriverLibraries();
|
||||
if (!webDrivers.contains(driver.getFullId())) {
|
||||
return false;
|
||||
}
|
||||
boolean hasAllFiles = true;
|
||||
for (DBPDriverLibrary lib : libraries) {
|
||||
if (!isDriverLibraryFilePresent(lib)) {
|
||||
hasAllFiles = false;
|
||||
log.error("\tDriver '" + driver.getId() + "' is missing library '" + lib.getDisplayName() + "'");
|
||||
} else {
|
||||
if (lib.getType() == DBPDriverLibrary.FileType.jar) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return hasAllFiles;
|
||||
}
|
||||
|
||||
private boolean isDriverLibraryFilePresent(@NotNull DBPDriverLibrary lib) {
|
||||
if (lib.getType() == DBPDriverLibrary.FileType.license) {
|
||||
return true;
|
||||
}
|
||||
Path localFile = lib.getLocalFile();
|
||||
return localFile != null && Files.exists(localFile);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@
|
||||
package io.cloudbeaver.registry;
|
||||
|
||||
import io.cloudbeaver.DBWFeatureSet;
|
||||
import io.cloudbeaver.utils.ServletAppUtils;
|
||||
import io.cloudbeaver.utils.WebAppUtils;
|
||||
import org.eclipse.core.runtime.IConfigurationElement;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.dbeaver.model.DBPImage;
|
||||
@@ -66,7 +66,7 @@ public class WebFeatureDescriptor extends AbstractContextDescriptor implements D
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return ServletAppUtils.getServletApplication().getAppConfiguration().isFeatureEnabled(this.id);
|
||||
return WebAppUtils.getWebApplication().getAppConfiguration().isFeatureEnabled(this.id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-71
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* 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.registry;
|
||||
|
||||
import io.cloudbeaver.DBWFeatureSet;
|
||||
import org.eclipse.core.runtime.IConfigurationElement;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.dbeaver.model.DBPImage;
|
||||
import org.jkiss.dbeaver.model.impl.AbstractContextDescriptor;
|
||||
|
||||
/**
|
||||
* WebFeatureDescriptor
|
||||
*/
|
||||
public class WebServerFeatureDescriptor extends AbstractContextDescriptor implements DBWFeatureSet {
|
||||
|
||||
public static final String EXTENSION_ID = "io.cloudbeaver.server.feature"; //$NON-NLS-1$
|
||||
|
||||
private final String id;
|
||||
private final String label;
|
||||
private final String description;
|
||||
private final DBPImage icon;
|
||||
|
||||
public WebServerFeatureDescriptor(IConfigurationElement config)
|
||||
{
|
||||
super(config);
|
||||
this.id = config.getAttribute("id");
|
||||
this.label = config.getAttribute("label");
|
||||
this.description = config.getAttribute("description");
|
||||
this.icon = iconToImage(config.getAttribute("icon"));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DBPImage getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
-68
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* 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.registry;
|
||||
|
||||
import io.cloudbeaver.DBWFeatureSet;
|
||||
import org.eclipse.core.runtime.IConfigurationElement;
|
||||
import org.eclipse.core.runtime.IExtensionRegistry;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class WebServerFeatureRegistry {
|
||||
|
||||
private static final Log log = Log.getLog(WebServerFeatureRegistry.class);
|
||||
|
||||
private static final String TAG_FEATURE = "feature"; //$NON-NLS-1$
|
||||
|
||||
private static WebServerFeatureRegistry instance = null;
|
||||
|
||||
public synchronized static WebServerFeatureRegistry getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new WebServerFeatureRegistry();
|
||||
instance.loadExtensions(Platform.getExtensionRegistry());
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private String[] serverFeatures = new String[0];
|
||||
|
||||
private WebServerFeatureRegistry() {
|
||||
}
|
||||
|
||||
private synchronized void loadExtensions(IExtensionRegistry registry) {
|
||||
IConfigurationElement[] extConfigs = registry.getConfigurationElementsFor(WebServerFeatureDescriptor.EXTENSION_ID);
|
||||
List<DBWFeatureSet> features = new ArrayList<>();
|
||||
for (IConfigurationElement ext : extConfigs) {
|
||||
if (TAG_FEATURE.equals(ext.getName())) {
|
||||
features.add(
|
||||
new WebServerFeatureDescriptor(ext));
|
||||
}
|
||||
}
|
||||
this.serverFeatures = features
|
||||
.stream()
|
||||
.map(DBWFeatureSet::getId)
|
||||
.toArray(String[]::new);
|
||||
}
|
||||
|
||||
public String[] getServerFeatures() {
|
||||
return serverFeatures;
|
||||
}
|
||||
|
||||
}
|
||||
+6
-13
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2025 DBeaver Corp and others
|
||||
* 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.
|
||||
@@ -17,7 +17,7 @@
|
||||
package io.cloudbeaver.server;
|
||||
|
||||
import io.cloudbeaver.DBWConstants;
|
||||
import io.cloudbeaver.server.websockets.WebSocketPingPongJob;
|
||||
import io.cloudbeaver.model.app.WebApplication;
|
||||
import org.eclipse.core.runtime.Plugin;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
@@ -41,18 +41,16 @@ import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public abstract class BaseWebPlatform extends BasePlatformImpl {
|
||||
private static final Log log = Log.getLog(BaseWebPlatform.class);
|
||||
public abstract class BaseGQLPlatform extends BasePlatformImpl {
|
||||
private static final Log log = Log.getLog(BaseGQLPlatform.class);
|
||||
public static final String BASE_TEMP_DIR = "dbeaver";
|
||||
public static final String TEMP_FILE_FOLDER = "temp-sql-upload-files";
|
||||
public static final String TEMP_FILE_IMPORT_FOLDER = "temp-import-files";
|
||||
|
||||
private Path tempFolder;
|
||||
|
||||
private QMRegistryImpl queryManager;
|
||||
private QMLogFileWriter qmLogWriter;
|
||||
private DBACertificateStorage certificateStorage;
|
||||
private ServerGlobalWorkspace workspace;
|
||||
private WebGlobalWorkspace workspace;
|
||||
|
||||
@Override
|
||||
protected synchronized void initialize() {
|
||||
@@ -60,8 +58,7 @@ public abstract class BaseWebPlatform extends BasePlatformImpl {
|
||||
SecurityProviderUtils.registerSecurityProvider();
|
||||
|
||||
// Register properties adapter
|
||||
getApplication().beforeWorkspaceInitialization();
|
||||
this.workspace = new ServerGlobalWorkspace(this, getApplication());
|
||||
this.workspace = new WebGlobalWorkspace(this, (WebApplication) getApplication());
|
||||
this.workspace.initializeProjects();
|
||||
QMUtils.initApplication(this);
|
||||
|
||||
@@ -132,10 +129,6 @@ public abstract class BaseWebPlatform extends BasePlatformImpl {
|
||||
@NotNull
|
||||
public abstract WebApplication getApplication();
|
||||
|
||||
protected void scheduleServerJobs() {
|
||||
new WebSocketPingPongJob(WebAppUtils.getWebPlatform()).scheduleMonitor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void dispose() {
|
||||
super.dispose();
|
||||
@@ -20,8 +20,6 @@ package io.cloudbeaver.server;
|
||||
* Various constants
|
||||
*/
|
||||
public class CBConstants {
|
||||
public static final int STATIC_CACHE_SECONDS = 60 * 60 * 24 * 3;
|
||||
|
||||
public static final String RUNTIME_DATA_DIR_NAME = ".data";
|
||||
public static final String RUNTIME_APP_CONFIG_FILE_NAME = ".cloudbeaver.runtime.conf";
|
||||
public static final String RUNTIME_PRODUCT_CONFIG_FILE_NAME = ".product.runtime.conf";
|
||||
@@ -46,7 +44,6 @@ public class CBConstants {
|
||||
public static final String PARAM_STATIC_CONTENT = "staticContent";
|
||||
public static final String PARAM_RESOURCE_QUOTAS = "resourceQuotas";
|
||||
public static final String PARAM_RESOURCE_MANAGER_ENABLED = "resourceManagerEnabled";
|
||||
public static final String PARAM_SECRET_MANAGER_ENABLED = "secretManagerEnabled";
|
||||
public static final String PARAM_SHOW_READ_ONLY_CONN_INFO = "showReadOnlyConnectionInfo";
|
||||
public static final String PARAM_CONN_GRANT_ANON_ACCESS = "grantConnectionsAccessToAnonymousTeam";
|
||||
public static final String PARAM_AUTH_PROVIDERS = "authConfiguration";
|
||||
|
||||
@@ -80,6 +80,6 @@ public class WebGlobalProject extends BaseProjectImpl {
|
||||
@NotNull
|
||||
@Override
|
||||
protected DBPDataSourceRegistry createDataSourceRegistry() {
|
||||
return new DataSourceRegistry<>(this);
|
||||
return new DataSourceRegistry(this);
|
||||
}
|
||||
}
|
||||
+8
-7
@@ -17,7 +17,8 @@
|
||||
package io.cloudbeaver.server;
|
||||
|
||||
import io.cloudbeaver.WebProjectImpl;
|
||||
import io.cloudbeaver.model.app.ServletApplication;
|
||||
import io.cloudbeaver.model.app.WebApplication;
|
||||
import io.cloudbeaver.utils.WebAppUtils;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
@@ -38,18 +39,18 @@ import java.util.Map;
|
||||
/**
|
||||
* Web global workspace.
|
||||
*/
|
||||
public class ServerGlobalWorkspace extends BaseWorkspaceImpl {
|
||||
public class WebGlobalWorkspace extends BaseWorkspaceImpl {
|
||||
|
||||
private static final Log log = Log.getLog(ServerGlobalWorkspace.class);
|
||||
private static final Log log = Log.getLog(WebGlobalWorkspace.class);
|
||||
|
||||
protected final Map<String, WebProjectImpl> projects = new LinkedHashMap<>();
|
||||
private WebGlobalProject globalProject;
|
||||
|
||||
private final ServletApplication application;
|
||||
private final WebApplication application;
|
||||
|
||||
public ServerGlobalWorkspace(
|
||||
public WebGlobalWorkspace(
|
||||
@NotNull DBPPlatform platform,
|
||||
@NotNull ServletApplication application
|
||||
@NotNull WebApplication application
|
||||
) {
|
||||
super(platform, application.getWorkspaceDirectory());
|
||||
this.application = application;
|
||||
@@ -60,7 +61,7 @@ public class ServerGlobalWorkspace extends BaseWorkspaceImpl {
|
||||
initializeWorkspaceSession();
|
||||
|
||||
// Load global project
|
||||
String defaultProjectName = application.getDefaultProjectName();
|
||||
String defaultProjectName = WebAppUtils.getWebApplication().getDefaultProjectName();
|
||||
if (CommonUtils.isNotEmpty(defaultProjectName)) {
|
||||
Path globalProjectPath = getAbsolutePath().resolve(defaultProjectName);
|
||||
if (!Files.exists(globalProjectPath)) {
|
||||
+2
-2
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
package io.cloudbeaver.server;
|
||||
|
||||
import io.cloudbeaver.utils.ServletAppUtils;
|
||||
import io.cloudbeaver.utils.WebAppUtils;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.dbeaver.model.impl.preferences.AbstractPreferenceStore;
|
||||
import org.jkiss.dbeaver.model.preferences.DBPPreferenceStore;
|
||||
@@ -185,7 +185,7 @@ public class WebServerPreferenceStore extends AbstractPreferenceStore {
|
||||
}
|
||||
|
||||
private Map<String, Object> productConf() {
|
||||
var app = ServletAppUtils.getServletApplication();
|
||||
var app = WebAppUtils.getWebApplication();
|
||||
return app.getServerConfiguration().getProductSettings();
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -16,14 +16,14 @@
|
||||
*/
|
||||
package io.cloudbeaver.service;
|
||||
|
||||
import io.cloudbeaver.model.app.ServletApplication;
|
||||
import io.cloudbeaver.model.app.WebApplication;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
|
||||
/**
|
||||
* Servlet service
|
||||
*/
|
||||
public interface DBWServiceBindingServlet<APPLICATION extends ServletApplication> extends DBWServiceBinding {
|
||||
default boolean isApplicable(ServletApplication application) {
|
||||
public interface DBWServiceBindingServlet<APPLICATION extends WebApplication> extends DBWServiceBinding {
|
||||
default boolean isApplicable(WebApplication application) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+8
-8
@@ -16,9 +16,9 @@
|
||||
*/
|
||||
package io.cloudbeaver.service;
|
||||
|
||||
import io.cloudbeaver.model.app.ServletAppConfiguration;
|
||||
import io.cloudbeaver.model.app.ServletApplication;
|
||||
import io.cloudbeaver.model.app.ServletServerConfiguration;
|
||||
import io.cloudbeaver.model.app.WebAppConfiguration;
|
||||
import io.cloudbeaver.model.app.WebApplication;
|
||||
import io.cloudbeaver.model.app.WebServerConfiguration;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
@@ -30,16 +30,16 @@ import org.jkiss.dbeaver.DBException;
|
||||
public interface DBWServiceServerConfigurator extends DBWServiceBinding {
|
||||
|
||||
void configureServer(
|
||||
@NotNull ServletApplication application,
|
||||
@NotNull WebApplication application,
|
||||
@Nullable WebSession session,
|
||||
@NotNull ServletServerConfiguration serverConfiguration,
|
||||
@NotNull ServletAppConfiguration appConfig
|
||||
@NotNull WebServerConfiguration serverConfiguration,
|
||||
@NotNull WebAppConfiguration appConfig
|
||||
) throws DBException;
|
||||
|
||||
default void migrateConfigurationIfNeeded(@NotNull ServletApplication application) throws DBException {
|
||||
default void migrateConfigurationIfNeeded(@NotNull WebApplication application) throws DBException {
|
||||
|
||||
}
|
||||
|
||||
void reloadConfiguration(@NotNull ServletAppConfiguration appConfig) throws DBException;
|
||||
void reloadConfiguration(@NotNull WebAppConfiguration appConfig) throws DBException;
|
||||
|
||||
}
|
||||
|
||||
+17
-17
@@ -19,8 +19,8 @@ package io.cloudbeaver.utils;
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.WebProjectImpl;
|
||||
import io.cloudbeaver.auth.NoAuthCredentialsProvider;
|
||||
import io.cloudbeaver.model.app.ServletApplication;
|
||||
import io.cloudbeaver.model.app.ServletAuthApplication;
|
||||
import io.cloudbeaver.model.app.WebApplication;
|
||||
import io.cloudbeaver.model.app.WebAuthApplication;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import jakarta.servlet.http.Cookie;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
@@ -41,8 +41,8 @@ import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class ServletAppUtils {
|
||||
private static final Log log = Log.getLog(ServletAppUtils.class);
|
||||
public class WebAppUtils {
|
||||
private static final Log log = Log.getLog(WebAppUtils.class);
|
||||
|
||||
public static String getRelativePath(String path, String curDir) {
|
||||
return getRelativePath(path, Path.of(curDir));
|
||||
@@ -55,19 +55,19 @@ public class ServletAppUtils {
|
||||
return curDir.resolve(path).toAbsolutePath().toString();
|
||||
}
|
||||
|
||||
public static ServletApplication getServletApplication() {
|
||||
return (ServletApplication) DBWorkbench.getPlatform().getApplication();
|
||||
public static WebApplication getWebApplication() {
|
||||
return (WebApplication) DBWorkbench.getPlatform().getApplication();
|
||||
}
|
||||
|
||||
public static ServletAuthApplication getAuthApplication() throws DBException {
|
||||
ServletApplication application = getServletApplication();
|
||||
if (!ServletAuthApplication.class.isAssignableFrom(application.getClass())) {
|
||||
public static WebAuthApplication getWebAuthApplication() throws DBException {
|
||||
WebApplication application = getWebApplication();
|
||||
if (!WebAuthApplication.class.isAssignableFrom(application.getClass())) {
|
||||
throw new DBException("The current application doesn't contain authorization configuration");
|
||||
}
|
||||
return (ServletAuthApplication) application;
|
||||
return (WebAuthApplication) application;
|
||||
}
|
||||
|
||||
public static SMAuthenticationManager getAuthManager(ServletApplication application) throws DBException {
|
||||
public static SMAuthenticationManager getAuthManager(WebApplication application) throws DBException {
|
||||
var smController = application.createSecurityController(new NoAuthCredentialsProvider());
|
||||
if (!SMAuthenticationManager.class.isAssignableFrom(smController.getClass())) {
|
||||
throw new DBException("The current application cannot be used for authorization");
|
||||
@@ -169,11 +169,11 @@ public class ServletAppUtils {
|
||||
|
||||
@NotNull
|
||||
public static StringBuilder getAuthApiPrefix(String serviceId) throws DBException {
|
||||
return getAuthApiPrefix(getAuthApplication(), serviceId);
|
||||
return getAuthApiPrefix(getWebAuthApplication(), serviceId);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static StringBuilder getAuthApiPrefix(ServletAuthApplication webAuthApplication, String serviceId) {
|
||||
public static StringBuilder getAuthApiPrefix(WebAuthApplication webAuthApplication, String serviceId) {
|
||||
String authUrl = removeSideSlashes(webAuthApplication.getAuthServiceURL());
|
||||
StringBuilder apiPrefix = new StringBuilder(authUrl);
|
||||
apiPrefix.append("/").append(serviceId).append("/");
|
||||
@@ -190,7 +190,7 @@ public class ServletAppUtils {
|
||||
sessionCookie.setMaxAge((int) (maxSessionIdleTime / 1000));
|
||||
}
|
||||
|
||||
String path = getServletApplication().getServerConfiguration().getRootURI();
|
||||
String path = getWebApplication().getServerConfiguration().getRootURI();
|
||||
|
||||
if (sameSite != null) {
|
||||
if (!request.isSecure()) {
|
||||
@@ -223,7 +223,7 @@ public class ServletAppUtils {
|
||||
}
|
||||
|
||||
public static String getGlobalProjectId() {
|
||||
String globalConfigurationName = getServletApplication().getDefaultProjectName();
|
||||
String globalConfigurationName = getWebApplication().getDefaultProjectName();
|
||||
return RMProjectType.GLOBAL.getPrefix() + "_" + globalConfigurationName;
|
||||
}
|
||||
|
||||
@@ -273,9 +273,9 @@ public class ServletAppUtils {
|
||||
|
||||
@NotNull
|
||||
public static String getFullServerUrl() {
|
||||
ServletApplication application = ServletAppUtils.getServletApplication();
|
||||
WebApplication application = WebAppUtils.getWebApplication();
|
||||
return Stream.of(application.getServerURL(), application.getRootURI())
|
||||
.map(ServletAppUtils::removeSideSlashes)
|
||||
.map(WebAppUtils::removeSideSlashes)
|
||||
.filter(CommonUtils::isNotEmpty)
|
||||
.collect(Collectors.joining("/"));
|
||||
}
|
||||
@@ -16,9 +16,7 @@
|
||||
*/
|
||||
package io.cloudbeaver.utils;
|
||||
|
||||
import io.cloudbeaver.model.WebAsyncTaskInfo;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.dbeaver.model.app.DBPProject;
|
||||
import org.jkiss.dbeaver.model.websocket.WSConstants;
|
||||
import org.jkiss.dbeaver.model.websocket.event.WSEvent;
|
||||
@@ -27,7 +25,6 @@ import org.jkiss.dbeaver.model.websocket.event.datasource.WSDataSourceProperty;
|
||||
import org.jkiss.dbeaver.model.websocket.event.datasource.WSDatasourceFolderEvent;
|
||||
import org.jkiss.dbeaver.model.websocket.event.resource.WSResourceProperty;
|
||||
import org.jkiss.dbeaver.model.websocket.event.resource.WSResourceUpdatedEvent;
|
||||
import org.jkiss.dbeaver.model.websocket.event.session.WSSessionTaskInfoEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -83,7 +80,7 @@ public class WebEventUtils {
|
||||
if (event == null) {
|
||||
return;
|
||||
}
|
||||
ServletAppUtils.getServletApplication().getEventController().addEvent(event);
|
||||
WebAppUtils.getWebApplication().getEventController().addEvent(event);
|
||||
}
|
||||
|
||||
public static void addNavigatorNodeUpdatedEvent(
|
||||
@@ -125,7 +122,7 @@ public class WebEventUtils {
|
||||
if (event == null) {
|
||||
return;
|
||||
}
|
||||
ServletAppUtils.getServletApplication().getEventController().addEvent(event);
|
||||
WebAppUtils.getWebApplication().getEventController().addEvent(event);
|
||||
}
|
||||
|
||||
public static void addRmResourceUpdatedEvent(
|
||||
@@ -182,17 +179,7 @@ public class WebEventUtils {
|
||||
if (event == null) {
|
||||
return;
|
||||
}
|
||||
ServletAppUtils.getServletApplication().getEventController().addEvent(event);
|
||||
}
|
||||
|
||||
public static void sendAsyncTaskEvent(@NotNull WebSession webSession, @NotNull WebAsyncTaskInfo taskInfo) {
|
||||
webSession.addSessionEvent(
|
||||
new WSSessionTaskInfoEvent(
|
||||
taskInfo.getId(),
|
||||
taskInfo.getStatus(),
|
||||
taskInfo.isRunning()
|
||||
)
|
||||
);
|
||||
WebAppUtils.getWebApplication().getEventController().addEvent(event);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,10 +3,10 @@ Bundle-ManifestVersion: 2
|
||||
Bundle-Vendor: DBeaver Corp
|
||||
Bundle-Name: Cloudbeaver Community Product
|
||||
Bundle-SymbolicName: io.cloudbeaver.product.ce;singleton:=true
|
||||
Bundle-Version: 24.3.4.qualifier
|
||||
Bundle-Release-Date: 20250203
|
||||
Bundle-Version: 24.2.5.qualifier
|
||||
Bundle-Release-Date: 20241118
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-17
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-ClassPath: .
|
||||
Require-Bundle: io.cloudbeaver.server.ce
|
||||
Require-Bundle: io.cloudbeaver.server
|
||||
Automatic-Module-Name: io.cloudbeaver.product.ce
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.product.ce</artifactId>
|
||||
<version>24.3.4-SNAPSHOT</version>
|
||||
<version>24.2.5-SNAPSHOT</version>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -2,8 +2,8 @@ Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Base JDBC drivers
|
||||
Bundle-SymbolicName: io.cloudbeaver.resources.drivers.base;singleton:=true
|
||||
Bundle-Version: 1.0.115.qualifier
|
||||
Bundle-Release-Date: 20250203
|
||||
Bundle-Version: 1.0.110.qualifier
|
||||
Bundle-Release-Date: 20241118
|
||||
Bundle-Vendor: DBeaver Corp
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Automatic-Module-Name: io.cloudbeaver.resources.drivers.base
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.resources.drivers.base</artifactId>
|
||||
<version>1.0.115-SNAPSHOT</version>
|
||||
<version>1.0.110-SNAPSHOT</version>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
</project>
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Vendor: DBeaver Corp
|
||||
Bundle-Name: Cloudbeaver CE Server
|
||||
Bundle-SymbolicName: io.cloudbeaver.server.ce;singleton:=true
|
||||
Bundle-Version: 24.3.4.qualifier
|
||||
Bundle-Release-Date: 20250203
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-17
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-Activator: io.cloudbeaver.server.CBPlatformActivator
|
||||
Bundle-ClassPath: .
|
||||
Require-Bundle: io.cloudbeaver.server;visibility:=reexport
|
||||
Export-Package: io.cloudbeaver,
|
||||
io.cloudbeaver.model,
|
||||
io.cloudbeaver.model.config,
|
||||
io.cloudbeaver.server,
|
||||
io.cloudbeaver.service,
|
||||
io.cloudbeaver.service.core,
|
||||
io.cloudbeaver.service.session
|
||||
Import-Package: org.slf4j
|
||||
Automatic-Module-Name: io.cloudbeaver.server.ce
|
||||
@@ -1,6 +0,0 @@
|
||||
source..=src/
|
||||
output..=target/classes/
|
||||
bin.includes=.,\
|
||||
META-INF/,\
|
||||
schema/,\
|
||||
plugin.xml
|
||||
@@ -1,30 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?eclipse version="3.2"?>
|
||||
|
||||
<plugin>
|
||||
<extension point="org.jkiss.dbeaver.dataSourceHandler">
|
||||
<handler id="db.access.check" class="io.cloudbeaver.model.WebDatasourceAccessCheckHandler"/>
|
||||
</extension>
|
||||
|
||||
<extension point="io.cloudbeaver.service">
|
||||
<service id="core_ce" label="Core service" description="Core services" class="io.cloudbeaver.service.core.CECoreModelExtender"/>
|
||||
</extension>
|
||||
|
||||
<extension point="org.jkiss.dbeaver.ws.event.handler">
|
||||
<eventHandler class="io.cloudbeaver.server.events.WSUserEventHandler">
|
||||
<topic id="cb_user"/>
|
||||
</eventHandler>
|
||||
<eventHandler class="io.cloudbeaver.server.events.WSSubjectPermissionUpdatedEventHandler">
|
||||
<topic id="cb_subject_permissions"/>
|
||||
</eventHandler>
|
||||
<eventHandler class="io.cloudbeaver.server.events.WSUserSecretEventHandlerImpl">
|
||||
<topic id="cb_user_secret"/>
|
||||
</eventHandler>
|
||||
<eventHandler class="io.cloudbeaver.server.events.WSObjectPermissionUpdatedEventHandler">
|
||||
<topic id="cb_object_permissions"/>
|
||||
</eventHandler>
|
||||
<eventHandler class="io.cloudbeaver.server.events.WSRmResourceUpdatedEventHandlerImpl">
|
||||
<topic id="cb_scripts"/>
|
||||
</eventHandler>
|
||||
</extension>
|
||||
</plugin>
|
||||
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>io.cloudbeaver</groupId>
|
||||
<artifactId>bundles</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.server.ce</artifactId>
|
||||
<version>24.3.4-SNAPSHOT</version>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
|
||||
</project>
|
||||
@@ -1,16 +0,0 @@
|
||||
extend type ServerConfig {
|
||||
serverURL: String!
|
||||
rootURI: String!
|
||||
hostName: String! @deprecated # use container id instead
|
||||
containerId: String!
|
||||
defaultAuthRole: String
|
||||
defaultUserTeam: String # [23.2.2]
|
||||
|
||||
sessionExpireTime: Int!
|
||||
localHostAddress: String
|
||||
|
||||
redirectOnFederatedAuth: Boolean!
|
||||
enabledAuthProviders: [ID!]!
|
||||
passwordPolicyConfiguration: PasswordPolicyConfig! @since(version: "23.3.3")
|
||||
}
|
||||
|
||||
-89
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* 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.model;
|
||||
|
||||
import io.cloudbeaver.model.config.PasswordPolicyConfiguration;
|
||||
import io.cloudbeaver.server.CBApplication;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.dbeaver.model.meta.Property;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
|
||||
public class CBWebServerConfig extends WebServerConfig {
|
||||
private final CBApplication<?> cbApp;
|
||||
|
||||
public CBWebServerConfig(@NotNull CBApplication<?> cbApp) {
|
||||
super(cbApp);
|
||||
this.cbApp = cbApp;
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getServerURL() {
|
||||
return CommonUtils.notEmpty(cbApp.getServerConfiguration().getServerURL());
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getRootURI() {
|
||||
return CommonUtils.notEmpty(cbApp.getServerConfiguration().getRootURI());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Property
|
||||
public String getHostName() {
|
||||
return getContainerId();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getContainerId() {
|
||||
return CommonUtils.notEmpty(cbApp.getContainerId());
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isRedirectOnFederatedAuth() {
|
||||
return cbApp.getAppConfiguration().isRedirectOnFederatedAuth();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getLocalHostAddress() {
|
||||
return cbApp.getLocalHostAddress();
|
||||
}
|
||||
|
||||
@Property
|
||||
public long getSessionExpireTime() {
|
||||
return cbApp.getServerConfiguration().getMaxSessionIdleTime();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String[] getEnabledAuthProviders() {
|
||||
return cbApp.getAppConfiguration().getEnabledAuthProviders();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDefaultAuthRole() {
|
||||
return cbApp.getDefaultAuthRole();
|
||||
}
|
||||
|
||||
|
||||
@Property
|
||||
public String getDefaultUserTeam() {
|
||||
return cbApp.getAppConfiguration().getDefaultUserTeam();
|
||||
}
|
||||
|
||||
@Property
|
||||
public PasswordPolicyConfiguration getPasswordPolicyConfiguration() {
|
||||
return cbApp.getSecurityManagerConfiguration().getPasswordPolicyConfiguration();
|
||||
}
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2025 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.server;
|
||||
|
||||
import io.cloudbeaver.server.jobs.SessionStateJob;
|
||||
import io.cloudbeaver.server.jobs.WebDataSourceMonitorJob;
|
||||
import io.cloudbeaver.server.jobs.WebSessionMonitorJob;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.impl.app.BaseApplicationImpl;
|
||||
import org.jkiss.dbeaver.model.preferences.DBPPreferenceStore;
|
||||
import org.jkiss.dbeaver.model.runtime.AbstractJob;
|
||||
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
|
||||
import org.jkiss.dbeaver.runtime.DBWorkbench;
|
||||
import org.jkiss.utils.IOUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* CBPlatform
|
||||
*/
|
||||
public class CBPlatform extends BaseWebPlatform {
|
||||
|
||||
// The plug-in ID
|
||||
public static final String PLUGIN_ID = "io.cloudbeaver.server"; //$NON-NLS-1$
|
||||
|
||||
private static final Log log = Log.getLog(CBPlatform.class);
|
||||
|
||||
private WebServerPreferenceStore preferenceStore;
|
||||
|
||||
public static CBPlatform getInstance() {
|
||||
return (CBPlatform) DBWorkbench.getPlatform();
|
||||
}
|
||||
|
||||
protected CBPlatform() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected synchronized void initialize() {
|
||||
long startTime = System.currentTimeMillis();
|
||||
log.info("Initialize web platform...: ");
|
||||
this.preferenceStore = new WebServerPreferenceStore(WebPlatformActivator.getInstance().getPreferences());
|
||||
super.initialize();
|
||||
scheduleServerJobs();
|
||||
log.info("Web platform initialized (" + (System.currentTimeMillis() - startTime) + "ms)");
|
||||
}
|
||||
|
||||
protected void scheduleServerJobs() {
|
||||
super.scheduleServerJobs();
|
||||
new WebSessionMonitorJob(this, getApplication().getSessionManager())
|
||||
.scheduleMonitor();
|
||||
|
||||
new SessionStateJob(this, getApplication().getSessionManager())
|
||||
.scheduleMonitor();
|
||||
|
||||
new WebDataSourceMonitorJob(this, getApplication().getSessionManager())
|
||||
.scheduleMonitor();
|
||||
|
||||
new AbstractJob("Delete temp folder") {
|
||||
@Override
|
||||
protected IStatus run(DBRProgressMonitor monitor) {
|
||||
try {
|
||||
IOUtils.deleteDirectory(getTempFolder(monitor, TEMP_FILE_FOLDER));
|
||||
IOUtils.deleteDirectory(getTempFolder(monitor, TEMP_FILE_IMPORT_FOLDER));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
}.schedule();
|
||||
}
|
||||
|
||||
public synchronized void dispose() {
|
||||
long startTime = System.currentTimeMillis();
|
||||
log.debug("Shutdown Core...");
|
||||
|
||||
super.dispose();
|
||||
|
||||
System.gc();
|
||||
log.debug("Shutdown completed in " + (System.currentTimeMillis() - startTime) + "ms");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public CBApplication<?> getApplication() {
|
||||
return (CBApplication) BaseApplicationImpl.getInstance();
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DBPPreferenceStore getPreferenceStore() {
|
||||
return preferenceStore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShuttingDown() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* 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.service.core;
|
||||
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.service.DBWBindingContext;
|
||||
import io.cloudbeaver.service.WebServiceBindingBase;
|
||||
|
||||
/**
|
||||
* extends the base gql model, to avoid unnecessary fields in other applications
|
||||
*/
|
||||
public class CECoreModelExtender extends WebServiceBindingBase<DBWVoidService> {
|
||||
public CECoreModelExtender() {
|
||||
super(DBWVoidService.class, new DBWVoidService(), "schema/service.core.graphqls");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindWiring(DBWBindingContext model) throws DBWebException {
|
||||
|
||||
}
|
||||
}
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* 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.service.core;
|
||||
|
||||
import io.cloudbeaver.service.DBWService;
|
||||
|
||||
public class DBWVoidService implements DBWService {
|
||||
}
|
||||
@@ -3,17 +3,18 @@ Bundle-ManifestVersion: 2
|
||||
Bundle-Vendor: DBeaver Corp
|
||||
Bundle-Name: Cloudbeaver Web Server
|
||||
Bundle-SymbolicName: io.cloudbeaver.server;singleton:=true
|
||||
Bundle-Version: 24.3.4.qualifier
|
||||
Bundle-Release-Date: 20250203
|
||||
Bundle-Version: 24.2.5.qualifier
|
||||
Bundle-Release-Date: 20241118
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-17
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-Activator: io.cloudbeaver.server.CBPlatformActivator
|
||||
Bundle-ClassPath: .
|
||||
Require-Bundle: org.eclipse.core.runtime;visibility:=reexport,
|
||||
org.apache.commons.jexl,
|
||||
org.jkiss.utils;visibility:=reexport,
|
||||
org.jkiss.dbeaver.model.sql;visibility:=reexport,
|
||||
org.jkiss.dbeaver.data.gis,
|
||||
org.jkiss.bundle.jakarta.jetty.server;visibility:=reexport,
|
||||
org.jkiss.bundle.jetty.server;visibility:=reexport,
|
||||
com.google.gson;visibility:=reexport,
|
||||
org.jkiss.bundle.graphql.java;visibility:=reexport,
|
||||
org.jkiss.bundle.apache.dbcp,
|
||||
@@ -22,7 +23,6 @@ Require-Bundle: org.eclipse.core.runtime;visibility:=reexport,
|
||||
io.cloudbeaver.service.security;visibility:=reexport
|
||||
Export-Package: io.cloudbeaver,
|
||||
io.cloudbeaver.model,
|
||||
io.cloudbeaver.model.app,
|
||||
io.cloudbeaver.model.user,
|
||||
io.cloudbeaver.registry,
|
||||
io.cloudbeaver.server.events,
|
||||
@@ -32,10 +32,10 @@ Export-Package: io.cloudbeaver,
|
||||
io.cloudbeaver.server.graphql,
|
||||
io.cloudbeaver.server.jobs,
|
||||
io.cloudbeaver.server.servlets,
|
||||
io.cloudbeaver.server.websockets,
|
||||
io.cloudbeaver.server.websockets,
|
||||
io.cloudbeaver.service,
|
||||
io.cloudbeaver.service.navigator,
|
||||
io.cloudbeaver.service.session,
|
||||
io.cloudbeaver.service.sql
|
||||
Import-Package: org.slf4j
|
||||
Bundle-Localization: OSGI-INF/l10n/bundle
|
||||
Automatic-Module-Name: io.cloudbeaver.server
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
log.api.graphql.debug = Enable detailed logging
|
||||
log.api.graphql.debug.description = Enable detailed logging of GraphQL queries in the server log, including all provided variables
|
||||
@@ -1,2 +0,0 @@
|
||||
log.api.graphql.debug = Включить подробное логирование
|
||||
log.api.graphql.debug.description = Включите подробное логирование запросов GraphQL в журнале сервера, включая все предоставленные переменные
|
||||
@@ -2,7 +2,6 @@ source.. = src/
|
||||
output.. = target/classes/
|
||||
bin.includes = .,\
|
||||
META-INF/,\
|
||||
OSGI-INF/,\
|
||||
schema/,\
|
||||
static/,\
|
||||
plugin.xml
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
</service>
|
||||
</extension>
|
||||
|
||||
<extension point="org.jkiss.dbeaver.dataSourceHandler">
|
||||
<handler id="db.access.check" class="io.cloudbeaver.model.WebDatasourceAccessCheckHandler"/>
|
||||
</extension>
|
||||
<extension point="io.cloudbeaver.valueSerializer">
|
||||
<serializer type="geometry" class="io.cloudbeaver.server.data.WebGeometryValueSerializer"/>
|
||||
</extension>
|
||||
@@ -43,9 +46,21 @@
|
||||
<eventHandler class="io.cloudbeaver.server.events.WSFolderUpdatedEventHandlerImpl">
|
||||
<topic id="cb_datasource_folder"/>
|
||||
</eventHandler>
|
||||
<eventHandler class="io.cloudbeaver.server.events.WSRmResourceUpdatedEventHandlerImpl">
|
||||
<topic id="cb_scripts"/>
|
||||
</eventHandler>
|
||||
<eventHandler class="io.cloudbeaver.server.events.WSObjectPermissionUpdatedEventHandler">
|
||||
<topic id="cb_object_permissions"/>
|
||||
</eventHandler>
|
||||
<eventHandler class="io.cloudbeaver.server.events.WSSubjectPermissionUpdatedEventHandler">
|
||||
<topic id="cb_subject_permissions"/>
|
||||
</eventHandler>
|
||||
<eventHandler class="io.cloudbeaver.server.events.WSProjectUpdatedEventHandler">
|
||||
<topic id="cb_projects"/>
|
||||
</eventHandler>
|
||||
<eventHandler class="io.cloudbeaver.server.events.WSUserSecretEventHandlerImpl">
|
||||
<topic id="cb_user_secret"/>
|
||||
</eventHandler>
|
||||
<eventHandler class="io.cloudbeaver.server.events.WSLogEventHandler">
|
||||
<topic id="cb_session_log"/>
|
||||
</eventHandler>
|
||||
@@ -55,14 +70,9 @@
|
||||
<eventHandler class="io.cloudbeaver.server.events.WSDeleteTempFileHandler">
|
||||
<topic id="cb_delete_temp_folder"/>
|
||||
</eventHandler>
|
||||
</extension>
|
||||
|
||||
<extension point="org.jkiss.dbeaver.settings">
|
||||
<propertyGroup id="log" label="Logger">
|
||||
<property id="log.api.graphql.debug" label="Enable detailed logging"
|
||||
type="boolean" scopes="global"
|
||||
description="Enable detailed logging of GraphQL queries in the server log, including all provided variables"/>
|
||||
</propertyGroup>
|
||||
<eventHandler class="io.cloudbeaver.server.events.WSUserEventHandler">
|
||||
<topic id="cb_user"/>
|
||||
</eventHandler>
|
||||
</extension>
|
||||
|
||||
</plugin>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<artifactId>io.cloudbeaver.server</artifactId>
|
||||
<version>24.3.4-SNAPSHOT</version>
|
||||
<version>24.2.5-SNAPSHOT</version>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -118,7 +118,6 @@ type ProductInfo {
|
||||
licenseInfo: String
|
||||
|
||||
latestVersionInfo: String
|
||||
productPurchaseURL: String
|
||||
}
|
||||
|
||||
type ServerConfig {
|
||||
@@ -126,12 +125,19 @@ type ServerConfig {
|
||||
version: String!
|
||||
workspaceId: ID!
|
||||
|
||||
serverURL: String!
|
||||
rootURI: String!
|
||||
hostName: String! @deprecated # use container id instead
|
||||
containerId: String!
|
||||
defaultAuthRole: String
|
||||
defaultUserTeam: String # [23.2.2]
|
||||
|
||||
anonymousAccessEnabled: Boolean!
|
||||
supportsCustomConnections: Boolean!
|
||||
supportsConnectionBrowser: Boolean!
|
||||
supportsWorkspaces: Boolean!
|
||||
resourceManagerEnabled: Boolean!
|
||||
|
||||
secretManagerEnabled: Boolean! @since(version: "24.3.2")
|
||||
|
||||
publicCredentialsSaveEnabled: Boolean!
|
||||
adminCredentialsSaveEnabled: Boolean!
|
||||
|
||||
@@ -139,14 +145,18 @@ type ServerConfig {
|
||||
licenseValid: Boolean!
|
||||
licenseStatus: String @since(version: "24.1.5")
|
||||
|
||||
sessionExpireTime: Int!
|
||||
localHostAddress: String
|
||||
|
||||
configurationMode: Boolean!
|
||||
# initializationMode: Boolean! @since(version: "24.1.5")
|
||||
developmentMode: Boolean!
|
||||
redirectOnFederatedAuth: Boolean!
|
||||
distributed: Boolean!
|
||||
|
||||
enabledFeatures: [ID!]!
|
||||
disabledBetaFeatures: [ID!] @since(version: "24.0.5")
|
||||
serverFeatures: [ID!] @since(version: "24.3.0")
|
||||
enabledAuthProviders: [ID!]!
|
||||
supportedLanguages: [ ServerLanguage! ]!
|
||||
services: [ WebServiceConfig ]
|
||||
productConfiguration: Object!
|
||||
@@ -154,6 +164,7 @@ type ServerConfig {
|
||||
defaultNavigatorSettings: NavigatorSettings!
|
||||
disabledDrivers: [ID!]!
|
||||
resourceQuotas: Object!
|
||||
passwordPolicyConfiguration: PasswordPolicyConfig! @since(version: "23.3.3")
|
||||
}
|
||||
|
||||
type ProductSettingsGroup @since(version: "24.0.1") {
|
||||
@@ -198,18 +209,14 @@ type DatabaseAuthModel {
|
||||
}
|
||||
|
||||
type DriverInfo {
|
||||
# Driver unique full ID. It is `providerId + "." + driverId`.
|
||||
# It is recommended to use providerId and driverId separately.
|
||||
id: ID!
|
||||
name: String
|
||||
description: String
|
||||
icon: String
|
||||
iconBig: String
|
||||
|
||||
# Driver ID. It is unique within provider
|
||||
driverId: ID!
|
||||
# Driver provider ID. It is globally unique
|
||||
providerId: ID!
|
||||
# Driver provider ID
|
||||
providerId: ID
|
||||
# Driver Java class name
|
||||
driverClassName: String
|
||||
defaultHost: String
|
||||
@@ -263,8 +270,6 @@ type DriverInfo {
|
||||
|
||||
configurationTypes: [DriverConfigurationType]!
|
||||
|
||||
downloadable: Boolean! @since(version: "24.3.3")
|
||||
driverInstalled: Boolean!
|
||||
driverLibraries: [DriverLibraryInfo!]!
|
||||
}
|
||||
|
||||
@@ -272,13 +277,6 @@ type DriverLibraryInfo {
|
||||
id: ID!
|
||||
name: String!
|
||||
icon: String
|
||||
libraryFiles: [DriverFileInfo!]
|
||||
}
|
||||
|
||||
type DriverFileInfo @since(version: "24.3.2") {
|
||||
id: ID!
|
||||
fileName: String!
|
||||
icon: String
|
||||
}
|
||||
|
||||
enum ResultDataFormat {
|
||||
@@ -356,7 +354,7 @@ type ConnectionInfo {
|
||||
|
||||
properties: Object
|
||||
|
||||
template: Boolean! @deprecated
|
||||
template: Boolean!
|
||||
connected: Boolean!
|
||||
provided: Boolean!
|
||||
readOnly: Boolean!
|
||||
@@ -502,7 +500,7 @@ input ConnectionConfig {
|
||||
description: String
|
||||
|
||||
# ID of template connection
|
||||
templateId: ID @deprecated
|
||||
templateId: ID
|
||||
# ID of database driver
|
||||
driverId: ID
|
||||
|
||||
@@ -529,7 +527,7 @@ input ConnectionConfig {
|
||||
autocommit: Boolean
|
||||
|
||||
# Return template connection state
|
||||
template: Boolean @deprecated
|
||||
template: Boolean
|
||||
# Return read-only connection state
|
||||
readOnly: Boolean
|
||||
|
||||
@@ -589,7 +587,7 @@ extend type Query {
|
||||
userConnections( projectId: ID, id: ID, projectIds: [ID!] ): [ ConnectionInfo! ]!
|
||||
|
||||
# Return list of template connections by project ID
|
||||
templateConnections( projectId: ID ): [ ConnectionInfo! ]! @deprecated
|
||||
templateConnections( projectId: ID ): [ ConnectionInfo! ]!
|
||||
|
||||
# List of connection folders
|
||||
connectionFolders( projectId: ID, path: ID ): [ ConnectionFolderInfo! ]!
|
||||
@@ -631,7 +629,7 @@ extend type Mutation {
|
||||
deleteConnection( id: ID!, projectId: ID ): Boolean!
|
||||
|
||||
# Create new custom connection from template
|
||||
createConnectionFromTemplate( templateId: ID!, projectId: ID!, connectionName: String ): ConnectionInfo! @deprecated
|
||||
createConnectionFromTemplate( templateId: ID!, projectId: ID!, connectionName: String ): ConnectionInfo!
|
||||
|
||||
# Create new folder for connections
|
||||
createConnectionFolder(parentFolderPath: ID, folderName: String!, projectId: ID ): ConnectionFolderInfo!
|
||||
|
||||
@@ -20,9 +20,6 @@ enum CBServerEventId {
|
||||
cb_datasource_folder_updated,
|
||||
cb_datasource_folder_deleted,
|
||||
|
||||
cb_datasource_disconnected,
|
||||
cb_datasource_connected,
|
||||
|
||||
cb_rm_resource_created,
|
||||
cb_rm_resource_updated,
|
||||
cb_rm_resource_deleted,
|
||||
@@ -33,11 +30,7 @@ enum CBServerEventId {
|
||||
cb_object_permissions_updated,
|
||||
cb_subject_permissions_updated,
|
||||
|
||||
cb_database_output_log_updated,
|
||||
|
||||
cb_transaction_count @since(version: "24.3.3")
|
||||
|
||||
cb_session_task_info_updated @since(version: "24.3.1")
|
||||
cb_database_output_log_updated
|
||||
}
|
||||
|
||||
# Events sent by client
|
||||
@@ -60,13 +53,7 @@ enum CBEventTopic {
|
||||
cb_object_permissions,
|
||||
cb_subject_permissions,
|
||||
cb_database_output_log,
|
||||
|
||||
cb_session_task, @since(version: "24.3.1")
|
||||
|
||||
cb_datasource_connection,
|
||||
cb_delete_temp_folder,
|
||||
|
||||
cb_transaction @since(version: "24.3.3")
|
||||
cb_delete_temp_folder
|
||||
}
|
||||
|
||||
# Base server event interface
|
||||
@@ -191,41 +178,6 @@ type WSOutputLogInfo {
|
||||
# Add more fields as needed
|
||||
}
|
||||
|
||||
# Async task info status event
|
||||
type WSAsyncTaskInfo @since(version: "24.3.1") {
|
||||
id: CBServerEventId!
|
||||
taskId: ID!
|
||||
statusName: String
|
||||
running: Boolean!
|
||||
}
|
||||
|
||||
# Datasource disconnect event
|
||||
type WSDataSourceDisconnectEvent implements CBServerEvent {
|
||||
id: CBServerEventId!
|
||||
topicId: CBEventTopic
|
||||
connectionId: String!
|
||||
projectId: String!
|
||||
timestamp: Int!
|
||||
}
|
||||
# Datasource connect event
|
||||
type WSDataSourceConnectEvent implements CBServerEvent {
|
||||
id: CBServerEventId!
|
||||
topicId: CBEventTopic
|
||||
connectionId: String!
|
||||
projectId: String!
|
||||
timestamp: Int!
|
||||
}
|
||||
|
||||
# Datasource count event in transactional mode
|
||||
type WSTransactionalCountEvent implements CBServerEvent {
|
||||
id: CBServerEventId!
|
||||
topicId: CBEventTopic
|
||||
contextId: String!
|
||||
projectId: String!
|
||||
connectionId: String!
|
||||
transactionalCount: Int!
|
||||
}
|
||||
|
||||
extend type Query {
|
||||
emptyEvent: Boolean
|
||||
}
|
||||
|
||||
@@ -223,24 +223,6 @@ type DynamicTraceProperty {
|
||||
description: String
|
||||
}
|
||||
|
||||
####################################################
|
||||
# Transactional info
|
||||
####################################################
|
||||
type TransactionLogInfoItem {
|
||||
id: Int!
|
||||
time: DateTime!
|
||||
type: String!
|
||||
queryString: String!
|
||||
durationMs: Int!
|
||||
rows: Int!
|
||||
result: String!
|
||||
}
|
||||
type TransactionLogInfos {
|
||||
count: Int!
|
||||
transactionLogInfos: [TransactionLogInfoItem!]!
|
||||
}
|
||||
|
||||
|
||||
####################################################
|
||||
# Query and Mutation
|
||||
####################################################
|
||||
@@ -349,12 +331,6 @@ extend type Mutation {
|
||||
dataFormat: ResultDataFormat
|
||||
): AsyncTaskInfo!
|
||||
|
||||
getTransactionLogInfo(
|
||||
projectId: ID!,
|
||||
connectionId: ID!,
|
||||
contextId: ID!
|
||||
): TransactionLogInfos!
|
||||
|
||||
# Close results (free resources)
|
||||
sqlResultClose(projectId: ID, connectionId: ID!, contextId: ID!, resultId: ID!): Boolean!
|
||||
|
||||
|
||||
@@ -23,20 +23,18 @@ import com.google.gson.Strictness;
|
||||
import io.cloudbeaver.model.WebConnectionConfig;
|
||||
import io.cloudbeaver.model.WebNetworkHandlerConfigInput;
|
||||
import io.cloudbeaver.model.WebPropertyInfo;
|
||||
import io.cloudbeaver.model.app.ServletApplication;
|
||||
import io.cloudbeaver.model.config.CBAppConfig;
|
||||
import io.cloudbeaver.model.session.WebActionParameters;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import io.cloudbeaver.registry.WebAuthProviderDescriptor;
|
||||
import io.cloudbeaver.registry.WebAuthProviderRegistry;
|
||||
import io.cloudbeaver.server.WebAppUtils;
|
||||
import io.cloudbeaver.server.WebApplication;
|
||||
import io.cloudbeaver.server.CBApplication;
|
||||
import io.cloudbeaver.server.CBPlatform;
|
||||
import io.cloudbeaver.service.navigator.WebPropertyFilter;
|
||||
import io.cloudbeaver.utils.ServletAppUtils;
|
||||
import io.cloudbeaver.utils.WebCommonUtils;
|
||||
import io.cloudbeaver.utils.WebDataSourceUtils;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.DBConstants;
|
||||
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
|
||||
@@ -132,17 +130,16 @@ public class WebServiceUtils extends WebCommonUtils {
|
||||
newDataSource.setSavePassword(true);
|
||||
newDataSource.setName(config.getName());
|
||||
newDataSource.setDescription(config.getDescription());
|
||||
newDataSource.setConnectionReadOnly(config.isReadOnly());
|
||||
if (config.getFolder() != null) {
|
||||
newDataSource.setFolder(registry.getFolder(config.getFolder()));
|
||||
}
|
||||
((DataSourceDescriptor)newDataSource).setTemplate(config.isTemplate());
|
||||
|
||||
ServletApplication app = ServletAppUtils.getServletApplication();
|
||||
if (app instanceof WebApplication webApplication) {
|
||||
((DataSourceDescriptor) newDataSource).setNavigatorSettings(
|
||||
webApplication.getAppConfiguration().getDefaultNavigatorSettings());
|
||||
}
|
||||
// Set default navigator settings
|
||||
DataSourceNavigatorSettings navSettings = new DataSourceNavigatorSettings(
|
||||
CBApplication.getInstance().getAppConfiguration().getDefaultNavigatorSettings());
|
||||
//navSettings.setShowSystemObjects(false);
|
||||
((DataSourceDescriptor)newDataSource).setNavigatorSettings(navSettings);
|
||||
|
||||
saveAuthProperties(
|
||||
newDataSource,
|
||||
@@ -314,6 +311,12 @@ public class WebServiceUtils extends WebCommonUtils {
|
||||
gson.toJsonTree(settingsMap), DataSourceNavigatorSettings.class);
|
||||
}
|
||||
|
||||
public static void checkServerConfigured() throws DBWebException {
|
||||
if (CBApplication.getInstance().isConfigurationMode()) {
|
||||
throw new DBWebException("Server is in configuration mode");
|
||||
}
|
||||
}
|
||||
|
||||
public static void fireActionParametersOpenEditor(WebSession webSession, DBPDataSourceContainer dataSource, boolean addEditorName) {
|
||||
Map<String, Object> actionParameters = new HashMap<>();
|
||||
actionParameters.put("action", "open-sql-editor");
|
||||
@@ -338,20 +341,13 @@ public class WebServiceUtils extends WebCommonUtils {
|
||||
}
|
||||
|
||||
public static boolean isGlobalProject(DBPProject project) {
|
||||
return project.getId()
|
||||
.equals(RMProjectType.GLOBAL.getPrefix() + "_" + ServletAppUtils.getServletApplication()
|
||||
.getDefaultProjectName());
|
||||
return project.getId().equals(RMProjectType.GLOBAL.getPrefix() + "_" + CBApplication.getInstance().getDefaultProjectName());
|
||||
}
|
||||
|
||||
public static List<WebAuthProviderDescriptor> getEnabledAuthProviders() {
|
||||
List<WebAuthProviderDescriptor> result = new ArrayList<>();
|
||||
String[] authProviders = null;
|
||||
try {
|
||||
authProviders = ServletAppUtils.getAuthApplication().getAuthConfiguration().getEnabledAuthProviders();
|
||||
} catch (DBException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return List.of();
|
||||
}
|
||||
CBAppConfig appConfig = CBApplication.getInstance().getAppConfiguration();
|
||||
String[] authProviders = appConfig.getEnabledAuthProviders();
|
||||
for (String apId : authProviders) {
|
||||
WebAuthProviderDescriptor authProvider = WebAuthProviderRegistry.getInstance().getAuthProvider(apId);
|
||||
if (authProvider != null) {
|
||||
@@ -366,7 +362,7 @@ public class WebServiceUtils extends WebCommonUtils {
|
||||
*/
|
||||
@NotNull
|
||||
public static Set<String> getApplicableDriversIds() {
|
||||
return WebAppUtils.getWebApplication().getDriverRegistry().getApplicableDrivers().stream()
|
||||
return CBPlatform.getInstance().getApplicableDrivers().stream()
|
||||
.map(DBPDriver::getId)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
+11
-36
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2025 DBeaver Corp and others
|
||||
* 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.
|
||||
@@ -18,14 +18,17 @@ package io.cloudbeaver.model;
|
||||
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.WebServiceUtils;
|
||||
import io.cloudbeaver.model.app.WebAppConfiguration;
|
||||
import io.cloudbeaver.model.config.CBAppConfig;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import io.cloudbeaver.model.utils.ConfigurationUtils;
|
||||
import io.cloudbeaver.server.WebAppUtils;
|
||||
import io.cloudbeaver.server.CBApplication;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.DBConstants;
|
||||
import org.jkiss.dbeaver.model.connection.*;
|
||||
import org.jkiss.dbeaver.model.connection.DBPAuthModelDescriptor;
|
||||
import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDriver;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDriverConfigurationType;
|
||||
import org.jkiss.dbeaver.model.impl.auth.AuthModelDatabaseNative;
|
||||
import org.jkiss.dbeaver.model.meta.Property;
|
||||
import org.jkiss.dbeaver.model.preferences.DBPPropertyDescriptor;
|
||||
@@ -39,8 +42,6 @@ import org.jkiss.utils.CommonUtils;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Web driver configuration
|
||||
@@ -52,7 +53,7 @@ public class WebDatabaseDriverInfo {
|
||||
public static final String URL_DATABASE_FIELD = ".*(?:\\{(?:database|file|folder)}).*";
|
||||
private final WebSession webSession;
|
||||
private final DBPDriver driver;
|
||||
private final String id;
|
||||
private String id;
|
||||
|
||||
public WebDatabaseDriverInfo(WebSession webSession, DBPDriver driver) {
|
||||
this.webSession = webSession;
|
||||
@@ -85,11 +86,6 @@ public class WebDatabaseDriverInfo {
|
||||
return WebServiceUtils.makeIconId(driver.getIconBig());
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDriverId() {
|
||||
return driver.getId();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getProviderId() {
|
||||
return driver.getProviderId();
|
||||
@@ -257,24 +253,14 @@ public class WebDatabaseDriverInfo {
|
||||
|
||||
@Property
|
||||
public WebPropertyInfo[] getProviderProperties() {
|
||||
WebPropertyInfo[] additionalWebProperty = Optional.of(WebAppUtils.getWebApplication())
|
||||
.filter(app -> app.getAppConfiguration().isSecretManagerEnabled())
|
||||
.map(app -> app.getConnectionController().getExternalInfo(webSession))
|
||||
.orElse(new WebPropertyInfo[0]);
|
||||
|
||||
WebPropertyInfo[] providerProperties = Arrays.stream(driver.getProviderPropertyDescriptors())
|
||||
return Arrays.stream(driver.getProviderPropertyDescriptors())
|
||||
.map(p -> new WebPropertyInfo(webSession, p, null))
|
||||
.toArray(WebPropertyInfo[]::new);
|
||||
|
||||
return Stream.concat(
|
||||
Arrays.stream(additionalWebProperty),
|
||||
Arrays.stream(providerProperties)
|
||||
).toArray(WebPropertyInfo[]::new);
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isEnabled() {
|
||||
WebAppConfiguration config = WebAppUtils.getWebApplication().getAppConfiguration();
|
||||
CBAppConfig config = CBApplication.getInstance().getAppConfiguration();
|
||||
return ConfigurationUtils.isDriverEnabled(
|
||||
driver,
|
||||
config.getEnabledDrivers(),
|
||||
@@ -305,21 +291,10 @@ public class WebDatabaseDriverInfo {
|
||||
@Property
|
||||
public WebDriverLibraryInfo[] getDriverLibraries() {
|
||||
return driver.getDriverLibraries().stream()
|
||||
.filter(library -> !library.isDisabled())
|
||||
.map(library -> new WebDriverLibraryInfo(driver, library))
|
||||
.map(dbpDriverLibrary -> new WebDriverLibraryInfo(webSession, dbpDriverLibrary))
|
||||
.toArray(WebDriverLibraryInfo[]::new);
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isDriverInstalled() {
|
||||
return driver.isDriverInstalled();
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isDownloadable() {
|
||||
return driver.getDriverLibraries().stream().anyMatch(DBPDriverLibrary::isDownloadable);
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean getUseCustomPage() {
|
||||
return !ArrayUtils.isEmpty(driver.getMainPropertyDescriptors());
|
||||
|
||||
+3
-2
@@ -20,13 +20,14 @@ package io.cloudbeaver.model;
|
||||
import io.cloudbeaver.model.config.CBAppConfig;
|
||||
import io.cloudbeaver.model.utils.ConfigurationUtils;
|
||||
import io.cloudbeaver.server.CBApplication;
|
||||
import io.cloudbeaver.utils.ServletAppUtils;
|
||||
import io.cloudbeaver.utils.WebAppUtils;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDriver;
|
||||
|
||||
//TODO move to a separate CBApplication plugin
|
||||
public class WebDatasourceAccessCheckHandler extends BaseDatasourceAccessCheckHandler {
|
||||
@Override
|
||||
protected boolean isDriverDisabled(DBPDriver driver) {
|
||||
if (!ServletAppUtils.getServletApplication().isMultiuser()) {
|
||||
if (!WebAppUtils.getWebApplication().isMultiuser()) {
|
||||
return false;
|
||||
}
|
||||
CBAppConfig config = CBApplication.getInstance().getAppConfiguration();
|
||||
-53
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* 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.model;
|
||||
|
||||
import io.cloudbeaver.WebServiceUtils;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.dbeaver.model.DBIcon;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDriverLibrary;
|
||||
import org.jkiss.dbeaver.model.meta.Property;
|
||||
import org.jkiss.dbeaver.registry.driver.DriverDescriptor;
|
||||
|
||||
public class WebDriverLibraryFileInfo {
|
||||
|
||||
@NotNull
|
||||
private final DriverDescriptor.DriverFileInfo fileInfo;
|
||||
|
||||
public WebDriverLibraryFileInfo(@NotNull DriverDescriptor.DriverFileInfo fileInfo) {
|
||||
this.fileInfo = fileInfo;
|
||||
}
|
||||
|
||||
|
||||
@Property
|
||||
public String getId() {
|
||||
return fileInfo.getId();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getFileName() {
|
||||
return fileInfo.toString();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getIcon() {
|
||||
if (fileInfo.getType() == DBPDriverLibrary.FileType.license) {
|
||||
return WebServiceUtils.makeIconId(DBIcon.TYPE_TEXT);
|
||||
}
|
||||
return WebServiceUtils.makeIconId(DBIcon.JAR);
|
||||
}
|
||||
}
|
||||
+4
-22
@@ -17,24 +17,18 @@
|
||||
package io.cloudbeaver.model;
|
||||
|
||||
import io.cloudbeaver.WebServiceUtils;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDriver;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDriverLibrary;
|
||||
import org.jkiss.dbeaver.model.meta.Property;
|
||||
import org.jkiss.dbeaver.registry.driver.DriverDescriptor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class WebDriverLibraryInfo {
|
||||
|
||||
@NotNull
|
||||
private final DBPDriver driver;
|
||||
@NotNull
|
||||
private final WebSession webSession;
|
||||
private final DBPDriverLibrary driverLibrary;
|
||||
|
||||
public WebDriverLibraryInfo(@NotNull DBPDriver driver, @NotNull DBPDriverLibrary driverLibrary) {
|
||||
this.driver = driver;
|
||||
public WebDriverLibraryInfo(@NotNull WebSession webSession, @NotNull DBPDriverLibrary driverLibrary) {
|
||||
this.webSession = webSession;
|
||||
this.driverLibrary = driverLibrary;
|
||||
}
|
||||
|
||||
@@ -49,18 +43,6 @@ public class WebDriverLibraryInfo {
|
||||
return driverLibrary.getDisplayName();
|
||||
}
|
||||
|
||||
@Property
|
||||
@Nullable
|
||||
public List<WebDriverLibraryFileInfo> getLibraryFiles() {
|
||||
var libraryFiles = ((DriverDescriptor) driver).getLibraryFiles(driverLibrary);
|
||||
if (libraryFiles == null) {
|
||||
return null;
|
||||
}
|
||||
return libraryFiles.stream()
|
||||
.map(WebDriverLibraryFileInfo::new)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getIcon() {
|
||||
return WebServiceUtils.makeIconId(driverLibrary.getIcon());
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
package io.cloudbeaver.model;
|
||||
|
||||
import io.cloudbeaver.utils.ServletAppUtils;
|
||||
import io.cloudbeaver.server.CBApplication;
|
||||
import org.eclipse.core.runtime.IProduct;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.jkiss.dbeaver.model.meta.Property;
|
||||
@@ -68,7 +68,7 @@ public class WebProductInfo {
|
||||
|
||||
@Property
|
||||
public String getLicenseInfo() {
|
||||
return ServletAppUtils.getServletApplication().getInfoDetails(new VoidProgressMonitor());
|
||||
return CBApplication.getInstance().getInfoDetails(new VoidProgressMonitor());
|
||||
}
|
||||
|
||||
@Property
|
||||
@@ -77,10 +77,4 @@ public class WebProductInfo {
|
||||
return CommonUtils.notEmpty(product.getProperty("versionUpdateURL"));
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getProductPurchaseURL() {
|
||||
IProduct product = Platform.getProduct();
|
||||
return CommonUtils.notEmpty(product.getProperty("productPurchaseURL"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+66
-11
@@ -16,11 +16,11 @@
|
||||
*/
|
||||
package io.cloudbeaver.model;
|
||||
|
||||
import io.cloudbeaver.registry.WebServerFeatureRegistry;
|
||||
import io.cloudbeaver.model.config.PasswordPolicyConfiguration;
|
||||
import io.cloudbeaver.registry.WebServiceDescriptor;
|
||||
import io.cloudbeaver.registry.WebServiceRegistry;
|
||||
import io.cloudbeaver.server.WebApplication;
|
||||
import org.jkiss.code.NotNull;
|
||||
import io.cloudbeaver.server.CBApplication;
|
||||
import io.cloudbeaver.server.CBPlatform;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.model.meta.Property;
|
||||
import org.jkiss.dbeaver.model.navigator.DBNBrowseSettings;
|
||||
@@ -39,9 +39,9 @@ import java.util.Map;
|
||||
*/
|
||||
public class WebServerConfig {
|
||||
|
||||
private final WebApplication application;
|
||||
private final CBApplication application;
|
||||
|
||||
public WebServerConfig(@NotNull WebApplication application) {
|
||||
public WebServerConfig(CBApplication application) {
|
||||
this.application = application;
|
||||
}
|
||||
|
||||
@@ -60,6 +60,27 @@ public class WebServerConfig {
|
||||
return DBWorkbench.getPlatform().getWorkspace().getWorkspaceId();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getServerURL() {
|
||||
return CommonUtils.notEmpty(application.getServerConfiguration().getServerURL());
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getRootURI() {
|
||||
return CommonUtils.notEmpty(application.getServerConfiguration().getRootURI());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Property
|
||||
public String getHostName() {
|
||||
return getContainerId();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getContainerId() {
|
||||
return CommonUtils.notEmpty(application.getContainerId());
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isAnonymousAccessEnabled() {
|
||||
return application.getAppConfiguration().isAnonymousAccessEnabled();
|
||||
@@ -70,6 +91,16 @@ public class WebServerConfig {
|
||||
return application.getAppConfiguration().isSupportsCustomConnections();
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isSupportsConnectionBrowser() {
|
||||
return application.getAppConfiguration().isSupportsConnectionBrowser();
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isSupportsWorkspaces() {
|
||||
return application.getAppConfiguration().isSupportsUserWorkspaces();
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isPublicCredentialsSaveEnabled() {
|
||||
return application.getAppConfiguration().isPublicCredentialsSaveEnabled();
|
||||
@@ -105,14 +136,24 @@ public class WebServerConfig {
|
||||
return application.getServerConfiguration().isDevelMode();
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isRedirectOnFederatedAuth() {
|
||||
return application.getAppConfiguration().isRedirectOnFederatedAuth();
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isResourceManagerEnabled() {
|
||||
return application.getAppConfiguration().isResourceManagerEnabled();
|
||||
}
|
||||
|
||||
@Property
|
||||
public boolean isSecretManagerEnabled() {
|
||||
return application.getAppConfiguration().isSecretManagerEnabled();
|
||||
public long getSessionExpireTime() {
|
||||
return application.getServerConfiguration().getMaxSessionIdleTime();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getLocalHostAddress() {
|
||||
return application.getLocalHostAddress();
|
||||
}
|
||||
|
||||
@Property
|
||||
@@ -127,9 +168,8 @@ public class WebServerConfig {
|
||||
}
|
||||
|
||||
@Property
|
||||
@NotNull
|
||||
public String[] getServerFeatures() {
|
||||
return WebServerFeatureRegistry.getInstance().getServerFeatures();
|
||||
public String[] getEnabledAuthProviders() {
|
||||
return application.getAppConfiguration().getEnabledAuthProviders();
|
||||
}
|
||||
|
||||
@Property
|
||||
@@ -153,7 +193,7 @@ public class WebServerConfig {
|
||||
|
||||
@Property
|
||||
public Map<String, Object> getProductConfiguration() {
|
||||
return application.getProductConfiguration();
|
||||
return CBPlatform.getInstance().getApplication().getProductConfiguration();
|
||||
}
|
||||
|
||||
@Property
|
||||
@@ -180,4 +220,19 @@ public class WebServerConfig {
|
||||
public Boolean isDistributed() {
|
||||
return application.isDistributed();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDefaultAuthRole() {
|
||||
return application.getDefaultAuthRole();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getDefaultUserTeam() {
|
||||
return application.getAppConfiguration().getDefaultUserTeam();
|
||||
}
|
||||
|
||||
@Property
|
||||
public PasswordPolicyConfiguration getPasswordPolicyConfiguration() {
|
||||
return application.getSecurityManagerConfiguration().getPasswordPolicyConfiguration();
|
||||
}
|
||||
}
|
||||
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2025 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.model;
|
||||
|
||||
import org.jkiss.code.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record WebTransactionLogInfo(@NotNull List<WebTransactionLogItemInfo> transactionLogInfos, int count) {
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2025 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.model;
|
||||
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
|
||||
public record WebTransactionLogItemInfo(
|
||||
@Nullable Integer id,
|
||||
@NotNull String time,
|
||||
@NotNull String type,
|
||||
@NotNull String queryString,
|
||||
long durationMs,
|
||||
long rows,
|
||||
String result
|
||||
) {
|
||||
}
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* 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.model.app;
|
||||
|
||||
import org.jkiss.code.Nullable;
|
||||
|
||||
/**
|
||||
* Web server configuration.
|
||||
* Contains only server configuration properties.
|
||||
*/
|
||||
public interface WebServerConfiguration extends ServletServerConfiguration {
|
||||
@Nullable
|
||||
String getServerName();
|
||||
}
|
||||
+10
-13
@@ -14,17 +14,16 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.cloudbeaver.service.auth.model.user;
|
||||
package io.cloudbeaver.model.user;
|
||||
|
||||
import io.cloudbeaver.WebServiceUtils;
|
||||
import io.cloudbeaver.auth.SMAuthProviderFederated;
|
||||
import io.cloudbeaver.auth.provisioning.SMProvisioner;
|
||||
import io.cloudbeaver.model.app.ServletAuthConfiguration;
|
||||
import io.cloudbeaver.model.config.CBAppConfig;
|
||||
import io.cloudbeaver.registry.WebAuthProviderConfiguration;
|
||||
import io.cloudbeaver.registry.WebAuthProviderDescriptor;
|
||||
import io.cloudbeaver.server.CBApplication;
|
||||
import io.cloudbeaver.server.WebAppUtils;
|
||||
import org.jkiss.code.NotNull;
|
||||
import io.cloudbeaver.server.CBPlatform;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.security.SMAuthCredentialsProfile;
|
||||
import org.jkiss.dbeaver.model.security.SMAuthProviderCustomConfiguration;
|
||||
@@ -38,15 +37,17 @@ import java.util.List;
|
||||
public class WebAuthProviderInfo {
|
||||
|
||||
private static final Log log = Log.getLog(WebAuthProviderInfo.class);
|
||||
private static final SMAuthProviderCustomConfiguration TEMPLATE_CONFIG = new SMAuthProviderCustomConfiguration("{configuration_id}");
|
||||
|
||||
@NotNull
|
||||
private final WebAuthProviderDescriptor descriptor;
|
||||
|
||||
public WebAuthProviderInfo(@NotNull WebAuthProviderDescriptor descriptor) {
|
||||
public WebAuthProviderInfo(WebAuthProviderDescriptor descriptor) {
|
||||
this.descriptor = descriptor;
|
||||
}
|
||||
|
||||
WebAuthProviderDescriptor getDescriptor() {
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return descriptor.getId();
|
||||
}
|
||||
@@ -64,8 +65,8 @@ public class WebAuthProviderInfo {
|
||||
}
|
||||
|
||||
public boolean isDefaultProvider() {
|
||||
if (WebAppUtils.getWebApplication().getAppConfiguration() instanceof ServletAuthConfiguration authConfiguration) {
|
||||
return descriptor.getId().equals(authConfiguration.getDefaultAuthProvider());
|
||||
if (CBPlatform.getInstance().getApplication().getAppConfiguration() instanceof CBAppConfig cbAppConfig) {
|
||||
return descriptor.getId().equals(cbAppConfig.getDefaultAuthProvider());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -124,10 +125,6 @@ public class WebAuthProviderInfo {
|
||||
return rf == null ? new String[0] : rf;
|
||||
}
|
||||
|
||||
public WebAuthProviderConfiguration getTemplateConfiguration() {
|
||||
return new WebAuthProviderConfiguration(descriptor, TEMPLATE_CONFIG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getLabel();
|
||||
+5
-14
@@ -19,21 +19,20 @@ package io.cloudbeaver.server;
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.model.session.BaseWebSession;
|
||||
import io.cloudbeaver.model.session.WebHeadlessSession;
|
||||
import io.cloudbeaver.model.session.WebHttpRequestInfo;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.Session;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface WebAppSessionManager {
|
||||
public interface AppWebSessionManager {
|
||||
BaseWebSession closeSession(@NotNull HttpServletRequest request);
|
||||
|
||||
BaseWebSession closeSession(@NotNull String sessionId);
|
||||
|
||||
@NotNull
|
||||
WebSession getWebSession(
|
||||
@NotNull HttpServletRequest request,
|
||||
@@ -57,17 +56,9 @@ public interface WebAppSessionManager {
|
||||
|
||||
Collection<BaseWebSession> getAllActiveSessions();
|
||||
|
||||
WebSession getOrRestoreWebSession(WebHttpRequestInfo httpRequest);
|
||||
WebSession getOrRestoreSession(Request httpRequest);
|
||||
|
||||
WebHeadlessSession getHeadlessSession(
|
||||
@Nullable String smAccessToken,
|
||||
@NotNull WebHttpRequestInfo requestInfo,
|
||||
boolean create
|
||||
) throws DBException;
|
||||
WebHeadlessSession getHeadlessSession(Request request, Session session, boolean create) throws DBException;
|
||||
|
||||
boolean touchSession(HttpServletRequest request, HttpServletResponse response) throws DBWebException;
|
||||
|
||||
default void expireIdleSessions() {
|
||||
|
||||
}
|
||||
}
|
||||
+14
-28
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2025 DBeaver Corp and others
|
||||
* 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.
|
||||
@@ -18,22 +18,18 @@ package io.cloudbeaver.server;
|
||||
|
||||
import io.cloudbeaver.WebServiceUtils;
|
||||
import io.cloudbeaver.auth.NoAuthCredentialsProvider;
|
||||
import io.cloudbeaver.model.CBWebServerConfig;
|
||||
import io.cloudbeaver.model.WebServerConfig;
|
||||
import io.cloudbeaver.model.app.BaseServletApplication;
|
||||
import io.cloudbeaver.model.app.ServletAuthApplication;
|
||||
import io.cloudbeaver.model.app.ServletAuthConfiguration;
|
||||
import io.cloudbeaver.model.app.BaseWebApplication;
|
||||
import io.cloudbeaver.model.app.WebAuthApplication;
|
||||
import io.cloudbeaver.model.app.WebAuthConfiguration;
|
||||
import io.cloudbeaver.model.config.CBAppConfig;
|
||||
import io.cloudbeaver.model.config.CBServerConfig;
|
||||
import io.cloudbeaver.model.config.SMControllerConfiguration;
|
||||
import io.cloudbeaver.registry.WebDriverRegistry;
|
||||
import io.cloudbeaver.registry.WebServiceRegistry;
|
||||
import io.cloudbeaver.server.jetty.CBJettyServer;
|
||||
import io.cloudbeaver.service.ConnectionController;
|
||||
import io.cloudbeaver.service.ConnectionControllerCE;
|
||||
import io.cloudbeaver.service.DBWServiceInitializer;
|
||||
import io.cloudbeaver.service.DBWServiceServerConfigurator;
|
||||
import io.cloudbeaver.service.session.CBSessionManager;
|
||||
import io.cloudbeaver.service.session.WebSessionManager;
|
||||
import io.cloudbeaver.utils.WebDataSourceUtils;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.osgi.service.datalocation.Location;
|
||||
@@ -78,7 +74,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
* This class controls all aspects of the application's execution
|
||||
*/
|
||||
public abstract class CBApplication<T extends CBServerConfig> extends
|
||||
BaseServletApplication implements ServletAuthApplication, WebApplication {
|
||||
BaseWebApplication implements WebAuthApplication, GQLApplicationAdapter {
|
||||
|
||||
private static final Log log = Log.getLog(CBApplication.class);
|
||||
|
||||
@@ -109,7 +105,7 @@ public abstract class CBApplication<T extends CBServerConfig> extends
|
||||
|
||||
protected final WSEventController eventController = new WSEventController();
|
||||
|
||||
private CBSessionManager sessionManager;
|
||||
private WebSessionManager sessionManager;
|
||||
|
||||
private final Map<String, String> initActions = new ConcurrentHashMap<>();
|
||||
|
||||
@@ -179,7 +175,7 @@ public abstract class CBApplication<T extends CBServerConfig> extends
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletAuthConfiguration getAuthConfiguration() {
|
||||
public WebAuthConfiguration getAuthConfiguration() {
|
||||
return getAppConfiguration();
|
||||
}
|
||||
|
||||
@@ -202,6 +198,7 @@ public abstract class CBApplication<T extends CBServerConfig> extends
|
||||
|
||||
@Override
|
||||
protected void startServer() {
|
||||
CBPlatform.setApplication(this);
|
||||
try {
|
||||
if (!loadServerConfiguration()) {
|
||||
return;
|
||||
@@ -663,15 +660,15 @@ public abstract class CBApplication<T extends CBServerConfig> extends
|
||||
return null;
|
||||
}
|
||||
|
||||
public CBSessionManager getSessionManager() {
|
||||
public WebSessionManager getSessionManager() {
|
||||
if (sessionManager == null) {
|
||||
sessionManager = createSessionManager();
|
||||
}
|
||||
return sessionManager;
|
||||
}
|
||||
|
||||
protected CBSessionManager createSessionManager() {
|
||||
return new CBSessionManager(this);
|
||||
protected WebSessionManager createSessionManager() {
|
||||
return new WebSessionManager(this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -712,7 +709,7 @@ public abstract class CBApplication<T extends CBServerConfig> extends
|
||||
|
||||
@Override
|
||||
public Class<? extends DBPPlatformUI> getPlatformUIClass() {
|
||||
return ServletPlatformUI.class;
|
||||
return CBPlatformUI.class;
|
||||
}
|
||||
|
||||
public void saveProductConfiguration(
|
||||
@@ -736,10 +733,9 @@ public abstract class CBApplication<T extends CBServerConfig> extends
|
||||
public abstract CBServerConfigurationController<T> getServerConfigurationController();
|
||||
|
||||
private void refreshDisabledDriversConfig() {
|
||||
getDriverRegistry().refreshApplicableDrivers();
|
||||
CBAppConfig config = getAppConfiguration();
|
||||
Set<String> disabledDrivers = new LinkedHashSet<>(Arrays.asList(config.getDisabledDrivers()));
|
||||
for (DBPDriver driver : getDriverRegistry().getApplicableDrivers()) {
|
||||
for (DBPDriver driver : CBPlatform.getInstance().getApplicableDrivers()) {
|
||||
if (!driver.isEmbedded() || config.isDriverForceEnabled(driver.getFullId())) {
|
||||
continue;
|
||||
}
|
||||
@@ -769,14 +765,4 @@ public abstract class CBApplication<T extends CBServerConfig> extends
|
||||
public Map<String, String> getInitActions() {
|
||||
return Map.copyOf(initActions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebServerConfig getWebServerConfig() {
|
||||
return new CBWebServerConfig(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionController getConnectionController() {
|
||||
return new ConnectionControllerCE();
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -17,8 +17,6 @@
|
||||
package io.cloudbeaver.server;
|
||||
|
||||
import io.cloudbeaver.auth.NoAuthCredentialsProvider;
|
||||
import io.cloudbeaver.model.CBWebServerConfig;
|
||||
import io.cloudbeaver.model.WebServerConfig;
|
||||
import io.cloudbeaver.model.config.CBServerConfig;
|
||||
import io.cloudbeaver.model.rm.local.LocalResourceController;
|
||||
import io.cloudbeaver.service.security.CBEmbeddedSecurityController;
|
||||
@@ -116,4 +114,5 @@ public class CBApplicationCE extends CBApplication<CBServerConfig> {
|
||||
embeddedSecurityController.finishConfiguration(adminName, adminPassword, authInfoList);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* 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.server;
|
||||
|
||||
import io.cloudbeaver.auth.NoAuthCredentialsProvider;
|
||||
import io.cloudbeaver.server.jobs.SessionStateJob;
|
||||
import io.cloudbeaver.server.jobs.WebDataSourceMonitorJob;
|
||||
import io.cloudbeaver.server.jobs.WebSessionMonitorJob;
|
||||
import io.cloudbeaver.service.session.WebSessionManager;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.DBFileController;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDataSourceProviderDescriptor;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDriver;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDriverLibrary;
|
||||
import org.jkiss.dbeaver.model.preferences.DBPPreferenceStore;
|
||||
import org.jkiss.dbeaver.model.runtime.AbstractJob;
|
||||
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
|
||||
import org.jkiss.dbeaver.registry.DataSourceProviderRegistry;
|
||||
import org.jkiss.dbeaver.runtime.DBWorkbench;
|
||||
import org.jkiss.utils.IOUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* CBPlatform
|
||||
*/
|
||||
public class CBPlatform extends BaseGQLPlatform {
|
||||
|
||||
// The plug-in ID
|
||||
public static final String PLUGIN_ID = "io.cloudbeaver.server"; //$NON-NLS-1$
|
||||
|
||||
private static final Log log = Log.getLog(CBPlatform.class);
|
||||
public static final String TEMP_FILE_FOLDER = "temp-sql-upload-files";
|
||||
public static final String TEMP_FILE_IMPORT_FOLDER = "temp-import-files";
|
||||
|
||||
@Nullable
|
||||
private static GQLApplicationAdapter application = null;
|
||||
|
||||
private WebServerPreferenceStore preferenceStore;
|
||||
protected final List<DBPDriver> applicableDrivers = new ArrayList<>();
|
||||
|
||||
public static CBPlatform getInstance() {
|
||||
return (CBPlatform) DBWorkbench.getPlatform();
|
||||
}
|
||||
|
||||
protected CBPlatform() {
|
||||
}
|
||||
|
||||
public static void setApplication(@NotNull GQLApplicationAdapter application) {
|
||||
CBPlatform.application = application;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected synchronized void initialize() {
|
||||
long startTime = System.currentTimeMillis();
|
||||
log.info("Initialize web platform...: ");
|
||||
this.preferenceStore = new WebServerPreferenceStore(WebPlatformActivator.getInstance().getPreferences());
|
||||
super.initialize();
|
||||
refreshApplicableDrivers();
|
||||
|
||||
scheduleServerJobs();
|
||||
log.info("Web platform initialized (" + (System.currentTimeMillis() - startTime) + "ms)");
|
||||
}
|
||||
|
||||
protected void scheduleServerJobs() {
|
||||
if (getSessionManager() instanceof WebSessionManager webSessionManager) {
|
||||
new WebSessionMonitorJob(this, webSessionManager)
|
||||
.scheduleMonitor();
|
||||
|
||||
new SessionStateJob(this, webSessionManager)
|
||||
.scheduleMonitor();
|
||||
}
|
||||
|
||||
new WebDataSourceMonitorJob(this, getSessionManager())
|
||||
.scheduleMonitor();
|
||||
|
||||
new AbstractJob("Delete temp folder") {
|
||||
@Override
|
||||
protected IStatus run(DBRProgressMonitor monitor) {
|
||||
try {
|
||||
IOUtils.deleteDirectory(getTempFolder(monitor, TEMP_FILE_FOLDER));
|
||||
IOUtils.deleteDirectory(getTempFolder(monitor, TEMP_FILE_IMPORT_FOLDER));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
}.schedule();
|
||||
}
|
||||
|
||||
public synchronized void dispose() {
|
||||
long startTime = System.currentTimeMillis();
|
||||
log.debug("Shutdown Core...");
|
||||
|
||||
super.dispose();
|
||||
|
||||
CBPlatform.application = null;
|
||||
System.gc();
|
||||
log.debug("Shutdown completed in " + (System.currentTimeMillis() - startTime) + "ms");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public GQLApplicationAdapter getApplication() {
|
||||
return application;
|
||||
}
|
||||
|
||||
public List<DBPDriver> getApplicableDrivers() {
|
||||
return applicableDrivers;
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DBPPreferenceStore getPreferenceStore() {
|
||||
return preferenceStore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShuttingDown() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public AppWebSessionManager getSessionManager() {
|
||||
return application.getSessionManager();
|
||||
}
|
||||
|
||||
public void refreshApplicableDrivers() {
|
||||
this.applicableDrivers.clear();
|
||||
|
||||
for (DBPDataSourceProviderDescriptor dspd : DataSourceProviderRegistry.getInstance().getEnabledDataSourceProviders()) {
|
||||
for (DBPDriver driver : dspd.getEnabledDrivers()) {
|
||||
List<? extends DBPDriverLibrary> libraries = driver.getDriverLibraries();
|
||||
{
|
||||
if (!application.getDriverRegistry().isDriverEnabled(driver)) {
|
||||
continue;
|
||||
}
|
||||
boolean hasAllFiles = true, hasJars = false;
|
||||
for (DBPDriverLibrary lib : libraries) {
|
||||
if (!DBWorkbench.isDistributed() && !lib.isOptional() && lib.getType() != DBPDriverLibrary.FileType.license &&
|
||||
(lib.getLocalFile() == null || !Files.exists(lib.getLocalFile())))
|
||||
{
|
||||
hasAllFiles = false;
|
||||
log.error("\tDriver '" + driver.getId() + "' is missing library '" + lib.getDisplayName() + "'");
|
||||
} else {
|
||||
if (lib.getType() == DBPDriverLibrary.FileType.jar) {
|
||||
hasJars = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasAllFiles || hasJars) {
|
||||
applicableDrivers.add(driver);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
log.info("Available drivers: " + applicableDrivers.stream().map(DBPDriver::getFullName).collect(Collectors.joining(",")));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DBFileController createFileController() {
|
||||
return getApplication().createFileController(new NoAuthCredentialsProvider());
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user