Skip to content

Commit

Permalink
Added support for v1 connectors with wallets (#1029)
Browse files Browse the repository at this point in the history
* added wallet support for the v1 connectors

Signed-off-by: RosieMurphy0 <[email protected]>

* added wallet support for the v1 connectors

Signed-off-by: RosieMurphy0 <[email protected]>

* added wallet support for the v1 connectors

Signed-off-by: RosieMurphy0 <[email protected]>
  • Loading branch information
RosieMurphy0 authored Oct 5, 2020
1 parent a42cd2f commit 4a3ed4e
Show file tree
Hide file tree
Showing 3 changed files with 238 additions and 0 deletions.
90 changes: 90 additions & 0 deletions packages/caliper-fabric/lib/connector-versions/v1/WalletFacade.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* 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 IWalletFacade = require('../../identity-management/IWalletFacade');
const ExportedIdentity = require('../../identity-management/ExportedIdentity');
const {FileSystemWallet, InMemoryWallet, X509WalletMixin} = require('fabric-network');

/**
* a Facade for the V1 Wallet implementation
*/
class WalletFacade extends IWalletFacade {

/**
*
* @param {string} [walletPath] an optional path to a file system wallet
*/
constructor(walletPath) {
super();
this.wallet = null;
if (!walletPath) {
this.wallet = new InMemoryWallet();
} else {
this.wallet = new FileSystemWallet(walletPath);
}
}

/**
* Import an identity
*
* @param {string} mspId The mspId that owns the identity
* @param {string} identityName The name of the identity
* @param {string} certificate The identity certificate
* @param {string} privateKey The identity private key
*/
async import(mspId, identityName, certificate, privateKey) {
const exists = await this.wallet.exists(identityName);

if (exists) {
throw new Error(`${identityName} already exists in the wallet`);
}

const identity = X509WalletMixin.createIdentity(mspId, certificate, privateKey);
await this.wallet.import(identityName, identity);
}

/**
* Export an identity
*
* @param {string} identityName The identity to export
* @returns {ExportedIdentity} The exported identity or null if it doesn't exist
*/
async export(identityName) {
const exported = await this.wallet.export(identityName);
if (exported) {
return new ExportedIdentity(exported.mspId, exported.certificate, exported.privateKey);
}
return null;
}

/**
* Get all the identity names in the wallet
*
* @returns {[string]} all the identity names in the wallet
*/
async getAllIdentityNames() {
return await this.wallet.getAllLabels();
}

/**
* @returns {*} wallet
*/
getWallet() {
return this.wallet;
}
}

module.exports = WalletFacade;
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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 IWalletFacadeFactory = require('../../identity-management/IWalletFacadeFactory');
const WalletFacade = require('./WalletFacade');

/**
* Factory for a V1 Wallet Facade
*/
class WalletFacadeFactory extends IWalletFacadeFactory {

/**
* create a V1 Wallet Facade
*
* @param {[string]} walletPath optional path to a file system wallet
*/
async create(walletPath) {
const walletFacade = new WalletFacade(walletPath);
return walletFacade;
}
}

module.exports = WalletFacadeFactory;
112 changes: 112 additions & 0 deletions packages/caliper-fabric/test/connector-versions/v1/WalletFacade.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* 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 chai = require('chai');
const chaiAsPromised = require('chai-as-promised');
chai.use(chaiAsPromised);
const should = chai.should();
const mockery = require('mockery');
/* eslint-disable require-jsdoc */

class StubWallet {
constructor() {
this.map = new Map();
}

async import(key, value) {
this.map.set(key, value);
}

async export(key) {
return this.map.get(key);
}

async getAllLabels() {
return Array.from(this.map.keys());
}

async exists(key) {
return this.map.has(key);
}
}

class InMemoryWallet extends StubWallet {}

class FileSystemWallet extends StubWallet {}

class X509WalletMixin {
static createIdentity(mspId, certificate, privateKey){
const identity = {
certificate,
privateKey,
mspId,
type: 'X.509',
};
return identity;
}
}

mockery.enable();
mockery.registerMock('fabric-network', {FileSystemWallet, InMemoryWallet, X509WalletMixin});

const WalletFacadeFactory = require('../../../lib/connector-versions/v1/WalletFacadeFactory');
const WalletFacade = require('../../../lib/connector-versions/v1/WalletFacade');

describe('When testing a V1 Wallet Facade Implementation', () => {

after(() => {
mockery.deregisterAll();
mockery.disable();
});
it('A Wallet Facade Factory should create a wallet facade', async () => {
const walletFacade = await new WalletFacadeFactory().create();
walletFacade.should.be.instanceOf(WalletFacade);
const walletFacade2 = await new WalletFacadeFactory().create('optionalString');
walletFacade2.should.be.instanceOf(WalletFacade);
});

it('A wallet facade should be able to import and export identities', async () => {
const walletFacade = await new WalletFacadeFactory().create();
await walletFacade.import('mspid', 'label', 'cert', 'key');
const exported = await walletFacade.export('label');
exported.should.deep.equal({mspid: 'mspid', certificate: 'cert', privateKey: 'key'});
});

it('A wallet facade should throw an error if an identity already exists', async () => {
const walletFacade = await new WalletFacadeFactory().create();
await walletFacade.import('mspid', 'label', 'cert', 'key');
await walletFacade.import('mspid', 'label', 'cert', 'key').should.be.rejectedWith(/already exists/);
});

it('A wallet facade should get all identity names it has', async () => {
const walletFacade = await new WalletFacadeFactory().create();
await walletFacade.import('mspid', 'label', 'cert', 'key');
await walletFacade.import('mspid', 'bart', 'cert', 'key');
await walletFacade.import('mspid', 'lisa', 'cert', 'key');
(await walletFacade.getAllIdentityNames()).should.deep.equal(['label', 'bart', 'lisa']);
});

it('A wallet facade should return the real wallet instance', async () => {
const walletFacade = await new WalletFacadeFactory().create();
walletFacade.getWallet().should.be.instanceOf(StubWallet);
});

it('A wallet facade should return null on export if the identity does not exist', async () => {
const walletFacade = await new WalletFacadeFactory().create();
const exported = await walletFacade.export('label');
should.equal(exported, null);
});
});

0 comments on commit 4a3ed4e

Please sign in to comment.