diff --git a/deploy/build.bat b/deploy/build.bat index 933ab320bf..8a4bcaf96b 100644 --- a/deploy/build.bat +++ b/deploy/build.bat @@ -27,7 +27,7 @@ xcopy /E /Q ..\server\product\web-server\target\products\io.cloudbeaver.product\ copy scripts\run-server.bat cloudbeaver >NUL mkdir cloudbeaver\workspace\GlobalConfiguration xcopy /E /Q ..\samples\sample-databases\GlobalConfiguration cloudbeaver\workspace\GlobalConfiguration >NUL -copy ..\samples\sample-databases\cloudbeaver-sample.conf cloudbeaver\conf\cloudbeaver.conf >NUL +copy ..\samples\sample-databases\*.conf cloudbeaver\conf >NUL echo "Build static content" diff --git a/deploy/build.sh b/deploy/build.sh index 85d0e30897..cce02908ae 100755 --- a/deploy/build.sh +++ b/deploy/build.sh @@ -31,7 +31,7 @@ cp -rp ../server/product/web-server/target/products/io.cloudbeaver.product/all/a cp -p ./scripts/run-server.sh ./cloudbeaver mkdir ./cloudbeaver/workspace/GlobalConfiguration cp -rp ../samples/sample-databases/GlobalConfiguration cloudbeaver/workspace -cp ../samples/sample-databases/cloudbeaver-sample.conf cloudbeaver/conf/cloudbeaver.conf +cp ../samples/sample-databases/*.conf cloudbeaver/conf/ echo "Build static content" diff --git a/samples/sample-databases/cloudbeaver-sample.conf b/samples/sample-databases/cloudbeaver.conf similarity index 59% rename from samples/sample-databases/cloudbeaver-sample.conf rename to samples/sample-databases/cloudbeaver.conf index c088199f12..a64065902e 100644 --- a/samples/sample-databases/cloudbeaver-sample.conf +++ b/samples/sample-databases/cloudbeaver.conf @@ -25,31 +25,13 @@ createDatabase: true, + initialDataConfiguration: "conf/initial-data.conf", + pool: { minIdleConnections: 4, maxIdleConnections: 10, maxConnections: 100, validationQuery: "SELECT 1" - }, - - initialData: { - adminName: "cbadmin", - adminPassword: "changeme20", - - roles: [ - { - id: "admin", - name: "Admin", - description: "Administrative access. Has all permissions.", - permissions: [ "public,admin" ] - }, - { - id: "user", - name: "User", - description: "Standard user.", - permissions: [ "public" ] - } - ] } } diff --git a/samples/sample-databases/initial-data.conf b/samples/sample-databases/initial-data.conf new file mode 100644 index 0000000000..d0adf85031 --- /dev/null +++ b/samples/sample-databases/initial-data.conf @@ -0,0 +1,19 @@ +initialData: { + adminName: "cbadmin", + adminPassword: "changeme20", + + roles: [ + { + id: "admin", + name: "Admin", + description: "Administrative access. Has all permissions.", + permissions: [ "public,admin" ] + }, + { + id: "user", + name: "User", + description: "Standard user.", + permissions: [ "public" ] + } + ] +} diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBApplication.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBApplication.java index 9f168742d4..2ae98e29d3 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBApplication.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBApplication.java @@ -63,6 +63,7 @@ public class CBApplication extends BaseApplicationImpl { private String workspaceLocation = CBConstants.DEFAULT_WORKSPACE_LOCATION; private String driversLocation = CBConstants.DEFAULT_DRIVERS_LOCATION; + private File homeDirectory; private Map productConfiguration = new HashMap<>(); private CBAppConfig appConfiguration; @@ -101,6 +102,10 @@ public class CBApplication extends BaseApplicationImpl { return driversLocation; } + public File getHomeDirectory() { + return homeDirectory; + } + public long getMaxSessionIdleTime() { return maxSessionIdleTime; } @@ -242,6 +247,7 @@ public class CBApplication extends BaseApplicationImpl { if (CommonUtils.isEmpty(homeFolder)) { homeFolder = "."; } + homeDirectory = new File(homeFolder); String productConfigPath = null; Gson gson = new GsonBuilder().setLenient().create(); @@ -252,13 +258,13 @@ public class CBApplication extends BaseApplicationImpl { Map serverConfig = JSONUtils.getObject(configProps, "server"); serverPort = JSONUtils.getInteger(serverConfig, CBConstants.PARAM_SERVER_PORT, CBConstants.DEFAULT_SERVER_PORT); serverName = JSONUtils.getString(serverConfig, CBConstants.PARAM_SERVER_NAME, CBConstants.DEFAULT_SERVER_NAME); - contentRoot = this.getRelativePath( + contentRoot = getRelativePath( JSONUtils.getString(serverConfig, CBConstants.PARAM_CONTENT_ROOT, CBConstants.DEFAULT_CONTENT_ROOT), homeFolder); rootURI = JSONUtils.getString(serverConfig, CBConstants.PARAM_ROOT_URI, CBConstants.DEFAULT_ROOT_URI); servicesURI = JSONUtils.getString(serverConfig, CBConstants.PARAM_SERVICES_URI, CBConstants.DEFAULT_SERVICES_URI); - driversLocation = this.getRelativePath( + driversLocation = getRelativePath( JSONUtils.getString(serverConfig, CBConstants.PARAM_DRIVERS_LOCATION, CBConstants.DEFAULT_DRIVERS_LOCATION), homeFolder); - workspaceLocation = this.getRelativePath( + workspaceLocation = getRelativePath( JSONUtils.getString(serverConfig, CBConstants.PARAM_WORKSPACE_LOCATION, CBConstants.DEFAULT_WORKSPACE_LOCATION), homeFolder); maxSessionIdleTime = JSONUtils.getLong(serverConfig, CBConstants.PARAM_SESSION_EXPIRE_PERIOD, CBConstants.MAX_SESSION_IDLE_TIME); @@ -271,7 +277,7 @@ public class CBApplication extends BaseApplicationImpl { databaseConfiguration = gson.fromJson( gson.toJsonTree(JSONUtils.getObject(serverConfig, "database")), CBDatabaseConfig.class); - productConfigPath = this.getRelativePath( + productConfigPath = getRelativePath( JSONUtils.getString(serverConfig, CBConstants.PARAM_PRODUCT_CONFIGURATION, CBConstants.DEFAULT_PRODUCT_CONFIGURATION), homeFolder); } catch (IOException e) { log.error("Error parsing server configuration", e); @@ -295,7 +301,11 @@ public class CBApplication extends BaseApplicationImpl { } } - private String getRelativePath(String path, String curDir) { + static String getRelativePath(String path, String curDir) { + return getRelativePath(path, new File(curDir)); + } + + static String getRelativePath(String path, File curDir) { if (path.startsWith("/") || path.length() > 2 && path.charAt(1) == ':') { return path; } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBDatabase.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBDatabase.java index 3097ae5f85..e01aa425bf 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBDatabase.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBDatabase.java @@ -16,6 +16,8 @@ */ package io.cloudbeaver.server; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import io.cloudbeaver.DBWSecurityController; import io.cloudbeaver.auth.provider.local.LocalAuthProvider; import io.cloudbeaver.model.user.WebRole; @@ -41,8 +43,7 @@ import org.jkiss.dbeaver.utils.SystemVariablesResolver; import org.jkiss.utils.CommonUtils; import org.jkiss.utils.IOUtils; -import java.io.ByteArrayOutputStream; -import java.io.InputStream; +import java.io.*; import java.nio.charset.StandardCharsets; import java.sql.*; import java.util.*; @@ -56,7 +57,7 @@ public class CBDatabase { private static final Log log = Log.getLog(CBDatabase.class); public static final String SCHEMA_CREATE_SQL_PATH = "db/cb-schema-create.sql"; - private static final String CURRENT_SCHEMA_VERSION = "2.beta"; + private static final String CURRENT_SCHEMA_VERSION = "5.beta"; private final CBApplication application; private final CBDatabaseConfig databaseConfiguration; @@ -231,46 +232,59 @@ public class CBDatabase { private void fillInitialData() throws DBCException { // Fill initial data DBWSecurityController serverController = application.getSecurityController(); - CBDatabaseConfig.InitialData initialData = databaseConfiguration.getInitialData(); - - WebUser adminUser = null; - if (!CommonUtils.isEmpty(initialData.getAdminName())) { - // Create admin user - adminUser = new WebUser(initialData.getAdminName()); - serverController.createUser(adminUser); - - String userPassword = initialData.getAdminPassword(); - - // This is how client password will be transmitted from client - String clientPassword = LocalAuthProvider.makeClientPasswordHash(adminUser.getUserId(), userPassword); - - Map credentials = new LinkedHashMap<>(); - credentials.put(LocalAuthProvider.CRED_USER, adminUser.getUserId()); - credentials.put(LocalAuthProvider.CRED_PASSWORD, clientPassword); - - WebAuthProviderDescriptor authProvider = WebServiceRegistry.getInstance().getAuthProvider(LocalAuthProvider.PROVIDER_ID); - if (authProvider != null) { - serverController.setUserCredentials(adminUser.getUserId(), authProvider, credentials); - } + String initialDataPath = databaseConfiguration.getInitialDataConfiguration(); + if (CommonUtils.isEmpty(initialDataPath)) { + return; } - if (!CommonUtils.isEmpty(initialData.getRoles())) { - // Create roles - for (WebRole role : initialData.getRoles()) { - serverController.createRole(role); - if (adminUser != null) { - serverController.setRolePermissions(role.getId(), role.getPermissions().toArray(new String[0]), adminUser.getUserId()); + initialDataPath = CBApplication.getRelativePath( + databaseConfiguration.getInitialDataConfiguration(), application.getHomeDirectory()); + + try (Reader reader = new InputStreamReader(new FileInputStream(initialDataPath), StandardCharsets.UTF_8)) { + Gson gson = new GsonBuilder().setLenient().create(); + CBDatabaseInitialData initialData = gson.fromJson(reader, CBDatabaseInitialData.class); + + WebUser adminUser = null; + if (!CommonUtils.isEmpty(initialData.getAdminName())) { + // Create admin user + adminUser = new WebUser(initialData.getAdminName()); + serverController.createUser(adminUser); + + String userPassword = initialData.getAdminPassword(); + + // This is how client password will be transmitted from client + String clientPassword = LocalAuthProvider.makeClientPasswordHash(adminUser.getUserId(), userPassword); + + Map credentials = new LinkedHashMap<>(); + credentials.put(LocalAuthProvider.CRED_USER, adminUser.getUserId()); + credentials.put(LocalAuthProvider.CRED_PASSWORD, clientPassword); + + WebAuthProviderDescriptor authProvider = WebServiceRegistry.getInstance().getAuthProvider(LocalAuthProvider.PROVIDER_ID); + if (authProvider != null) { + serverController.setUserCredentials(adminUser.getUserId(), authProvider, credentials); } } - } - if (adminUser != null) { - // Grant all roles - WebRole[] allRoles = serverController.readAllRoles(); - serverController.setUserRoles( - adminUser.getUserId(), - Arrays.stream(allRoles).map(WebRole::getId).toArray(String[]::new), - adminUser.getUserId()); + if (!CommonUtils.isEmpty(initialData.getRoles())) { + // Create roles + for (WebRole role : initialData.getRoles()) { + serverController.createRole(role); + if (adminUser != null) { + serverController.setRolePermissions(role.getId(), role.getPermissions().toArray(new String[0]), adminUser.getUserId()); + } + } + } + + if (adminUser != null) { + // Grant all roles + WebRole[] allRoles = serverController.readAllRoles(); + serverController.setUserRoles( + adminUser.getUserId(), + Arrays.stream(allRoles).map(WebRole::getId).toArray(String[]::new), + adminUser.getUserId()); + } + } catch (IOException e) { + log.error("Error loading initial data configuration", e); } } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBDatabaseConfig.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBDatabaseConfig.java index b1e6ae29a3..acf78fdff7 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBDatabaseConfig.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBDatabaseConfig.java @@ -16,14 +16,6 @@ */ package io.cloudbeaver.server; -import io.cloudbeaver.model.user.WebRole; -import org.jkiss.dbeaver.model.DBConstants; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.List; - /** * Database configuration */ @@ -35,9 +27,9 @@ public class CBDatabaseConfig { private boolean createDatabase = true; private boolean allowPublicAccess = true; + private String initialDataConfiguration; private final Pool pool = new Pool(); - private final InitialData initialData = new InitialData(); public static class Pool { private int minIdleConnections = 2; @@ -62,28 +54,6 @@ public class CBDatabaseConfig { } } - public static class InitialData { - private String adminName = "cbadmin"; - private String adminPassword = "cbadmin20"; - private List roles; - - public String getAdminName() { - return adminName; - } - - public String getAdminPassword() { - return adminPassword; - } - - public List getRoles() { - return roles; - } - - public void setRoles(List roles) { - this.roles = roles; - } - } - public String getDriver() { return driver; } @@ -112,11 +82,12 @@ public class CBDatabaseConfig { return allowPublicAccess; } + public String getInitialDataConfiguration() { + return initialDataConfiguration; + } + public Pool getPool() { return pool; } - public InitialData getInitialData() { - return initialData; - } } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBDatabaseInitialData.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBDatabaseInitialData.java new file mode 100644 index 0000000000..63c2faad00 --- /dev/null +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBDatabaseInitialData.java @@ -0,0 +1,43 @@ +/* + * 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.server; + +import io.cloudbeaver.model.user.WebRole; + +import java.util.List; + +class CBDatabaseInitialData { + private String adminName = "cbadmin"; + private String adminPassword = "cbadmin20"; + private List roles; + + public String getAdminName() { + return adminName; + } + + public String getAdminPassword() { + return adminPassword; + } + + public List getRoles() { + return roles; + } + + public void setRoles(List roles) { + this.roles = roles; + } +}