Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/devel' into CB-4113-managing-fil…
Browse files Browse the repository at this point in the history
…es-on-external-file-systems
  • Loading branch information
yagudin10 committed Oct 25, 2023
2 parents 9a4655c + 72b3838 commit 7de4a45
Show file tree
Hide file tree
Showing 15 changed files with 120 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

package io.cloudbeaver.model.session;

import io.cloudbeaver.DBWConstants;
import io.cloudbeaver.DBWUserIdentity;
import io.cloudbeaver.DBWebException;
import io.cloudbeaver.auth.SMAuthProviderExternal;
Expand All @@ -38,7 +37,6 @@

import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

Expand Down Expand Up @@ -114,15 +112,6 @@ private List<WebAuthInfo> finishWebSessionAuthorization(SMAuthInfo authInfo) thr
SMAuthProviderExternal<?> authProviderExternal = authProviderInstance instanceof SMAuthProviderExternal<?> ?
(SMAuthProviderExternal<?>) authProviderInstance : null;

boolean providerDisabled = !isProviderEnabled(providerId);
if (configMode || webSession.hasPermission(DBWConstants.PERMISSION_ADMIN)) {
// 1. Admin can authorize in any providers
// 2. When it authorizes in non-local provider for the first time we force linkUser flag
if (providerDisabled && webSession.getUser() != null) {
linkWithActiveUser = true;
}
}

SMSession authSession;

if (authProviderExternal != null && !configMode && !alreadyLoggedIn) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package io.cloudbeaver.server;

import org.jkiss.dbeaver.model.auth.AuthInfo;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.InstanceCreator;
Expand All @@ -24,7 +25,6 @@
import io.cloudbeaver.model.app.BaseWebApplication;
import io.cloudbeaver.model.app.WebAuthApplication;
import io.cloudbeaver.model.app.WebAuthConfiguration;
import io.cloudbeaver.model.session.WebAuthInfo;
import io.cloudbeaver.registry.WebDriverRegistry;
import io.cloudbeaver.registry.WebServiceRegistry;
import io.cloudbeaver.server.jetty.CBJettyServer;
Expand Down Expand Up @@ -825,7 +825,7 @@ public synchronized void finishConfiguration(
@NotNull String newServerURL,
@NotNull String adminName,
@Nullable String adminPassword,
@NotNull List<WebAuthInfo> authInfoList,
@NotNull List<AuthInfo> authInfoList,
long sessionExpireTime,
@NotNull CBAppConfig appConfig,
@Nullable SMCredentialsProvider credentialsProvider
Expand Down Expand Up @@ -886,7 +886,7 @@ protected Map<String, Object> readRuntimeConfigurationProperties() throws DBExce
protected abstract void finishSecurityServiceConfiguration(
@NotNull String adminName,
@Nullable String adminPassword,
@NotNull List<WebAuthInfo> authInfoList
@NotNull List<AuthInfo> authInfoList
) throws DBException;

public synchronized void flushConfiguration(SMCredentialsProvider credentialsProvider) throws DBException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
*/
package io.cloudbeaver.server;

import org.jkiss.dbeaver.model.auth.AuthInfo;
import io.cloudbeaver.auth.NoAuthCredentialsProvider;
import io.cloudbeaver.model.rm.local.LocalResourceController;
import io.cloudbeaver.model.session.WebAuthInfo;
import io.cloudbeaver.service.security.CBEmbeddedSecurityController;
import io.cloudbeaver.service.security.EmbeddedSecurityControllerFactory;
import org.jkiss.code.NotNull;
Expand All @@ -31,7 +31,6 @@
import org.jkiss.dbeaver.model.rm.RMController;
import org.jkiss.dbeaver.model.security.SMAdminController;
import org.jkiss.dbeaver.model.security.SMController;
import org.jkiss.dbeaver.registry.BasePlatformImpl;
import org.jkiss.dbeaver.registry.LocalFileController;
import org.jkiss.dbeaver.runtime.DBWorkbench;

Expand Down Expand Up @@ -94,7 +93,7 @@ protected void shutdown() {
protected void finishSecurityServiceConfiguration(
@NotNull String adminName,
@Nullable String adminPassword,
@NotNull List<WebAuthInfo> authInfoList
@NotNull List<AuthInfo> authInfoList
) throws DBException {
if (securityController instanceof CBEmbeddedSecurityController) {
((CBEmbeddedSecurityController) securityController).finishConfiguration(adminName, adminPassword, authInfoList);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@
import org.jkiss.dbeaver.model.navigator.DBNDatabaseItem;
import org.jkiss.dbeaver.model.navigator.DBNNode;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.sql.SQLQuery;
import org.jkiss.dbeaver.model.sql.SQLSyntaxManager;
import org.jkiss.dbeaver.model.sql.SQLUtils;
import org.jkiss.dbeaver.model.sql.*;
import org.jkiss.dbeaver.model.sql.parser.SQLParserContext;
import org.jkiss.dbeaver.model.sql.parser.SQLRuleManager;
import org.jkiss.dbeaver.model.sql.parser.SQLScriptParser;
Expand Down Expand Up @@ -173,7 +171,7 @@ public WebSQLExecuteInfo processQuery(
long startTime = System.currentTimeMillis();
WebSQLExecuteInfo executeInfo = new WebSQLExecuteInfo();

DBSDataContainer dataContainer = new WebSQLQueryDataContainer(connection.getDataSource(), sql);
var dataContainer = new WebSQLQueryDataContainer(connection.getDataSource(), sql);

DBCExecutionContext context = getExecutionContext(dataContainer);

Expand All @@ -198,63 +196,69 @@ public WebSQLExecuteInfo processQuery(
ruleManager,
document);

SQLQuery sqlQuery = (SQLQuery) SQLScriptParser.extractActiveQuery(parserContext, 0, sql.length());

DBExecUtils.tryExecuteRecover(monitor, connection.getDataSource(), param -> {
try (DBCSession session = context.openSession(monitor, resolveQueryPurpose(dataFilter), "Execute SQL")) {
AbstractExecutionSource source = new AbstractExecutionSource(
dataContainer,
session.getExecutionContext(),
WebSQLProcessor.this,
sqlQuery);

try (DBCStatement dbStat = DBUtils.makeStatement(
source,
session,
DBCStatementType.SCRIPT,
sqlQuery,
webDataFilter.getOffset(),
webDataFilter.getLimit()))
{
SqlOutputLogReaderJob sqlOutputLogReaderJob = null;
if (readLogs) {
DBPDataSource dataSource = context.getDataSource();
DBCServerOutputReader dbcServerOutputReader = DBUtils.getAdapter(DBCServerOutputReader.class, dataSource);
if (dbcServerOutputReader == null) {
dbcServerOutputReader = new DefaultServerOutputReader();
SQLScriptElement element = SQLScriptParser.extractActiveQuery(parserContext, 0, sql.length());

if (element instanceof SQLControlCommand command) {
dataContainer.getScriptContext().executeControlCommand(command);
WebSQLQueryResults stats = new WebSQLQueryResults(webSession, dataFormat);
executeInfo.setResults(new WebSQLQueryResults[]{stats});
} else if (element instanceof SQLQuery sqlQuery) {
DBExecUtils.tryExecuteRecover(monitor, connection.getDataSource(), param -> {
try (DBCSession session = context.openSession(monitor, resolveQueryPurpose(dataFilter), "Execute SQL")) {
AbstractExecutionSource source = new AbstractExecutionSource(
dataContainer,
session.getExecutionContext(),
WebSQLProcessor.this,
sqlQuery);

try (DBCStatement dbStat = DBUtils.makeStatement(
source,
session,
DBCStatementType.SCRIPT,
sqlQuery,
webDataFilter.getOffset(),
webDataFilter.getLimit()))
{
SqlOutputLogReaderJob sqlOutputLogReaderJob = null;
if (readLogs) {
DBPDataSource dataSource = context.getDataSource();
DBCServerOutputReader dbcServerOutputReader = DBUtils.getAdapter(DBCServerOutputReader.class, dataSource);
if (dbcServerOutputReader == null) {
dbcServerOutputReader = new DefaultServerOutputReader();
}
sqlOutputLogReaderJob = new SqlOutputLogReaderJob(
webSession, context, dbStat, dbcServerOutputReader, contextInfo.getId());
sqlOutputLogReaderJob.schedule();
}
sqlOutputLogReaderJob = new SqlOutputLogReaderJob(
webSession, context, dbStat, dbcServerOutputReader, contextInfo.getId());
sqlOutputLogReaderJob.schedule();
}
// Set query timeout
int queryTimeout = (int) session.getDataSource().getContainer().getPreferenceStore()
.getDouble(WebSQLConstants.QUOTA_PROP_SQL_QUERY_TIMEOUT);
if (queryTimeout <= 0) {
queryTimeout = CommonUtils.toInt(
getWebSession().getApplication().getAppConfiguration()
.getResourceQuota(WebSQLConstants.QUOTA_PROP_SQL_QUERY_TIMEOUT));
}
if (queryTimeout > 0) {
try {
dbStat.setStatementTimeout(queryTimeout);
} catch (Throwable e) {
log.debug("Can't set statement timeout:" + e.getMessage());
// Set query timeout
int queryTimeout = (int) session.getDataSource().getContainer().getPreferenceStore()
.getDouble(WebSQLConstants.QUOTA_PROP_SQL_QUERY_TIMEOUT);
if (queryTimeout <= 0) {
queryTimeout = CommonUtils.toInt(
getWebSession().getApplication().getAppConfiguration()
.getResourceQuota(WebSQLConstants.QUOTA_PROP_SQL_QUERY_TIMEOUT));
}
if (queryTimeout > 0) {
try {
dbStat.setStatementTimeout(queryTimeout);
} catch (Throwable e) {
log.debug("Can't set statement timeout:" + e.getMessage());
}
}
}

boolean hasResultSet = dbStat.executeStatement();
boolean hasResultSet = dbStat.executeStatement();

// Wait SqlLogStateJob, if its starts
if (sqlOutputLogReaderJob != null) {
sqlOutputLogReaderJob.join();
// Wait SqlLogStateJob, if its starts
if (sqlOutputLogReaderJob != null) {
sqlOutputLogReaderJob.join();
}
fillQueryResults(contextInfo, dataContainer, dbStat, hasResultSet, executeInfo, webDataFilter, dataFilter, dataFormat);
} catch (DBException e) {
throw new InvocationTargetException(e);
}
fillQueryResults(contextInfo, dataContainer, dbStat, hasResultSet, executeInfo, webDataFilter, dataFilter, dataFormat);
} catch (DBException e) {
throw new InvocationTargetException(e);
}
}
});
});
}
} catch (DBException e) {
throw new DBWebException("Error executing query", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,9 @@ public DBCExecutionContext getExecutionContext() {
return DBUtils.getDefaultContext(dataSource, false);
}

@NotNull
public SQLScriptContext getScriptContext() {
return queryDataContainer.getScriptContext();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry;
import org.jkiss.dbeaver.model.app.DBPProject;
import org.jkiss.dbeaver.model.auth.AuthInfo;
import org.jkiss.dbeaver.model.navigator.DBNBrowseSettings;
import org.jkiss.dbeaver.model.preferences.DBPPropertyDescriptor;
import org.jkiss.dbeaver.model.security.*;
Expand Down Expand Up @@ -514,6 +515,7 @@ public boolean configureServer(WebSession webSession, Map<String, Object> params
adminName = curUser == null ? null : curUser.getUserId();
adminPassword = null;
}
List<AuthInfo> authInfos = new ArrayList<>();
List<WebAuthInfo> authInfoList = webSession.getAllAuthInfo();
if (CommonUtils.isEmpty(adminName)) {
// Try to get admin name from existing authentications (first one)
Expand All @@ -524,6 +526,11 @@ public boolean configureServer(WebSession webSession, Map<String, Object> params
if (CommonUtils.isEmpty(adminName)) {
adminName = CBConstants.DEFAULT_ADMIN_NAME;
}
for (WebAuthInfo webAuthInfo : authInfoList) {
authInfos.add(new AuthInfo(
webAuthInfo.getAuthProviderDescriptor().getId(),
webAuthInfo.getUserCredentials()));
}

// Patch configuration by services
for (DBWServiceServerConfigurator wsc : WebServiceRegistry.getInstance().getWebServices(DBWServiceServerConfigurator.class)) {
Expand All @@ -541,7 +548,7 @@ public boolean configureServer(WebSession webSession, Map<String, Object> params
serverURL,
adminName,
adminPassword,
authInfoList,
authInfos,
sessionExpireTime,
appConfig,
webSession
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ public WebAuthStatus authLogin(
if (CommonUtils.isEmpty(providerId)) {
throw new DBWebException("Missing auth provider parameter");
}
WebAuthProviderDescriptor authProviderDescriptor = WebAuthProviderRegistry.getInstance()
.getAuthProvider(providerId);
if (authProviderDescriptor.isTrusted()) {
throw new DBWebException(authProviderDescriptor.getLabel() + " not allowed for authorization via GQL API");
}
if (authParameters == null) {
authParameters = Map.of();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import io.cloudbeaver.model.app.WebAppConfiguration;
import io.cloudbeaver.model.app.WebAuthApplication;
import io.cloudbeaver.model.app.WebAuthConfiguration;
import io.cloudbeaver.model.session.WebAuthInfo;
import io.cloudbeaver.registry.WebAuthProviderDescriptor;
import io.cloudbeaver.registry.WebAuthProviderRegistry;
import io.cloudbeaver.registry.WebMetaParametersRegistry;
Expand Down Expand Up @@ -1242,6 +1241,9 @@ private String createSmSession(

@Override
public SMAuthInfo authenticateAnonymousUser(@NotNull String appSessionId, @NotNull Map<String, Object> sessionParameters, @NotNull SMSessionType sessionType) throws DBException {
if (!application.getAppConfiguration().isAnonymousAccessEnabled()) {
throw new SMException("Anonymous access restricted");
}
try (Connection dbCon = database.openConnection()) {
try (JDBCTransaction txn = new JDBCTransaction(dbCon)) {
var smSessionId = createSmSession(appSessionId, null, sessionParameters, sessionType, dbCon);
Expand Down Expand Up @@ -1277,6 +1279,9 @@ public SMAuthInfo authenticate(
@Nullable String authProviderConfigurationId,
@NotNull Map<String, Object> userCredentials
) throws DBException {
if (isProviderDisabled(authProviderId, authProviderConfigurationId)) {
throw new SMException("Unsupported authentication provider: " + authProviderId);
}
var authProgressMonitor = new LoggingProgressMonitor(log);
try (Connection dbCon = database.openConnection()) {
try (JDBCTransaction txn = new JDBCTransaction(dbCon)) {
Expand Down Expand Up @@ -2625,7 +2630,7 @@ public void shutdown() {
public void finishConfiguration(
@NotNull String adminName,
@Nullable String adminPassword,
@NotNull List<WebAuthInfo> authInfoList
@NotNull List<AuthInfo> authInfoList
) throws DBException {
database.finishConfiguration(adminName, adminPassword, authInfoList);
}
Expand Down Expand Up @@ -2727,9 +2732,17 @@ private String getUserIdOrNull() {
return activeUserCredentials.getUserId();
}

private boolean isProviderEnabled(@NotNull String providerId) {
private boolean isProviderDisabled(@NotNull String providerId, @Nullable String authConfigurationId) {
WebAuthConfiguration appConfiguration = application.getAuthConfiguration();
return appConfiguration.isAuthProviderEnabled(providerId);
if (!appConfiguration.isAuthProviderEnabled(providerId)) {
return true;
}
if (authConfigurationId != null) {
SMAuthProviderCustomConfiguration configuration =
appConfiguration.getAuthProviderConfiguration(authConfigurationId);
return configuration == null || configuration.isDisabled();
}
return false;
}

public void clearOldAuthAttemptInfo() throws DBException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import com.google.gson.GsonBuilder;
import io.cloudbeaver.auth.provider.local.LocalAuthProviderConstants;
import io.cloudbeaver.model.app.WebApplication;
import io.cloudbeaver.model.session.WebAuthInfo;
import io.cloudbeaver.registry.WebAuthProviderDescriptor;
import io.cloudbeaver.registry.WebAuthProviderRegistry;
import io.cloudbeaver.utils.WebAppUtils;
Expand All @@ -32,6 +31,7 @@
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.DBConstants;
import org.jkiss.dbeaver.model.auth.AuthInfo;
import org.jkiss.dbeaver.model.connection.DBPDriver;
import org.jkiss.dbeaver.model.impl.jdbc.JDBCUtils;
import org.jkiss.dbeaver.model.impl.jdbc.exec.JDBCTransaction;
Expand Down Expand Up @@ -246,7 +246,7 @@ protected PoolingDataSource<PoolableConnection> initConnectionPool(
public void finishConfiguration(
@NotNull String adminName,
@Nullable String adminPassword,
@NotNull List<WebAuthInfo> authInfoList
@NotNull List<AuthInfo> authInfoList
) throws DBException {
if (!application.isConfigurationMode()) {
throw new DBException("Database is already configured");
Expand All @@ -264,12 +264,11 @@ public void finishConfiguration(
createAdminUser(adminName, adminPassword);

// Associate all auth credentials with admin user
for (WebAuthInfo ai : authInfoList) {
for (AuthInfo ai : authInfoList) {
if (!ai.getAuthProvider().equals(LocalAuthProviderConstants.PROVIDER_ID)) {
WebAuthProviderDescriptor authProvider = ai.getAuthProviderDescriptor();
Map<String, Object> userCredentials = ai.getUserCredentials();
if (!CommonUtils.isEmpty(userCredentials)) {
adminSecurityController.setUserCredentials(adminName, authProvider.getId(), userCredentials);
adminSecurityController.setUserCredentials(adminName, ai.getAuthProvider(), userCredentials);
}
}
}
Expand Down
Loading

0 comments on commit 7de4a45

Please sign in to comment.