Merge branch 'devel' of https://github.com/dbeaver/cloudbeaver into devel

This commit is contained in:
Wroud
2020-10-20 20:21:59 +03:00
12 changed files with 117 additions and 30 deletions
@@ -9,18 +9,18 @@ CREATE TABLE CB_SERVER(
);
CREATE TABLE CB_AUTH_SUBJECT(
SUBJECT_ID VARCHAR(64) NOT NULL,
SUBJECT_ID VARCHAR(128) NOT NULL,
SUBJECT_TYPE VARCHAR(8) NOT NULL,
PRIMARY KEY(SUBJECT_ID)
);
CREATE TABLE CB_AUTH_PERMISSIONS(
SUBJECT_ID VARCHAR(32) NOT NULL,
SUBJECT_ID VARCHAR(128) NOT NULL,
PERMISSION_ID VARCHAR(64) NOT NULL,
GRANT_TIME TIMESTAMP NOT NULL,
GRANTED_BY VARCHAR(64) NOT NULL,
GRANTED_BY VARCHAR(128) NOT NULL,
PRIMARY KEY(SUBJECT_ID,PERMISSION_ID),
FOREIGN KEY(SUBJECT_ID) REFERENCES CB_AUTH_SUBJECT(SUBJECT_ID) ON DELETE CASCADE
@@ -28,17 +28,17 @@ CREATE TABLE CB_AUTH_PERMISSIONS(
CREATE TABLE CB_DATASOURCE_ACCESS(
DATASOURCE_ID VARCHAR(128) NOT NULL,
SUBJECT_ID VARCHAR(32) NOT NULL,
SUBJECT_ID VARCHAR(128) NOT NULL,
GRANT_TIME TIMESTAMP NOT NULL,
GRANTED_BY VARCHAR(64) NOT NULL,
GRANTED_BY VARCHAR(128) NOT NULL,
PRIMARY KEY(SUBJECT_ID,DATASOURCE_ID),
FOREIGN KEY(SUBJECT_ID) REFERENCES CB_AUTH_SUBJECT(SUBJECT_ID) ON DELETE CASCADE
);
CREATE TABLE CB_USER(
USER_ID VARCHAR(64) NOT NULL,
USER_ID VARCHAR(128) NOT NULL,
IS_ACTIVE CHAR(1) NOT NULL,
CREATE_TIME TIMESTAMP NOT NULL,
@@ -49,7 +49,7 @@ CREATE TABLE CB_USER(
-- Additional user properties (profile)
CREATE TABLE CB_USER_META(
USER_ID VARCHAR(64) NOT NULL,
USER_ID VARCHAR(128) NOT NULL,
META_ID VARCHAR(32) NOT NULL,
META_VALUE VARCHAR(1024),
@@ -58,7 +58,7 @@ CREATE TABLE CB_USER_META(
);
CREATE TABLE CB_ROLE(
ROLE_ID VARCHAR(32) NOT NULL,
ROLE_ID VARCHAR(128) NOT NULL,
ROLE_NAME VARCHAR(100) NOT NULL,
ROLE_DESCRIPTION VARCHAR(255) NOT NULL,
@@ -69,11 +69,11 @@ CREATE TABLE CB_ROLE(
);
CREATE TABLE CB_USER_ROLE(
USER_ID VARCHAR(64) NOT NULL,
ROLE_ID VARCHAR(32) NOT NULL,
USER_ID VARCHAR(128) NOT NULL,
ROLE_ID VARCHAR(128) NOT NULL,
GRANT_TIME TIMESTAMP NOT NULL,
GRANTED_BY VARCHAR(32) NOT NULL,
GRANTED_BY VARCHAR(128) NOT NULL,
PRIMARY KEY(USER_ID,ROLE_ID),
FOREIGN KEY(USER_ID) REFERENCES CB_USER(USER_ID) ON DELETE CASCADE,
@@ -97,7 +97,7 @@ CREATE TABLE CB_AUTH_CONFIGURATION(
);
CREATE TABLE CB_USER_CREDENTIALS(
USER_ID VARCHAR(64) NOT NULL,
USER_ID VARCHAR(128) NOT NULL,
PROVIDER_ID VARCHAR(32) NOT NULL,
CRED_ID VARCHAR(32) NOT NULL,
CRED_VALUE VARCHAR(1024) NOT NULL,
@@ -109,7 +109,7 @@ CREATE TABLE CB_USER_CREDENTIALS(
CREATE INDEX CB_USER_CREDENTIALS_SEARCH_IDX ON CB_USER_CREDENTIALS(PROVIDER_ID,CRED_ID);
CREATE TABLE CB_USER_STATE(
USER_ID VARCHAR(64) NOT NULL,
USER_ID VARCHAR(128) NOT NULL,
USER_CONFIGURATION TEXT NULL,
@@ -121,7 +121,7 @@ CREATE TABLE CB_USER_STATE(
CREATE TABLE CB_SESSION(
SESSION_ID VARCHAR(64) NOT NULL,
USER_ID VARCHAR(64) NULL,
USER_ID VARCHAR(128) NULL,
CREATE_TIME TIMESTAMP NOT NULL,
LAST_ACCESS_REMOTE_ADDRESS NULL,
@@ -90,12 +90,26 @@ public class CBAppConfig {
return defaultAuthProvider;
}
public Map<String, Object> getPlugins() {
return plugins;
}
public Map<String, Object> getPluginConfig(String pluginId) {
return getPluginConfig(pluginId, false);
}
public Map<String, Object> getPluginConfig(String pluginId, boolean create) {
Object config = plugins.get(pluginId);
if (config instanceof Map) {
return (Map<String, Object>) config;
} else {
return Collections.emptyMap();
if (create) {
Map<String, Object> newConfig = new LinkedHashMap<>();
plugins.put(pluginId, newConfig);
return newConfig;
} else {
return Collections.emptyMap();
}
}
}
@@ -554,6 +554,7 @@ public class CBApplication extends BaseApplicationImpl {
.setPrettyPrinting()
.create();
try (JsonWriter json = gson.newJsonWriter(out)) {
json.setLenient(true);
json.beginObject();
{
json.name("server");
@@ -572,6 +573,11 @@ public class CBApplication extends BaseApplicationImpl {
JSONUtils.field(json, "anonymousAccessEnabled", appConfig.isAnonymousAccessEnabled());
JSONUtils.field(json, "authenticationEnabled", appConfig.isAuthenticationEnabled());
JSONUtils.field(json, "supportsCustomConnections", appConfig.isSupportsCustomConnections());
if (!CommonUtils.isEmpty(appConfig.getPlugins())) {
JSONUtils.serializeProperties(json, "plugins", appConfig.getPlugins());
}
json.endObject();
}
json.endObject();
@@ -172,6 +172,8 @@ public class CBDatabase {
// Create new admin user
if (!CommonUtils.isEmpty(adminName) && !CommonUtils.isEmpty(adminPassword)) {
createAdminUser(adminName, adminPassword);
} else {
grantAdminPermissionsToUser(adminName);
}
}
@@ -344,16 +346,21 @@ public class CBDatabase {
serverController.setUserCredentials(adminUser.getUserId(), authProvider, credentials);
}
// Grant all roles
WebRole[] allRoles = serverController.readAllRoles();
serverController.setUserRoles(
adminUser.getUserId(),
Arrays.stream(allRoles).map(WebRole::getRoleId).toArray(String[]::new),
adminUser.getUserId());
grantAdminPermissionsToUser(adminUser.getUserId());
return adminUser;
}
private void grantAdminPermissionsToUser(String userId) throws DBCException {
// Grant all roles
DBWSecurityController securityController = application.getSecurityController();
WebRole[] allRoles = securityController.readAllRoles();
securityController.setUserRoles(
userId,
Arrays.stream(allRoles).map(WebRole::getRoleId).toArray(String[]::new),
userId);
}
void shutdown() {
log.debug("Shutdown database");
if (cbDataSource != null) {
@@ -0,0 +1,33 @@
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2020 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.service;
import io.cloudbeaver.model.session.WebSession;
import io.cloudbeaver.server.CBAppConfig;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.app.DBPApplication;
/**
* Web service implementation
*/
public interface DBWServiceServerConfigurator extends DBWServiceBinding {
void configureServer(@NotNull DBPApplication application, @Nullable WebSession session, @NotNull CBAppConfig appConfig) throws DBException;
}
@@ -16,6 +16,8 @@
*/
package io.cloudbeaver.service.admin;
import io.cloudbeaver.server.CBAppConfig;
import io.cloudbeaver.server.CBApplication;
import org.jkiss.dbeaver.model.data.json.JSONUtils;
import java.util.Map;
@@ -41,9 +43,10 @@ public class AdminServerConfig {
this.adminName = JSONUtils.getString(params, "adminName");
this.adminPassword = JSONUtils.getString(params, "adminPassword");
this.anonymousAccessEnabled = JSONUtils.getBoolean(params, "anonymousAccessEnabled");
this.authenticationEnabled = JSONUtils.getBoolean(params, "authenticationEnabled");
this.customConnectionsEnabled = JSONUtils.getBoolean(params, "customConnectionsEnabled");
CBAppConfig appConfig = CBApplication.getInstance().getAppConfiguration();
this.anonymousAccessEnabled = JSONUtils.getBoolean(params, "anonymousAccessEnabled", appConfig.isAnonymousAccessEnabled());
this.authenticationEnabled = JSONUtils.getBoolean(params, "authenticationEnabled", appConfig.isAuthenticationEnabled());
this.customConnectionsEnabled = JSONUtils.getBoolean(params, "customConnectionsEnabled", appConfig.isSupportsCustomConnections());
this.sessionExpireTime = JSONUtils.getLong(params, "sessionExpireTime", -1);
}
@@ -32,6 +32,7 @@ import io.cloudbeaver.registry.WebServiceRegistry;
import io.cloudbeaver.server.CBAppConfig;
import io.cloudbeaver.server.CBApplication;
import io.cloudbeaver.server.CBPlatform;
import io.cloudbeaver.service.DBWServiceServerConfigurator;
import io.cloudbeaver.service.admin.*;
import org.jkiss.code.NotNull;
import org.jkiss.dbeaver.Log;
@@ -298,12 +299,31 @@ public class WebServiceAdmin implements DBWServiceAdmin {
appConfig.setAnonymousAccessEnabled(config.isAnonymousAccessEnabled());
appConfig.setAuthenticationEnabled(config.isAuthenticationEnabled());
appConfig.setSupportsCustomConnections(config.isCustomConnectionsEnabled());
String adminName = config.getAdminName();
String adminPassword = config.getAdminPassword();
if (CommonUtils.isEmpty(adminName)) {
// Grant admin permissions to the current user
WebUser curUser = webSession.getUser();
adminName = curUser == null ? null : curUser.getUserId();
adminPassword = null;
}
// Patch configuration by services
for (DBWServiceServerConfigurator wsc : WebServiceRegistry.getInstance().getWebServices(DBWServiceServerConfigurator.class)) {
try {
wsc.configureServer(CBApplication.getInstance(), webSession, appConfig);
} catch (Exception e) {
log.warn("Error configuring server by web service " + wsc.getClass().getName(), e);
}
}
CBApplication.getInstance().finishConfiguration(
config.getServerName(),
config.getAdminName(),
config.getAdminPassword(),
adminName,
adminPassword,
config.getSessionExpireTime(),
appConfig);
// Refresh active session
webSession.forceUserRefresh(null);
} catch (Throwable e) {
@@ -84,8 +84,9 @@ export class ConnectionsAdministrationController {
.filter(Boolean);
const confirmed = await this.commonDialogService.open(ConfirmationDialog, {
title: 'authentication_administration_confirm_user_deletion',
message: `Would you like to delete connections: ${connectionNames.join(', ')}`,
title: 'authentication_administration_confirm_connection_deletion',
message: `You're going to delete these connections: ${connectionNames.join(', ')}. Are you sure?`,
confirmActionText: 'ui_delete',
});
if (!confirmed) {
@@ -83,7 +83,7 @@ export class ConnectionsManagerService {
const confirmed = await this.commonDialogService.open(ConfirmationDialog, {
title: 'app_shared_navigationTree_delete_connection_confirm',
message: `Would you like to delete ${connection.name} connection?`,
message: `You're going to delete ${connection.name} connection. Are you sure?`,
confirmActionText: 'ui_delete',
});
if (!confirmed) {
@@ -99,7 +99,8 @@ export class UsersAdministrationController {
const confirmed = await this.commonDialogService.open(ConfirmationDialog, {
title: 'authentication_administration_confirm_user_deletion',
message: `Would you like to delete users: ${deletionList.join(', ')}`,
message: `You're going to delete these users: ${deletionList.join(', ')}. Are you sure?`,
confirmActionText: 'ui_delete',
});
if (!confirmed) {
@@ -14,6 +14,7 @@ export default [
['authentication_administration_user_info', 'Info'],
['authentication_administration_item', 'Users'],
['authentication_administration_confirm_user_deletion', 'Confirm user deletion'],
['authentication_administration_confirm_connection_deletion', 'Confirm connection deletion'],
['authentication_administration_user_updated', 'User updated'],
['authentication_administration_user_created', 'User was created successfully'],
['authentication_user_name', 'User name'],
@@ -14,6 +14,7 @@ export default [
['authentication_administration_user_info', 'Общее'],
['authentication_administration_item', 'Пользователи'],
['authentication_administration_confirm_user_deletion', 'Подтвердите удаление'],
['authentication_administration_confirm_connection_deletion', 'Подтвердите удаление'],
['authentication_administration_user_updated', 'User updated'],
['authentication_administration_user_created', 'Пользователь создан успешно'],
['authentication_user_name', 'Имя'],