diff --git a/scm-ui/public/locales/en/config.json b/scm-ui/public/locales/en/config.json index 8a19b01026..143755a318 100644 --- a/scm-ui/public/locales/en/config.json +++ b/scm-ui/public/locales/en/config.json @@ -43,16 +43,19 @@ "add-user-textfield": "Add user you want to add to admin users here", "add-user-button": "Add Admin User" }, + "login-attempt": { + "name": "Login Attempt", + "login-attempt-limit": "Login Attempt Limit", + "login-attempt-limit-timeout": "Login Attempt Limit Timeout" + }, "general-settings": { "realm-description": "Realm Description", "enable-repository-archive": "Enable Repository Archive", "disable-grouping-grid": "Disable Grouping Grid", "date-format": "Date Format", "anonymous-access-enabled": "Anonymous Access Enabled", - "login-attempt-limit": "Login Attempt Limit", "skip-failed-authenticators": "Skip Failed Authenticators", "plugin-url": "Plugin URL", - "login-attempt-limit-timeout": "Login Attempt Limit Timeout", "enabled-xsrf-protection": "Enabled XSRF Protection", "default-namespace-strategy": "Default Namespace Strategy" }, diff --git a/scm-ui/src/config/components/form/ConfigForm.js b/scm-ui/src/config/components/form/ConfigForm.js index bc4a94b501..430ad6abb2 100644 --- a/scm-ui/src/config/components/form/ConfigForm.js +++ b/scm-ui/src/config/components/form/ConfigForm.js @@ -8,6 +8,7 @@ import GeneralSettings from "./GeneralSettings"; import BaseUrlSettings from "./BaseUrlSettings"; import AdminSettings from "./AdminSettings"; import Notification from "../../../components/Notification"; +import LoginAttempt from "./LoginAttempt"; type Props = { submitForm: Config => void, @@ -19,7 +20,8 @@ type Props = { type State = { config: Config, - showNotification: boolean + showNotification: boolean, + loginAttemptError: boolean }; class ConfigForm extends React.Component { @@ -51,7 +53,8 @@ class ConfigForm extends React.Component { defaultNamespaceStrategy: "", _links: {} }, - showNotification: false + showNotification: false, + loginAttemptError: true }; } @@ -95,10 +98,8 @@ class ConfigForm extends React.Component { disableGroupingGrid={config.disableGroupingGrid} dateFormat={config.dateFormat} anonymousAccessEnabled={config.anonymousAccessEnabled} - loginAttemptLimit={config.loginAttemptLimit} skipFailedAuthenticators={config.skipFailedAuthenticators} pluginUrl={config.pluginUrl} - loginAttemptLimitTimeout={config.loginAttemptLimitTimeout} enabledXsrfProtection={config.enabledXsrfProtection} defaultNamespaceStrategy={config.defaultNamespaceStrategy} onChange={(isValid, changedValue, name) => @@ -107,6 +108,15 @@ class ConfigForm extends React.Component { hasUpdatePermission={configUpdatePermission} />
+ + this.onChange(isValid, changedValue, name) + } + hasUpdatePermission={configUpdatePermission} + /> +
{ />
); } + onChange = (isValid: boolean, changedValue: any, name: string) => { - if (isValid) { - this.setState({ - ...this.state, - config: { - ...this.state.config, - [name]: changedValue - } - }); - } + this.setState({ + ...this.state, + config: { + ...this.state.config, + [name]: changedValue + } + }); + }; + + isValid = () => { + return this.state.loginAttemptError; }; onClose = () => { diff --git a/scm-ui/src/config/components/form/GeneralSettings.js b/scm-ui/src/config/components/form/GeneralSettings.js index cb4e4e72b9..5ae999509e 100644 --- a/scm-ui/src/config/components/form/GeneralSettings.js +++ b/scm-ui/src/config/components/form/GeneralSettings.js @@ -2,7 +2,6 @@ import React from "react"; import { translate } from "react-i18next"; import { Checkbox, InputField } from "../../../components/forms/index"; -import * as validator from "../../../components/validation"; type Props = { realmDescription: string, @@ -10,10 +9,8 @@ type Props = { disableGroupingGrid: boolean, dateFormat: string, anonymousAccessEnabled: boolean, - loginAttemptLimit: number, skipFailedAuthenticators: boolean, pluginUrl: string, - loginAttemptLimitTimeout: number, enabledXsrfProtection: boolean, defaultNamespaceStrategy: string, t: string => string, @@ -21,23 +18,7 @@ type Props = { hasUpdatePermission: boolean }; -type State = { - loginAttemptLimitError: boolean, - loginAttemptLimitTimeoutError: boolean -}; - -class GeneralSettings extends React.Component { - constructor(props: Props) { - super(props); - - this.state = { - loginAttemptLimitError: false, - loginAttemptLimitTimeoutError: false, - baseUrlError: false, - pluginUrlError: false - }; - } - +class GeneralSettings extends React.Component { render() { const { t, @@ -46,10 +27,8 @@ class GeneralSettings extends React.Component { disableGroupingGrid, dateFormat, anonymousAccessEnabled, - loginAttemptLimit, skipFailedAuthenticators, pluginUrl, - loginAttemptLimitTimeout, enabledXsrfProtection, defaultNamespaceStrategy, hasUpdatePermission @@ -63,6 +42,30 @@ class GeneralSettings extends React.Component { value={realmDescription} disabled={!hasUpdatePermission} /> + + + + { onChange={this.handleDisableGroupingGridChange} disabled={!hasUpdatePermission} /> - - - - - - ); } @@ -146,26 +109,14 @@ class GeneralSettings extends React.Component { handleAnonymousAccessEnabledChange = (value: string) => { this.props.onChange(true, value, "anonymousAccessEnabled"); }; - handleLoginAttemptLimitChange = (value: string) => { - this.setState({ - ...this.state, - loginAttemptLimitError: !validator.isNumberValid(value) - }); - this.props.onChange(true, value, "loginAttemptLimit"); - }; + handleSkipFailedAuthenticatorsChange = (value: string) => { this.props.onChange(true, value, "skipFailedAuthenticators"); }; handlePluginUrlChange = (value: string) => { this.props.onChange(true, value, "pluginUrl"); }; - handleLoginAttemptLimitTimeoutChange = (value: string) => { - this.setState({ - ...this.state, - loginAttemptLimitTimeoutError: !validator.isNumberValid(value) - }); - this.props.onChange(true, value, "loginAttemptLimitTimeout"); - }; + handleEnabledXsrfProtectionChange = (value: boolean) => { this.props.onChange(true, value, "enabledXsrfProtection"); }; diff --git a/scm-ui/src/config/components/form/LoginAttempt.js b/scm-ui/src/config/components/form/LoginAttempt.js new file mode 100644 index 0000000000..489828fd0b --- /dev/null +++ b/scm-ui/src/config/components/form/LoginAttempt.js @@ -0,0 +1,90 @@ +// @flow +import React from "react"; +import { translate } from "react-i18next"; +import { InputField } from "../../../components/forms/index"; +import Subtitle from "../../../components/layout/Subtitle"; +import * as validator from "../../../components/validation"; + +type Props = { + loginAttemptLimit: number, + loginAttemptLimitTimeout: number, + t: string => string, + onChange: (boolean, any, string) => void, + hasUpdatePermission: boolean +}; + +type State = { + loginAttemptLimitError: boolean, + loginAttemptLimitTimeoutError: boolean +}; + +class LoginAttempt extends React.Component { + constructor(props: Props) { + super(props); + + this.state = { + loginAttemptLimitError: false, + loginAttemptLimitTimeoutError: false + }; + } + render() { + const { + t, + loginAttemptLimit, + loginAttemptLimitTimeout, + hasUpdatePermission + } = this.props; + + return ( +
+ + + +
+ ); + } + + //TODO: set Error in ConfigForm to disable Submit Button! + handleLoginAttemptLimitChange = (value: string) => { + this.setState({ + ...this.state, + loginAttemptLimitError: !validator.isNumberValid(value) + }); + this.props.onChange(this.loginAttemptIsValid(), value, "loginAttemptLimit"); + }; + + handleLoginAttemptLimitTimeoutChange = (value: string) => { + this.setState({ + ...this.state, + loginAttemptLimitTimeoutError: !validator.isNumberValid(value) + }); + this.props.onChange( + this.loginAttemptIsValid(), + value, + "loginAttemptLimitTimeout" + ); + }; + + loginAttemptIsValid = () => { + return ( + this.state.loginAttemptLimitError || + this.state.loginAttemptLimitTimeoutError + ); + }; +} + +export default translate("config")(LoginAttempt);