Skip to content

Commit

Permalink
Check that wallet directory exists on file system store creation (#13)
Browse files Browse the repository at this point in the history
- Change the API to export just the newFileSystemWalletStore
  factory function.
- newFileSystemWalletStore is now async to enable async I/O.
- Code example in README updated to reflect current API.

Signed-off-by: Mark S. Lewis <[email protected]>
  • Loading branch information
bestbeforetoday authored Mar 11, 2020
1 parent 56d87c1 commit 9690bb9
Show file tree
Hide file tree
Showing 10 changed files with 70 additions and 42 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ used with the Hyperledger Fabric version 2.0 SDK for Node.
## Example migration from 1.4 to 2.0 wallet format

```javascript
import { WalletStores } from "fabric-wallet-migration";
import * as WalletMigration from "fabric-wallet-migration";
import { Wallet, Wallets } from "fabric-network";

async function migrateWallet(oldWalletDirectory: string, newWalletDirectory: string) {
const walletStore = WalletStores.newFileSystemWalletStore(oldWalletDirectory);
const walletStore = await WalletMigration.newFileSystemWalletStore(oldWalletDirectory);
const oldWallet = new Wallet(walletStore);

const newWallet = await Wallets.newFileSystemWallet(newWalletDirectory);
Expand Down
5 changes: 1 addition & 4 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,4 @@ stages:
displayName: Build
- script: npm test
displayName: Unit test

- script: npm run scenario
displayName: Scenario test
displayName: Test
3 changes: 1 addition & 2 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@
* SPDX-License-Identifier: Apache-2.0
*/

import * as WalletStores from "./dist/WalletStores";
export { WalletStores };
export { newFileSystemWalletStore } from "./dist/WalletStores";
3 changes: 2 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
* SPDX-License-Identifier: Apache-2.0
*/

module.exports.WalletStores = require("./dist/WalletStores");
const WalletStores = require("./dist/WalletStores");
module.exports.newFileSystemWalletStore = WalletStores.newFileSystemWalletStore;
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
{
"name": "fabric-wallet-migration",
"version": "0.0.8",
"version": "0.1.0",
"description": "Migration from Hyperledger Fabric 1.4 to 2.0 wallets",
"main": "index.js",
"types": "index.d.ts",
"scripts": {
"build": "npm run compile && npm run lint",
"clean": "rm -rf dist *.tgz",
"clean": "rm -rf dist *.tgz scenario/package-lock.json",
"compile": "tsc",
"lint": "eslint . --ext .js,.ts",
"lint": "eslint . --ext .ts",
"scenario": "./runScenario.sh",
"test": "jest"
"test": "npm run unitTest && npm run scenario",
"unitTest": "jest"
},
"repository": {
"type": "git",
Expand Down
6 changes: 3 additions & 3 deletions scenario/test/Migrate.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { WalletStores } from "fabric-wallet-migration";
import * as WalletMigration from "fabric-wallet-migration";
import { Wallet, Wallets, Identity, X509Identity } from "fabric-network";

import fs = require("fs");
Expand All @@ -15,7 +15,7 @@ const rimraf = util.promisify(_rimraf);
const oldWalletPath = path.resolve(__dirname, "..", "wallet");

async function createTempDir(): Promise<string> {
const prefix = path.join(os.tmpdir(), "wallet-");
const prefix = path.join(os.tmpdir(), path.sep);
return await fs.promises.mkdtemp(prefix);
}

Expand All @@ -24,7 +24,7 @@ describe("Wallet migration", () => {
let wallet: Wallet;

async function migrate(): Promise<string[]> {
const walletStore = WalletStores.newFileSystemWalletStore(oldWalletPath);
const walletStore = await WalletMigration.newFileSystemWalletStore(oldWalletPath);
const oldWallet = new Wallet(walletStore);

const newWallet = await Wallets.newFileSystemWallet(walletPath);
Expand Down
7 changes: 5 additions & 2 deletions src/WalletStores.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@

import { FileSystemWalletStoreV1 } from "./FileSystemWalletStoreV1";

interface WalletStore {
import fs = require("fs");

export interface WalletStore {
get(label: string): Promise<Buffer | undefined>;
list(): Promise<string[]>;
put(label: string, data: Buffer): Promise<void>;
remove(label: string): Promise<void>;
}

export function newFileSystemWalletStore(directory: string): WalletStore {
export async function newFileSystemWalletStore(directory: string): Promise<WalletStore> {
await fs.promises.access(directory); // Throws if directory does not exist
return new FileSystemWalletStoreV1(directory);
}
29 changes: 5 additions & 24 deletions test/FileSystemWalletStoreV1.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,12 @@

import { X509WalletMixin, Identity, Wallet, FileSystemWallet } from "fabric-network";

import { FileSystemWalletStoreV1 } from "../src/FileSystemWalletStoreV1";
import { newFileSystemWalletStore, WalletStore } from "../src/WalletStores";
import { IdentityData } from "../src/IdentityData";
import { createTempDir, stripNewlines, readFile, rmdir } from "./TestUtils";

import fs = require("fs");
import util = require("util");
import path = require("path");
import os = require("os");
import _rimraf = require("rimraf");
const rimraf = util.promisify(_rimraf);

const certificateFile = "certificate.pem";
const privateKeyFile = "privateKey.pem";
Expand All @@ -27,28 +24,12 @@ function objectToBuffer(jsonObj: object): Buffer {
return Buffer.from(json, "utf8");
}

async function readFile(fileName: string): Promise<string> {
const readFileAsync = util.promisify(fs.readFile);
const filePath = path.resolve(__dirname, fileName);
const buffer = await readFileAsync(filePath);
return buffer.toString("utf8");
}

function stripNewlines(text: string): string {
return text.replace(/[\r\n]/g, "");
}

async function createTempDir(): Promise<string> {
const prefix = path.join(os.tmpdir(), "wallet-");
return await fs.promises.mkdtemp(prefix);
}

describe("FileSystemWalletStoreV1", () => {
let identity: Identity;
let x509Data: IdentityData;
let hsmData: IdentityData;
let wallet: Wallet;
let store: FileSystemWalletStoreV1;
let store: WalletStore;
let tempDir: string;

async function removePrivateKeyFiles(label: string): Promise<void> {
Expand Down Expand Up @@ -90,11 +71,11 @@ describe("FileSystemWalletStoreV1", () => {

identity = X509WalletMixin.createIdentity(mspId, certificate, privateKey);

store = new FileSystemWalletStoreV1(tempDir);
store = await newFileSystemWalletStore(tempDir);
});

afterEach(async () => {
await rimraf(tempDir);
await rmdir(tempDir);
});

describe("#get", () => {
Expand Down
29 changes: 29 additions & 0 deletions test/TestUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* SPDX-License-Identifier: Apache-2.0
*/

import fs = require("fs");
import util = require("util");
import path = require("path");
import os = require("os");
import _rimraf = require("rimraf");
const rimraf = util.promisify(_rimraf);

export async function readFile(fileName: string): Promise<string> {
const filePath = path.resolve(__dirname, fileName);
const buffer = await fs.promises.readFile(filePath);
return buffer.toString("utf8");
}

export function stripNewlines(text: string): string {
return text.replace(/[\r\n]/g, "");
}

export async function createTempDir(): Promise<string> {
const prefix = path.join(os.tmpdir() + path.sep);
return await fs.promises.mkdtemp(prefix);
}

export async function rmdir(path: string): Promise<void> {
await rimraf(path);
}
17 changes: 17 additions & 0 deletions test/WalletStores.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* SPDX-License-Identifier: Apache-2.0
*/

import { newFileSystemWalletStore } from "../src/WalletStores";
import { createTempDir, rmdir } from "./TestUtils";

describe("WalletStores", () => {
it("throws if file system wallet directory does not exist", async () => {
const dir = await createTempDir();
await rmdir(dir);

const f = newFileSystemWalletStore(dir);

await expect(f).rejects.toThrow(dir);
});
});

0 comments on commit 9690bb9

Please sign in to comment.