Merge remote-tracking branch 'origin/devel' into feat/cb-2479/shared-projects-ux

This commit is contained in:
Wroud
2022-09-22 12:27:24 +03:00
6 changed files with 68 additions and 38 deletions
@@ -1,3 +1,20 @@
/*
* 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.auth.provider.local;
//TODO remove after CBDatabase refactoring
@@ -289,14 +289,13 @@ public class WebConnectionInfo {
}
// Fill session and user provided credentials
boolean hasContextCredentials = session.hasContextCredentials();
DBPConnectionConfiguration configWithAuth = new DBPConnectionConfiguration(dataSourceContainer.getConnectionConfiguration());
session.provideAuthParameters(session.getProgressMonitor(), dataSourceContainer, configWithAuth);
DBPPropertySource credentialsSource = authModel.createCredentialsSource(dataSourceContainer, configWithAuth);
return Arrays.stream(credentialsSource.getProperties())
.filter(p -> WebCommonUtils.isAuthPropertyApplicable(p, hasContextCredentials))
.filter(p -> WebCommonUtils.isAuthPropertyApplicable(p, session.getContextCredentialsProviders()))
.map(p -> new WebPropertyInfo(session, p, credentialsSource)).toArray(WebPropertyInfo[]::new);
}
@@ -86,8 +86,7 @@ public class WebSession extends AbstractSessionPersistent implements SMSession,
private static final Log log = Log.getLog(WebSession.class);
public static final SMSessionType CB_SESSION_TYPE = new SMSessionType("CloudBeaver");
public static final SMObjectType CB_DATASOURCE_OBJECT = new SMObjectType("datasource");
private static final String WEB_SESSION_AUTH_CONTEXT_TYPE = "web-session";
private static final String ATTR_LOCALE = "locale";
private static final AtomicInteger TASK_ID = new AtomicInteger();
@@ -873,8 +872,8 @@ public class WebSession extends AbstractSessionPersistent implements SMSession,
}
}
public boolean hasContextCredentials() {
return getAdapter(DBACredentialsProvider.class) != null;
public List<DBACredentialsProvider> getContextCredentialsProviders() {
return getAdapters(DBACredentialsProvider.class);
}
// Auth credentials provider
@@ -883,13 +882,10 @@ public class WebSession extends AbstractSessionPersistent implements SMSession,
public boolean provideAuthParameters(@NotNull DBRProgressMonitor monitor, @NotNull DBPDataSourceContainer dataSourceContainer, @NotNull DBPConnectionConfiguration configuration) {
try {
// Properties from nested auth sessions
// FIXME: we need to support multiple credential providers (e.g. multiple clouds).
DBACredentialsProvider nestedProvider = getAdapter(DBACredentialsProvider.class);
if (nestedProvider != null) {
if (!nestedProvider.provideAuthParameters(monitor, dataSourceContainer, configuration)) {
return false;
}
for (DBACredentialsProvider contextCredentialsProvider : getContextCredentialsProviders()) {
contextCredentialsProvider.provideAuthParameters(monitor, dataSourceContainer, configuration);
}
WebConnectionInfo webConnectionInfo = findWebConnectionInfo(dataSourceContainer.getId());
if (webConnectionInfo != null) {
WebDataSourceUtils.saveCredentialsInDataSource(webConnectionInfo, dataSourceContainer, configuration);
@@ -927,21 +923,44 @@ public class WebSession extends AbstractSessionPersistent implements SMSession,
return true;
}
@NotNull
@Override
public String getAuthContextType() {
return WEB_SESSION_AUTH_CONTEXT_TYPE;
}
// May be called to extract auth information from session
@Override
public <T> T getAdapter(Class<T> adapter) {
synchronized (authTokens) {
for (WebAuthInfo authInfo : authTokens) {
if (authInfo != null && authInfo.getAuthSession() != null) {
if (adapter.isInstance(authInfo.getAuthSession())) {
return adapter.cast(authInfo.getAuthSession());
}
if (isAuthInfoInstanceOf(authInfo, adapter)) {
return adapter.cast(authInfo.getAuthSession());
}
}
}
return null;
}
@NotNull
public <T> List<T> getAdapters(Class<T> adapter) {
synchronized (authTokens) {
return authTokens.stream()
.filter(token -> isAuthInfoInstanceOf(token, adapter))
.map(token -> adapter.cast(token.getAuthSession()))
.collect(Collectors.toList());
}
}
private <T> boolean isAuthInfoInstanceOf(WebAuthInfo authInfo, Class<T> adapter) {
if (authInfo != null && authInfo.getAuthSession() != null) {
if (adapter.isInstance(authInfo.getAuthSession())) {
return true;
}
}
return false;
}
///////////////////////////////////////////////////////
// Utils
@@ -22,12 +22,15 @@ import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.model.DBPImage;
import org.jkiss.dbeaver.model.DBPObject;
import org.jkiss.dbeaver.model.access.DBACredentialsProvider;
import org.jkiss.dbeaver.model.auth.AuthProperty;
import org.jkiss.dbeaver.model.preferences.DBPPropertyDescriptor;
import org.jkiss.dbeaver.runtime.properties.ObjectPropertyDescriptor;
import org.jkiss.dbeaver.runtime.properties.PropertyCollector;
import org.jkiss.utils.CommonUtils;
import java.util.Arrays;
import java.util.Collection;
public class WebCommonUtils {
@@ -44,13 +47,21 @@ public class WebCommonUtils {
.map(p -> new WebPropertyInfo(session, p, propertyCollector)).toArray(WebPropertyInfo[]::new);
}
public static boolean isAuthPropertyApplicable(DBPPropertyDescriptor prop, boolean hasContextCredentials) {
if (hasContextCredentials && prop instanceof ObjectPropertyDescriptor) {
public static boolean isAuthPropertyApplicable(
DBPPropertyDescriptor prop,
@NotNull Collection<DBACredentialsProvider> credentialsProviders
) {
if (!CommonUtils.isEmpty(credentialsProviders) && prop instanceof ObjectPropertyDescriptor) {
if (((ObjectPropertyDescriptor) prop).isHidden()) {
return false;
}
AuthProperty authProperty = ((ObjectPropertyDescriptor) prop).getAnnotation(AuthProperty.class);
if (authProperty != null) return !authProperty.contextProvided();
if (authProperty != null) {
var requiredContext = authProperty.authContextType();
return CommonUtils.isEmpty(requiredContext)
|| credentialsProviders.stream()
.noneMatch(provider -> provider.getAuthContextType().equals(requiredContext));
}
}
return true;
}
@@ -65,11 +65,10 @@ public class WebDatabaseAuthModel {
@Property
public WebPropertyInfo[] getProperties() throws DBWebException {
boolean hasContextCredentials = webSession.hasContextCredentials();
DBPPropertySource credentialsSource = model.createCredentialsSource(null, null);
return Arrays.stream(credentialsSource.getProperties())
.filter(p -> WebServiceUtils.isAuthPropertyApplicable(p, hasContextCredentials))
.filter(p -> WebServiceUtils.isAuthPropertyApplicable(p, webSession.getContextCredentialsProviders()))
.map(p -> new WebPropertyInfo(webSession, p, credentialsSource)).toArray(WebPropertyInfo[]::new);
}
@@ -210,24 +210,9 @@ public class WebSQLUtils {
switch ((String)typeAttr) {
case WebSQLConstants.VALUE_TYPE_CONTENT: {
if (map.get(WebSQLConstants.ATTR_BINARY) != null) {
DBDContentStorage storage;
Path openFile = WebSQLDataLOBReceiver.DATA_EXPORT_FOLDER.resolve((String) map.get("fileName"));
Object tempValue = ((DBDAttributeBinding) attribute).getValueHandler().getValueFromObject(
session,
attribute,
null, false, true);
storage = new ExternalContentStorage(DBWorkbench.getPlatform(), openFile);
if (tempValue instanceof DBDContent) {
try {
((DBDContent) tempValue).updateContents(session.getProgressMonitor(), storage);
} catch (Exception e) {
throw new DBCException("Error with inserting file into DB");
}
}
value = tempValue;
} else {
value = map.get(WebSQLConstants.ATTR_TEXT);
throw new DBCException("Binary content edit is not supported yet");
}
value = map.get(WebSQLConstants.ATTR_TEXT);
break;
}
default: {