Skip to content

Commit

Permalink
Remove fabric-network dependency (#6)
Browse files Browse the repository at this point in the history
Couldn't overcome dependency conflicts for packages that depended
on both this module and different versions of fabric-network.
Read and write the old style wallet files directly instead of using
fabric-network.

Signed-off-by: Mark S. Lewis <mark_lewis@uk.ibm.com>
  • Loading branch information
bestbeforetoday authored Feb 29, 2020
1 parent f4df973 commit f1e8d4d
Show file tree
Hide file tree
Showing 17 changed files with 1,191 additions and 884 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules
dist
*.tsbuildinfo
coverage
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ tsconfig.json
src
test
jest.config.js
coverage
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
collectCoverage: true
};
1,269 changes: 708 additions & 561 deletions package-lock.json

Large diffs are not rendered by default.

11 changes: 7 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
{
"name": "fabric-wallet-migration",
"version": "0.0.4",
"version": "0.0.5",
"description": "Migration from Hyperledger Fabric 1.4 to 2.0 wallets",
"main": "index.js",
"types": "index.d.ts",
"scripts": {
"clean": "rm -rf dist",
"compile": "tsc --project .",
"prepack": "npm run clean && npm run compile && npm test",
"test": "jest test"
},
"repository": {
Expand All @@ -24,13 +25,15 @@
"homepage": "https://github.com/bestbeforetoday/fabric-wallet-migration#readme",
"devDependencies": {
"@types/jest": "^25.1.3",
"@types/rimraf": "^2.0.3",
"@types/uuid": "^7.0.0",
"fabric-network": "^1.4.7",
"jest": "^25.1.0",
"rimraf": "^3.0.2",
"ts-jest": "^25.2.1",
"typescript": "^3.8.2"
},
"dependencies": {
"fabric-ca-client": "1.4.7",
"fabric-client": "1.4.7",
"fabric-network": "1.4.7"
"uuid": "^7.0.1"
}
}
122 changes: 122 additions & 0 deletions src/FileSystemWalletStoreV1.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/**
* SPDX-License-Identifier: Apache-2.0
*/

import { User } from "./User";
import { IdentityConverter } from "./IdentityConverter";
import { IdentityData } from "./IdentityData";

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

const encoding = "utf8";
const privateKeyExtension = "-priv";

export class FileSystemWalletStoreV1 {
private readonly directory: string;
private readonly converter = new IdentityConverter();

constructor(directory: string) {
this.directory = directory;
}

async get(label: string): Promise<Buffer | undefined> {
try {
const user = await this.getUser(label);
const privateKey = await this.getPrivateKey(user);
const storeData = this.converter.userToStoreData(user, privateKey);
const json = JSON.stringify(storeData);
return Buffer.from(json, encoding);
} catch (error) {
return undefined;
}
}

async list(): Promise<string[]> {
const dirEntries = await fs.promises.readdir(this.directory, { withFileTypes: true });
const labels = dirEntries
.filter((dirEntry) => dirEntry.isDirectory())
.map((dirEntry) => dirEntry.name);

const results: string[] = [];
for (const label of labels) {
try {
await this.getUser(label);
results.push(label);
} catch (error) {
// Not a valid user
}
}

return results;
}

async put(label: string, data: Buffer): Promise<void> {
const json = data.toString(encoding);
const storeData = JSON.parse(json) as IdentityData;
const { user, privateKey } = this.converter.storeDataToUser(storeData, label);

await this.createIdentityDir(label);
await this.writeUser(user, label);
if (privateKey) {
await this.writePrivateKey(user, privateKey);
}
}

async remove(label: string): Promise<void> {
const identityDir = this.getIdentityDir(label);
await rimraf(identityDir);
}

private async getUser(label: string): Promise<User> {
const userPath = this.getUserPath(label);
const userData = await fs.promises.readFile(userPath);
return JSON.parse(userData.toString(encoding));
}

private getUserPath(label: string) {
const identityDir = this.getIdentityDir(label);
return path.join(identityDir, label);
}

private getIdentityDir(label: string) {
return path.join(this.directory, label);
}

private async getPrivateKey(user: User) {
const keyPath = this.getPrivateKeyPath(user);
try {
const keyData = await fs.promises.readFile(keyPath);
return keyData.toString(encoding).trim();
} catch (error) {
// No private key
return undefined;
}
}

private getPrivateKeyPath(user: User) {
const identityDir = this.getIdentityDir(user.name);
const file = user.enrollment.signingIdentity + privateKeyExtension;
return path.join(identityDir, file);
}

private async createIdentityDir(label: string) {
const identityDir = this.getIdentityDir(label);
await fs.promises.mkdir(identityDir);
}

private async writeUser(user: User, label: string) {
const userJson = JSON.stringify(user);
const userData = Buffer.from(userJson);
const userPath = this.getUserPath(label);
await fs.promises.writeFile(userPath, userData);
}

private async writePrivateKey(user: User, privateKey: string) {
const privateKeyPath = this.getPrivateKeyPath(user);
await fs.promises.writeFile(privateKeyPath, privateKey);
}
}
46 changes: 39 additions & 7 deletions src/IdentityConverter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,44 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { Identity } from "fabric-network";
import { User } from "./User";
import { IdentityData } from "./IdentityData";

export interface IdentityConverter {
readonly identityType: string;
readonly storeDataType: string;
identityToStoreData(identity: Identity): IdentityData;
storeDataToIdentity(storeData: IdentityData): Identity;
}
import uuid = require("uuid");

const hsmType = "HSM-X.509";
const x509Type = "X.509";

export class IdentityConverter implements IdentityConverter {
userToStoreData(user: User, privateKey?: string): IdentityData {
return {
type: privateKey ? x509Type : hsmType,
version: 1,
mspId: user.mspid,
credentials: {
certificate: user.enrollment.identity.certificate,
privateKey
}
};
}

storeDataToUser(storeData: IdentityData, label: string) {
if (storeData.type !== x509Type) {
throw new Error("Invalid identity type: " + storeData.type);
}

const user: User = {
name: label,
mspid: storeData.mspId,
enrollment: {
identity: {
certificate: storeData.credentials.certificate,
},
signingIdentity: uuid.v4().replace("-", "")
}
};
const privateKey = storeData.credentials.privateKey;

return { user, privateKey };
}
}
13 changes: 13 additions & 0 deletions src/IdentityData.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* SPDX-License-Identifier: Apache-2.0
*/

export interface IdentityData {
type: "X.509" | "HSM-X.509";
version: 1;
credentials: {
certificate: string;
privateKey?: string;
};
mspId: string;
}
27 changes: 0 additions & 27 deletions src/IdentityData.ts

This file was deleted.

16 changes: 16 additions & 0 deletions src/User.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* SPDX-License-Identifier: Apache-2.0
*/

export interface User {
name: string;
mspid: string;
enrollment: Enrollment;
}

export interface Enrollment {
identity: {
certificate: string;
};
signingIdentity: string;
}
43 changes: 0 additions & 43 deletions src/WalletStoreAdapter.ts

This file was deleted.

6 changes: 2 additions & 4 deletions src/WalletStores.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { FileSystemWallet } from "fabric-network";
import { WalletStoreAdapter } from "./WalletStoreAdapter";
import { FileSystemWalletStoreV1 } from "./FileSystemWalletStoreV1";

export function newFileSystemWalletStore(directory: string) {
const wallet = new FileSystemWallet(directory);
return new WalletStoreAdapter(wallet);
return new FileSystemWalletStoreV1(directory);
}
45 changes: 0 additions & 45 deletions src/X509IdentityConverter.ts

This file was deleted.

Loading

0 comments on commit f1e8d4d

Please sign in to comment.