outsourcing of login attemt variables

This commit is contained in:
Maren Süwer
2018-08-16 16:41:17 +02:00
parent fb28677a61
commit 2198db867f
4 changed files with 149 additions and 93 deletions

View File

@@ -43,16 +43,19 @@
"add-user-textfield": "Add user you want to add to admin users here", "add-user-textfield": "Add user you want to add to admin users here",
"add-user-button": "Add Admin User" "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": { "general-settings": {
"realm-description": "Realm Description", "realm-description": "Realm Description",
"enable-repository-archive": "Enable Repository Archive", "enable-repository-archive": "Enable Repository Archive",
"disable-grouping-grid": "Disable Grouping Grid", "disable-grouping-grid": "Disable Grouping Grid",
"date-format": "Date Format", "date-format": "Date Format",
"anonymous-access-enabled": "Anonymous Access Enabled", "anonymous-access-enabled": "Anonymous Access Enabled",
"login-attempt-limit": "Login Attempt Limit",
"skip-failed-authenticators": "Skip Failed Authenticators", "skip-failed-authenticators": "Skip Failed Authenticators",
"plugin-url": "Plugin URL", "plugin-url": "Plugin URL",
"login-attempt-limit-timeout": "Login Attempt Limit Timeout",
"enabled-xsrf-protection": "Enabled XSRF Protection", "enabled-xsrf-protection": "Enabled XSRF Protection",
"default-namespace-strategy": "Default Namespace Strategy" "default-namespace-strategy": "Default Namespace Strategy"
}, },

View File

@@ -8,6 +8,7 @@ import GeneralSettings from "./GeneralSettings";
import BaseUrlSettings from "./BaseUrlSettings"; import BaseUrlSettings from "./BaseUrlSettings";
import AdminSettings from "./AdminSettings"; import AdminSettings from "./AdminSettings";
import Notification from "../../../components/Notification"; import Notification from "../../../components/Notification";
import LoginAttempt from "./LoginAttempt";
type Props = { type Props = {
submitForm: Config => void, submitForm: Config => void,
@@ -19,7 +20,8 @@ type Props = {
type State = { type State = {
config: Config, config: Config,
showNotification: boolean showNotification: boolean,
loginAttemptError: boolean
}; };
class ConfigForm extends React.Component<Props, State> { class ConfigForm extends React.Component<Props, State> {
@@ -51,7 +53,8 @@ class ConfigForm extends React.Component<Props, State> {
defaultNamespaceStrategy: "", defaultNamespaceStrategy: "",
_links: {} _links: {}
}, },
showNotification: false showNotification: false,
loginAttemptError: true
}; };
} }
@@ -95,10 +98,8 @@ class ConfigForm extends React.Component<Props, State> {
disableGroupingGrid={config.disableGroupingGrid} disableGroupingGrid={config.disableGroupingGrid}
dateFormat={config.dateFormat} dateFormat={config.dateFormat}
anonymousAccessEnabled={config.anonymousAccessEnabled} anonymousAccessEnabled={config.anonymousAccessEnabled}
loginAttemptLimit={config.loginAttemptLimit}
skipFailedAuthenticators={config.skipFailedAuthenticators} skipFailedAuthenticators={config.skipFailedAuthenticators}
pluginUrl={config.pluginUrl} pluginUrl={config.pluginUrl}
loginAttemptLimitTimeout={config.loginAttemptLimitTimeout}
enabledXsrfProtection={config.enabledXsrfProtection} enabledXsrfProtection={config.enabledXsrfProtection}
defaultNamespaceStrategy={config.defaultNamespaceStrategy} defaultNamespaceStrategy={config.defaultNamespaceStrategy}
onChange={(isValid, changedValue, name) => onChange={(isValid, changedValue, name) =>
@@ -107,6 +108,15 @@ class ConfigForm extends React.Component<Props, State> {
hasUpdatePermission={configUpdatePermission} hasUpdatePermission={configUpdatePermission}
/> />
<hr /> <hr />
<LoginAttempt
loginAttemptLimit={config.loginAttemptLimit}
loginAttemptLimitTimeout={config.loginAttemptLimitTimeout}
onChange={(isValid, changedValue, name) =>
this.onChange(isValid, changedValue, name)
}
hasUpdatePermission={configUpdatePermission}
/>
<hr />
<BaseUrlSettings <BaseUrlSettings
baseUrl={config.baseUrl} baseUrl={config.baseUrl}
forceBaseUrl={config.forceBaseUrl} forceBaseUrl={config.forceBaseUrl}
@@ -139,17 +149,16 @@ class ConfigForm extends React.Component<Props, State> {
/> />
<hr /> <hr />
<SubmitButton <SubmitButton
// disabled={!this.isValid()}
loading={loading} loading={loading}
label={t("config-form.submit")} label={t("config-form.submit")}
disabled={!configUpdatePermission} disabled={!configUpdatePermission || !this.isValid()}
/> />
</form> </form>
); );
} }
onChange = (isValid: boolean, changedValue: any, name: string) => { onChange = (isValid: boolean, changedValue: any, name: string) => {
if (isValid) {
this.setState({ this.setState({
...this.state, ...this.state,
config: { config: {
@@ -157,7 +166,10 @@ class ConfigForm extends React.Component<Props, State> {
[name]: changedValue [name]: changedValue
} }
}); });
} };
isValid = () => {
return this.state.loginAttemptError;
}; };
onClose = () => { onClose = () => {

View File

@@ -2,7 +2,6 @@
import React from "react"; import React from "react";
import { translate } from "react-i18next"; import { translate } from "react-i18next";
import { Checkbox, InputField } from "../../../components/forms/index"; import { Checkbox, InputField } from "../../../components/forms/index";
import * as validator from "../../../components/validation";
type Props = { type Props = {
realmDescription: string, realmDescription: string,
@@ -10,10 +9,8 @@ type Props = {
disableGroupingGrid: boolean, disableGroupingGrid: boolean,
dateFormat: string, dateFormat: string,
anonymousAccessEnabled: boolean, anonymousAccessEnabled: boolean,
loginAttemptLimit: number,
skipFailedAuthenticators: boolean, skipFailedAuthenticators: boolean,
pluginUrl: string, pluginUrl: string,
loginAttemptLimitTimeout: number,
enabledXsrfProtection: boolean, enabledXsrfProtection: boolean,
defaultNamespaceStrategy: string, defaultNamespaceStrategy: string,
t: string => string, t: string => string,
@@ -21,23 +18,7 @@ type Props = {
hasUpdatePermission: boolean hasUpdatePermission: boolean
}; };
type State = { class GeneralSettings extends React.Component<Props> {
loginAttemptLimitError: boolean,
loginAttemptLimitTimeoutError: boolean
};
class GeneralSettings extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
loginAttemptLimitError: false,
loginAttemptLimitTimeoutError: false,
baseUrlError: false,
pluginUrlError: false
};
}
render() { render() {
const { const {
t, t,
@@ -46,10 +27,8 @@ class GeneralSettings extends React.Component<Props, State> {
disableGroupingGrid, disableGroupingGrid,
dateFormat, dateFormat,
anonymousAccessEnabled, anonymousAccessEnabled,
loginAttemptLimit,
skipFailedAuthenticators, skipFailedAuthenticators,
pluginUrl, pluginUrl,
loginAttemptLimitTimeout,
enabledXsrfProtection, enabledXsrfProtection,
defaultNamespaceStrategy, defaultNamespaceStrategy,
hasUpdatePermission hasUpdatePermission
@@ -63,6 +42,30 @@ class GeneralSettings extends React.Component<Props, State> {
value={realmDescription} value={realmDescription}
disabled={!hasUpdatePermission} disabled={!hasUpdatePermission}
/> />
<InputField
label={t("general-settings.date-format")}
onChange={this.handleDateFormatChange}
value={dateFormat}
disabled={!hasUpdatePermission}
/>
<InputField
label={t("general-settings.plugin-url")}
onChange={this.handlePluginUrlChange}
value={pluginUrl}
disabled={!hasUpdatePermission}
/>
<InputField
label={t("general-settings.default-namespace-strategy")}
onChange={this.handleDefaultNamespaceStrategyChange}
value={defaultNamespaceStrategy}
disabled={!hasUpdatePermission}
/>
<Checkbox
checked={enabledXsrfProtection}
label={t("general-settings.enabled-xsrf-protection")}
onChange={this.handleEnabledXsrfProtectionChange}
disabled={!hasUpdatePermission}
/>
<Checkbox <Checkbox
checked={enableRepositoryArchive} checked={enableRepositoryArchive}
label={t("general-settings.enable-repository-archive")} label={t("general-settings.enable-repository-archive")}
@@ -75,58 +78,18 @@ class GeneralSettings extends React.Component<Props, State> {
onChange={this.handleDisableGroupingGridChange} onChange={this.handleDisableGroupingGridChange}
disabled={!hasUpdatePermission} disabled={!hasUpdatePermission}
/> />
<InputField
label={t("general-settings.date-format")}
onChange={this.handleDateFormatChange}
value={dateFormat}
disabled={!hasUpdatePermission}
/>
<Checkbox <Checkbox
checked={anonymousAccessEnabled} checked={anonymousAccessEnabled}
label={t("general-settings.anonymous-access-enabled")} label={t("general-settings.anonymous-access-enabled")}
onChange={this.handleAnonymousAccessEnabledChange} onChange={this.handleAnonymousAccessEnabledChange}
disabled={!hasUpdatePermission} disabled={!hasUpdatePermission}
/> />
<InputField
label={t("general-settings.login-attempt-limit")}
onChange={this.handleLoginAttemptLimitChange}
value={loginAttemptLimit}
disabled={!hasUpdatePermission}
validationError={this.state.loginAttemptLimitError}
errorMessage={t("validation.login-attempt-limit-invalid")}
/>
<InputField
label={t("general-settings.login-attempt-limit-timeout")}
onChange={this.handleLoginAttemptLimitTimeoutChange}
value={loginAttemptLimitTimeout}
disabled={!hasUpdatePermission}
validationError={this.state.loginAttemptLimitTimeoutError}
errorMessage={t("validation.login-attempt-limit-timeout-invalid")}
/>
<Checkbox <Checkbox
checked={skipFailedAuthenticators} checked={skipFailedAuthenticators}
label={t("general-settings.skip-failed-authenticators")} label={t("general-settings.skip-failed-authenticators")}
onChange={this.handleSkipFailedAuthenticatorsChange} onChange={this.handleSkipFailedAuthenticatorsChange}
disabled={!hasUpdatePermission} disabled={!hasUpdatePermission}
/> />
<InputField
label={t("general-settings.plugin-url")}
onChange={this.handlePluginUrlChange}
value={pluginUrl}
disabled={!hasUpdatePermission}
/>
<Checkbox
checked={enabledXsrfProtection}
label={t("general-settings.enabled-xsrf-protection")}
onChange={this.handleEnabledXsrfProtectionChange}
disabled={!hasUpdatePermission}
/>
<InputField
label={t("general-settings.default-namespace-strategy")}
onChange={this.handleDefaultNamespaceStrategyChange}
value={defaultNamespaceStrategy}
disabled={!hasUpdatePermission}
/>
</div> </div>
); );
} }
@@ -146,26 +109,14 @@ class GeneralSettings extends React.Component<Props, State> {
handleAnonymousAccessEnabledChange = (value: string) => { handleAnonymousAccessEnabledChange = (value: string) => {
this.props.onChange(true, value, "anonymousAccessEnabled"); 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) => { handleSkipFailedAuthenticatorsChange = (value: string) => {
this.props.onChange(true, value, "skipFailedAuthenticators"); this.props.onChange(true, value, "skipFailedAuthenticators");
}; };
handlePluginUrlChange = (value: string) => { handlePluginUrlChange = (value: string) => {
this.props.onChange(true, value, "pluginUrl"); 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) => { handleEnabledXsrfProtectionChange = (value: boolean) => {
this.props.onChange(true, value, "enabledXsrfProtection"); this.props.onChange(true, value, "enabledXsrfProtection");
}; };

View File

@@ -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<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
loginAttemptLimitError: false,
loginAttemptLimitTimeoutError: false
};
}
render() {
const {
t,
loginAttemptLimit,
loginAttemptLimitTimeout,
hasUpdatePermission
} = this.props;
return (
<div>
<Subtitle subtitle={t("login-attempt.name")} />
<InputField
label={t("login-attempt.login-attempt-limit")}
onChange={this.handleLoginAttemptLimitChange}
value={loginAttemptLimit}
disabled={!hasUpdatePermission}
validationError={this.state.loginAttemptLimitError}
errorMessage={t("validation.login-attempt-limit-invalid")}
/>
<InputField
label={t("login-attempt.login-attempt-limit-timeout")}
onChange={this.handleLoginAttemptLimitTimeoutChange}
value={loginAttemptLimitTimeout}
disabled={!hasUpdatePermission}
validationError={this.state.loginAttemptLimitTimeoutError}
errorMessage={t("validation.login-attempt-limit-timeout-invalid")}
/>
</div>
);
}
//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);