/*
* 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 { Certificate, ConnectionManager } = require('composer-common');
const EmbeddedConnection = require('./embeddedconnection');
const EmbeddedDataService = require('composer-runtime-embedded').EmbeddedDataService;
const uuid = require('uuid');
const IDENTITY_COLLECTION_ID = 'identities';
/**
* Base class representing a connection manager that establishes and manages
* connections to one or more business networks.
* @protected
* @abstract
*/
class EmbeddedConnectionManager extends ConnectionManager {
/**
* Creates a new EmbeddedConnectionManager
* @param {ConnectionProfileManager} connectionProfileManager
* - the ConnectionProfileManager used to manage access connection profiles.
*/
constructor(connectionProfileManager) {
super(connectionProfileManager);
this.dataService = new EmbeddedDataService(null, true);
}
/**
* Import an identity into a profile wallet or keystore.
* @param {string} connectionProfile The name of the connection profile
* @param {object} connectionOptions The connection options loaded from the profile
* @param {string} id the id to associate with the identity
* @param {string} certificate the certificate
* @param {string} privateKey the private key
*/
async importIdentity(connectionProfile, connectionOptions, id, certificate, privateKey) {
const identities = await this.dataService.ensureCollection(IDENTITY_COLLECTION_ID);
const certificateObj = new Certificate(certificate);
const identifier = certificateObj.getIdentifier();
const publicKey = certificateObj.getPublicKey();
const name = certificateObj.getName();
const issuer = certificateObj.getIssuer();
let secret = uuid.v4().substring(0, 8);
let options = {};
// Allow an existing identity to be replaced in the connector wallet.
if (await identities.exists(id)) {
const curid = await identities.get(id);
secret = curid.secret;
options = curid.options;
await identities.remove(id);
}
const identity = {
identifier,
name,
issuer,
secret,
certificate,
publicKey,
privateKey,
imported: true,
options
};
await identities.add(id, identity);
}
/**
* Obtain the credentials associated with a given identity.
* @param {String} connectionProfileName - Name of the connection profile.
* @param {Object} connectionOptions - connection options loaded from the profile.
* @param {String} id - Name of the identity.
* @return {Promise} Resolves to credentials in the form <em>{ certificate: String, privateKey: String }</em>, or
* {@link null} if the named identity does not exist.
*/
async exportIdentity(connectionProfileName, connectionOptions, id) {
const identities = await this.dataService.ensureCollection(IDENTITY_COLLECTION_ID);
const exists = await identities.exists(id);
if (!exists) {
return null;
}
const { certificate, privateKey, imported } = await identities.get(id);
if (imported) {
return { certificate, privateKey };
}
return null;
}
/**
* Remove an identity from the profile wallet.
* @param {string} connectionProfile The name of the connection profile
* @param {object} connectionOptions The connection options loaded from the profile
* @param {string} id the id to associate with the identity
* @returns {Promise} a promise which resolves to true if identity existed and removed, false otherwise
* or rejects with an error.
*/
async removeIdentity(connectionProfile, connectionOptions, id) {
const identities = await this.dataService.ensureCollection(IDENTITY_COLLECTION_ID);
const exists = await identities.exists(id);
if (!exists) {
return exists;
}
const identity = await identities.get(id);
if (identity.imported) {
identity.imported = false;
await identities.update(id, identity);
return true;
}
return false;
}
/**
* Establish a connection to the business network.
* @param {string} connectionProfile The name of the connection profile
* @param {string} businessNetworkIdentifier The identifier of the business network
* @param {object} connectionOptions The connection options loaded from the profile
* @return {Promise} A promise that is resolved with a {@link Connection}
* object once the connection is established, or rejected with a connection error.
*/
async connect(connectionProfile, businessNetworkIdentifier, connectionOptions) {
return new EmbeddedConnection(this, connectionProfile, businessNetworkIdentifier);
}
}
module.exports = EmbeddedConnectionManager;