create api and cleanup controller
Project: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/commit/bd90f757 Tree: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/tree/bd90f757 Diff: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/diff/bd90f757 Branch: refs/heads/new-replication Commit: bd90f75713fbe4aea4bf46427e64f64e665b24ad Parents: 555a263 Author: Garren Smith <garren.sm...@gmail.com> Authored: Thu Aug 18 14:08:33 2016 +0200 Committer: Garren Smith <garren.sm...@gmail.com> Committed: Wed Sep 14 17:22:30 2016 +0200 ---------------------------------------------------------------------- app/addons/replication/actions.js | 10 +- app/addons/replication/api.js | 126 +++++++++++++++++++++++ app/addons/replication/components/source.js | 2 +- app/addons/replication/components/target.js | 2 +- app/addons/replication/controller.js | 55 +++++++--- app/addons/replication/helpers.js | 11 ++ 6 files changed, 186 insertions(+), 20 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/bd90f757/app/addons/replication/actions.js ---------------------------------------------------------------------- diff --git a/app/addons/replication/actions.js b/app/addons/replication/actions.js index 5c2fde5..c886750 100644 --- a/app/addons/replication/actions.js +++ b/app/addons/replication/actions.js @@ -13,6 +13,7 @@ import app from '../../app'; import FauxtonAPI from '../../core/api'; import ActionTypes from './actiontypes'; import Helpers from './helpers'; +import {createReplicationDoc} from './api'; function initReplicator (sourceDatabase) { @@ -39,16 +40,18 @@ function initReplicator (sourceDatabase) { } function replicate (params) { + const replicationDoc = createReplicationDoc(params); + const promise = $.ajax({ url: window.location.origin + '/_replicator', contentType: 'application/json', type: 'POST', dataType: 'json', - data: JSON.stringify(params) + data: JSON.stringify(replicationDoc) }); - const source = Helpers.getDatabaseLabel(params.source); - const target = Helpers.getDatabaseLabel(params.target); + const source = Helpers.getDatabaseLabel(replicationDoc.source); + const target = Helpers.getDatabaseLabel(replicationDoc.target); promise.then(() => { FauxtonAPI.addNotification({ @@ -68,7 +71,6 @@ function replicate (params) { } function updateFormField (fieldName, value) { - console.log('ff', fieldName, value); FauxtonAPI.dispatch({ type: ActionTypes.REPLICATION_UPDATE_FORM_FIELD, options: { http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/bd90f757/app/addons/replication/api.js ---------------------------------------------------------------------- diff --git a/app/addons/replication/api.js b/app/addons/replication/api.js new file mode 100644 index 0000000..037c53e --- /dev/null +++ b/app/addons/replication/api.js @@ -0,0 +1,126 @@ +// 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 Constants from './constants'; +import app from '../../app'; +import base64 from 'base-64'; + +export const getUsername = () => { + return app.session.get('userCtx').name; +}; + +export const getAuthHeaders = (username, password) => { + return { + 'Authorization': 'Basic ' + base64.encode(username + ':' + password) + }; +}; + +export const getSource = ({replicationSource, localSource, remoteSource, username, password}) => { + if (replicationSource === Constants.REPLICATION_SOURCE.LOCAL) { + return { + headers: getAuthHeaders(username, password), + url: window.location.origin + '/' + localSource + }; + } else { + return remoteSource; + } +}; + +export const getTarget = ({replicationTarget, localTarget, remoteTarget, replicationSource, username, password}) => { + let target = remoteTarget; + const headers = getAuthHeaders(username, password); + + if (replicationTarget === Constants.REPLICATION_TARGET.EXISTING_LOCAL_DATABASE) { + target = { + headers: headers, + url: window.location.origin + '/' + localTarget + }; + } else if (replicationTarget === Constants.REPLICATION_TARGET.NEW_LOCAL_DATABASE) { + + // check to see if we really need to send headers here or can just do the ELSE clause in all scenarioe + if (replicationSource === Constants.REPLICATION_SOURCE.LOCAL) { + target = { + headers: headers, + url: window.location.origin + '/' + localTarget + }; + } else { + const port = window.location.port === '' ? '' : ':' + window.location.port; + target = `${window.location.protocol}//${username}:${password}@${window.location.hostname}${port}/${localTarget}`; + } + } + + return target; +}; + +export const createTarget = (replicationTarget) => { + if (_.contains([ + Constants.REPLICATION_TARGET.NEW_LOCAL_DATABASE, + Constants.REPLICATION_TARGET.NEW_REMOTE_DATABASE], + replicationTarget)) { + return true; + } + + return false; +}; + +export const continuous = (replicationType) => { + if (replicationType === Constants.REPLICATION_TYPE.CONTINUOUS) { + return true; + } + + return false; +}; + +export const addDocId = (docId, doc) => { + if (docId) { + doc._id = docId; + } + + return doc; +}; + +export const createReplicationDoc = ({ + replicationTarget, + replicationSource, + replicationType, + replicationDocName, + password, + localTarget, + localSource, + remoteTarget, + remoteSource +}) => { + const username = getUsername(); + return addDocId(replicationDocName, { + user_ctx: { + name: username, + roles: ['_admin', '_reader', '_writer'] + }, + source: getSource({ + replicationSource, + localSource, + remoteSource, + username, + password + }), + target: getTarget({ + replicationTarget, + replicationSource, + remoteTarget, + localTarget, + username, + password + }), + create_target: createTarget(replicationTarget), + continuous: continuous(replicationType), + }); +}; http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/bd90f757/app/addons/replication/components/source.js ---------------------------------------------------------------------- diff --git a/app/addons/replication/components/source.js b/app/addons/replication/components/source.js index 7336804..d2153cf 100644 --- a/app/addons/replication/components/source.js +++ b/app/addons/replication/components/source.js @@ -45,7 +45,7 @@ const LocalSourceInput = ({value, onChange, databases}) => { placeholder="Database name" options={options} clearable={false} - onChange={onChange} /> + onChange={({value}) => onChange(value)} /> </div> </div> ); http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/bd90f757/app/addons/replication/components/target.js ---------------------------------------------------------------------- diff --git a/app/addons/replication/components/target.js b/app/addons/replication/components/target.js index 1472118..86ed5fd 100644 --- a/app/addons/replication/components/target.js +++ b/app/addons/replication/components/target.js @@ -76,7 +76,7 @@ const ExistingLocalTargetReplicationRow = ({onChange, value, databases}) => { options={options} placeholder="Database name" clearable={false} - onChange={(selected) => onChange(selected.value)} + onChange={({value}) => onChange(value)} /> </div> ); http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/bd90f757/app/addons/replication/controller.js ---------------------------------------------------------------------- diff --git a/app/addons/replication/controller.js b/app/addons/replication/controller.js index 92d3150..7c92ee2 100644 --- a/app/addons/replication/controller.js +++ b/app/addons/replication/controller.js @@ -22,7 +22,9 @@ import {ReplicationTarget} from './components/target'; import {ReplicationOptions} from './components/options'; import {ReplicationSubmit} from './components/submit'; import Components from '../components/react-components.react'; +import AuthComponents from '../auth/components.react'; +const {PasswordModal} = AuthComponents; const {LoadLines, ConfirmButton} = Components; const store = Stores.replicationStore; @@ -98,25 +100,35 @@ export default class ReplicationController extends React.Component { AuthActions.showPasswordModal(); } - getUsername () { + /*getUsername () { return app.session.get('userCtx').name; - } + }*/ - getAuthHeaders () { + /*getAuthHeaders () { const username = this.getUsername(); return { 'Authorization': 'Basic ' + base64.encode(username + ':' + this.state.password) }; - } + }*/ submit () { - const { replicationTarget, replicationType, replicationDocName} = this.state; + const { + replicationTarget, + replicationSource, + replicationType, + replicationDocName, + password, + remoteTarget, + remoteSource, + targetDatabase, + sourceDatabase + } = this.state; if (!this.validate()) { return; } - const params = { + /*const params = { source: this.getSource(), target: this.getTarget() }; @@ -130,20 +142,30 @@ export default class ReplicationController extends React.Component { if (replicationDocName) { params._id = this.state.replicationDocName; - } + }*/ // POSTing to the _replicator DB requires auth - const user = FauxtonAPI.session.user(); + /*const user = FauxtonAPI.session.user(); const userName = _.isNull(user) ? '' : FauxtonAPI.session.user().name; params.user_ctx = { name: userName, roles: ['_admin', '_reader', '_writer'] - }; - - Actions.replicate(params); + };*/ + + Actions.replicate({ + replicationTarget, + replicationSource, + replicationType, + replicationDocName, + password, + localTarget: targetDatabase, + localSource: sourceDatabase, + remoteTarget, + remoteSource + }); } - getSource () { + /*getSource () { const { replicationSource, sourceDatabase, remoteSource } = this.state; if (replicationSource === Constants.REPLICATION_SOURCE.LOCAL) { return { @@ -180,7 +202,7 @@ export default class ReplicationController extends React.Component { } return target; - } + }*/ validate () { const { replicationTarget, targetDatabase, databases } = this.state; @@ -276,9 +298,14 @@ export default class ReplicationController extends React.Component { /> <ReplicationSubmit disabled={!this.confirmButtonEnabled()} - onClick={() => {}} + onClick={this.showPasswordModal} onClear={Actions.clearReplicationForm} /> + <PasswordModal + visible={passwordModalVisible} + modalMessage={<p>Replication requires authentication.</p>} + submitBtnLabel="Continue Replication" + onSuccess={this.submit} /> </div> ); } http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/bd90f757/app/addons/replication/helpers.js ---------------------------------------------------------------------- diff --git a/app/addons/replication/helpers.js b/app/addons/replication/helpers.js index 4584faf..807cedd 100644 --- a/app/addons/replication/helpers.js +++ b/app/addons/replication/helpers.js @@ -1,3 +1,14 @@ +// 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. const getDatabaseLabel = db => { let dbString = (_.isString(db)) ? db.trim().replace(/\/$/, '') : db.url;