Skip to content
This repository has been archived by the owner on Mar 8, 2020. It is now read-only.

Commit

Permalink
HLFV1 Beta and Query (#1247) (#1255)
Browse files Browse the repository at this point in the history
System and unit tests
Rich query support for fabric V1 alpha
Alpha 2 Support
  • Loading branch information
cazfletch authored Jun 13, 2017
1 parent 3095dfb commit 4d12f90
Show file tree
Hide file tree
Showing 121 changed files with 3,123 additions and 2,497 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ jspm_packages
.DS_Store
*.swp

# vscode folder
.vscode

#generated jsdoc
packages/composer-website/jekylldocs/jsdoc/

Expand Down
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ matrix:
- env: DOCS=full FC_TASK=docs
- env: SYSTEST=embedded FC_TASK=systest
- env: SYSTEST=hlf FC_TASK=systest
- env: SYSTEST=hlfv1 FC_TASK=systest
- env: SYSTEST=hlfv1_tls FC_TASK=systest
- env: SYSTEST=proxy FC_TASK=systest
- env: SYSTEST=web FC_TASK=systest
dist: trusty
Expand Down
21 changes: 21 additions & 0 deletions .travis/before-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,27 @@
set -ev
set -o pipefail

# Download specific version of docker-compose
export DOCKER_COMPOSE_VERSION=1.11.2
sudo rm /usr/local/bin/docker-compose
curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose
chmod +x docker-compose
sudo mv docker-compose /usr/local/bin
echo "Docker-compose version: "
docker-compose --version

# Update docker
sudo apt-get update
sudo apt-get remove docker docker-engine
sudo apt-get install linux-image-extra-$(uname -r) linux-image-extra-virtual
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-get install docker-ce
echo "Docker version: "
docker --version

# Grab the parent (root) directory.
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )"

Expand Down
23 changes: 0 additions & 23 deletions .vscode/launch.json

This file was deleted.

5 changes: 0 additions & 5 deletions .vscode/settings.json

This file was deleted.

1 change: 1 addition & 0 deletions packages/composer-admin/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ class AdminConnection {
+ Promise update(BusinessNetworkDefinition)
+ Promise ping()
+ Promise list()
+ Promise importIdentity(string,string,string,string)
}
2 changes: 2 additions & 0 deletions packages/composer-admin/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#
# Note that the latest public API is documented using JSDocs and is available in api.txt.
#
Version 0.7.5 {3981adc1fb192a8e53d2250ea8feec9a} 2017-05-22
- added importIdentity method.

Version 0.3.7 {af35a7b1a5872beed588f70d3ee0f345} 2017-01-24
- Move to single version
Expand Down
26 changes: 26 additions & 0 deletions packages/composer-admin/lib/adminconnection.js
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,32 @@ class AdminConnection {
return this.connection.list(this.securityContext);
}

/**
* import an identity into a profiles' wallet
*
* @param {string} connectionProfile Name of the connection profile
* @param {string} id The id to associate with this identity
* @param {string} publicKey The signer cert in PEM format
* @param {string} privateKey The private key in PEM format
* @returns {Promise} A promise which is resolved when the identity is imported
*
* @memberOf AdminConnection
*/
importIdentity(connectionProfile, id, publicKey, privateKey) {
let savedConnectionManager;
return this.connectionProfileManager.getConnectionManager(connectionProfile)
.then((connectionManager) => {
savedConnectionManager = connectionManager;
return this.getProfile(connectionProfile);
})
.then((profileData) => {
return savedConnectionManager.importIdentity(profileData, id, publicKey, privateKey);
})
.catch((error) => {
throw new Error('failed to import identity. ' + error.message);
});
}

}

module.exports = AdminConnection;
25 changes: 25 additions & 0 deletions packages/composer-admin/test/adminconnection.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ describe('AdminConnection', () => {
mockConnectionManager.connect.resolves(mockConnection);
adminConnection = new AdminConnection();
sinon.stub(adminConnection.connectionProfileManager, 'connect').resolves(mockConnection);
sinon.stub(adminConnection.connectionProfileManager, 'getConnectionManager').resolves(mockConnectionManager);
sinon.stub(adminConnection.connectionProfileStore, 'save').withArgs('testprofile', sinon.match.any).resolves();
sinon.stub(adminConnection.connectionProfileStore, 'load').withArgs('testprofile').resolves(config);
sinon.stub(adminConnection.connectionProfileStore, 'loadAll').resolves({ profile1: config, profile2: config2 });
Expand Down Expand Up @@ -253,4 +254,28 @@ describe('AdminConnection', () => {

});

describe('#importIdentity', () => {
it('should be able to import an identity', () => {
mockConnectionManager.importIdentity = sinon.stub();
adminConnection.connection = mockConnection;
adminConnection.securityContext = mockSecurityContext;
return adminConnection.importIdentity('testprofile', 'anid', 'acerttosign', 'akey')
.then(() => {
sinon.assert.calledOnce(mockConnectionManager.importIdentity);
sinon.assert.calledWith(mockConnectionManager.importIdentity, config, 'anid', 'acerttosign', 'akey');
});
});

it('should throw an error if import fails', () => {
mockConnectionManager.importIdentity = sinon.stub();
mockConnectionManager.importIdentity.rejects(new Error('no identity imported'));
adminConnection.connection = mockConnection;
adminConnection.securityContext = mockSecurityContext;
return adminConnection.importIdentity('testprofile', 'anid', 'acerttosign', 'akey')
.should.be.rejectedWith(/no identity imported/);
});


});

});
5 changes: 3 additions & 2 deletions packages/composer-cli/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ let results = yargs
.version(function() {
return getInfo('composer-cli')+
getInfo('composer-admin')+getInfo('composer-client')+
getInfo('composer-common')+getInfo('composer-runtime')+
getInfo('composer-connector-hlfv1')+getInfo('composer-runtime-hlfv1');
getInfo('composer-common')+getInfo('composer-runtime-hlf')+
getInfo('composer-connector-hlf')+getInfo('composer-runtime-hlfv1')+
getInfo('composer-connector-hlfv1');
})
.describe('v', 'show version information')
.command(
Expand Down
34 changes: 34 additions & 0 deletions packages/composer-cli/lib/cmds/identity/importCommand.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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.
*/

'use strict';

const Import = require ('./lib/import.js');

module.exports.command = 'import [options]';
module.exports.describe = 'Import an identity to wallet defined by the connection profile';
module.exports.builder = {
connectionProfileName: {alias: 'p', required: true, describe: 'The connection profile name', type: 'string' },
userId: { alias: 'u', required: true, describe: 'The user ID for the new identity', type: 'string' },
publicKeyFile: { alias: 'c', required: true, describe: 'File containing the public key', type: 'string' },
privateKeyFile: { alias: 'k', required: true, describe: 'File containing the private key', type: 'string' }
};

module.exports.handler = (argv) => {
argv.thePromise = Import.handler(argv)
.then(() => {
console.log ('Command completed successfully.');
});
return argv.thePromise;
};
65 changes: 65 additions & 0 deletions packages/composer-cli/lib/cmds/identity/lib/import.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* 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.
*/

'use strict';

const fs = require('fs');

const cmdUtil = require('../../utils/cmdutils');

/**
* <p>
* Composer "identity issue" command
* </p>
* <p><a href="diagrams/Deploy.svg"><img src="diagrams/deploy.svg" style="width:100%;"/></a></p>
* @private
*/
class Import {

/**
* Command process for deploy command
* @param {string} argv argument list from composer command
* @return {Promise} promise when command complete
*/
static handler(argv) {
let userId;
let publicKeyFile;
let privateKeyFile;
let connectionProfileName;

userId = argv.userId;
publicKeyFile = argv.publicKeyFile;
privateKeyFile = argv.privateKeyFile;
connectionProfileName = argv.connectionProfileName;
let adminConnection = cmdUtil.createAdminConnection();
let signerCert;
let key;
try {
signerCert = fs.readFileSync(publicKeyFile).toString();
} catch(error) {
return Promise.reject(new Error('Unable to read public key file ' + publicKeyFile + '. ' + error.message));
}
try {
key = fs.readFileSync(privateKeyFile).toString();
} catch(error) {
return Promise.reject(new Error('Unable to read private key file ' + privateKeyFile + '. ' + error.message));
}
return adminConnection.importIdentity(connectionProfileName, userId, signerCert, key)
.then((result) => {
console.log(`An identity was imported with name '${userId}' successfully`);
});
}
}

module.exports = Import;
115 changes: 115 additions & 0 deletions packages/composer-cli/test/identity/import.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
* 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.
*/

'use strict';

const Client = require('composer-admin');

const Import = require('../../lib/cmds/identity/importCommand.js');
const CmdUtil = require('../../lib/cmds/utils/cmdutils.js');
const fs = require('fs');

const sinon = require('sinon');
require('sinon-as-promised');
const chai = require('chai');
chai.should();
chai.use(require('chai-as-promised'));

const PROFILE_NAME = 'myprofile';
const USER_ID = 'SuccessKid';
const CERT_PATH = 'someCertPath';
const KEY_PATH = 'someKeyPath';

describe('composer identity import CLI unit tests', () => {

let sandbox;
let mockAdminConnection;

beforeEach(() => {
sandbox = sinon.sandbox.create();
mockAdminConnection = sinon.createStubInstance(Client.AdminConnection);
sandbox.stub(CmdUtil, 'createAdminConnection').returns(mockAdminConnection);
sandbox.stub(process, 'exit');
});

afterEach(() => {
sandbox.restore();
});

it('should import a new identity using the specified profile', () => {
let argv = {
connectionProfileName: PROFILE_NAME,
userId: USER_ID,
publicKeyFile: CERT_PATH,
privateKeyFile: KEY_PATH
};

let fsStub = sandbox.stub(fs, 'readFileSync').withArgs(CERT_PATH).returns('acert');
fsStub.withArgs(KEY_PATH).returns('akey');
mockAdminConnection.importIdentity.withArgs(PROFILE_NAME, USER_ID, 'acert', 'akey').resolves();
return Import.handler(argv)
.then(() => {
sinon.assert.calledOnce(mockAdminConnection.importIdentity);
sinon.assert.calledWith(mockAdminConnection.importIdentity, PROFILE_NAME, USER_ID, 'acert', 'akey');
});
});

it('should fail gracefully if importIdentity fails', () => {
let argv = {
connectionProfileName: PROFILE_NAME,
userId: USER_ID,
publicKeyFile: CERT_PATH,
privateKeyFile: KEY_PATH
};

let fsStub = sandbox.stub(fs, 'readFileSync').withArgs(CERT_PATH).returns('acert');
fsStub.withArgs(KEY_PATH).returns('akey');
mockAdminConnection.importIdentity.withArgs(PROFILE_NAME, USER_ID, 'acert', 'akey').rejects('some error');
return Import.handler(argv)
.should.be.rejectedWith(/some error/);
});

it('should fail gracefully if cert file cannot be found', () => {
let argv = {
connectionProfileName: PROFILE_NAME,
userId: USER_ID,
publicKeyFile: CERT_PATH,
privateKeyFile: KEY_PATH
};

let fsStub = sandbox.stub(fs, 'readFileSync').withArgs(CERT_PATH).throws(new Error('no file found'));
fsStub.withArgs(KEY_PATH).returns('akey');
mockAdminConnection.importIdentity.withArgs(PROFILE_NAME, USER_ID, 'acert', 'akey').resolves();
return Import.handler(argv)
.should.be.rejectedWith(/no file found/);

});

it('should fail gracefully if key file cannot be found', () => {
let argv = {
connectionProfileName: PROFILE_NAME,
userId: USER_ID,
publicKeyFile: CERT_PATH,
privateKeyFile: KEY_PATH
};

let fsStub = sandbox.stub(fs, 'readFileSync').withArgs(CERT_PATH).returns('acert');
fsStub.withArgs(KEY_PATH).throws(new Error('no key file found'));
mockAdminConnection.importIdentity.withArgs(PROFILE_NAME, USER_ID, 'acert', 'akey').resolves();
return Import.handler(argv)
.should.be.rejectedWith(/no key file found/);

});

});
Loading

0 comments on commit 4d12f90

Please sign in to comment.