Skip to content

Commit

Permalink
Merge branch 'devel' into CB-5386-fix-npe
Browse files Browse the repository at this point in the history
  • Loading branch information
EvgeniaBzzz authored Aug 14, 2024
2 parents 0a08382 + 95046f0 commit 307dd43
Show file tree
Hide file tree
Showing 56 changed files with 597 additions and 233 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,6 @@ public void deleteResource(@NotNull String projectId, @NotNull String resourcePa
if (log.isDebugEnabled()) {
log.debug("Removing resource from '" + resourcePath + "' in project '" + projectId + "'" + (recursive ? " recursive" : ""));
}
validateResourcePath(resourcePath);
Path targetPath = getTargetPath(projectId, resourcePath);
doFileWriteOperation(projectId, targetPath, () -> {
if (!Files.exists(targetPath)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ public static void updateHandlerConfig(DBWHandlerConfiguration handlerConfig, We
private static void setSecureProperties(DBWHandlerConfiguration handlerConfig, WebNetworkHandlerConfigInput cfgInput, boolean ignoreNulls) {
var secureProperties = cfgInput.getSecureProperties();
if (secureProperties == null) {
if (!handlerConfig.isSavePassword()) {
// clear all secure properties from handler config
handlerConfig.setSecureProperties(Map.of());
}
return;
}
for (var pr : secureProperties.entrySet()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ type ServerConfig {

licenseRequired: Boolean!
licenseValid: Boolean!
licenseStatus: String @since(version: "24.1.5")

sessionExpireTime: Int!
localHostAddress: String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ public boolean isLicenseValid() {
return application.isLicenseValid();
}

@Property
public String getLicenseStatus() {
return application.getLicenseStatus();
}

@Property
public boolean isConfigurationMode() {
return application.isConfigurationMode();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
*/
package io.cloudbeaver.service;

import io.cloudbeaver.server.CBApplication;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.app.DBPApplication;

/**
* Web service implementation
*/
public interface DBWServiceInitializer extends DBWServiceBinding {

void initializeService(DBPApplication application) throws DBException;
void initializeService(CBApplication<?> application) throws DBException;

}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class AdministrationScreenService {
}

get publicDisabled(): boolean {
return this.serverConfigResource.publicDisabled;
return this.permissionsService.publicDisabled;
}

readonly ensurePermissions: IExecutor;
Expand Down
15 changes: 9 additions & 6 deletions webapp/packages/core-authentication/src/PasswordPolicyService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { computed, makeObservable } from 'mobx';

import { injectable } from '@cloudbeaver/core-di';
import { LocalizationService } from '@cloudbeaver/core-localization';
import { ServerConfigResource } from '@cloudbeaver/core-root';
import { PasswordPolicyResource } from '@cloudbeaver/core-root';
import type { PasswordPolicyConfig } from '@cloudbeaver/core-sdk';

const DEFAULT_PASSWORD_POLICY: PasswordPolicyConfig = {
Expand All @@ -25,22 +25,25 @@ type ValidationResult = { isValid: true; errorMessage: null } | { isValid: false
export class PasswordPolicyService {
get config(): PasswordPolicyConfig {
return {
minLength: this.serverConfigResource.data?.passwordPolicyConfiguration?.minLength || DEFAULT_PASSWORD_POLICY.minLength,
minNumberCount: this.serverConfigResource.data?.passwordPolicyConfiguration?.minNumberCount || DEFAULT_PASSWORD_POLICY.minNumberCount,
minSymbolCount: this.serverConfigResource.data?.passwordPolicyConfiguration?.minSymbolCount || DEFAULT_PASSWORD_POLICY.minSymbolCount,
requireMixedCase: this.serverConfigResource.data?.passwordPolicyConfiguration?.requireMixedCase || DEFAULT_PASSWORD_POLICY.requireMixedCase,
minLength: this.passwordPolicyResource.data?.minLength || DEFAULT_PASSWORD_POLICY.minLength,
minNumberCount: this.passwordPolicyResource.data?.minNumberCount || DEFAULT_PASSWORD_POLICY.minNumberCount,
minSymbolCount: this.passwordPolicyResource.data?.minSymbolCount || DEFAULT_PASSWORD_POLICY.minSymbolCount,
requireMixedCase: this.passwordPolicyResource.data?.requireMixedCase || DEFAULT_PASSWORD_POLICY.requireMixedCase,
};
}

constructor(
private readonly serverConfigResource: ServerConfigResource,
private readonly passwordPolicyResource: PasswordPolicyResource,
private readonly localizationService: LocalizationService,
) {
makeObservable(this, {
config: computed,
});
}

/**
* PasswordPolicyResource should be loaded before calling this method
*/
validatePassword(password: string): ValidationResult {
const trimmedPassword = password.trim();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,7 @@
display: none;
}
}

.uploadButton {
margin-top: 4px;
}
43 changes: 38 additions & 5 deletions webapp/packages/core-blocks/src/FormControls/Textarea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,14 @@
import { observer } from 'mobx-react-lite';
import { useCallback, useContext, useLayoutEffect, useRef } from 'react';

import { getTextFileReadingProcess } from '@cloudbeaver/core-utils';

import { Button } from '../Button';
import { filterLayoutFakeProps, getLayoutProps } from '../Containers/filterLayoutFakeProps';
import type { ILayoutSizeProps } from '../Containers/ILayoutSizeProps';
import { useTranslate } from '../localization/useTranslate';
import { s } from '../s';
import { UploadArea } from '../UploadArea';
import { useS } from '../useS';
import { Field } from './Field';
import { FieldDescription } from './FieldDescription';
Expand All @@ -24,6 +29,7 @@ type BaseProps = Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, 'onChan
labelTooltip?: string;
embedded?: boolean;
cursorInitiallyAtEnd?: boolean;
uploadable?: boolean;
};

type ControlledProps = BaseProps & {
Expand Down Expand Up @@ -56,25 +62,27 @@ export const Textarea: TextareaType = observer(function Textarea({
labelTooltip,
embedded,
cursorInitiallyAtEnd,
uploadable,
onChange = () => {},
...rest
}: ControlledProps | ObjectProps<any, any>) {
const translate = useTranslate();
const textareaRef = useRef<HTMLTextAreaElement | null>(null);
const layoutProps = getLayoutProps(rest);
rest = filterLayoutFakeProps(rest);
const styles = useS(textareaStyle);
const context = useContext(FormContext);

const handleChange = useCallback(
(event: React.ChangeEvent<HTMLTextAreaElement>) => {
(value: string) => {
if (state) {
state[name] = event.target.value;
state[name] = value;
}
if (onChange) {
onChange(event.target.value, name);
onChange(value, name);
}
if (context) {
context.change(event.target.value, name);
context.change(value, name);
}
},
[state, name, onChange],
Expand Down Expand Up @@ -102,9 +110,34 @@ export const Textarea: TextareaType = observer(function Textarea({
value={value ?? ''}
name={name}
data-embedded={embedded}
onChange={handleChange}
onChange={event => handleChange(event.target.value)}
/>
{description && <FieldDescription>{description}</FieldDescription>}
{uploadable && (
<UploadArea
className={s(styles, { uploadButton: true })}
disabled={rest.disabled || rest.readOnly}
reset
onChange={async event => {
const file = event.target.files?.[0];

if (!file) {
throw new Error('File is not found');
}

const process = getTextFileReadingProcess(file);
const value = await process.promise;

if (value) {
handleChange(value);
}
}}
>
<Button tag="div" disabled={rest.disabled || rest.readOnly} mod={['outlined']}>
{translate('ui_file')}
</Button>
</UploadArea>
)}
</Field>
);
});
3 changes: 3 additions & 0 deletions webapp/packages/core-blocks/src/usePasswordValidation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@
*/
import { PasswordPolicyService } from '@cloudbeaver/core-authentication';
import { useService } from '@cloudbeaver/core-di';
import { PasswordPolicyResource } from '@cloudbeaver/core-root';

import { useCustomInputValidation } from './FormControls/useCustomInputValidation';
import { useResource } from './ResourcesHooks/useResource';

export function usePasswordValidation() {
useResource(usePasswordValidation, PasswordPolicyResource, undefined);
const passwordPolicyService = useService(PasswordPolicyService);

const ref = useCustomInputValidation<string>(value => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export interface IConnectionFolderParam {
folderId: string;
}

export const CONNECTION_FOLDER_NAME_VALIDATION = /^(?!\.)[^\\/:\\"]+$/u;
export const CONNECTION_FOLDER_NAME_VALIDATION = /^(?!\.)[^\\/:\\"'<>|?*]+$/u;

export const ConnectionFolderProjectKey = resourceKeyAliasFactory('@connection-folder/project', (projectId: string) => ({ projectId }));

Expand Down
2 changes: 1 addition & 1 deletion webapp/packages/core-connections/src/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export default [
['connections_connection_edit_search_hosts', 'Host names'],
['connections_connection_address', 'Address'],
['connections_connection_folder', 'Folder'],
['connections_connection_folder_validation', "Folder's name may not contain the following symbols / : \" \\ and can't start with a dot"],
['connections_connection_folder_validation', "Folder's name may not contain the following symbols / : \" \\ ' <> | ? * and can't start with a dot"],
['connections_connection_name', 'Connection name'],
['connections_connection_access_user_or_team_name', 'User or Team name'],
['connections_connection_access_filter_placeholder', 'Search for user or team name'],
Expand Down
7 changes: 5 additions & 2 deletions webapp/packages/core-connections/src/locales/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,15 @@ export default [
['connections_connection_folder', 'Dossier'],
[
'connections_connection_folder_validation',
'Le nom du dossier ne peut pas contenir les symboles suivants : / : " \\ et ne peut pas commencer par un point',
'Le nom du dossier ne peut pas contenir les symboles suivants / : " \\ \' <> | ? * et ne peut pas commencer par un point',
],
['connections_connection_name', 'Nom de la connexion'],
['connections_connection_access_user_or_team_name', "Nom de l'utilisateur ou de l'équipe"],
['connections_connection_access_filter_placeholder', "Rechercher un nom d'utilisateur ou d'équipe"],
['connections_connection_access_admin_info', "Les administrateurs voient toutes les connexions à l'exception des connexions privées des autres utilisateurs."],
[
'connections_connection_access_admin_info',
"Les administrateurs voient toutes les connexions à l'exception des connexions privées des autres utilisateurs.",
],
['connections_connection_description', 'Description'],
['connections_connection_project', 'Projet'],
['connections_connection_driver', 'Pilote'],
Expand Down
2 changes: 1 addition & 1 deletion webapp/packages/core-connections/src/locales/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export default [
['connections_connection_edit_search_hosts', 'Host names'],
['connections_connection_address', 'Indirizzo'],
['connections_connection_folder', 'Folder'],
['connections_connection_folder_validation', "Folder's name may not contain the following symbols / : \" \\ and can't start with a dot"],
['connections_connection_folder_validation', "Folder's name may not contain the following symbols / : \" \\ ' <> | ? * and can't start with a dot"],
['connections_connection_name', 'Nome della connessione'],
['connections_connection_access_revoke', 'Revoca'],
['connections_connection_access_grant', 'Permetti'],
Expand Down
2 changes: 1 addition & 1 deletion webapp/packages/core-connections/src/locales/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export default [
['connections_connection_edit_search_hosts', 'Названия хостов'],
['connections_connection_address', 'Адрес'],
['connections_connection_folder', 'Папка'],
['connections_connection_folder_validation', 'Имя папки не может содержать следующие символы / : " \\ и не может начинаться с точки'],
['connections_connection_folder_validation', 'Имя папки не может содержать следующие символы / : " \\ \' <> | ? * и не может начинаться с точки'],
['connections_connection_name', 'Название подключения'],
['connections_connection_access_user_or_team_name', 'Имя пользователя или команды'],
['connections_connection_access_filter_placeholder', 'Поиск по имени пользователя или команде'],
Expand Down
2 changes: 1 addition & 1 deletion webapp/packages/core-connections/src/locales/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export default [
['connections_connection_edit_search_hosts', '主机名称'],
['connections_connection_address', '地址'],
['connections_connection_folder', 'Folder'],
['connections_connection_folder_validation', "Folder's name may not contain the following symbols / : \" \\ and can't start with a dot"],
['connections_connection_folder_validation', "Folder's name may not contain the following symbols / : \" \\ ' <> | ? * and can't start with a dot"],
['connections_connection_name', '连接名称'],
['connections_connection_access_admin_info', 'Administrators see all connections except private connections of other users.'],
['connections_connection_description', '描述'],
Expand Down
53 changes: 34 additions & 19 deletions webapp/packages/core-events/src/NotificationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,26 +80,41 @@ export class NotificationService {

const id = this.notificationNextId++;

const notification: INotification<TProps> = {
id,
uuid: options.uuid,
title: options.title,
message: options.message,
details: options.details,
isSilent: !!options.isSilent,
customComponent: options.customComponent,
extraProps: options.extraProps || ({} as TProps),
autoClose: options.autoClose,
persistent: options.persistent,
state: observable({ deleteDelay: 0 }),
timestamp: options.timestamp || Date.now(),
type,
close: delayDeleting => {
this.close(id, delayDeleting);
options.onClose?.(delayDeleting);
const notification: INotification<TProps> = observable(
{
id,
uuid: options.uuid,
title: options.title,
message: options.message,
details: options.details,
isSilent: !!options.isSilent,
customComponent: options.customComponent,
extraProps: options.extraProps || ({} as TProps),
autoClose: options.autoClose,
persistent: options.persistent,
state: observable({ deleteDelay: 0 }),
timestamp: options.timestamp || Date.now(),
type,
close: delayDeleting => {
this.close(id, delayDeleting);
options.onClose?.(delayDeleting);
},
showDetails: this.showDetails.bind(this, id),
},
{
title: observable.ref,
message: observable.ref,
details: observable.ref,
persistent: observable.ref,
isSilent: observable.ref,
customComponent: observable.ref,
extraProps: observable.ref,
autoClose: observable.ref,
type: observable.ref,
timestamp: observable.ref,
showDetails: observable.ref,
},
showDetails: this.showDetails.bind(this, id),
};
);

this.notificationList.addValue(notification);

Expand Down
6 changes: 3 additions & 3 deletions webapp/packages/core-projects/src/ProjectInfoResource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import { AppAuthService, UserInfoResource } from '@cloudbeaver/core-authentication';
import { injectable } from '@cloudbeaver/core-di';
import { CachedMapAllKey, CachedMapResource, resourceKeyList } from '@cloudbeaver/core-resource';
import { ServerConfigResource } from '@cloudbeaver/core-root';
import { PermissionsService } from '@cloudbeaver/core-root';
import { GraphQLService, RmResourceType, ProjectInfo as SchemaProjectInfo } from '@cloudbeaver/core-sdk';

import { createResourceOfType } from './createResourceOfType';
Expand All @@ -21,7 +21,7 @@ export class ProjectInfoResource extends CachedMapResource<string, ProjectInfo>
constructor(
private readonly graphQLService: GraphQLService,
private readonly userInfoResource: UserInfoResource,
serverConfigResource: ServerConfigResource,
permissionsService: PermissionsService,
appAuthService: AppAuthService,
) {
super(() => new Map(), []);
Expand All @@ -32,7 +32,7 @@ export class ProjectInfoResource extends CachedMapResource<string, ProjectInfo>
() => CachedMapAllKey,
);
appAuthService.requireAuthentication(this);
serverConfigResource.requirePublic(this);
permissionsService.requirePublic(this);
this.userInfoResource.onUserChange.addPostHandler(() => {
this.clear();
});
Expand Down
Loading

0 comments on commit 307dd43

Please sign in to comment.