Skip to content

Commit

Permalink
Merge branch 'devel' into CB-5377-do-not-show-null-as-driver-paramete…
Browse files Browse the repository at this point in the history
…r-value
  • Loading branch information
EvgeniaBzzz authored Aug 14, 2024
2 parents c3cca14 + 95046f0 commit fd65208
Show file tree
Hide file tree
Showing 73 changed files with 740 additions and 270 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public class DBWebException extends DBException implements GraphQLError {

public static final String ERROR_CODE_SESSION_EXPIRED = "sessionExpired";
public static final String ERROR_CODE_ACCESS_DENIED = "accessDenied";
public static final String ERROR_CODE_SERVER_NOT_INITIALIZED = "serverNotInitialized";
public static final String ERROR_CODE_LICENSE_DENIED = "licenseRequired";
public static final String ERROR_CODE_IDENT_REQUIRED = "identRequired";
public static final String ERROR_CODE_AUTH_REQUIRED = "authRequired";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@
public interface WebApplication extends DBPApplication {
boolean isConfigurationMode();

default boolean isInitializationMode() {
return false;
}

WebAppConfiguration getAppConfiguration();

WebServerConfiguration getServerConfiguration();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,6 @@ public void deleteResource(@NotNull String projectId, @NotNull String resourcePa
if (log.isDebugEnabled()) {
log.debug("Removing resource from '" + resourcePath + "' in project '" + projectId + "'" + (recursive ? " recursive" : ""));
}
validateResourcePath(resourcePath);
Path targetPath = getTargetPath(projectId, resourcePath);
doFileWriteOperation(projectId, targetPath, () -> {
if (!Files.exists(targetPath)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ public static void updateHandlerConfig(DBWHandlerConfiguration handlerConfig, We
private static void setSecureProperties(DBWHandlerConfiguration handlerConfig, WebNetworkHandlerConfigInput cfgInput, boolean ignoreNulls) {
var secureProperties = cfgInput.getSecureProperties();
if (secureProperties == null) {
if (!handlerConfig.isSavePassword()) {
// clear all secure properties from handler config
handlerConfig.setSecureProperties(Map.of());
}
return;
}
for (var pr : secureProperties.entrySet()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,13 @@ type ServerConfig {

licenseRequired: Boolean!
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!
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* 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;

/**
* "Access denied" exception
*/
public class DBWebExceptionServerNotInitialized extends DBWebException {

public DBWebExceptionServerNotInitialized(String message) {
super(message, ERROR_CODE_SERVER_NOT_INITIALIZED);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,6 @@

boolean authRequired() default true;

boolean initializationRequired() default true;

}
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ public boolean isLicenseValid() {
return application.isLicenseValid();
}

@Property
public String getLicenseStatus() {
return application.getLicenseStatus();
}

@Property
public boolean isConfigurationMode() {
return application.isConfigurationMode();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
import java.security.Policy;
import java.security.ProtectionDomain;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
* This class controls all aspects of the application's execution
Expand Down Expand Up @@ -108,6 +109,8 @@ public static CBApplication getInstance() {

private WebSessionManager sessionManager;

private final Map<String, String> initActions = new ConcurrentHashMap<>();

public CBApplication() {
this.homeDirectory = new File(initHomeFolder());
}
Expand Down Expand Up @@ -552,7 +555,8 @@ public synchronized void finishConfiguration(
reloadConfiguration(credentialsProvider);
}

public synchronized void reloadConfiguration(@Nullable SMCredentialsProvider credentialsProvider) throws DBException {
public synchronized void reloadConfiguration(@Nullable SMCredentialsProvider credentialsProvider)
throws DBException {
// Re-load runtime configuration
try {
Path runtimeAppConfigPath = getServerConfigurationController().getRuntimeAppConfigPath();
Expand Down Expand Up @@ -717,7 +721,10 @@ public Class<? extends DBPPlatformUI> getPlatformUIClass() {
return CBPlatformUI.class;
}

public void saveProductConfiguration(SMCredentialsProvider credentialsProvider, Map<String, Object> productConfiguration) throws DBException {
public void saveProductConfiguration(
SMCredentialsProvider credentialsProvider,
Map<String, Object> productConfiguration
) throws DBException {
getServerConfigurationController().saveProductConfiguration(productConfiguration);
flushConfiguration(credentialsProvider);
sendConfigChangedEvent(credentialsProvider);
Expand Down Expand Up @@ -750,4 +757,21 @@ private void refreshDisabledDriversConfig() {
public boolean isEnvironmentVariablesAccessible() {
return getAppConfiguration().isSystemVariablesResolvingEnabled();
}

@Override
public boolean isInitializationMode() {
return !initActions.isEmpty();
}

public void addInitAction(@NotNull String actionId, @NotNull String description) {
initActions.put(actionId, description);
}

public void removeInitAction(@NotNull String actionId) {
initActions.remove(actionId);
}

public Map<String, String> getInitActions() {
return Map.copyOf(initActions);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -330,15 +330,15 @@ protected GsonBuilder getGsonBuilder() {
.registerTypeAdapter(PasswordPolicyConfiguration.class, smPasswordPoliceConfigCreator);
}

protected void saveRuntimeConfig(SMCredentialsProvider credentialsProvider) throws DBException {
public synchronized void saveRuntimeConfig(SMCredentialsProvider credentialsProvider) throws DBException {
saveRuntimeConfig(
serverConfiguration,
appConfiguration,
credentialsProvider
);
}

protected void saveRuntimeConfig(
protected synchronized void saveRuntimeConfig(
@NotNull CBServerConfig serverConfig,
@NotNull CBAppConfig appConfig,
SMCredentialsProvider credentialsProvider
Expand All @@ -350,7 +350,7 @@ protected void saveRuntimeConfig(
writeRuntimeConfig(getRuntimeAppConfigPath(), configurationProperties);
}

private void writeRuntimeConfig(Path runtimeConfigPath, Map<String, Object> configurationProperties)
private synchronized void writeRuntimeConfig(Path runtimeConfigPath, Map<String, Object> configurationProperties)
throws DBException {
if (Files.exists(runtimeConfigPath)) {
ContentUtils.makeFileBackup(runtimeConfigPath);
Expand All @@ -370,7 +370,8 @@ private void writeRuntimeConfig(Path runtimeConfigPath, Map<String, Object> conf
}


public void updateServerUrl(@NotNull SMCredentialsProvider credentialsProvider, @Nullable String newPublicUrl) throws DBException {
public synchronized void updateServerUrl(@NotNull SMCredentialsProvider credentialsProvider,
@Nullable String newPublicUrl) throws DBException {
getServerConfiguration().setServerURL(newPublicUrl);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
*/
package io.cloudbeaver.service;

import io.cloudbeaver.server.CBApplication;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.app.DBPApplication;

/**
* Web service implementation
*/
public interface DBWServiceInitializer extends DBWServiceBinding {

void initializeService(DBPApplication application) throws DBException;
void initializeService(CBApplication<?> application) throws DBException;

}
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,12 @@ private void checkServicePermissions(Method method, WebActionSet actionSet) thro
}

private void checkActionPermissions(@NotNull Method method, @NotNull WebAction webAction) throws DBWebException {
CBApplication<?> application = CBApplication.getInstance();
if (application.isInitializationMode() && webAction.initializationRequired()) {
String message = "Server initialization in progress: "
+ String.join(",", application.getInitActions().values()) + ".\nDo not restart the server.";
throw new DBWebExceptionServerNotInitialized(message);
}
String[] reqPermissions = webAction.requirePermissions();
if (reqPermissions.length == 0 && !webAction.authRequired()) {
return;
Expand All @@ -258,7 +264,6 @@ private void checkActionPermissions(@NotNull Method method, @NotNull WebAction w
if (session == null) {
throw new DBWebExceptionAccessDenied("No open session - anonymous access restricted");
}
CBApplication<?> application = CBApplication.getInstance();
if (!application.isConfigurationMode()) {
if (webAction.authRequired() && !session.isAuthorizedInSecurityManager()) {
log.debug("Anonymous access to " + method.getName() + " restricted");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
*/
public interface DBWServiceCore extends DBWService {

@WebAction(authRequired = false)
@WebAction(authRequired = false, initializationRequired = false)
WebServerConfig getServerConfig() throws DBWebException;

@WebAction(authRequired = false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Require-Bundle: org.jkiss.dbeaver.model;visibility:=reexport,
org.jkiss.dbeaver.model.sql,
org.jkiss.dbeaver.model.sql.jdbc,
org.jkiss.dbeaver.registry;visibility:=reexport,
org.jkiss.bundle.apache.dbcp,
org.jkiss.bundle.apache.dbcp;visibility:=reexport,
io.cloudbeaver.model
Export-Package: io.cloudbeaver.auth.provider.local,
io.cloudbeaver.auth.provider.rp,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
*/
package io.cloudbeaver.service.security;

import io.cloudbeaver.auth.NoAuthCredentialsProvider;
import io.cloudbeaver.model.app.WebAuthApplication;
import io.cloudbeaver.service.security.db.CBDatabase;
import io.cloudbeaver.service.security.db.WebDatabaseConfig;
import io.cloudbeaver.service.security.internal.ClearAuthAttemptInfoJob;
import org.jkiss.code.NotNull;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.auth.SMCredentialsProvider;

Expand All @@ -36,7 +38,7 @@ public static CBDatabase getDbInstance() {
/**
* Create new security controller instance with custom configuration
*/
public CBEmbeddedSecurityController createSecurityService(
public CBEmbeddedSecurityController<T> createSecurityService(
T application,
WebDatabaseConfig databaseConfig,
SMCredentialsProvider credentialsProvider,
Expand All @@ -45,32 +47,53 @@ public CBEmbeddedSecurityController createSecurityService(
if (DB_INSTANCE == null) {
synchronized (EmbeddedSecurityControllerFactory.class) {
if (DB_INSTANCE == null) {
DB_INSTANCE = new CBDatabase(application, databaseConfig);
DB_INSTANCE = createAndInitDatabaseInstance(
application,
databaseConfig,
smConfig
);
}
}
var securityController = createEmbeddedSecurityController(
application, DB_INSTANCE, credentialsProvider, smConfig
);
//FIXME circular dependency
DB_INSTANCE.setAdminSecurityController(securityController);
DB_INSTANCE.initialize();

if (application.isLicenseRequired()) {
// delete expired auth info job in enterprise products
new ClearAuthAttemptInfoJob(securityController).schedule();
new ClearAuthAttemptInfoJob(createEmbeddedSecurityController(
application, DB_INSTANCE, new NoAuthCredentialsProvider(), smConfig
)).schedule();
}
return securityController;
}
return createEmbeddedSecurityController(
application, DB_INSTANCE, credentialsProvider, smConfig
);
}

protected CBEmbeddedSecurityController createEmbeddedSecurityController(
protected @NotNull CBDatabase createAndInitDatabaseInstance(
@NotNull T application,
@NotNull WebDatabaseConfig databaseConfig,
@NotNull SMControllerConfiguration smConfig
) throws DBException {
var database = new CBDatabase(application, databaseConfig);
var securityController = createEmbeddedSecurityController(
application, database, new NoAuthCredentialsProvider(), smConfig
);
//FIXME circular dependency
database.setAdminSecurityController(securityController);
try {
database.initialize();
} catch (DBException e) {
database.shutdown();
throw e;
}

return database;
}

protected CBEmbeddedSecurityController<T> createEmbeddedSecurityController(
T application,
CBDatabase database,
SMCredentialsProvider credentialsProvider,
SMControllerConfiguration smConfig
) {
return new CBEmbeddedSecurityController(application, database, credentialsProvider, smConfig);
return new CBEmbeddedSecurityController<T>(application, database, credentialsProvider, smConfig);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ public void close() throws SQLException {
// Persistence


private void validateInstancePersistentState(Connection connection) throws IOException, SQLException, DBException {
protected void validateInstancePersistentState(Connection connection) throws IOException, SQLException, DBException {
try (JDBCTransaction txn = new JDBCTransaction(connection)) {
checkInstanceRecord(connection);
var defaultTeamId = application.getAppConfiguration().getDefaultUserTeam();
Expand Down Expand Up @@ -587,10 +587,24 @@ public SQLDialect getDialect() {
}

public static boolean isDefaultH2Configuration(WebDatabaseConfig databaseConfiguration) {
var v1DefaultUrl = "jdbc:h2:/opt/cloudbeaver/workspace/.data/" + V1_DB_NAME;
var v2DefaultUrl = "jdbc:h2:/opt/cloudbeaver/workspace/.data/" + V2_DB_NAME;
var workspace = WebAppUtils.getWebApplication().getWorkspaceDirectory();
var v1Path = workspace.resolve(".data").resolve(V1_DB_NAME);
var v2Path = workspace.resolve(".data").resolve(V2_DB_NAME);
var v1DefaultUrl = "jdbc:h2:" + v1Path;
var v2DefaultUrl = "jdbc:h2:" + v2Path;
return v1DefaultUrl.equals(databaseConfiguration.getUrl())
|| v2DefaultUrl.equals(databaseConfiguration.getUrl());
}

protected WebDatabaseConfig getDatabaseConfiguration() {
return databaseConfiguration;
}

protected WebApplication getApplication() {
return application;
}

protected SMAdminController getAdminSecurityController() {
return adminSecurityController;
}
}
Loading

0 comments on commit fd65208

Please sign in to comment.