Skip to content
This repository was archived by the owner on Apr 22, 2025. It is now read-only.

Commit 229c0fa

Browse files
committed
[FAB-6507] NodeSDK - add caname
NodeSDK use of the common network config was missing the caname. Also added a method to the Client to be able to get a CA based on the common config. Change-Id: Ib507c37dfd35686437d7239e2b1052add882969f Signed-off-by: Bret Harrison <beharrison@nc.rr.com>
1 parent 4800f64 commit 229c0fa

File tree

10 files changed

+204
-33
lines changed

10 files changed

+204
-33
lines changed

fabric-ca-client/lib/FabricCAClientImpl.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ var FabricCAServices = class extends BaseClient {
4646
/**
4747
* constructor
4848
*
49-
* @param {string} url The endpoint URL for Fabric CA services of the form: "http://host:port" or "https://host:port"
49+
* @param {string | object} url The endpoint URL for Fabric CA services of the form: "http://host:port" or "https://host:port"
50+
When this parameter is an object then it must include the parameters listed as key value pairs.
5051
* @param {TLSOptions} tlsOptions The TLS settings to use when the Fabric CA services endpoint uses "https"
5152
* @param {string} caName The optional name of the CA. Fabric-ca servers support multiple Certificate Authorities from
5253
* a single server. If omitted or null or an empty string, then the default CA is the target of requests
@@ -60,8 +61,20 @@ var FabricCAServices = class extends BaseClient {
6061
* is provided for this purpose, which can be used on top of any implementation of the {@link KeyValueStore} interface,
6162
* such as a file-based store or a database-based one. The specific implementation is determined by the value of this configuration setting.
6263
*/
63-
constructor(url, tlsOptions, caName, cryptoSuite) {
64+
constructor(url_p, tlsOptions_p, caName_p, cryptoSuite_p) {
6465
super();
66+
let url, tlsOptions, caName, cryptoSuite;
67+
if(typeof url_p === 'object') {
68+
url = url_p.url;
69+
tlsOptions = url_p.tlsOptions;
70+
caName = url_p.caName;
71+
cryptoSuite = url_p.cryptoSuite
72+
} else {
73+
url = url_p;
74+
tlsOptions = tlsOptions_p;
75+
caName = caName_p;
76+
cryptoSuite = cryptoSuite_p;
77+
}
6578

6679
var endpoint = FabricCAServices._parseURL(url);
6780

fabric-client/lib/CertificateAuthority.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ var CertificateAuthority = class {
3636
3737
* @returns {CertificateAuthority} The CertificateAuthority instance.
3838
*/
39-
constructor(name, url, connection_options, tlsCACerts, registrar) {
39+
constructor(name, caname, url, connection_options, tlsCACerts, registrar) {
4040
logger.debug('CertificateAuthority.const ');
4141
logger.debug('Organization.const ');
4242
if (typeof name === 'undefined' || name === null) {
@@ -46,6 +46,11 @@ var CertificateAuthority = class {
4646
throw new Error('Missing url parameter');
4747
}
4848
this._name = name;
49+
if(caname) {
50+
this._caname = caname;
51+
} else {
52+
this._caname = name;
53+
}
4954
this._url = url;
5055
this._connection_options = connection_options;
5156
this._tlsCACerts = tlsCACerts;;
@@ -61,6 +66,15 @@ var CertificateAuthority = class {
6166
return this._name;
6267
}
6368

69+
/**
70+
* Gets the name of this CertificateAuthority to use in request
71+
*
72+
* @returns {string} The ca name of this CertificateAuthority
73+
*/
74+
getCaName() {
75+
return this._caname;
76+
}
77+
6478
/**
6579
* Gets the url of this CertificateAuthority
6680
*

fabric-client/lib/Client.js

Lines changed: 61 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ var Client = class extends BaseClient {
9494
// an admin defined for the current user's organization.
9595
// This will get set during the setUserFromConfig
9696
this._adminSigningIdentity = null;
97+
98+
this._certificate_authority = null;
9799
}
98100

99101
/**
@@ -108,6 +110,7 @@ var Client = class extends BaseClient {
108110
if(client._network_config.hasClient()) {
109111
client._setAdminFromConfig();
110112
}
113+
111114
return client;
112115
}
113116

@@ -126,7 +129,10 @@ var Client = class extends BaseClient {
126129
}
127130
if(this._network_config.hasClient()) {
128131
this._setAdminFromConfig();
132+
// reset the CA incase the org changed
133+
this._certificate_authority = null;
129134
}
135+
130136
}
131137

132138
/**
@@ -278,6 +284,48 @@ var Client = class extends BaseClient {
278284
return orderer;
279285
}
280286

287+
/**
288+
* Returns a CertificateAuthority implementation as defined by the settings in the
289+
* currently loaded network configuration and the client configuration. A network
290+
* configuration must be loaded for this get method to return a Certificate Authority.
291+
*/
292+
getCertificateAuthority() {
293+
if(this._certificate_authority) {
294+
return this._certificate_authority;
295+
}
296+
if(!this._network_config) {
297+
throw new Error('No network configuration has been loaded');
298+
}
299+
let ca_url, tls_options, ca_name = null;
300+
let client_config = this._network_config.getClientConfig();
301+
if(client_config && client_config.organization) {
302+
let organization_config = this._network_config.getOrganization(client_config.organization);
303+
if(organization_config) {
304+
let cas = organization_config.getCertificateAuthorities();
305+
if(cas.length > 0) {
306+
let ca = cas[0];
307+
tls_options = {
308+
trustedRoots: [ca.getTlsCACerts()], //TODO handle non existent
309+
verify: ca.getConnectionOptions().verify //TODO handle non existent
310+
};
311+
ca_url = ca.getUrl();
312+
ca_name = ca.getCaName();
313+
}
314+
}
315+
}
316+
317+
if(!ca_url) {
318+
throw new Error('Network configuration is missing this client\'s organization and certificate authority');
319+
}
320+
321+
let ca_service_class = Client.getConfigSetting('certificate-authority-client');
322+
let ca_service_impl = require(ca_service_class);
323+
let ca_service = new ca_service_impl( {url : ca_url, tlsOptions : tls_options, caName : ca_name, cryptoSuite : this._crypto_suite});
324+
this._certificate_authority = ca_service;
325+
326+
return ca_service;
327+
}
328+
281329
/**
282330
* Returns a new {@link TransactionID} object. Fabric transaction ids are constructed
283331
* as a hash of a nonce concatenated with the signing identity's serialized bytes. The
@@ -1058,33 +1106,23 @@ var Client = class extends BaseClient {
10581106
return reject( new Error('Missing parameter. Must have a password.'));
10591107
}
10601108

1061-
let ca_url, tls_options, ca_name = null;
1062-
let client_config = self._network_config.getClientConfig();
1063-
if(client_config && client_config.organization) {
1064-
let organization_config = self._network_config.getOrganization(client_config.organization);
1065-
if(organization_config) {
1066-
mspid = organization_config.getMspid();
1067-
let cas = organization_config.getCertificateAuthorities();
1068-
if(cas.length > 0) {
1069-
let ca = cas[0];
1070-
tls_options = {
1071-
trustedRoots: [ca.getTlsCACerts()], //TODO handle non existent
1072-
verify: ca.getConnectionOptions().verify //TODO handle non existent
1073-
};
1074-
ca_url = ca.getUrl();
1075-
ca_name = ca.getName();
1109+
let ca_service, mspid = null;
1110+
try {
1111+
let client_config = this._network_config.getClientConfig();
1112+
if(client_config && client_config.organization) {
1113+
let organization_config = this._network_config.getOrganization(client_config.organization);
1114+
if(organization_config) {
1115+
mspid = organization_config.getMspid();
10761116
}
10771117
}
1118+
if(!mspid) {
1119+
throw new Error('Network configuration is missing this client\'s organization and mspid');
1120+
}
1121+
ca_service = self.getCertificateAuthority();
1122+
} catch(err) {
1123+
reject(err);
10781124
}
10791125

1080-
if(!ca_url || !tls_options || !mspid) {
1081-
return reject(new Error('Configuration is missing this client\'s organization and certificate authority'));
1082-
}
1083-
1084-
let ca_service_class = Client.getConfigSetting('certificate-authority-client');
1085-
var ca_service_impl = require(ca_service_class);
1086-
var ca_service = new ca_service_impl(ca_url, tls_options, ca_name, self._crypto_suite);
1087-
10881126
return ca_service.enroll({
10891127
enrollmentID: opts.username,
10901128
enrollmentSecret: opts.password

fabric-client/lib/impl/NetworkConfig_1_0.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ var HTTP_CONNECTION_OPTIONS = 'httpOptions';
4343
var URL = 'url';
4444
var EVENT_URL = 'eventUrl';
4545
var NAME = 'name';
46+
var CANAME = 'caName';
4647
var PEM = 'pem';
4748
var PATH = 'path';
4849
var REGISTRAR = 'registrar';
@@ -271,6 +272,7 @@ var NetworkConfig_1_0 = class {
271272
if(certificateAuthority_config) {
272273
certificateAuthority = new CertificateAuthority(
273274
name,
275+
certificateAuthority_config[CANAME],
274276
certificateAuthority_config[URL],
275277
certificateAuthority_config[HTTP_CONNECTION_OPTIONS],
276278
getTLSCACert(certificateAuthority_config),

test/fixtures/network.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ certificateAuthorities:
216216
- enrollId: admin
217217
enrollSecret: adminpw
218218
# [Optional] The optional name of the CA.
219-
caName: caNameHere
219+
caName: ca-org1
220220

221221
ca-org2:
222222
url: https://localhost:8054
@@ -228,4 +228,4 @@ certificateAuthorities:
228228
- enrollId: admin
229229
enrollSecret: adminpw
230230
# [Optional] The optional name of the CA.
231-
caName: caNameHere
231+
caName: ca-org2

test/integration/network-config.js

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,11 +312,28 @@ test('\n\n***** use the network configuration file *****\n\n', function(t) {
312312
/*
313313
* S T A R T U S I N G
314314
*/
315+
/*
316+
* switch to organization org2
317+
*/
318+
319+
client.loadFromConfig('test/fixtures/org2.yaml');
320+
321+
return client.initCredentialStores();
322+
}).then((nothing) => {
323+
t.pass('Successfully created the key value store and crypto store based on the config and network config');
324+
325+
let ca = client.getCertificateAuthority();
326+
if(ca) {
327+
t.equals(ca._fabricCAClient._caName,'ca-org2', 'checking that caname is correct for the newly created ca');
328+
} else {
329+
t.fail('Failed - CertificateAuthority should have been created');
330+
}
331+
315332
/*
316333
* switch to organization org1
317334
*/
318335
client.loadFromConfig('test/fixtures/org1.yaml');
319-
t.pass('Successfully loaded \'admin\' for org1');
336+
t.pass('Successfully loaded config for org1');
320337

321338
return client.initCredentialStores();
322339
}).then((nothing) => {
@@ -326,6 +343,21 @@ test('\n\n***** use the network configuration file *****\n\n', function(t) {
326343
}).then((admin) => {
327344
t.pass('Successfully enrolled user \'admin\' for org1');
328345

346+
let ca = client.getCertificateAuthority();
347+
if(ca) {
348+
t.equals(ca._fabricCAClient._caName,'ca-org1', 'checking that caname is correct after resetting the config');
349+
} else {
350+
t.fail('Failed - CertificateAuthority should have been created');
351+
}
352+
353+
return ca.register({enrollmentID: 'user1', affiliation: 'org1'}, admin);
354+
}).then((secret) => {
355+
t.pass('Successfully registered user \'user1\' for org1');
356+
357+
return client.setUserContext({username:'user1', password:secret});
358+
}).then((user)=> {
359+
t.pass('Successfully enrolled user \'user1\' for org1');
360+
329361
let tx_id = client.newTransactionID(); // get a non admin transaction ID
330362
var request = {
331363
chaincodeId : 'example',

test/unit/certificate-authority.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,14 @@ test('\n\n ** CertificateAuthority - constructor set get tests **\n\n', function
4242
'Test Missing url parameter');
4343

4444
t.doesNotThrow(()=>{
45-
new CertificateAuthority('name', 'url');
45+
new CertificateAuthority('name', 'caname', 'url');
4646
},
4747
null,
4848
'Test good construction');
4949

50-
var ca = new CertificateAuthority('name','url','opts', 'certs', 'user');
50+
var ca = new CertificateAuthority('name', 'caname', 'url','opts', 'certs', 'user');
5151
t.equals('name',ca.getName(),'test method getName');
52+
t.equals('caname',ca.getCaName(),'test method getCaName');
5253
t.equals('url',ca.getUrl(),'test method getUrl');
5354
t.equals('opts',ca.getConnectionOptions(),'test method getConnectionOptions');
5455
t.equals('certs',ca.getTlsCACerts(),'test method getTlsCACerts');
@@ -63,4 +64,4 @@ test('\n\n ** CertificateAuthority - constructor set get tests **\n\n', function
6364
}
6465

6566
t.end();
66-
});
67+
});

test/unit/client.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,3 +1205,17 @@ test('\n\n*** Test per-call timeout support ***\n', function(t) {
12051205
t.end();
12061206
});
12071207
});
1208+
1209+
test('\n\n*** Test per-call timeout support ***\n', function(t) {
1210+
let client = new Client();
1211+
t.throws(
1212+
() => {
1213+
1214+
client.getCertificateAuthority();
1215+
},
1216+
/No network configuration has been loaded/,
1217+
'Check that No network configuration has been loaded'
1218+
);
1219+
1220+
t.end();
1221+
});

test/unit/fabric-ca-client.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,52 @@ test('FabricCAServices: Test newCryptoKeyStore() function', function(t) {
269269
}
270270
t.end();
271271
});
272+
// Test optional consturctor
273+
test('FabricCAServices: Test optional consturctor', function(t) {
274+
let opts = {
275+
url : 'http://localhost:7054'
276+
}
277+
278+
t.doesNotThrow(
279+
function () {
280+
let service = new FabricCAServices(opts);
281+
},
282+
null,
283+
'FabricCAServices consturctor with object and just url'
284+
);
285+
286+
opts.caName = 'someca';
287+
t.doesNotThrow(
288+
function () {
289+
let service = new FabricCAServices(opts);
290+
t.equals(service._fabricCAClient._caName,'someca','Caname should have been passed correctly');
291+
},
292+
null,
293+
'FabricCAServices consturctor with object and just url'
294+
);
295+
296+
opts.cryptoSuite = 'somesuite';
297+
t.doesNotThrow(
298+
function () {
299+
let service = new FabricCAServices(opts);
300+
t.equals(service._fabricCAClient._cryptoPrimitives,'somesuite','CryptoSuite should have been passed correctly');
301+
},
302+
null,
303+
'FabricCAServices consturctor with object and just url'
304+
);
305+
306+
opts.tlsOptions = {verify : 'someverify'};
307+
t.doesNotThrow(
308+
function () {
309+
let service = new FabricCAServices(opts);
310+
t.equals(service._fabricCAClient._tlsOptions.verify,'someverify','tlsOptions should have been passed correctly');
311+
},
312+
null,
313+
'FabricCAServices consturctor with object and just url'
314+
);
315+
316+
t.end();
317+
});
272318

273319
// Test getCryptoSuite() function
274320
test('FabricCAServices: Test getCryptoSuite() function', function(t) {

test/unit/network-config.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,16 @@ test('\n\n ** configuration testing **\n\n', function (t) {
134134
'Should be able to instantiate a new instance of "Channel" with blank definition in the network configuration'
135135
);
136136

137+
t.throws(
138+
() => {
139+
var client = new Client();
140+
client._network_config = new NetworkConfig({}, client);
141+
client.getCertificateAuthority();
142+
},
143+
/Network configuration is missing this client\'s organization and certificate authority/,
144+
'Check for Network configuration is missing this client\'s organization and certificate authority'
145+
);
146+
137147
network_config.version = '1.0.0';
138148
network_config.channels = {
139149
'mychannel' : {
@@ -607,8 +617,9 @@ test('\n\n ** configuration testing **\n\n', function (t) {
607617

608618
t.doesNotThrow(
609619
() => {
610-
var certificateAuthority = new CertificateAuthority('name', 'url', 'connection', 'tlscert', 'registrar');
620+
var certificateAuthority = new CertificateAuthority('name', 'caname', 'url', 'connection', 'tlscert', 'registrar');
611621
t.equals('name',certificateAuthority.getName(), 'check name');
622+
t.equals('caname',certificateAuthority.getCaName(), 'check caname');
612623
t.equals('url',certificateAuthority.getUrl(), 'check url');
613624
t.equals('connection',certificateAuthority.getConnectionOptions(), 'check connection options');
614625
t.equals('tlscert',certificateAuthority.getTlsCACerts(), 'check tlscert');

0 commit comments

Comments
 (0)