blob: fd0558261f49034a69d2eb438547f3ce977f7f27 [file] [log] [blame]
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
import PropTypes from 'prop-types';
import FauxtonAPI from '../../../core/api';
import app from '../../../app';
import React from 'react';
import Constants from '../constants';
import Form from 'react-bootstrap/Form';
export class ReplicationAuth extends React.Component {
constructor (props) {
super(props);
this.onChangeType = this.onChangeType.bind(this);
this.onChangeValue = this.onChangeValue.bind(this);
// init auth extensions
// The extension should provide:
// - 'inputComponent' a React component that will be displayed when the user selects the auth method.
// - 'typeValue' field with an arbitrary ID representing the auth type the extension supports.
// - 'typeLabel' field containing the display label for the authentication method.
this.customAuths = FauxtonAPI.getExtensions('Replication:Auth');
if (!this.customAuths) {
this.customAuths = [];
}
this.customAuthTypes = this.customAuths.map(auth => auth.typeValue);
// The extension should provide:
// - 'authType' is a string representing the auth type.
// - 'helpText' string with the text to be displayed when the auth type is selected.
this.customAuthHelp = FauxtonAPI.getExtensions('Replication:Auth-help');
if (!this.customAuthHelp) {
this.customAuthHelp = [];
}
}
getAuthOptions = () => {
const userPasswordLabel = app.i18n.en_US['replication-user-password-auth-label'];
const authOptions = [
{ value: Constants.REPLICATION_AUTH_METHOD.NO_AUTH, label: 'None' },
{ value: Constants.REPLICATION_AUTH_METHOD.BASIC, label: userPasswordLabel }
];
this.customAuths.map(auth => {
authOptions.push({ value: auth.typeValue, label: auth.typeLabel });
});
return authOptions.map(option => <option value={option.value} key={option.value}>{option.label}</option>);
};
onChangeType(newType) {
this.props.onChangeAuthType(newType);
}
onChangeValue(newValue) {
this.props.onChangeAuth(newValue);
}
getAuthInputFields(authValue, authType) {
const {authId} = this.props;
if (authType == Constants.REPLICATION_AUTH_METHOD.BASIC) {
return <UserPasswordAuthInput onChange={this.onChangeValue} auth={authValue} authId={authId}/>;
}
const matchedAuths = this.customAuths.filter(el => el.typeValue === authType);
if (matchedAuths && matchedAuths.length > 0) {
const InputComp = matchedAuths[0].inputComponent;
return <InputComp onChange={this.onChangeValue} auth={authValue} />;
}
return null;
}
getHelpText(authType) {
const helpText = this.customAuthHelp.filter(el => authType === el.authType).map(el => el.helpText);
if (helpText.length == 0) {
return null;
}
return (
<span id="replications-auth-help-span" className="form-text">{helpText[0]}</span>
);
}
render () {
const {credentials, authType, authId} = this.props;
return (
<div className="row">
<div className="col-12 col-md-2">Authentication:</div>
<div className="col-12 col-md mt-1 mt-md-0">
<Form.Select
onChange={(e) => this.onChangeType(e.target.value)}
id={'select-' + authId}
value={authType}
>
{this.getAuthOptions()}
</Form.Select>
{this.getAuthInputFields(credentials, authType)}
{this.getHelpText(authType)}
</div>
</div>
);
}
}
ReplicationAuth.propTypes = {
authId: PropTypes.string.isRequired,
authType: PropTypes.string.isRequired,
credentials: PropTypes.object,
onChangeAuth: PropTypes.func.isRequired,
onChangeAuthType: PropTypes.func.isRequired
};
ReplicationAuth.defaultProps = {
authType: Constants.REPLICATION_AUTH_METHOD.NO_AUTH,
onChangeAuthType: () => {},
onChangeAuth: () => {}
};
export class UserPasswordAuthInput extends React.Component {
constructor (props) {
super(props);
this.updatePassword = this.updatePassword.bind(this);
this.updateUsername = this.updateUsername.bind(this);
this.state = {
username: props.auth && props.auth.username ? props.auth.username : '',
password: props.auth && props.auth.password ? props.auth.password : ''
};
}
updatePassword(newValue) {
this.setState({password: newValue});
this.props.onChange({
username: this.state.username,
password: newValue
});
}
updateUsername(newValue) {
this.setState({username: newValue});
this.props.onChange({
username: newValue,
password: this.state.password
});
}
render () {
const usernamePlaceholder = app.i18n.en_US['replication-username-input-placeholder'];
const passwordPlaceholder = app.i18n.en_US['replication-password-input-placeholder'];
const { authId } = this.props;
return (
<React.Fragment>
<div className="row">
<div className="col-12 mt-2">
<Form.Control
id={authId + '-username'}
type="text"
className="form-control"
placeholder={usernamePlaceholder}
value={this.state.username}
onChange={(e) => this.updateUsername(e.target.value)}
/>
</div>
<div className="col-12 mt-2">
<Form.Control
id={authId + '-password'}
type="password"
className="form-control"
placeholder={passwordPlaceholder}
value={this.state.password}
onChange={(e) => this.updatePassword(e.target.value)}
/>
</div>
</div>
</React.Fragment>
);
}
}
UserPasswordAuthInput.propTypes = {
auth: PropTypes.object.isRequired,
onChange: PropTypes.func.isRequired
};