mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-10-16 14:50:15 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
549e55ef3e | ||
|
|
99b0c11f2b | ||
|
|
466af8f750 | ||
|
|
4523144d9f | ||
|
|
221bef13a6 | ||
|
|
3b2fd282c9 | ||
|
|
6828098650 | ||
|
|
fffb3a0842 | ||
|
|
f345e5e25b |
@@ -18,4 +18,4 @@ echo "Copy static content"
|
||||
|
||||
cp -rp ../webapp/packages/product-default/lib/* cloudbeaver/web
|
||||
|
||||
echo "Cloudbeaver is ready. Run run-server.bat in cloudbeaver folder to start the server."
|
||||
echo "Cloudbeaver is ready. Run run-server.sh in cloudbeaver folder to start the server."
|
||||
|
||||
+3
-1
@@ -114,7 +114,9 @@ public abstract class BaseWebSession extends AbstractSessionPersistent {
|
||||
public synchronized void refreshUserData() {
|
||||
try {
|
||||
userContext.refreshPermissions();
|
||||
userContext.refreshAccessibleProjects();
|
||||
if (userContext.isAuthorizedInSecurityManager()) {
|
||||
userContext.refreshAccessibleProjects();
|
||||
}
|
||||
} catch (DBException e) {
|
||||
addSessionError(e);
|
||||
log.error("Error refreshing accessible projects", e);
|
||||
|
||||
+5
-5
@@ -214,12 +214,12 @@ public class WebDatabaseDriverInfo {
|
||||
|
||||
@Property
|
||||
public String[] getApplicableNetworkHandlers() {
|
||||
if (driver.isEmbedded()) {
|
||||
return new String[0];
|
||||
if (!driver.isEmbedded() || CommonUtils.toBoolean(driver.getDriverParameter(DBConstants.DRIVER_PARAM_ENABLE_NETWORK_PARAMETERS))) {
|
||||
return NetworkHandlerRegistry.getInstance().getDescriptors(driver).stream()
|
||||
.filter(h -> !h.isDesktopHandler())
|
||||
.map(NetworkHandlerDescriptor::getId).toArray(String[]::new);
|
||||
}
|
||||
return NetworkHandlerRegistry.getInstance().getDescriptors(driver).stream()
|
||||
.filter(h -> !h.isDesktopHandler())
|
||||
.map(NetworkHandlerDescriptor::getId).toArray(String[]::new);
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Property
|
||||
|
||||
@@ -48,6 +48,7 @@ import org.jkiss.dbeaver.model.app.DBPApplication;
|
||||
import org.jkiss.dbeaver.model.app.DBPPlatform;
|
||||
import org.jkiss.dbeaver.model.auth.AuthInfo;
|
||||
import org.jkiss.dbeaver.model.auth.SMCredentialsProvider;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDriver;
|
||||
import org.jkiss.dbeaver.model.data.json.JSONUtils;
|
||||
import org.jkiss.dbeaver.model.navigator.DBNBrowseSettings;
|
||||
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
|
||||
@@ -260,6 +261,7 @@ public abstract class CBApplication extends BaseWebApplication implements WebAut
|
||||
log.error(e);
|
||||
return;
|
||||
}
|
||||
refreshDisabledDriversConfig();
|
||||
|
||||
configurationMode = CommonUtils.isEmpty(serverName);
|
||||
|
||||
@@ -541,7 +543,6 @@ public abstract class CBApplication extends BaseWebApplication implements WebAut
|
||||
log.debug("Runtime configuration [" + runtimeConfigFile.getAbsolutePath() + "]");
|
||||
parseConfiguration(runtimeConfigFile);
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
@@ -1216,6 +1217,11 @@ public abstract class CBApplication extends BaseWebApplication implements WebAut
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getLicenseStatus() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@@ -1333,4 +1339,16 @@ public abstract class CBApplication extends BaseWebApplication implements WebAut
|
||||
}
|
||||
eventController.addEvent(new WSServerConfigurationChangedEvent(sessionId, null));
|
||||
}
|
||||
|
||||
private void refreshDisabledDriversConfig() {
|
||||
CBAppConfig config = getAppConfiguration();
|
||||
Set<String> disabledDrivers = new LinkedHashSet<>(Arrays.asList(config.getDisabledDrivers()));
|
||||
for (DBPDriver driver : CBPlatform.getInstance().getApplicableDrivers()) {
|
||||
if (!driver.isEmbedded() || config.isDriverForceEnabled(driver.getFullId())) {
|
||||
continue;
|
||||
}
|
||||
disabledDrivers.add(driver.getFullId());
|
||||
}
|
||||
config.setDisabledDrivers(disabledDrivers.toArray(new String[0]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,8 +119,6 @@ public class CBPlatform extends BasePlatformImpl {
|
||||
|
||||
refreshApplicableDrivers();
|
||||
|
||||
refreshDisabledDriversConfig();
|
||||
|
||||
new WebSessionMonitorJob(this)
|
||||
.scheduleMonitor();
|
||||
|
||||
@@ -293,18 +291,6 @@ public class CBPlatform extends BasePlatformImpl {
|
||||
log.info("Available drivers: " + applicableDrivers.stream().map(DBPDriver::getFullName).collect(Collectors.joining(",")));
|
||||
}
|
||||
|
||||
private void refreshDisabledDriversConfig() {
|
||||
CBAppConfig config = application.getAppConfiguration();
|
||||
Set<String> disabledDrivers = new LinkedHashSet<>(Arrays.asList(config.getDisabledDrivers()));
|
||||
for (DBPDriver driver : applicableDrivers) {
|
||||
if (!driver.isEmbedded() || config.isDriverForceEnabled(driver.getFullId())) {
|
||||
continue;
|
||||
}
|
||||
disabledDrivers.add(driver.getFullId());
|
||||
}
|
||||
config.setDisabledDrivers(disabledDrivers.toArray(new String[0]));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DBFileController createFileController() {
|
||||
|
||||
+6
-1
@@ -265,8 +265,13 @@ public abstract class WebServiceBindingBase<API_TYPE extends DBWService> impleme
|
||||
// Check license
|
||||
if (application.isLicenseRequired() && !application.isLicenseValid()) {
|
||||
if (!ArrayUtils.contains(reqPermissions, DBWConstants.PERMISSION_ADMIN)) {
|
||||
String errorMessage = "Invalid server license";
|
||||
String licenseStatus = application.getLicenseStatus();
|
||||
if (licenseStatus != null) {
|
||||
errorMessage = errorMessage + ": " + licenseStatus;
|
||||
}
|
||||
// Only admin permissions are allowed
|
||||
throw new DBWebExceptionLicenseRequired("Invalid server license");
|
||||
throw new DBWebExceptionLicenseRequired(errorMessage);
|
||||
}
|
||||
}
|
||||
// Check permissions
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
<configuration>
|
||||
<propertyGroup label="Configuration">
|
||||
<property id="logout-url" label="Logout url" type="string" description="Logout url"/>
|
||||
<property id="user-header" label="User header name" type="string" description="User header name"/>
|
||||
<property id="team-header" label="Team name" type="string" description="Team header name"/>
|
||||
<property id="user-header" label="Username header" type="string" description="Username header"/>
|
||||
<property id="team-header" label="Team header" type="string" description="Team header"/>
|
||||
<property id="team-delimiter" label="Team delimiter symbol" type="string" description="Team delimiter symbol, default: |"/>
|
||||
<property id="first-name-header" label="First name header" type="string" description="First name header name"/>
|
||||
<property id="last-name-header" label="Last name header" type="string" description="Last name header name"/>
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import '@testing-library/jest-dom';
|
||||
|
||||
import { coreBrowserManifest } from '@cloudbeaver/core-browser';
|
||||
import { coreClientActivityManifest } from '@cloudbeaver/core-client-activity';
|
||||
import { coreEventsManifest } from '@cloudbeaver/core-events';
|
||||
import { coreLocalizationManifest } from '@cloudbeaver/core-localization';
|
||||
import { corePluginManifest } from '@cloudbeaver/core-plugin';
|
||||
import { coreProductManifest } from '@cloudbeaver/core-product';
|
||||
import { coreRootManifest, ServerConfigResource } from '@cloudbeaver/core-root';
|
||||
import { createGQLEndpoint } from '@cloudbeaver/core-root/dist/__custom_mocks__/createGQLEndpoint';
|
||||
import { mockAppInit } from '@cloudbeaver/core-root/dist/__custom_mocks__/mockAppInit';
|
||||
import { mockGraphQL } from '@cloudbeaver/core-root/dist/__custom_mocks__/mockGraphQL';
|
||||
import { mockServerConfig } from '@cloudbeaver/core-root/dist/__custom_mocks__/resolvers/mockServerConfig';
|
||||
import { coreSDKManifest } from '@cloudbeaver/core-sdk';
|
||||
import { coreSettingsManifest } from '@cloudbeaver/core-settings';
|
||||
import { createApp } from '@cloudbeaver/tests-runner';
|
||||
|
||||
import { AdministrationSettings, AdministrationSettingsService } from './AdministrationSettingsService';
|
||||
import { coreAdministrationManifest } from './manifest';
|
||||
|
||||
const endpoint = createGQLEndpoint();
|
||||
const app = createApp(
|
||||
coreAdministrationManifest,
|
||||
coreEventsManifest,
|
||||
corePluginManifest,
|
||||
coreProductManifest,
|
||||
coreRootManifest,
|
||||
coreSDKManifest,
|
||||
coreSettingsManifest,
|
||||
coreBrowserManifest,
|
||||
// coreRoutingManifest,
|
||||
// coreThemingManifest,
|
||||
coreLocalizationManifest,
|
||||
coreClientActivityManifest,
|
||||
);
|
||||
|
||||
const server = mockGraphQL(...mockAppInit(endpoint));
|
||||
|
||||
beforeAll(() => app.init());
|
||||
|
||||
const testValue = ['none'];
|
||||
|
||||
const equalConfig = {
|
||||
core: {
|
||||
administration: {
|
||||
baseFeatures: testValue,
|
||||
} as AdministrationSettings,
|
||||
},
|
||||
};
|
||||
|
||||
test('Read settings', async () => {
|
||||
const settings = app.injector.getServiceByClass(AdministrationSettingsService);
|
||||
const config = app.injector.getServiceByClass(ServerConfigResource);
|
||||
|
||||
server.use(endpoint.query('serverConfig', mockServerConfig(equalConfig)));
|
||||
|
||||
await config.refresh();
|
||||
|
||||
expect(settings.settings.getValue('baseFeatures')).toEqual(testValue);
|
||||
});
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
import { PluginManagerService, PluginSettings } from '@cloudbeaver/core-plugin';
|
||||
import { schema } from '@cloudbeaver/core-utils';
|
||||
|
||||
const settingsSchema = schema.object({
|
||||
baseFeatures: schema.array(schema.string()).default([]),
|
||||
});
|
||||
|
||||
export type AdministrationSettings = schema.infer<typeof settingsSchema>;
|
||||
|
||||
@injectable()
|
||||
export class AdministrationSettingsService {
|
||||
readonly settings: PluginSettings<typeof settingsSchema>;
|
||||
|
||||
constructor(private readonly pluginManagerService: PluginManagerService) {
|
||||
this.settings = this.pluginManagerService.createSettings('administration', 'core', settingsSchema);
|
||||
}
|
||||
|
||||
isBase(feature: string): boolean {
|
||||
return this.getBase().includes(feature);
|
||||
}
|
||||
|
||||
getBase(): string[] {
|
||||
return this.settings.getValue('baseFeatures');
|
||||
}
|
||||
}
|
||||
@@ -9,5 +9,4 @@ export * from './AdministrationScreen/AdministrationScreenService';
|
||||
export * from './AdministrationScreen/ConfigurationWizard/ConfigurationWizardService';
|
||||
export * from './DataContext/DATA_CONTEXT_ADMINISTRATION_ITEM_ROUTE';
|
||||
export * from './AdministrationLocaleService';
|
||||
export * from './AdministrationSettingsService';
|
||||
export * from './PermissionsResource';
|
||||
|
||||
@@ -11,7 +11,6 @@ import { AdministrationItemService } from './AdministrationItem/AdministrationIt
|
||||
import { AdministrationLocaleService } from './AdministrationLocaleService';
|
||||
import { AdministrationScreenService } from './AdministrationScreen/AdministrationScreenService';
|
||||
import { ConfigurationWizardService } from './AdministrationScreen/ConfigurationWizard/ConfigurationWizardService';
|
||||
import { AdministrationSettingsService } from './AdministrationSettingsService';
|
||||
import { PermissionsResource } from './PermissionsResource';
|
||||
|
||||
export const coreAdministrationManifest: PluginManifest = {
|
||||
@@ -19,12 +18,5 @@ export const coreAdministrationManifest: PluginManifest = {
|
||||
name: 'Core Administration',
|
||||
},
|
||||
|
||||
providers: [
|
||||
AdministrationItemService,
|
||||
PermissionsResource,
|
||||
AdministrationScreenService,
|
||||
ConfigurationWizardService,
|
||||
AdministrationLocaleService,
|
||||
AdministrationSettingsService,
|
||||
],
|
||||
providers: [AdministrationItemService, PermissionsResource, AdministrationScreenService, ConfigurationWizardService, AdministrationLocaleService],
|
||||
};
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { makeObservable, observable } from 'mobx';
|
||||
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
import { CachedDataResource } from '@cloudbeaver/core-resource';
|
||||
import { GraphQLService, WebFeatureSet } from '@cloudbeaver/core-sdk';
|
||||
@@ -16,10 +18,24 @@ export type ApplicationFeature = WebFeatureSet;
|
||||
|
||||
@injectable()
|
||||
export class FeaturesResource extends CachedDataResource<ApplicationFeature[]> {
|
||||
private baseFeatures: string[];
|
||||
constructor(private readonly graphQLService: GraphQLService, permissionsResource: SessionPermissionsResource) {
|
||||
super(() => []);
|
||||
|
||||
this.baseFeatures = [];
|
||||
permissionsResource.require(this, EAdminPermission.admin).outdateResource(this);
|
||||
|
||||
makeObservable<this, 'baseFeatures'>(this, {
|
||||
baseFeatures: observable,
|
||||
});
|
||||
}
|
||||
|
||||
isBase(id: string) {
|
||||
return this.baseFeatures.includes(id);
|
||||
}
|
||||
|
||||
setBaseFeatures(features: string[]) {
|
||||
this.baseFeatures = features;
|
||||
}
|
||||
|
||||
protected async loader(): Promise<ApplicationFeature[]> {
|
||||
|
||||
@@ -77,3 +77,4 @@ export * from './removeLineBreak';
|
||||
export * from './replaceSubstring';
|
||||
export * from './formatNumber';
|
||||
export * from './withTimestamp';
|
||||
export * from './toSafeHtmlString';
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { toSafeHtmlString } from './toSafeHtmlString';
|
||||
|
||||
describe('toSafeHtmlString', () => {
|
||||
it('should make html string safe', () => {
|
||||
const input = '<script>alert("some unsafe action")</script>';
|
||||
const output = toSafeHtmlString(input);
|
||||
expect(output).toBe('<script>alert("some unsafe action")</script>');
|
||||
});
|
||||
|
||||
it('should return empty string', () => {
|
||||
const input = '';
|
||||
const output = toSafeHtmlString(input);
|
||||
expect(output).toBe('');
|
||||
});
|
||||
|
||||
it('should return the same string', () => {
|
||||
const input = 'some safe string';
|
||||
const output = toSafeHtmlString(input);
|
||||
expect(output).toBe(input);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
export function toSafeHtmlString(dirty: string): string {
|
||||
const el = document.createElement('div');
|
||||
el.innerText = el.textContent = dirty;
|
||||
dirty = el.innerHTML;
|
||||
|
||||
return dirty;
|
||||
}
|
||||
+1
-4
@@ -8,9 +8,7 @@
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useContext } from 'react';
|
||||
|
||||
import { AdministrationSettingsService } from '@cloudbeaver/core-administration';
|
||||
import { FormContext, GroupTitle, PlaceholderComponent, Switch, useResource, useTranslate } from '@cloudbeaver/core-blocks';
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
import { FeaturesResource } from '@cloudbeaver/core-root';
|
||||
|
||||
import type { IConfigurationPlaceholderProps } from '../ServerConfigurationService';
|
||||
@@ -23,7 +21,6 @@ export const ServerConfigurationFeaturesForm: PlaceholderComponent<IConfiguratio
|
||||
throw new Error('Form state should be provided');
|
||||
}
|
||||
|
||||
const administrationSettingsService = useService(AdministrationSettingsService);
|
||||
const features = useResource(ServerConfigurationFeaturesForm, FeaturesResource, configurationWizard ? null : undefined);
|
||||
const translate = useTranslate();
|
||||
|
||||
@@ -41,7 +38,7 @@ export const ServerConfigurationFeaturesForm: PlaceholderComponent<IConfiguratio
|
||||
name="enabledFeatures"
|
||||
state={serverConfig}
|
||||
description={feature.description}
|
||||
disabled={administrationSettingsService.isBase(feature.id)}
|
||||
disabled={features.resource.isBase(feature.id)}
|
||||
mod={['primary']}
|
||||
small
|
||||
>
|
||||
|
||||
+5
-1
@@ -5,7 +5,7 @@
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { action, makeObservable, observable } from 'mobx';
|
||||
import { action, computed, makeObservable, observable } from 'mobx';
|
||||
|
||||
import { DataTypeLogicalOperation, ResultDataFormat, SqlResultColumn } from '@cloudbeaver/core-sdk';
|
||||
|
||||
@@ -55,6 +55,10 @@ export class ResultSetViewAction extends DatabaseDataAction<any, IDatabaseResult
|
||||
makeObservable<this, 'columnsOrder'>(this, {
|
||||
columnsOrder: observable,
|
||||
setColumnOrder: action,
|
||||
rows: computed,
|
||||
rowKeys: computed,
|
||||
columns: computed,
|
||||
columnKeys: computed,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -6429,9 +6429,9 @@ caniuse-api@^3.0.0:
|
||||
lodash.uniq "^4.5.0"
|
||||
|
||||
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001538, caniuse-lite@^1.0.30001565:
|
||||
version "1.0.30001566"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001566.tgz#61a8e17caf3752e3e426d4239c549ebbb37fef0d"
|
||||
integrity sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA==
|
||||
version "1.0.30001591"
|
||||
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001591.tgz"
|
||||
integrity sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==
|
||||
|
||||
capital-case@^1.0.4:
|
||||
version "1.0.4"
|
||||
|
||||
Reference in New Issue
Block a user