diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebAuthProviderDescriptor.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebAuthProviderDescriptor.java index 6fa301fb760..c42a4b4e3f9 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebAuthProviderDescriptor.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebAuthProviderDescriptor.java @@ -56,6 +56,7 @@ public class WebAuthProviderDescriptor extends AbstractDescriptor { private final boolean isPrivate; private final String[] requiredFeatures; private final boolean isRequired; + private final String[] types; public WebAuthProviderDescriptor(IConfigurationElement cfg) { super(cfg); @@ -68,13 +69,9 @@ public WebAuthProviderDescriptor(IConfigurationElement cfg) { this.isRequired = CommonUtils.toBoolean(cfg.getAttribute("required")); for (IConfigurationElement cfgElement : cfg.getChildren("configuration")) { - for (IConfigurationElement propGroup : ArrayUtils.safeArray(cfgElement.getChildren(PropertyDescriptor.TAG_PROPERTY_GROUP))) { - String category = propGroup.getAttribute(PropertyDescriptor.ATTR_LABEL); - IConfigurationElement[] propElements = propGroup.getChildren(PropertyDescriptor.TAG_PROPERTY); - for (IConfigurationElement prop : propElements) { - WebAuthProviderProperty propertyDescriptor = new WebAuthProviderProperty(category, prop); - configurationParameters.put(CommonUtils.toString(propertyDescriptor.getId()), propertyDescriptor); - } + List properties = WebAuthProviderRegistry.readProperties(cfgElement); + for (WebAuthProviderProperty property : properties) { + configurationParameters.put(CommonUtils.toString(property.getId()), property); } } for (IConfigurationElement credElement : cfg.getChildren("credentials")) { @@ -90,11 +87,10 @@ public WebAuthProviderDescriptor(IConfigurationElement cfg) { } String rfList = cfg.getAttribute("requiredFeatures"); - if (!CommonUtils.isEmpty(rfList)) { - requiredFeatures = rfList.split(","); - } else { - requiredFeatures = null; - } + requiredFeatures = CommonUtils.isEmpty(rfList) ? null : rfList.split(","); + + String typesAttr = cfg.getAttribute("types"); + this.types = CommonUtils.isEmpty(typesAttr) ? new String[0] : typesAttr.split(","); } @NotNull @@ -198,4 +194,7 @@ public List getMetaParameters(SMSubjectType subjectType) return metaParameters.get(subjectType); } + public String[] getTypes() { + return types; + } } diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebAuthProviderProperty.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebAuthProviderProperty.java index e755acae3d9..cf30e979889 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebAuthProviderProperty.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebAuthProviderProperty.java @@ -18,19 +18,28 @@ import org.eclipse.core.runtime.IConfigurationElement; import org.jkiss.code.NotNull; +import org.jkiss.code.Nullable; import org.jkiss.dbeaver.model.impl.PropertyDescriptor; public class WebAuthProviderProperty extends PropertyDescriptor { private final String[] requiredFeatures; + @Nullable + private final String type; public WebAuthProviderProperty(String category, IConfigurationElement config) { super(category, config); String featuresAttr = config.getAttribute("requiredFeatures"); this.requiredFeatures = featuresAttr == null ? new String[0] : featuresAttr.split(","); + this.type = config.getAttribute("type"); } @NotNull public String[] getRequiredFeatures() { return requiredFeatures; } + + @Nullable + public String getType() { + return type; + } } diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebAuthProviderRegistry.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebAuthProviderRegistry.java index 5f2a8cb86a3..e2a842ffdb9 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebAuthProviderRegistry.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebAuthProviderRegistry.java @@ -20,7 +20,9 @@ import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.Platform; import org.jkiss.dbeaver.Log; +import org.jkiss.dbeaver.model.impl.PropertyDescriptor; import org.jkiss.dbeaver.registry.RegistryConstants; +import org.jkiss.utils.ArrayUtils; import java.util.ArrayList; import java.util.LinkedHashMap; @@ -33,6 +35,7 @@ public class WebAuthProviderRegistry { private static final String TAG_AUTH_PROVIDER = "authProvider"; //$NON-NLS-1$ private static final String TAG_AUTH_PROVIDER_DISABLE = "authProviderDisable"; //$NON-NLS-1$ + private static final String TAG_COMMON_PROVIDER_PROPERTIES = "commonProviderProperties"; //$NON-NLS-1$ private static WebAuthProviderRegistry instance = null; @@ -45,6 +48,7 @@ public synchronized static WebAuthProviderRegistry getInstance() { } private final Map authProviders = new LinkedHashMap<>(); + private final List commonProperties = new ArrayList<>(); private WebAuthProviderRegistry() { } @@ -57,6 +61,9 @@ private void loadExtensions(IExtensionRegistry registry) { if (TAG_AUTH_PROVIDER.equals(ext.getName())) { WebAuthProviderDescriptor providerDescriptor = new WebAuthProviderDescriptor(ext); this.authProviders.put(providerDescriptor.getId(), providerDescriptor); + } else if (TAG_COMMON_PROVIDER_PROPERTIES.equals(ext.getName())) { + var commonProperties = new WebCommonAuthProviderPropertyDescriptor(ext); + this.commonProperties.add(commonProperties); } } @@ -74,6 +81,23 @@ private void loadExtensions(IExtensionRegistry registry) { } } + static List readProperties(IConfigurationElement root) { + List properties = new ArrayList<>(); + for (IConfigurationElement propGroup : ArrayUtils.safeArray(root.getChildren(PropertyDescriptor.TAG_PROPERTY_GROUP))) { + String category = propGroup.getAttribute(PropertyDescriptor.ATTR_LABEL); + IConfigurationElement[] propElements = propGroup.getChildren(PropertyDescriptor.TAG_PROPERTY); + for (IConfigurationElement prop : propElements) { + WebAuthProviderProperty propertyDescriptor = new WebAuthProviderProperty(category, prop); + properties.add(propertyDescriptor); + } + } + return properties; + } + + public List getCommonProperties() { + return commonProperties; + } + public List getAuthProviders() { return new ArrayList<>(authProviders.values()); } diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebCommonAuthProviderPropertyDescriptor.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebCommonAuthProviderPropertyDescriptor.java new file mode 100644 index 00000000000..fecbe551fff --- /dev/null +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebCommonAuthProviderPropertyDescriptor.java @@ -0,0 +1,67 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2024 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.cloudbeaver.registry; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.jkiss.code.NotNull; +import org.jkiss.dbeaver.model.impl.AbstractDescriptor; +import org.jkiss.utils.CommonUtils; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class WebCommonAuthProviderPropertyDescriptor extends AbstractDescriptor { + private final Set supportedTypes = new HashSet<>(); + private final Set excludedTypes = new HashSet<>(); + @NotNull + private final List configurationParameters; + + public WebCommonAuthProviderPropertyDescriptor(IConfigurationElement cfg) { + super(cfg); + configurationParameters = WebAuthProviderRegistry.readProperties(cfg); + String supportedTypesAttr = cfg.getAttribute("supportedTypes"); + if (CommonUtils.isNotEmpty(supportedTypesAttr)) { + supportedTypes.addAll(Arrays.stream(supportedTypesAttr.split(",")).toList()); + } + + String excludeAttr = cfg.getAttribute("exclude"); + if (CommonUtils.isNotEmpty(excludeAttr)) { + supportedTypes.addAll(Arrays.stream(excludeAttr.split(",")).toList()); + } + } + + + @NotNull + public List getConfigurationParameters() { + return configurationParameters; + } + + public boolean isApplicableFor(@NotNull WebAuthProviderDescriptor providerDescriptor) { + boolean supported = supportedTypes.isEmpty(); + for (String type : providerDescriptor.getTypes()) { + if (excludedTypes.contains(type)) { + return false; + } + if (supportedTypes.contains(type)) { + supported = true; + } + } + return supported; + } +} diff --git a/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/WebServiceAdmin.java b/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/WebServiceAdmin.java index 9be0a2321ba..64c12098263 100644 --- a/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/WebServiceAdmin.java +++ b/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/WebServiceAdmin.java @@ -53,6 +53,7 @@ import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; +import java.util.stream.Stream; /** * Web service implementation @@ -405,20 +406,29 @@ public List listAuthProviderConfigurationParameters(@NotNull We throw new DBWebException("Invalid provider ID " + providerId); } var application = CBApplication.getInstance(); - return authProvider.getConfigurationParameters().stream().filter(p -> { - boolean allFeaturesEnabled = true; - for (String feature : p.getRequiredFeatures()) { - if (feature.equals("distributed")) { - allFeaturesEnabled = CBApplication.getInstance().isDistributed(); - } else { - allFeaturesEnabled = application.getAppConfiguration().isFeatureEnabled(feature); - } - if (!allFeaturesEnabled) { - break; + + + Stream commonPropertiesStream = WebAuthProviderRegistry.getInstance() + .getCommonProperties() + .stream() + .filter(commonProperties -> commonProperties.isApplicableFor(authProvider)) + .flatMap(commonProperties -> commonProperties.getConfigurationParameters().stream()); + + return Stream.concat(authProvider.getConfigurationParameters().stream(), commonPropertiesStream) + .filter(p -> { + boolean allFeaturesEnabled = true; + for (String feature : p.getRequiredFeatures()) { + if (feature.equals("distributed")) { + allFeaturesEnabled = CBApplication.getInstance().isDistributed(); + } else { + allFeaturesEnabled = application.getAppConfiguration().isFeatureEnabled(feature); + } + if (!allFeaturesEnabled) { + break; + } } - } - return allFeaturesEnabled; - }).map(p -> new WebPropertyInfo(webSession, p)).collect(Collectors.toList()); + return allFeaturesEnabled; + }).map(p -> new WebPropertyInfo(webSession, p)).collect(Collectors.toList()); } @Override