feat(plugin-administration): CB-340 session expire time

This commit is contained in:
Wroud
2020-10-11 20:58:07 +03:00
parent 35a79def39
commit b95c470e7d
15 changed files with 195 additions and 90 deletions
@@ -2,37 +2,4 @@ export default [
['administration_menu_enter', 'Administration'],
['administration_menu_back', 'Back to app'],
['administration_configuration_wizard_title', 'Initial Server Configuration'],
['administration_configuration_wizard_welcome', 'Welcome'],
['administration_configuration_wizard_welcome_step_description', 'Welcome to CloudBeaver'],
['administration_configuration_wizard_welcome_title', 'Welcome to CloudBeaver, cloud database management system!'],
['administration_configuration_wizard_welcome_message', 'The easy configuration wizard will guide you through several simple steps to set up the CloudBeaver server. You will need to set server information and administrator credentials. You can also add first database connections here.'],
['administration_configuration_wizard_welcome_note', 'Note: you will be able to change these configuration parameters later on the administration panel.'],
['administration_configuration_wizard_configuration', 'Server configuration'],
['administration_configuration_wizard_configuration_step_description', 'Main server configuration'],
['administration_configuration_wizard_configuration_title', 'You can configure the main server parameters here.'],
['administration_configuration_wizard_configuration_message', 'Administrator is a super user who can configure server, set databases connections, manage other users and much more. Please, remember the entered password. It is not possible to recover administrator password automatically.'],
['administration_configuration_wizard_configuration_plugins', 'Configuration'],
['administration_configuration_wizard_configuration_server_info', 'Server Info'],
['administration_configuration_wizard_configuration_server_name', 'Server Name'],
['administration_configuration_wizard_configuration_admin', 'Administrator'],
['administration_configuration_wizard_configuration_admin_name', 'Admin user name'],
['administration_configuration_wizard_configuration_admin_password', 'Admin password'],
['administration_configuration_wizard_configuration_anonymous_access', 'Allow anonymous access'],
['administration_configuration_wizard_configuration_anonymous_access_description', 'Allows to work with CloudBeaver without user authentication'],
['administration_configuration_wizard_configuration_authentication', 'Enable users authentication'],
['administration_configuration_wizard_configuration_authentication_description', 'Allows users to authenticate. Otherwise only anonymous access is enabled'],
['administration_configuration_wizard_configuration_custom_connections', 'Enable custom connections'],
['administration_configuration_wizard_configuration_custom_connections_description', 'Allows users to create custom connections. Otherwise only administrator can create connections'],
['administration_configuration_wizard_configuration_navigator', 'Navigator'],
['administration_configuration_wizard_configuration_navigator_hide_folders', 'Hide Folders'],
['administration_configuration_wizard_configuration_navigator_hide_schemas', 'Hide Schemas'],
['administration_configuration_wizard_configuration_navigator_hide_virtual_model', 'Hide Virtual Model'],
['administration_configuration_wizard_configuration_navigator_merge_entities', 'Merge Entities'],
['administration_configuration_wizard_configuration_navigator_show_only_entities', 'Only Entities'],
['administration_configuration_wizard_configuration_navigator_show_system_objects', 'System Objects'],
['administration_configuration_wizard_configuration_navigator_show_utility_objects', 'Utility Objects'],
['administration_configuration_wizard_finish', 'Confirmation'],
['administration_configuration_wizard_finish_step_description', 'Confirmation'],
['administration_configuration_wizard_finish_title', 'That is almost it.'],
['administration_configuration_wizard_finish_message', 'Press the Finish button to complete the server configuration. You can return to the previous pages if you want to change or add something.\nWhen the configuration is completed all entered settings will be applied for your CloudBeaver server. You will be redirected to the main page to start working.\nYou can always login to the system as administrator to change the server settings.'],
];
@@ -1,4 +1,5 @@
export default [
['administration_menu_enter', 'Администрирование'],
['administration_menu_back', 'Вернуться в приложение'],
['administration_configuration_wizard_title', 'Начальная настройка сервера'],
];
@@ -89,6 +89,14 @@
</g>
</symbol>
<symbol id="admin-cancel" width="28" height="28" viewBox="0 0 28 28">
<path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M3.5 0.5C1.83974 0.5 0.5 1.84469 0.5 3.5V24.5C0.5 26.1553 1.83974 27.5 3.5 27.5H24.5C26.1603 27.5 27.5 26.1553 27.5 24.5V3.5C27.5 1.84469 26.1603 0.5 24.5 0.5H3.5ZM2.5 3.5C2.5 2.94731 2.94626 2.5 3.5 2.5H24.5C25.0537 2.5 25.5 2.94731 25.5 3.5V24.5C25.5 25.0527 25.0537 25.5 24.5 25.5H3.5C2.94626 25.5 2.5 25.0527 2.5 24.5V3.5ZM7.64974 9.05025L9.06396 7.63604L14.0137 12.5858L18.9635 7.63604L20.3777 9.05025L15.4279 14L20.3777 18.9497L18.9635 20.364L14.0137 15.4142L9.06396 20.364L7.64974 18.9497L12.5995 14L7.64974 9.05025Z"/>
</symbol>
<symbol id="admin-save" width="28" height="28" viewBox="0 0 28 28">
<path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M3.5 0.5C1.83974 0.5 0.5 1.84469 0.5 3.5V24.5C0.5 26.1553 1.83974 27.5 3.5 27.5H24.5C26.1603 27.5 27.5 26.1553 27.5 24.5V3.5C27.5 1.84469 26.1603 0.5 24.5 0.5H3.5ZM2.5 3.5C2.5 2.94731 2.94626 2.5 3.5 2.5H24.5C25.0537 2.5 25.5 2.94731 25.5 3.5V24.5C25.5 25.0527 25.0537 25.5 24.5 25.5H3.5C2.94626 25.5 2.5 25.0527 2.5 24.5V3.5ZM13.75 8.22234C11.6806 8.22234 10.0892 9.73996 10.0039 11.5227C9.98214 11.9771 9.64303 12.3533 9.19322 12.4219C7.91877 12.6162 7.05914 13.6031 7.05914 14.6681C7.05914 15.8504 8.1313 16.9474 9.63254 16.9474H11.2011V18.8591H9.63254C7.23549 18.8591 5.14746 17.0593 5.14746 14.6681C5.14746 12.7804 6.45662 11.2552 8.18139 10.7021C8.6699 8.16465 11.0207 6.31067 13.75 6.31067C16.4793 6.31067 18.8301 8.16465 19.3186 10.7021C21.0434 11.2552 22.3525 12.7804 22.3525 14.6681C22.3525 17.0593 20.2645 18.8591 17.8675 18.8591H16.2989V16.9474H17.8675C19.3687 16.9474 20.4409 15.8504 20.4409 14.6681C20.4409 13.6031 19.5812 12.6162 18.3068 12.4219C17.857 12.3533 17.5179 11.9771 17.4961 11.5227C17.4108 9.73996 15.8194 8.22234 13.75 8.22234ZM15.623 15.0292C15.9963 15.4024 16.6015 15.4024 16.9748 15.0292C17.3481 14.6559 17.3481 14.0507 16.9748 13.6774L13.75 10.4526L10.5252 13.6774C10.1519 14.0507 10.1519 14.6559 10.5252 15.0292C10.8985 15.4024 11.5037 15.4024 11.877 15.0292L12.7942 14.112V22H14.7058V14.112L15.623 15.0292Z"/>
</symbol>
<symbol id="angle" viewBox="0 0 15 8">
<path class="icon-fill" fill-rule="evenodd" d="M14.5.954l-.875-.88L7.5 6.238 1.375 0 .5.88 7.5 8z"/>
</symbol>

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 28 KiB

@@ -49,7 +49,7 @@ export class DriverPropertiesController implements IInitializableController {
id: uuid(),
key: key ?? 'property',
defaultValue: value ?? '',
new: !key,
new: !key
});
};
@@ -63,10 +63,10 @@ export class DriverPropertiesController implements IInitializableController {
this.driverProperties = observable(driverProperties.map(property => ({
id: property.id!,
key: property.id!,
displayName: property.displayName!,
displayName: property.displayName,
defaultValue: property.defaultValue,
description: property.description,
validValues: property.validValues,
validValues: property.validValues
})));
for (const key of Object.keys(this.state)) {
@@ -73,11 +73,11 @@ const styles = composes(
`
);
export const ConnectionsAdministration = observer(function ConnectionsAdministration({
export const ConnectionsAdministration: React.FC<AdministrationItemContentProps> = observer(function ConnectionsAdministration({
sub,
param,
configurationWizard,
}: AdministrationItemContentProps) {
configurationWizard
}) {
const controller = useController(ConnectionsAdministrationController);
return styled(useStyles(styles))(
@@ -6,6 +6,7 @@ query serverConfig {
supportsCustomConnections
supportsConnectionBrowser
supportsWorkspaces
sessionExpireTime
anonymousAccessEnabled
authenticationEnabled
+4 -1
View File
@@ -439,6 +439,7 @@ export interface ServerConfig {
supportsCustomConnections?: Maybe<Scalars['Boolean']>;
supportsConnectionBrowser?: Maybe<Scalars['Boolean']>;
supportsWorkspaces?: Maybe<Scalars['Boolean']>;
sessionExpireTime?: Maybe<Scalars['Int']>;
configurationMode?: Maybe<Scalars['Boolean']>;
developmentMode?: Maybe<Scalars['Boolean']>;
supportedLanguages: ServerLanguage[];
@@ -773,6 +774,7 @@ export interface ServerConfigInput {
anonymousAccessEnabled?: Maybe<Scalars['Boolean']>;
authenticationEnabled?: Maybe<Scalars['Boolean']>;
customConnectionsEnabled?: Maybe<Scalars['Boolean']>;
sessionExpireTime?: Maybe<Scalars['Int']>;
}
export enum AuthCredentialEncryption {
@@ -1337,7 +1339,7 @@ export type ServerConfigQueryVariables = Exact<{ [key: string]: never }>;
export interface ServerConfigQuery {
serverConfig: (
Pick<ServerConfig, 'name' | 'version' | 'productConfiguration' | 'supportsCustomConnections' | 'supportsConnectionBrowser' | 'supportsWorkspaces' | 'anonymousAccessEnabled' | 'authenticationEnabled' | 'configurationMode' | 'developmentMode'>
Pick<ServerConfig, 'name' | 'version' | 'productConfiguration' | 'supportsCustomConnections' | 'supportsConnectionBrowser' | 'supportsWorkspaces' | 'sessionExpireTime' | 'anonymousAccessEnabled' | 'authenticationEnabled' | 'configurationMode' | 'developmentMode'>
& { supportedLanguages: Array<Pick<ServerLanguage, 'isoCode' | 'displayName' | 'nativeName'>>; defaultNavigatorSettings: Pick<NavigatorSettings, 'showSystemObjects' | 'showUtilityObjects' | 'showOnlyEntities' | 'mergeEntities' | 'hideFolders' | 'hideSchemas' | 'hideVirtualModel'> }
);
}
@@ -2202,6 +2204,7 @@ export const ServerConfigDocument = `
supportsCustomConnections
supportsConnectionBrowser
supportsWorkspaces
sessionExpireTime
anonymousAccessEnabled
authenticationEnabled
configurationMode
@@ -51,17 +51,19 @@ interface Props {
serverConfig: ServerConfigInput;
validationTask?: IExecutor<boolean>;
editing?: boolean;
className?: string;
onChange: () => void;
onSubmit: () => void;
}
export const ServerConfigurationForm = observer(function ServerConfigurationForm({
export const ServerConfigurationForm: React.FC<Props> = observer(function ServerConfigurationForm({
serverConfig,
validationTask,
editing,
className,
onChange,
onSubmit,
}: Props) {
}) {
const translate = useTranslate();
const [focusedRef] = useFocus<HTMLFormElement>({ focusFirstChild: true });
@@ -80,7 +82,7 @@ export const ServerConfigurationForm = observer(function ServerConfigurationForm
}, [validationTask]);
return styled(useStyles(formStyles, boxStyles))(
<SubmittingForm ref={focusedRef} name='server_config' onSubmit={onSubmit}>
<SubmittingForm ref={focusedRef} name='server_config' className={className} onSubmit={onSubmit}>
<box as="div">
<box-element as='div'>
<group as="div">
@@ -98,37 +100,47 @@ export const ServerConfigurationForm = observer(function ServerConfigurationForm
{translate('administration_configuration_wizard_configuration_server_name')}
</InputField>
</group>
{editing
? <group as="div"><Button mod={['raised']}>Save</Button></group>
: (
<>
<group as="div">
<InputGroup long>{translate('administration_configuration_wizard_configuration_admin')}</InputGroup>
</group>
<InputField
type="text"
name="adminName"
state={serverConfig}
mod='surface'
minLength={6}
required
long
>
{translate('administration_configuration_wizard_configuration_admin_name')}
</InputField>
<InputField
type="password"
name="adminPassword"
state={serverConfig}
autoComplete='new-password'
mod='surface'
required
long
>
{translate('administration_configuration_wizard_configuration_admin_password')}
</InputField>
</>
)}
<group as="div">
<InputField
type="number"
name='sessionExpireTime'
state={serverConfig}
mod='surface'
required
long
>
{translate('administration_configuration_wizard_configuration_server_session_expire_time')}
</InputField>
</group>
{!editing && (
<>
<group as="div">
<InputGroup long>{translate('administration_configuration_wizard_configuration_admin')}</InputGroup>
</group>
<InputField
type="text"
name="adminName"
state={serverConfig}
mod='surface'
minLength={6}
required
long
>
{translate('administration_configuration_wizard_configuration_admin_name')}
</InputField>
<InputField
type="password"
name="adminPassword"
state={serverConfig}
autoComplete='new-password'
mod='surface'
required
long
>
{translate('administration_configuration_wizard_configuration_admin_password')}
</InputField>
</>
)}
</box-element>
<box-element as='div'>
<group as="div">
@@ -9,6 +9,8 @@
import { observer } from 'mobx-react';
import styled, { use, css } from 'reshadow';
import { AdministrationTools } from '@cloudbeaver/core-administration';
import { IconButton } from '@cloudbeaver/core-blocks';
import { useController, useService } from '@cloudbeaver/core-di';
import { useTranslate } from '@cloudbeaver/core-localization';
import { useStyles, composes } from '@cloudbeaver/core-theming';
@@ -19,13 +21,13 @@ import { ServerConfigurationService } from './ServerConfigurationService';
const styles = composes(
css`
layout-grid-cell {
composes: theme-background-surface theme-text-on-surface from global;
}
AdministrationTools, layout-grid-cell {
composes: theme-background-surface theme-text-on-surface theme-border-color-background from global;
}
layout-grid-cell {
composes: theme-border-color-background from global;
}
layout-grid-cell, message-box {
composes: theme-border-color-background from global;
}
`,
css`
layout-grid {
@@ -40,7 +42,27 @@ const styles = composes(
layout-grid-cell {
position: relative;
border: solid 1px;
padding: 16px 24px
}
message-box, AdministrationTools {
border-bottom: solid 1px;
}
message-box, ServerConfigurationForm {
padding: 16px 24px;
}
AdministrationTools {
display: flex;
padding: 0 16px;
align-items: center;
border-bottom: solid 1px;
}
IconButton {
height: 32px;
width: 32px;
margin-right: 16px;
}
p {
@@ -58,11 +80,16 @@ export const ServerConfigurationPage = observer(function ServerConfigurationPage
<layout-grid as="div">
<layout-grid-inner as="div">
<layout-grid-cell as='div' {...use({ span: 12 })}>
{!controller.editing && (
<>
{!controller.editing ? (
<message-box as='div'>
<h3>{translate('administration_configuration_wizard_configuration_title')}</h3>
<p>{translate('administration_configuration_wizard_configuration_message')}</p>
</>
</message-box>
) : (
<AdministrationTools>
<IconButton name="admin-save" viewBox="0 0 28 28" onClick={controller.finish} />
<IconButton name="admin-cancel" viewBox="0 0 28 28" onClick={controller.reset} />
</AdministrationTools>
)}
<ServerConfigurationForm
serverConfig={controller.state.serverConfig}
@@ -25,10 +25,14 @@ export class ServerConfigurationPageController {
constructor(
private readonly configurationWizardService: ConfigurationWizardService,
private readonly serverConfigurationService: ServerConfigurationService,
private readonly administrationScreenService: AdministrationScreenService,
private readonly administrationScreenService: AdministrationScreenService
) {
}
reset = (): void => {
this.serverConfigurationService.loadConfig();
};
onChange = (): void => {
if (!this.state.serverConfig.authenticationEnabled) {
this.state.serverConfig.anonymousAccessEnabled = true;
@@ -6,6 +6,8 @@
* you may not use this file except in compliance with the License.
*/
import { observable } from 'mobx';
import { AdministrationScreenService } from '@cloudbeaver/core-administration';
import { UsersResource } from '@cloudbeaver/core-authentication';
import { injectable } from '@cloudbeaver/core-di';
@@ -23,8 +25,7 @@ export interface IValidationStatusContext {
@injectable()
export class ServerConfigurationService {
state: IServerConfigurationPageState;
@observable state: IServerConfigurationPageState;
readonly validationTask: IExecutor<boolean>;
constructor(
@@ -37,7 +38,7 @@ export class ServerConfigurationService {
this.state = this.administrationScreenService
.getItemState(
'server-configuration',
() => this.getConfig(),
() => this.getConfig()
);
this.validationTask = new Executor();
}
@@ -85,7 +86,12 @@ export class ServerConfigurationService {
try {
await this.graphQLService.sdk.setDefaultNavigatorSettings({ settings: this.state.navigatorConfig });
await this.graphQLService.sdk.configureServer({ configuration: this.state.serverConfig });
await this.graphQLService.sdk.configureServer({
configuration: {
...this.state.serverConfig,
sessionExpireTime: (this.state.serverConfig.sessionExpireTime ?? 30) * 1000 * 60,
},
});
if (!this.serverConfigResource.data?.configurationMode) {
await this.serverConfigResource.refresh(null);
@@ -102,6 +108,9 @@ export class ServerConfigurationService {
if (!this.state?.serverConfig.serverName) {
return false;
}
if ((this.state.serverConfig.sessionExpireTime ?? 0) < 1) {
return false;
}
if (this.administrationScreenService.isConfigurationMode) {
if (!this.state.serverConfig.adminName
|| this.state.serverConfig.adminName.length < 6
@@ -123,6 +132,7 @@ export class ServerConfigurationService {
anonymousAccessEnabled: true,
authenticationEnabled: false,
customConnectionsEnabled: false,
sessionExpireTime: 30,
},
navigatorConfig: {
hideFolders: false,
@@ -142,6 +152,7 @@ export class ServerConfigurationService {
anonymousAccessEnabled: config.anonymousAccessEnabled,
authenticationEnabled: config.authenticationEnabled,
customConnectionsEnabled: config.supportsCustomConnections,
sessionExpireTime: (config.sessionExpireTime ?? 1800000) / 1000 / 60,
},
navigatorConfig: {
hideFolders: false,
@@ -154,5 +165,4 @@ export class ServerConfigurationService {
},
};
}
}
@@ -0,0 +1,32 @@
/*
* cloudbeaver - Cloud Database Manager
* Copyright (C) 2020 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 { Bootstrap, injectable } from '@cloudbeaver/core-di';
import { LocalizationService } from '@cloudbeaver/core-localization';
@injectable()
export class LocaleService extends Bootstrap {
constructor(private localizationService: LocalizationService) {
super();
}
register(): void | Promise<void> {
this.localizationService.addProvider(this.provider.bind(this));
}
load(): void | Promise<void> { }
private async provider(locale: string) {
switch (locale) {
case 'ru':
return (await import('./locales/ru')).default;
default:
return (await import('./locales/en')).default;
}
}
}
@@ -0,0 +1,36 @@
export default [
['administration_configuration_wizard_welcome', 'Welcome'],
['administration_configuration_wizard_welcome_step_description', 'Welcome to CloudBeaver'],
['administration_configuration_wizard_welcome_title', 'Welcome to CloudBeaver, cloud database management system!'],
['administration_configuration_wizard_welcome_message', 'The easy configuration wizard will guide you through several simple steps to set up the CloudBeaver server. You will need to set server information and administrator credentials. You can also add first database connections here.'],
['administration_configuration_wizard_welcome_note', 'Note: you will be able to change these configuration parameters later on the administration panel.'],
['administration_configuration_wizard_configuration', 'Server configuration'],
['administration_configuration_wizard_configuration_step_description', 'Main server configuration'],
['administration_configuration_wizard_configuration_title', 'You can configure the main server parameters here.'],
['administration_configuration_wizard_configuration_message', 'Administrator is a super user who can configure server, set databases connections, manage other users and much more. Please, remember the entered password. It is not possible to recover administrator password automatically.'],
['administration_configuration_wizard_configuration_plugins', 'Configuration'],
['administration_configuration_wizard_configuration_server_info', 'Server Info'],
['administration_configuration_wizard_configuration_server_name', 'Server Name'],
['administration_configuration_wizard_configuration_server_session_expire_time', 'Session Expire Time'],
['administration_configuration_wizard_configuration_admin', 'Administrator'],
['administration_configuration_wizard_configuration_admin_name', 'Admin user name'],
['administration_configuration_wizard_configuration_admin_password', 'Admin password'],
['administration_configuration_wizard_configuration_anonymous_access', 'Allow anonymous access'],
['administration_configuration_wizard_configuration_anonymous_access_description', 'Allows to work with CloudBeaver without user authentication'],
['administration_configuration_wizard_configuration_authentication', 'Enable users authentication'],
['administration_configuration_wizard_configuration_authentication_description', 'Allows users to authenticate. Otherwise only anonymous access is enabled'],
['administration_configuration_wizard_configuration_custom_connections', 'Enable custom connections'],
['administration_configuration_wizard_configuration_custom_connections_description', 'Allows users to create custom connections. Otherwise only administrator can create connections'],
['administration_configuration_wizard_configuration_navigator', 'Navigator'],
['administration_configuration_wizard_configuration_navigator_hide_folders', 'Hide Folders'],
['administration_configuration_wizard_configuration_navigator_hide_schemas', 'Hide Schemas'],
['administration_configuration_wizard_configuration_navigator_hide_virtual_model', 'Hide Virtual Model'],
['administration_configuration_wizard_configuration_navigator_merge_entities', 'Merge Entities'],
['administration_configuration_wizard_configuration_navigator_show_only_entities', 'Only Entities'],
['administration_configuration_wizard_configuration_navigator_show_system_objects', 'System Objects'],
['administration_configuration_wizard_configuration_navigator_show_utility_objects', 'Utility Objects'],
['administration_configuration_wizard_finish', 'Confirmation'],
['administration_configuration_wizard_finish_step_description', 'Confirmation'],
['administration_configuration_wizard_finish_title', 'That is almost it.'],
['administration_configuration_wizard_finish_message', 'Press the Finish button to complete the server configuration. You can return to the previous pages if you want to change or add something.\nWhen the configuration is completed all entered settings will be applied for your CloudBeaver server. You will be redirected to the main page to start working.\nYou can always login to the system as administrator to change the server settings.'],
];
@@ -0,0 +1,2 @@
export default [
];
@@ -10,6 +10,7 @@ import { PluginManifest } from '@cloudbeaver/core-di';
import { ConfigurationWizardPagesBootstrapService } from './ConfigurationWizard/ConfigurationWizardPagesBootstrapService';
import { ServerConfigurationService } from './ConfigurationWizard/ServerConfiguration/ServerConfigurationService';
import { LocaleService } from './LocaleService';
export const manifest: PluginManifest = {
info: {
@@ -19,5 +20,6 @@ export const manifest: PluginManifest = {
providers: [
ServerConfigurationService,
ConfigurationWizardPagesBootstrapService,
LocaleService,
],
};