Skip to content

Commit

Permalink
feat(deploy-toolbar): add basic and bearer auth
Browse files Browse the repository at this point in the history
Closes #741
  • Loading branch information
barmac committed Dec 6, 2018
1 parent f22f457 commit 1fba919
Show file tree
Hide file tree
Showing 5 changed files with 296 additions and 52 deletions.
115 changes: 113 additions & 2 deletions client/src/app/__tests__/DeployDiagramModalSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {

import { DeployDiagramModal } from '../deploy-diagram-modal';
import View from '../deploy-diagram-modal/View';
import AuthTypes from '../deploy-diagram-modal/AuthTypes';

const MOCK_ENDPOINT_URL = 'http://example.com/deployment/create';

Expand Down Expand Up @@ -337,6 +338,116 @@ describe('<DeployDiagramModal>', function() {
});


describe('authentication', function() {

it('should not pass auth option when no auth method was chosen', async function() {
// given
const endpointUrl = 'http://example.com/',
deploymentName = 'deploymentName';

const onDeployStub = sinon.stub().resolves();

const wrapper = shallow(
<DeployDiagramModal
onDeploy={ onDeployStub }
/>
);
const instance = wrapper.instance();

// when
await instance.handleDeploy({
endpointUrl,
deploymentName
}, {
setSubmitting: sinon.spy()
});

// expect
expect(onDeployStub).to.be.calledOnce;

const payload = onDeployStub.getCall(0).args[0];

expect(payload).to.not.have.property('auth');
});


it('should pass username and password when authenticating with Basic', async function() {
// given
const endpointUrl = 'http://example.com/',
deploymentName = 'deploymentName',
username = 'username',
password = 'password',
authType = AuthTypes.basic;

const onDeployStub = sinon.stub().resolves();

const wrapper = shallow(
<DeployDiagramModal
onDeploy={ onDeployStub }
/>
);
const instance = wrapper.instance();

// when
await instance.handleDeploy({
endpointUrl,
deploymentName,
username,
password,
authType
}, {
setSubmitting: sinon.spy()
});

// expect
expect(onDeployStub).to.be.calledOnce;

const payload = onDeployStub.getCall(0).args[0];

expect(payload).to.have.property('auth');
expect(payload.auth).to.have.property('username').eql(username);
expect(payload.auth).to.have.property('password').eql(password);
});


it('should pass token when authenticating with Bearer', async function() {
// given
const endpointUrl = 'http://example.com/',
deploymentName = 'deploymentName',
bearer = 'bearer',
authType = AuthTypes.bearer;

const onDeployStub = sinon.stub().resolves();

const wrapper = shallow(
<DeployDiagramModal
onDeploy={ onDeployStub }
/>
);
const instance = wrapper.instance();

// when
await instance.handleDeploy({
endpointUrl,
deploymentName,
bearer,
authType
}, {
setSubmitting: sinon.spy()
});

// expect
expect(onDeployStub).to.be.calledOnce;

const payload = onDeployStub.getCall(0).args[0];

expect(payload).to.have.property('auth');
expect(payload.auth).to.have.property('bearer').eql(bearer);
});

});


describe('<View>', function() {

it('should render', function() {
Expand All @@ -346,7 +457,7 @@ describe('<DeployDiagramModal>', function() {

it('should render error message', function() {
// given
const wrapper = mount(<View error={ 'Error message' } />);
const wrapper = mount(<View validators={ { auth: {} } } error={ 'Error message' } />);

// then
expect(wrapper.find('.deploy-message.error')).to.have.lengthOf(1);
Expand All @@ -357,7 +468,7 @@ describe('<DeployDiagramModal>', function() {

it('should render success message', function() {
// given
const wrapper = mount(<View success={ 'Success message' } />);
const wrapper = mount(<View validators={ { auth: {} } } success={ 'Success message' } />);

// then
expect(wrapper.find('.deploy-message.success')).to.have.lengthOf(1);
Expand Down
7 changes: 7 additions & 0 deletions client/src/app/deploy-diagram-modal/AuthTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const AuthTypes = {
none: 'none',
basic: 'basic',
bearer: 'bearer'
};

export default AuthTypes;
67 changes: 62 additions & 5 deletions client/src/app/deploy-diagram-modal/DeployDiagramModal.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';

import View from './View';
import AuthTypes from './AuthTypes';

import errorMessageFunctions from './error-messages';

Expand All @@ -15,6 +16,17 @@ const defaultState = {
error: ''
};

const initialFormValues = {
endpointUrl: '',
tenantId: '',
deploymentName: '',
authType: 'none',
username: '',
password: '',
bearer: ''
};


class DeployDiagramModal extends React.Component {
constructor(props) {
super(props);
Expand Down Expand Up @@ -69,8 +81,34 @@ class DeployDiagramModal extends React.Component {
}
}

validateUsername = username => {
if (!username.length) {
return 'Username must not be void.';
}
}

validatePassword = password => {
if (!password.length) {
return 'Password must not be void.';
}
}

validateBearer = bearer => {
if (!bearer.length) {
return 'Token must not be void.';
}
}

render() {
const { endpoints } = this.props;
const validators = {
endpointUrl: this.validateEndpointUrl,
deploymentName: this.validateDeploymentName,
username: this.validateUsername,
password: this.validatePassword,
bearer: this.validateBearer
};

return <View
onClose={ this.props.onClose }
onDeploy={ this.handleDeploy }
Expand All @@ -79,12 +117,10 @@ class DeployDiagramModal extends React.Component {
error={ this.state.error }

initialValues={ {
endpointUrl: endpoints[endpoints.length - 1] || '',
tenantId: '',
deploymentName: ''
...initialFormValues,
endpointUrl: endpoints[endpoints.length - 1] || ''
} }
validateEndpointUrl={ this.validateEndpointUrl }
validateDeploymentName={ this.validateDeploymentName }
validators={ validators }
/>;
}

Expand All @@ -101,6 +137,12 @@ class DeployDiagramModal extends React.Component {
tenantId: values.tenantId
};

const auth = this.getAuth(values);

if (auth) {
payload.auth = auth;
}

return payload;
}

Expand All @@ -120,6 +162,21 @@ class DeployDiagramModal extends React.Component {
return url;
}

getAuth({ authType, username, password, bearer }) {
switch (authType) {
case AuthTypes.basic:
return {
username,
password
};
case AuthTypes.bearer: {
return {
bearer
};
}
}
}

getErrorMessage(error) {
for (const getMessage of errorMessageFunctions) {
const errorMessage = getMessage(error);
Expand Down
Loading

0 comments on commit 1fba919

Please sign in to comment.