Skip to content

Commit

Permalink
Add support for V2 Wallets (#1014)
Browse files Browse the repository at this point in the history
* Add support for V2 Wallets

Signed-off-by: D Kelsey <d_kelsey@uk.ibm.com>

* Removed whitespace

Signed-off-by: D Kelsey <d_kelsey@uk.ibm.com>
  • Loading branch information
Dave Kelsey committed Sep 25, 2020
1 parent 52c0afd commit 1cf7f49
Show file tree
Hide file tree
Showing 4 changed files with 254 additions and 0 deletions.
103 changes: 103 additions & 0 deletions packages/caliper-fabric/lib/connector-versions/v2/WalletFacade.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* 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 {Wallets} = require('fabric-network');

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

/**
*/
constructor() {
super();
this.wallet = null;
}

/**
* initialize this WalletFacade
*
* @param {atring} [walletPath] an optional path to a file system wallet
*/
async initialize(walletPath) {
if (!walletPath) {
this.wallet = await Wallets.newInMemoryWallet();
} else {
this.wallet = await Wallets.newFileSystemWallet(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.get(identityName);

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

const identity = {
credentials: {
certificate,
privateKey
},
mspId,
type: 'X.509',
};
await this.wallet.put(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.get(identityName);
if (exported) {
return new ExportedIdentity(exported.mspId, exported.credentials.certificate, exported.credentials.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.list();
}

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

module.exports = WalletFacade;
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* 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 V2 Wallet Facade
*/
class WalletFacadeFactory extends IWalletFacadeFactory {

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

module.exports = WalletFacadeFactory;
1 change: 1 addition & 0 deletions packages/caliper-fabric/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"chai-as-promised": "^7.1.1",
"eslint": "^5.16.0",
"mocha": "3.4.2",
"mockery": "^2.1.0",
"nyc": "11.1.0",
"sinon": "^7.3.2",
"license-check-and-add": "2.3.6"
Expand Down
113 changes: 113 additions & 0 deletions packages/caliper-fabric/test/connector-versions/v2/WalletFacade.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
* 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);
chai.should();
const mockery = require('mockery');

/**
* simulate a node sdk v2 wallet
*/
class StubWallet {
/**
* Mock V2 wallet implementation
*/
constructor() {
this.map = new Map();
}

/**
*
* @param {*} key b
* @param {*} value b
*/
async put(key, value) {
this.map.set(key, value);
}

/**
*
* @param {*} key b
*/
async get(key) {
return this.map.get(key);
}

/**
*
*/
async list() {
return Array.from(this.map.keys());
}
}

const Wallets = {
newInMemoryWallet: async () => {
return new StubWallet();
},
newFileSystemWallet: async(walletPath) => {
return new StubWallet();
}
};

mockery.enable();
mockery.registerMock('fabric-network', {Wallets});

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

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

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('dsgdsfdsjfdk');
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('should unregister and disable mockery', () => {
mockery.deregisterAll();
mockery.disable();
});
});

0 comments on commit 1cf7f49

Please sign in to comment.