Skip to content

Commit

Permalink
Merge branch 'devel' into CB-4346-session-doesnt-expire-after-30-min
Browse files Browse the repository at this point in the history
  • Loading branch information
EvgeniaBzzz authored Feb 23, 2024
2 parents 4069d98 + 888b29c commit 81c0879
Show file tree
Hide file tree
Showing 20 changed files with 112 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import io.cloudbeaver.service.DBWServiceServerConfigurator;
import io.cloudbeaver.service.admin.*;
import io.cloudbeaver.service.security.SMUtils;
import io.cloudbeaver.utils.WebAppUtils;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
Expand Down Expand Up @@ -257,7 +258,9 @@ public boolean grantUserTeam(@NotNull WebSession webSession, String user, String
if (grantor == null) {
throw new DBWebException("Cannot grant team in anonymous mode");
}
if (CommonUtils.equalObjects(user, webSession.getUser().getUserId())) {
if (!WebAppUtils.getWebApplication().isDistributed()
&& CommonUtils.equalObjects(user, webSession.getUser().getUserId())
) {
throw new DBWebException("You cannot edit your own permissions");
}
try {
Expand All @@ -281,7 +284,9 @@ public boolean revokeUserTeam(@NotNull WebSession webSession, String user, Strin
if (grantor == null) {
throw new DBWebException("Cannot revoke team in anonymous mode");
}
if (CommonUtils.equalObjects(user, webSession.getUser().getUserId())) {
if (!WebAppUtils.getWebApplication().isDistributed() &&
CommonUtils.equalObjects(user, webSession.getUser().getUserId())
) {
throw new DBWebException("You cannot edit your own permissions");
}
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;

public class WebDataTransferServlet extends WebServiceServletBase {

Expand Down Expand Up @@ -67,7 +68,7 @@ protected void processServiceRequest(WebSession session, HttpServletRequest requ
}
String fileName = taskInfo.getExportFileName();
if (!CommonUtils.isEmpty(fileName)) {
fileName += "." + WebDataTransferUtils.getProcessorFileExtension(processor);
fileName += "." + WebDataTransferUtils.getProcessorFileExtension(processor, taskInfo.getParameters().getProcessorProperties());
} else {
fileName = taskInfo.getDataFileId();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@
import org.jkiss.dbeaver.tools.transfer.registry.DataTransferProcessorDescriptor;
import org.jkiss.utils.CommonUtils;

import java.util.Map;

class WebDataTransferUtils {

private static final Log log = Log.getLog(WebDataTransferUtils.class);
public static final String EXTENSION = "extension";


public static String getProcessorFileExtension(DataTransferProcessorDescriptor processor) {
Expand All @@ -34,6 +37,14 @@ public static String getProcessorFileExtension(DataTransferProcessorDescriptor p
return CommonUtils.isEmpty(ext) ? "data" : ext;
}

public static String getProcessorFileExtension(DataTransferProcessorDescriptor processor, Map<String, Object> processorProperties) {
if (processorProperties != null && processorProperties.get(EXTENSION) != null) {
return CommonUtils.toString(processorProperties.get(EXTENSION), "data");
}

return getProcessorFileExtension(processor);
}

public static String normalizeFileName(
@NotNull String fileName,
@NotNull WebDataTransferOutputSettings outputSettings
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,15 @@ public WebAsyncTaskInfo dataTransferExportDataFromContainer(
}

@NotNull
private String makeUniqueFileName(WebSQLProcessor sqlProcessor, DataTransferProcessorDescriptor processor) {
private String makeUniqueFileName(
WebSQLProcessor sqlProcessor,
DataTransferProcessorDescriptor processor,
Map<String, Object> processorProperties
) {
if (processorProperties != null && processorProperties.get(StreamConsumerSettings.PROP_FILE_EXTENSION) != null) {
return sqlProcessor.getWebSession().getSessionId() + "_" + UUID.randomUUID() +
"." + processorProperties.get(StreamConsumerSettings.PROP_FILE_EXTENSION);
}
return sqlProcessor.getWebSession().getSessionId() + "_" + UUID.randomUUID() + "." + WebDataTransferUtils.getProcessorFileExtension(processor);
}

Expand Down Expand Up @@ -157,7 +165,8 @@ public void run(DBRProgressMonitor monitor) throws InvocationTargetException {
monitor.beginTask("Export data", 1);
try {
monitor.subTask("Export data using " + processor.getName());
Path exportFile = dataExportFolder.resolve(makeUniqueFileName(sqlProcessor, processor));
Path exportFile = dataExportFolder.resolve(
makeUniqueFileName(sqlProcessor, processor, parameters.getProcessorProperties()));
try {
exportData(monitor, processor, dataContainer, parameters, resultsInfo, exportFile);
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import type { ILayoutSizeProps } from '../../Containers/ILayoutSizeProps';
import { s } from '../../s';
import { useS } from '../../useS';
import { Field } from '../Field';
import { FieldDescription } from '../FieldDescription';
import { FieldLabel } from '../FieldLabel';
import { isControlPresented } from '../isControlPresented';
import { Checkbox, CheckboxBaseProps, CheckboxType, ICheckboxControlledProps, ICheckboxObjectProps } from './Checkbox';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
export interface IFormStateControl<TState extends Record<string, any>, TKey extends keyof TState> {
name: TKey;
state: TState;
defaultState?: TState;
defaultState?: Readonly<Partial<TState>>;
autoHide?: boolean;
mapState?: (value: TState[TKey]) => string;
mapValue?: (value: string) => TState[TKey];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export const InputFieldBase = observer<InputFieldBaseProps, HTMLInputElement>(
},
ref,
) {
const [uncontrolledInputValue, setUncontrolledInputValue] = useState(value);
const inputRef = useRef<HTMLInputElement | null>(null);
const mergedRef = useCombinedRef(inputRef, ref);
const capsLock = useCapsLockTracker();
Expand All @@ -81,6 +82,7 @@ export const InputFieldBase = observer<InputFieldBaseProps, HTMLInputElement>(

const handleChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
setUncontrolledInputValue(event.target.value);
onChange?.(event.target.value, name);
},
[name, onChange],
Expand All @@ -97,16 +99,21 @@ export const InputFieldBase = observer<InputFieldBaseProps, HTMLInputElement>(
}

uncontrolled ||= value === undefined;
if (!value) {
canShowPassword = false;
}

useLayoutEffect(() => {
if (uncontrolled && isNotNullDefined(value) && inputRef.current) {
inputRef.current.value = value;

if (uncontrolledInputValue !== value) {
setUncontrolledInputValue(value);
}
}
});

if (!uncontrolledInputValue) {
canShowPassword = false;
}

return (
<Field {...layoutProps} className={s(styles, {}, className)}>
<FieldLabel title={labelTooltip || rest.title} className={s(styles, { fieldLabel: true })} required={required}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const InputFieldState: InputFieldType = observer<InputFieldStateProps<any
<InputFieldBase
ref={ref}
name={name}
value={controlState.stringValue ?? controlState.defaultValue ?? ''}
value={(controlState.stringValue || controlState.defaultValue) ?? ''}
onChange={controlState.onChange}
{...rest}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { isNotNullDefined } from '@cloudbeaver/core-utils';
import { isNotNullDefined, isObject } from '@cloudbeaver/core-utils';

export function isControlPresented(name: string | undefined, state: any, defaultValue?: any): boolean {
if (isNotNullDefined(state) && isNotNullDefined(name)) {
if (typeof state === 'object' && name in state) {
return isNotNullDefined(state[name]);
export function isControlPresented(name: string | number | symbol | undefined, state: any, defaultValue?: any): boolean {
if (isObject(state) && isNotNullDefined(state) && isNotNullDefined(name)) {
if (name in state) {
return isNotNullDefined((state as Record<string | number | symbol, any>)[name]);
}
return defaultValue !== undefined;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,16 @@ export function useFormStateControl<TState extends Record<string, any>, TKey ext
onChange(inputValue as any, name as any);
}
});

let presented: boolean | undefined;

if (isNotNullDefined(defaultValue) && isObject(defaultValue)) {
presented = isControlPresented(name, defaultValue);
defaultValue = defaultValue[name];
}

if (isNotNullDefined(value) && isObject(value)) {
presented = presented || isControlPresented(name, value, defaultValue);
value = value[name];
}

Expand All @@ -48,11 +53,11 @@ export function useFormStateControl<TState extends Record<string, any>, TKey ext
stringValue = mapToString(value as any);
defaultStringValue = mapToString(defaultValue as any);
} else {
stringValue = value;
defaultStringValue = defaultValue;
stringValue = isNotNullDefined(value) ? String(value) : '';
defaultStringValue = isNotNullDefined(defaultValue) ? String(defaultValue) : '';
}

const hide = 'autoHide' in rest && !!rest.autoHide && !isControlPresented(String(name), stringValue, defaultStringValue);
const hide = 'autoHide' in rest && !!rest.autoHide && presented === false;

return { name, value, stringValue, defaultValue, defaultStringValue, hide, onChange: handleChange };
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export const RenderField = observer<RenderFieldProps>(function RenderField({
}

if (!editable) {
if (autoHide && !isControlPresented(property.id!, state)) {
if (autoHide && !isControlPresented(property.id, state)) {
return null;
}
return (
Expand Down Expand Up @@ -239,9 +239,8 @@ export const RenderField = observer<RenderFieldProps>(function RenderField({
labelTooltip={property.description || property.displayName}
name={property.id!}
state={state}
defaultState={defaultState}
defaultState={defaultState || { [property.id!]: defaultValue }}
autoHide={autoHide}
defaultValue={defaultValue}
description={property.hint}
placeholder={passwordSavedMessage}
disabled={disabled}
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-localization/src/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export default [
['ui_readonly', 'Read-only'],
['ui_test', 'Test'],
['ui_export', 'Export'],
['ui_you', 'You'],

['root_permission_denied', "You don't have permissions"],
['root_permission_no_permission', "You don't have permission for this action"],
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-localization/src/locales/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ export default [
['ui_readonly', 'In sola lettura'],
['ui_test', 'Test'],
['ui_export', 'Export'],
['ui_you', 'You'],

['root_permission_denied', 'Non hai i permessi'],
['app_root_session_expire_warning_title', 'La sessione sta per scadere'],
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-localization/src/locales/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ export default [
['ui_readonly', 'Доступно только для чтения'],
['ui_test', 'Проверить'],
['ui_export', 'Экспорт'],
['ui_you', 'Вы'],

['root_permission_denied', 'Отказано в доступе'],
['root_permission_no_permission', 'У вас нет разрешения на это действие'],
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-localization/src/locales/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ export default [
['ui_readonly', '只读'],
['ui_test', 'Test'],
['ui_export', 'Export'],
['ui_you', 'You'],

['root_permission_denied', '您没有权限'],
['root_permission_no_permission', '您没有权限执行此操作'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
} from '@cloudbeaver/core-blocks';
import { useService } from '@cloudbeaver/core-di';
import type { TLocalizationToken } from '@cloudbeaver/core-localization';
import { ServerConfigResource } from '@cloudbeaver/core-root';
import type { AdminUserInfoFragment } from '@cloudbeaver/core-sdk';

import { getFilteredUsers } from './getFilteredUsers';
Expand All @@ -47,6 +48,7 @@ export const GrantedUserList = observer<Props>(function GrantedUserList({ grante
const translate = useTranslate();

const usersResource = useService(UsersResource);
const serverConfigResource = useService(ServerConfigResource);

const [selectedSubjects] = useState<Map<any, boolean>>(() => observable(new Map()));
const [filterState] = useState<IFilterState>(() => observable({ filterValue: '' }));
Expand All @@ -70,6 +72,14 @@ export const GrantedUserList = observer<Props>(function GrantedUserList({ grante
}
}

function isEditable(userId: string) {
if (serverConfigResource.distributed) {
return true;
}

return !usersResource.isActiveUser(userId);
}

return (
<Group className={s(styles, { box: true })} box medium overflow>
<div className={s(styles, { innerBox: true })}>
Expand All @@ -82,33 +92,25 @@ export const GrantedUserList = observer<Props>(function GrantedUserList({ grante
</Button>
</GrantedUsersTableHeader>
<div className={s(styles, { tableBox: true })}>
<Table
className={s(styles, { table: true })}
keys={keys}
selectedItems={selectedSubjects}
isItemSelectable={item => !usersResource.isActiveUser(item)}
>
<Table className={s(styles, { table: true })} keys={keys} selectedItems={selectedSubjects} isItemSelectable={item => isEditable(item)}>
<GrantedUsersTableInnerHeader disabled={disabled} />
<TableBody>
{tableInfoText && (
<TableItem item="tableInfo" selectDisabled>
<TableColumnValue colSpan={5}>{translate(tableInfoText)}</TableColumnValue>
</TableItem>
)}
{users.map(user => {
const activeUser = usersResource.isActiveUser(user.userId);
return (
<GrantedUsersTableItem
key={user.userId}
id={user.userId}
name={`${user.userId}${activeUser ? ' (you)' : ''}`}
tooltip={activeUser ? translate('administration_teams_team_granted_users_permission_denied') : user.userId}
icon="/icons/user.svg"
iconTooltip={translate('authentication_user_icon_tooltip')}
disabled={disabled}
/>
);
})}
{users.map(user => (
<GrantedUsersTableItem
key={user.userId}
id={user.userId}
name={`${user.userId}${usersResource.isActiveUser(user.userId) ? ` (${translate('ui_you')})` : ''}`}
tooltip={isEditable(user.userId) ? user.userId : translate('administration_teams_team_granted_users_permission_denied')}
icon="/icons/user.svg"
iconTooltip={translate('authentication_user_icon_tooltip')}
disabled={disabled}
/>
))}
</TableBody>
</Table>
</div>
Expand Down
Loading

0 comments on commit 81c0879

Please sign in to comment.