mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
Merge pull request #924 from dbeaver/feature/CB-2128
CB-2128 refactor authentication interfaces
This commit is contained in:
@@ -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,
|
||||
|
||||
+147
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
+27
-1
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -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 "";
|
||||
}
|
||||
}
|
||||
|
||||
+24
@@ -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();
|
||||
}
|
||||
-1
@@ -34,5 +34,4 @@ public interface WebAuthConfiguration {
|
||||
List<SMAuthProviderCustomConfiguration> getAuthCustomConfigurations();
|
||||
|
||||
SMAuthProviderCustomConfiguration getAuthProviderConfiguration(String configId);
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
+3
-3
@@ -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;
|
||||
}
|
||||
|
||||
+3
-2
@@ -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 {
|
||||
|
||||
+1
-1
@@ -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");
|
||||
|
||||
+4
-1
@@ -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;
|
||||
|
||||
+1
-1
@@ -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";
|
||||
|
||||
|
||||
+2
-2
@@ -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);
|
||||
|
||||
+1
-1
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user