Merge pull request #924 from dbeaver/feature/CB-2128

CB-2128 refactor authentication interfaces
This commit is contained in:
Serge Rider
2022-06-28 15:42:24 +02:00
committed by GitHub
22 changed files with 319 additions and 223 deletions
@@ -14,7 +14,8 @@ Require-Bundle: org.jkiss.dbeaver.model;visibility:=reexport,
org.jkiss.bundle.graphql.java;visibility:=reexport,
org.jkiss.bundle.apache.dbcp,
com.google.gson;visibility:=reexport,
jakarta.servlet-api;bundle-version="4.0.0";visibility:=reexport
jakarta.servlet-api;bundle-version="4.0.0";visibility:=reexport,
org.eclipse.jetty.servlet
Export-Package: io.cloudbeaver,
io.cloudbeaver.auth,
io.cloudbeaver.auth.provider,
@@ -25,6 +26,7 @@ Export-Package: io.cloudbeaver,
io.cloudbeaver.model.rm.local,
io.cloudbeaver.model.session,
io.cloudbeaver.model.user,
io.cloudbeaver.registry,
io.cloudbeaver.server,
io.cloudbeaver.service,
io.cloudbeaver.service.sql,
@@ -0,0 +1,147 @@
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2022 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 com.google.gson.annotations.Expose;
import io.cloudbeaver.auth.provider.local.LocalAuthProviderConstants;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.model.security.SMAuthProviderCustomConfiguration;
import org.jkiss.dbeaver.registry.auth.AuthProviderDescriptor;
import org.jkiss.dbeaver.registry.auth.AuthProviderRegistry;
import org.jkiss.utils.ArrayUtils;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public abstract class BaseAuthWebAppConfiguration extends BaseWebAppConfiguration implements WebAuthConfiguration {
private String defaultAuthProvider;
private String[] enabledAuthProviders;
private final List<SMAuthProviderCustomConfiguration> authConfigurations;
// Legacy auth configs, left for backward compatibility
@Expose(serialize = false)
private final Map<String, SMAuthProviderCustomConfiguration> authConfiguration;
public BaseAuthWebAppConfiguration() {
super();
this.defaultAuthProvider = LocalAuthProviderConstants.PROVIDER_ID;
this.enabledAuthProviders = null;
this.authConfigurations = new ArrayList<>();
this.authConfiguration = new LinkedHashMap<>();
}
public BaseAuthWebAppConfiguration(BaseAuthWebAppConfiguration src) {
super(src);
this.defaultAuthProvider = src.defaultAuthProvider;
this.enabledAuthProviders = src.enabledAuthProviders;
this.authConfigurations = new ArrayList<>(src.authConfigurations);
this.authConfiguration = new LinkedHashMap<>(src.authConfiguration);
}
@Override
public String getDefaultAuthProvider() {
return defaultAuthProvider;
}
public void setDefaultAuthProvider(String defaultAuthProvider) {
this.defaultAuthProvider = defaultAuthProvider;
}
@Override
public String[] getEnabledAuthProviders() {
if (enabledAuthProviders == null) {
// No config - enable all providers (+backward compatibility)
return AuthProviderRegistry.getInstance().getAuthProviders()
.stream().map(AuthProviderDescriptor::getId).toArray(String[]::new);
}
return enabledAuthProviders;
}
public void setEnabledAuthProviders(String[] enabledAuthProviders) {
this.enabledAuthProviders = enabledAuthProviders;
}
@Override
public boolean isAuthProviderEnabled(String id) {
var authProviderDescriptor = AuthProviderRegistry.getInstance().getAuthProvider(id);
if (authProviderDescriptor == null) {
return false;
}
if (!ArrayUtils.contains(getEnabledAuthProviders(), id)) {
return false;
}
if (!ArrayUtils.isEmpty(authProviderDescriptor.getRequiredFeatures())) {
for (String rf : authProviderDescriptor.getRequiredFeatures()) {
if (!isFeatureEnabled(rf)) {
return false;
}
}
}
return true;
}
////////////////////////////////////////////
// Auth provider configs
@Override
public List<SMAuthProviderCustomConfiguration> getAuthCustomConfigurations() {
return authConfigurations;
}
@Override
@Nullable
public SMAuthProviderCustomConfiguration getAuthProviderConfiguration(@NotNull String id) {
synchronized (authConfigurations) {
return authConfigurations.stream().filter(c -> c.getId().equals(id)).findAny().orElse(null);
}
}
public void addAuthProviderConfiguration(@NotNull SMAuthProviderCustomConfiguration config) {
synchronized (authConfigurations) {
authConfigurations.removeIf(c -> c.getId().equals(config.getId()));
authConfigurations.add(config);
}
}
public void setAuthProvidersConfigurations(List<SMAuthProviderCustomConfiguration> authProviders) {
synchronized (authConfigurations) {
authConfigurations.clear();
authConfigurations.addAll(authProviders);
}
}
public boolean deleteAuthProviderConfiguration(@NotNull String id) {
synchronized (authConfigurations) {
return authConfigurations.removeIf(c -> c.getId().equals(id));
}
}
public void loadLegacyCustomConfigs() {
// Convert legacy map of configs into list
if (!authConfiguration.isEmpty()) {
for (Map.Entry<String, SMAuthProviderCustomConfiguration> entry : authConfiguration.entrySet()) {
entry.getValue().setId(entry.getKey());
authConfigurations.add(entry.getValue());
}
authConfiguration.clear();
}
}
}
@@ -16,7 +16,10 @@
*/
package io.cloudbeaver.model.app;
import io.cloudbeaver.DBWFeatureSet;
import io.cloudbeaver.registry.WebFeatureRegistry;
import org.jkiss.code.NotNull;
import org.jkiss.utils.ArrayUtils;
import java.util.Collections;
import java.util.LinkedHashMap;
@@ -30,6 +33,7 @@ public abstract class BaseWebAppConfiguration implements WebAppConfiguration {
protected String anonymousUserRole;
protected String defaultUserRole;
protected boolean resourceManagerEnabled;
protected String[] enabledFeatures;
public BaseWebAppConfiguration() {
this.plugins = new LinkedHashMap<>();
@@ -37,7 +41,7 @@ public abstract class BaseWebAppConfiguration implements WebAppConfiguration {
this.anonymousUserRole = DEFAULT_APP_ANONYMOUS_ROLE_NAME;
this.defaultUserRole = DEFAULT_APP_ANONYMOUS_ROLE_NAME;
this.resourceManagerEnabled = true;
this.enabledFeatures = null;
}
public BaseWebAppConfiguration(BaseWebAppConfiguration src) {
@@ -46,6 +50,7 @@ public abstract class BaseWebAppConfiguration implements WebAppConfiguration {
this.anonymousUserRole = src.anonymousUserRole;
this.defaultUserRole = src.defaultUserRole;
this.resourceManagerEnabled = src.resourceManagerEnabled;
this.enabledFeatures = src.enabledFeatures;
}
@Override
@@ -88,4 +93,25 @@ public abstract class BaseWebAppConfiguration implements WebAppConfiguration {
public boolean isResourceManagerEnabled() {
return resourceManagerEnabled;
}
public boolean isFeatureEnabled(String id) {
return ArrayUtils.contains(getEnabledFeatures(), id);
}
public boolean isFeaturesEnabled(String[] features) {
return ArrayUtils.containsAll(getEnabledFeatures(), features);
}
public String[] getEnabledFeatures() {
if (enabledFeatures == null) {
// No config - enable all features (+backward compatibility)
return WebFeatureRegistry.getInstance().getWebFeatures()
.stream().map(DBWFeatureSet::getId).toArray(String[]::new);
}
return enabledFeatures;
}
public void setEnabledFeatures(String[] enabledFeatures) {
this.enabledFeatures = enabledFeatures;
}
}
@@ -39,4 +39,6 @@ public interface WebAppConfiguration {
boolean isResourceManagerEnabled();
boolean isFeaturesEnabled(String[] requiredFeatures);
boolean isFeatureEnabled(String id);
}
@@ -46,4 +46,12 @@ public interface WebApplication extends DBPApplication {
RMController getResourceController(@NotNull SMCredentialsProvider credentialsProvider);
String getServerURL();
default String getServicesURI() {
return "/";
}
default String getRootURI() {
return "";
}
}
@@ -0,0 +1,24 @@
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2022 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;
public interface WebAuthApplication extends WebApplication {
WebAuthConfiguration getAuthConfiguration();
String getAuthServiceURL();
}
@@ -34,5 +34,4 @@ public interface WebAuthConfiguration {
List<SMAuthProviderCustomConfiguration> getAuthCustomConfigurations();
SMAuthProviderCustomConfiguration getAuthProviderConfiguration(String configId);
}
@@ -18,7 +18,7 @@
package io.cloudbeaver.registry;
import io.cloudbeaver.DBWFeatureSet;
import io.cloudbeaver.server.CBApplication;
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 CBApplication.getInstance().getAppConfiguration().isFeatureEnabled(this.id);
return WebAppUtils.getWebApplication().getAppConfiguration().isFeatureEnabled(this.id);
}
}
@@ -16,14 +16,14 @@
*/
package io.cloudbeaver.service;
import io.cloudbeaver.server.CBApplication;
import io.cloudbeaver.model.app.WebApplication;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.jkiss.dbeaver.DBException;
/**
* Servlet service
*/
public interface DBWServiceBindingServlet extends DBWServiceBinding {
public interface DBWServiceBindingServlet<APPLICATION extends WebApplication> extends DBWServiceBinding {
void addServlets(CBApplication application, ServletContextHandler servletContextHandler) throws DBException;
void addServlets(APPLICATION application, ServletContextHandler servletContextHandler) throws DBException;
}
@@ -18,10 +18,18 @@ package io.cloudbeaver.utils;
import io.cloudbeaver.auth.NoAuthCredentialsProvider;
import io.cloudbeaver.model.app.WebApplication;
import io.cloudbeaver.model.app.WebAuthApplication;
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.auth.SMAuthenticationManager;
import org.jkiss.dbeaver.runtime.DBWorkbench;
import org.jkiss.utils.CommonUtils;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.HashSet;
@@ -29,6 +37,8 @@ import java.util.Map;
import java.util.Set;
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));
}
@@ -45,7 +55,7 @@ public class WebAppUtils {
}
public static SMAuthenticationManager getAuthManager(WebApplication application) throws DBException {
var smController = getWebApplication().getSecurityController(new NoAuthCredentialsProvider());
var smController = application.getSecurityController(new NoAuthCredentialsProvider());
if (!SMAuthenticationManager.class.isAssignableFrom(smController.getClass())) {
throw new DBException("The current application cannot be used for authorization");
}
@@ -80,4 +90,66 @@ public class WebAppUtils {
return resultConfig;
}
@NotNull
public static String removeSideSlashes(String action) {
if (CommonUtils.isEmpty(action)) {
return action;
}
while (action.startsWith("/")) action = action.substring(1);
while (action.endsWith("/")) action = action.substring(0, action.length() - 1);
return action;
}
@NotNull
public static StringBuilder getAuthApiPrefix(String serviceId) throws DBException {
WebApplication application = getWebApplication();
if (!WebAuthApplication.class.isAssignableFrom(application.getClass())) {
throw new DBException("The current application doesn't contain authorization configuration");
}
WebAuthApplication webAuthApplication = (WebAuthApplication) application;
return getAuthApiPrefix(webAuthApplication, serviceId);
}
@NotNull
public static StringBuilder getAuthApiPrefix(WebAuthApplication webAuthApplication, String serviceId) {
String authUrl = removeSideSlashes(webAuthApplication.getAuthServiceURL());
StringBuilder apiPrefix = new StringBuilder(authUrl);
apiPrefix.append("/").append(serviceId).append("/");
return apiPrefix;
}
public static void addResponseCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, long maxSessionIdleTime) {
addResponseCookie(request, response, cookieName, cookieValue, maxSessionIdleTime, null);
}
public static void addResponseCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, long maxSessionIdleTime, @Nullable String sameSite) {
Cookie sessionCookie = new Cookie(cookieName, cookieValue);
if (maxSessionIdleTime > 0) {
sessionCookie.setMaxAge((int) (maxSessionIdleTime / 1000));
}
String path = getWebApplication().getRootURI();
if (sameSite != null) {
if (sameSite.toLowerCase() == "none" && request.isSecure() == false) {
log.debug("Attempt to set Cookie `" + cookieName + "` with `SameSite=None` failed, it require a secure context/HTTPS");
} else {
sessionCookie.setSecure(true);
path = path.concat("; SameSite=" + sameSite);
}
}
sessionCookie.setPath(path);
response.addCookie(sessionCookie);
}
public static String getRequestCookie(HttpServletRequest request, String cookieName) {
for (Cookie cookie : request.getCookies()) {
if (cookie.getName().equals(cookieName)) {
return cookie.getValue();
}
}
return null;
}
}
@@ -48,9 +48,6 @@ import org.jkiss.dbeaver.registry.network.NetworkHandlerRegistry;
import org.jkiss.dbeaver.runtime.DBWorkbench;
import org.jkiss.utils.CommonUtils;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.HashMap;
import java.util.LinkedHashMap;
@@ -294,65 +291,6 @@ public class WebServiceUtils extends WebCommonUtils {
}
}
public static void addResponseCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, long maxSessionIdleTime) {
addResponseCookie(request, response, cookieName, cookieValue, maxSessionIdleTime, null);
}
public static void addResponseCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, long maxSessionIdleTime, @Nullable String sameSite) {
Cookie sessionCookie = new Cookie(cookieName, cookieValue);
if (maxSessionIdleTime > 0) {
sessionCookie.setMaxAge((int) (maxSessionIdleTime / 1000));
}
String path = CBApplication.getInstance().getRootURI();
if (sameSite != null) {
if (sameSite.toLowerCase() == "none" && request.isSecure() == false) {
log.debug("Attempt to set Cookie `" + cookieName + "` with `SameSite=None` failed, it require a secure context/HTTPS");
} else {
sessionCookie.setSecure(true);
path = path.concat("; SameSite=" + sameSite);
}
}
sessionCookie.setPath(path);
response.addCookie(sessionCookie);
}
public static String getRequestCookie(HttpServletRequest request, String cookieName) {
for (Cookie cookie : request.getCookies()) {
if (cookie.getName().equals(cookieName)) {
return cookie.getValue();
}
}
return null;
}
@NotNull
public static String removeSideSlashes(String action) {
if (CommonUtils.isEmpty(action)) {
return action;
}
while (action.startsWith("/")) action = action.substring(1);
while (action.endsWith("/")) action = action.substring(0, action.length() - 1);
return action;
}
@NotNull
public static StringBuilder getApiPrefix(String serviceId) {
CBApplication application = CBApplication.getInstance();
StringBuilder apiPrefix = new StringBuilder();
apiPrefix.append(removeSideSlashes(application.getServerURL()));
apiPrefix.append("/");
String rootURI = removeSideSlashes(application.getRootURI());
if (!CommonUtils.isEmpty(rootURI)) {
apiPrefix.append(rootURI).append("/");
}
apiPrefix.append(removeSideSlashes(application.getServicesURI()));
apiPrefix.append("/").append(serviceId).append("/");
return apiPrefix;
}
public static void fireActionParametersOpenEditor(WebSession webSession, DBPDataSourceContainer dataSource, boolean addEditorName) {
Map<String, Object> actionParameters = new HashMap<>();
actionParameters.put("action", "open-sql-editor");
@@ -18,32 +18,23 @@ package io.cloudbeaver.server;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.Expose;
import io.cloudbeaver.DBWFeatureSet;
import io.cloudbeaver.auth.provider.local.LocalAuthProvider;
import io.cloudbeaver.model.app.BaseWebAppConfiguration;
import io.cloudbeaver.model.app.BaseAuthWebAppConfiguration;
import io.cloudbeaver.model.app.WebAuthConfiguration;
import io.cloudbeaver.registry.WebFeatureRegistry;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.navigator.DBNBrowseSettings;
import org.jkiss.dbeaver.model.security.SMAuthProviderCustomConfiguration;
import org.jkiss.dbeaver.registry.DataSourceNavigatorSettings;
import org.jkiss.dbeaver.registry.auth.AuthProviderDescriptor;
import org.jkiss.dbeaver.registry.auth.AuthProviderRegistry;
import org.jkiss.utils.ArrayUtils;
import org.jkiss.utils.CommonUtils;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* Application configuration
*/
public class CBAppConfig extends BaseWebAppConfiguration implements WebAuthConfiguration {
public class CBAppConfig extends BaseAuthWebAppConfiguration implements WebAuthConfiguration {
public static final DataSourceNavigatorSettings DEFAULT_VIEW_SETTINGS = DataSourceNavigatorSettings.PRESET_FULL.getSettings();
private boolean supportsCustomConnections;
@@ -59,19 +50,10 @@ public class CBAppConfig extends BaseWebAppConfiguration implements WebAuthConfi
private String[] enabledDrivers;
private String[] disabledDrivers;
private String[] enabledFeatures;
private DataSourceNavigatorSettings defaultNavigatorSettings;
private final Map<String, Object> resourceQuotas;
private String defaultAuthProvider;
private String[] enabledAuthProviders;
private final List<SMAuthProviderCustomConfiguration> authConfigurations;
// Legacy auth configs, left for backward compatibility
@Expose(serialize = false)
private final Map<String, SMAuthProviderCustomConfiguration> authConfiguration;
public CBAppConfig() {
super();
this.supportsCustomConnections = true;
@@ -82,12 +64,7 @@ public class CBAppConfig extends BaseWebAppConfiguration implements WebAuthConfi
this.redirectOnFederatedAuth = false;
this.enabledDrivers = new String[0];
this.disabledDrivers = new String[0];
this.defaultAuthProvider = LocalAuthProvider.PROVIDER_ID;
this.enabledFeatures = null;
this.enabledAuthProviders = null;
this.defaultNavigatorSettings = DEFAULT_VIEW_SETTINGS;
this.authConfiguration = new LinkedHashMap<>();
this.authConfigurations = new ArrayList<>();
this.resourceQuotas = new LinkedHashMap<>();
this.enableReverseProxyAuth = false;
this.forwardProxy = false;
@@ -104,19 +81,13 @@ public class CBAppConfig extends BaseWebAppConfiguration implements WebAuthConfi
this.redirectOnFederatedAuth = src.redirectOnFederatedAuth;
this.enabledDrivers = src.enabledDrivers;
this.disabledDrivers = src.disabledDrivers;
this.defaultAuthProvider = src.defaultAuthProvider;
this.enabledFeatures = src.enabledFeatures;
this.enabledAuthProviders = src.enabledAuthProviders;
this.defaultNavigatorSettings = src.defaultNavigatorSettings;
this.authConfiguration = new LinkedHashMap<>(src.authConfiguration);
this.authConfigurations = new ArrayList<>(src.authConfigurations);
this.resourceQuotas = new LinkedHashMap<>(src.resourceQuotas);
this.enableReverseProxyAuth = src.enableReverseProxyAuth;
this.forwardProxy = src.forwardProxy;
this.linkExternalCredentialsWithUser = src.linkExternalCredentialsWithUser;
}
public void setAnonymousAccessEnabled(boolean anonymousAccessEnabled) {
this.anonymousAccessEnabled = anonymousAccessEnabled;
}
@@ -177,70 +148,6 @@ public class CBAppConfig extends BaseWebAppConfiguration implements WebAuthConfi
this.disabledDrivers = disabledDrivers;
}
public boolean isFeatureEnabled(String id) {
return ArrayUtils.contains(getEnabledFeatures(), id);
}
public boolean isFeaturesEnabled(String[] features) {
return ArrayUtils.containsAll(getEnabledFeatures(), features);
}
public String[] getEnabledFeatures() {
if (enabledFeatures == null) {
// No config - enable all features (+backward compatibility)
return WebFeatureRegistry.getInstance().getWebFeatures()
.stream().map(DBWFeatureSet::getId).toArray(String[]::new);
}
return enabledFeatures;
}
public void setEnabledFeatures(String[] enabledFeatures) {
this.enabledFeatures = enabledFeatures;
}
@Override
public boolean isAuthProviderEnabled(String id) {
var authProviderDescriptor = AuthProviderRegistry.getInstance().getAuthProvider(id);
if (authProviderDescriptor == null) {
return false;
}
if (!ArrayUtils.contains(getEnabledAuthProviders(), id)) {
return false;
}
if (!ArrayUtils.isEmpty(authProviderDescriptor.getRequiredFeatures())) {
for (String rf : authProviderDescriptor.getRequiredFeatures()) {
if (!isFeatureEnabled(rf)) {
return false;
}
}
}
return true;
}
@Override
public String getDefaultAuthProvider() {
return defaultAuthProvider;
}
public void setDefaultAuthProvider(String defaultAuthProvider) {
this.defaultAuthProvider = defaultAuthProvider;
}
@Override
public String[] getEnabledAuthProviders() {
if (enabledAuthProviders == null) {
// No config - enable all providers (+backward compatibility)
return AuthProviderRegistry.getInstance().getAuthProviders()
.stream().map(AuthProviderDescriptor::getId).toArray(String[]::new);
}
return enabledAuthProviders;
}
public void setEnabledAuthProviders(String[] enabledAuthProviders) {
this.enabledAuthProviders = enabledAuthProviders;
}
public String[] getAllAuthProviders() {
return AuthProviderRegistry.getInstance().getAuthProviders()
.stream().map(AuthProviderDescriptor::getId).toArray(String[]::new);
@@ -300,54 +207,6 @@ public class CBAppConfig extends BaseWebAppConfiguration implements WebAuthConfi
}
}
////////////////////////////////////////////
// Auth provider configs
@Override
public List<SMAuthProviderCustomConfiguration> getAuthCustomConfigurations() {
return authConfigurations;
}
@Override
@Nullable
public SMAuthProviderCustomConfiguration getAuthProviderConfiguration(@NotNull String id) {
synchronized (authConfigurations) {
return authConfigurations.stream().filter(c -> c.getId().equals(id)).findAny().orElse(null);
}
}
public void addAuthProviderConfiguration(@NotNull SMAuthProviderCustomConfiguration config) {
synchronized (authConfigurations) {
authConfigurations.removeIf(c -> c.getId().equals(config.getId()));
authConfigurations.add(config);
}
}
public void setAuthProvidersConfigurations(List<SMAuthProviderCustomConfiguration> authProviders) {
synchronized (authConfigurations) {
authConfigurations.clear();
authConfigurations.addAll(authProviders);
}
}
public boolean deleteAuthProviderConfiguration(@NotNull String id) {
synchronized (authConfigurations) {
return authConfigurations.removeIf(c -> c.getId().equals(id));
}
}
public void loadLegacyCustomConfigs() {
// Convert legacy map of configs into list
if (!authConfiguration.isEmpty()) {
for (Map.Entry<String, SMAuthProviderCustomConfiguration> entry : authConfiguration.entrySet()) {
entry.getValue().setId(entry.getKey());
authConfigurations.add(entry.getValue());
}
authConfiguration.clear();
}
}
public boolean isLinkExternalCredentialsWithUser() {
return linkExternalCredentialsWithUser;
}
@@ -21,6 +21,8 @@ import com.google.gson.GsonBuilder;
import com.google.gson.InstanceCreator;
import io.cloudbeaver.WebServiceUtils;
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.WebServiceRegistry;
import io.cloudbeaver.server.jetty.CBJettyServer;
@@ -77,7 +79,7 @@ import java.util.stream.Stream;
/**
* This class controls all aspects of the application's execution
*/
public class CBApplication extends BaseWebApplication {
public class CBApplication extends BaseWebApplication implements WebAuthApplication {
private static final Log log = Log.getLog(CBApplication.class);
@@ -176,6 +178,19 @@ public class CBApplication extends BaseWebApplication {
return appConfiguration;
}
@Override
public WebAuthConfiguration getAuthConfiguration() {
return appConfiguration;
}
@Override
public String getAuthServiceURL() {
return Stream.of(getServerURL(), getRootURI(), getServicesURI())
.map(WebAppUtils::removeSideSlashes)
.filter(CommonUtils::isNotEmpty)
.collect(Collectors.joining("/"));
}
public Map<String, Object> getProductConfiguration() {
return productConfiguration;
}
@@ -38,6 +38,7 @@ import io.cloudbeaver.registry.WebServiceRegistry;
import io.cloudbeaver.server.CBApplication;
import io.cloudbeaver.service.DBWServiceBindingGraphQL;
import io.cloudbeaver.service.WebServiceBindingBase;
import io.cloudbeaver.utils.WebAppUtils;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.DBConstants;
import org.jkiss.utils.IOUtils;
@@ -269,8 +270,8 @@ public class GraphQLEndpoint extends HttpServlet {
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
String cookieValue = sdf.format(new Date(System.currentTimeMillis() + maxSessionIdleTime));
WebServiceUtils.addResponseCookie(
request, response, SESSION_TEMP_COOKIE, cookieValue, maxSessionIdleTime);
WebAppUtils.addResponseCookie(
request, response, SESSION_TEMP_COOKIE, cookieValue, maxSessionIdleTime);
}
private static class WebInstrumentation extends SimpleInstrumentation {
@@ -40,7 +40,7 @@ import java.util.stream.Collectors;
/**
* Web service implementation
*/
public class WebServiceBindingSQL extends WebServiceBindingBase<DBWServiceSQL> implements DBWServiceBindingServlet {
public class WebServiceBindingSQL extends WebServiceBindingBase<DBWServiceSQL> implements DBWServiceBindingServlet<CBApplication> {
public WebServiceBindingSQL() {
super(DBWServiceSQL.class, new WebServiceSQL(), "schema/service.sql.graphqls");
@@ -16,7 +16,10 @@
*/
package io.cloudbeaver.service.admin;
import io.cloudbeaver.*;
import io.cloudbeaver.DBWConstants;
import io.cloudbeaver.DBWFeatureSet;
import io.cloudbeaver.DBWebException;
import io.cloudbeaver.WebAction;
import io.cloudbeaver.model.WebConnectionConfig;
import io.cloudbeaver.model.WebConnectionInfo;
import io.cloudbeaver.model.WebPropertyInfo;
@@ -32,7 +32,7 @@ import org.jkiss.utils.CommonUtils;
/**
* Web service implementation
*/
public class WebServiceBindingAdmin extends WebServiceBindingBase<DBWServiceAdmin> implements DBWServiceBindingServlet {
public class WebServiceBindingAdmin extends WebServiceBindingBase<DBWServiceAdmin> implements DBWServiceBindingServlet<CBApplication> {
private static final String SCHEMA_FILE_NAME = "schema/service.admin.graphqls";
@@ -16,10 +16,10 @@
*/
package io.cloudbeaver.service.auth.local;
import io.cloudbeaver.WebServiceUtils;
import io.cloudbeaver.model.session.WebSession;
import io.cloudbeaver.server.CBPlatform;
import io.cloudbeaver.server.actions.AbstractActionServletHandler;
import io.cloudbeaver.utils.WebAppUtils;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log;
@@ -39,7 +39,7 @@ public class LocalServletHandler extends AbstractActionServletHandler {
@Override
public boolean handleRequest(Servlet servlet, HttpServletRequest request, HttpServletResponse response) throws DBException, IOException {
if (URI_PREFIX.equals(WebServiceUtils.removeSideSlashes(request.getPathInfo()))) {
if (URI_PREFIX.equals(WebAppUtils.removeSideSlashes(request.getPathInfo()))) {
try {
WebSession webSession = CBPlatform.getInstance().getSessionManager().getWebSession(request, response, true);
createActionFromParams(webSession, request, response);
@@ -30,7 +30,7 @@ import org.eclipse.jetty.servlet.ServletHolder;
/**
* Web service implementation
*/
public class WebServiceBindingDataTransfer extends WebServiceBindingBase<DBWServiceDataTransfer> implements DBWServiceBindingServlet {
public class WebServiceBindingDataTransfer extends WebServiceBindingBase<DBWServiceDataTransfer> implements DBWServiceBindingServlet<CBApplication> {
public WebServiceBindingDataTransfer() {
super(DBWServiceDataTransfer.class, new WebServiceDataTransfer(), "schema/service.data.transfer.graphqls");