balace tranfer 解析及api深度追踪(一)注册用户

一 注册用户代码代码
var getRegisteredUsers = function(username, userOrg, isJson) {
var member;
var client = getClientForOrg(userOrg);
var enrollmentSecret = null;
// 设置公私钥存储的地方
return hfc.newDefaultKeyValueStore({
// 这里只要求path参数 来作为存储的地方
path: getKeyStoreForOrg(getOrgName(userOrg))
}).then((store) => {
// 设置状态持久化存储(如(证书,私钥。。))
client.setStateStore(store);
// clearing the user context before switching
client._userContext = null;
//1 获取用户信息 (从 内存–>statestore 依次查找)
return client.getUserContext(1)(username, true).then((user) => {
if (user && user.isEnrolled()) {
// 从持久化中 成功加载此 user
logger.info(‘Successfully loaded member from persistence’);
return user;
} else {
let caClient = caClients[userOrg];
//2 获得adminuser 来注册账户
return getAdminUser(userOrg)().then(function(adminUserObj) {
member = adminUserObj;
return caClient.register(2)({
enrollmentID: username,
// 与此用户关联的隶属关系
affiliation: userOrg + ‘.department1’
}, member); // 注册员
}).then((secret) => {
enrollmentSecret = secret;
logger.debug(username + ’ registered successfully’);
//3 注册成功后 拿着secret 来enroll
return caClient.enroll(3)({
enrollmentID: username,
enrollmentSecret: secret
});
}, (err) => {
logger.debug(username + ’ failed to register’);
return ‘’ + err;
//return ‘Failed to register ‘+username+’. Error: ’ + err.stack ? err.stack : err;
}).then((message) => { // enroll 返回的信息
if (message && typeof message == ‘string’ && message.includes(
‘Error:’)) {
logger.error(username + ’ enrollment failed’);
return message;
}
logger.debug(username + ’ enrolled successfully’);
// 构建user对象
member = new User(username);
member._enrollmentSecret = enrollmentSecret;
//4 设置此User实例的注册对象 来持久化在client中
return member.setEnrollment(message.key, message.certificate, getMspID(userOrg));
}).then(() => {
//5 保存用户的上下文环境(e.g 证书 私钥 ) 用户签名 各种请求
client.setUserContext(member);
return member;
}, (err) => {
logger.error(util.format(’%s enroll failed: %s’, username, err.stack ? err.stack : err));
return ‘’ + err;
});;
}
});
}).then((user) => {
// 6 返回用户信息
if (isJson && isJson=== true) {
var response = {
success: true,
secret: user._enrollmentSecret,
message: username + ’ enrolled Successfully’,
};
return response;
}
return user;
}, (err) => {
logger.error(util.format(‘Failed to get registered user: %s, error: %s’, username, err.stack ? err.stack : err));
return ‘’ + err;
});
};
二 代码里api追踪
)var getAdminUser = function(userOrg) {
var users = hfc.getConfigSetting(‘admins’);//获得用户的admin(0)
var username = users[0].username;
var password = users[0].secret;
var member;
var client = getClientForOrg(userOrg);
return hfc.newDefaultKeyValueStore({
path: getKeyStoreForOrg(getOrgName(userOrg))
}).then((store) => {
client.setStateStore(store);
// clearing the user context before switching
client._userContext = null;
return client.getUserContext(username, true).then((user) => {
if (user && user.isEnrolled()) {
logger.info(‘Successfully loaded member from persistence’);
return user;
} else {
let caClient = caClients[userOrg];
// need to enroll it with CA server
return caClient.enroll({
enrollmentID: username,
enrollmentSecret: password
}).then((enrollment) => {
logger.info(‘Successfully enrolled user ‘’ + username + ‘’’);
member = new User(username);
member.setCryptoSuite(client.getCryptoSuite());
return member.setEnrollment(enrollment.key, enrollment.certificate, getMspID(userOrg));
}).then(() => {
return client.setUserContext(member);
}).then(() => {
return member;
}).catch((err) => {
logger.error('Failed to enroll and persist user. Error: ’ + err.stack ?
err.stack : err);
return null;
});
}
});
});
};
(0)//Internal method to get an override setting to the configuration settings
//
module.exports.getConfigSetting = function(name, default_value) {
var config = this.getConfig();
return config.get(name, default_value);
};

(1)

  • @param {String} name - Optional. If not specified, will only return the current in-memory user context object, or null
    * if none has been set. If “name” is specified, will also attempt to load it from the state store
    * if search in memory failed.
    * @param {boolean} checkPersistence - Optional. If specified and truthy, the method returns a Promise and will
    * attempt to check the state store for the requested user by the “name”. If not
    * specified or falsey, the method is synchronous and returns the requested user from memory
    * @returns {Promise | User} Promise for the user object corresponding to the name, or null if the user does not exist or if the
    * state store has not been set. If “checkPersistence” is not specified or falsey, then the user object
    * is returned synchronously.
    */

      getUserContext(name, checkPersistence) {
      	// first check if only one param is passed in for "checkPersistence"
      	if (typeof name === 'boolean' && name && typeof checkPersistence === 'undefined')
      		throw new Error('Illegal arguments: "checkPersistence" is truthy but "name" is undefined');
    
      	if (typeof checkPersistence === 'boolean' && checkPersistence &&
      		(typeof name !== 'string' || name === null || name === ''))
      		throw new Error('Illegal arguments: "checkPersistence" is truthy but "name" is not a valid string value');
    
      	var self = this;
      	var username = name;
      	if ((self._userContext && name && self._userContext.getName() === name) || (self._userContext && !name)) {
      		if (typeof checkPersistence === 'boolean' && checkPersistence)
      			return Promise.resolve(self._userContext);
      		else
      			return self._userContext;
      	} else {
      		if (typeof username === 'undefined' || !username) {
      			if (typeof checkPersistence === 'boolean' && checkPersistence)
      				return Promise.resolve(null);
      			else
      				return null;
      		}
    
      		// this could be because the application has not set a user context yet for this client, which would
      		// be an error condiditon, or it could be that this app has crashed before and is recovering, so we
      		// should allow the previously saved user context object to be deserialized
    
      		// first check if there is a user context of the specified name in persistence
      		if (typeof checkPersistence === 'boolean' && checkPersistence) {
      			if (self._stateStore) {
      				return self.loadUserFromStateStore(username).then(
      					function(userContext) {
      						if (userContext) {
      							logger.debug('Requested user "%s" loaded successfully from the state store on this Client instance: name - %s', name, name);
      							return self.setUserContext(userContext, false);
      						} else {
      							logger.debug('Requested user "%s" not loaded from the state store on this Client instance: name - %s', name, name);
      							return null;
      						}
      					}
      				).then(
      					function(userContext) {
      						return Promise.resolve(userContext);
      					}
      				).catch(
      					function(err) {
      						logger.error('Failed to load an instance of requested user "%s" from the state store on this Client instance. Error: %s', name, err.stack ? err.stack : err);
      						return Promise.reject(err);
      					}
      				);
      			} else {
      				// we don't have it in memory or persistence, just return null
      				return Promise.resolve(null);
      			}
      		} else
      			return null;
      	}
      }
    

(2)
* Register the member and return an enrollment secret.
* @param {Object} req Registration request with the following fields:
*
- enrollmentID {string}. ID which will be used for enrollment
*
- enrollmentSecret {string}. Optional enrollment secret to set for the registered user.
* If not provided, the server will generate one.
*
- role {string}. An arbitrary string representing a role value for the user
*
- affiliation {string}. Affiliation with which this user will be associated, like a company or an organization
*
- maxEnrollments {number}. The maximum number of times this user will be permitted to enroll
*
- attrs {{@link KeyValueAttribute}[]}. Array of key/value attributes to assign to the user.
* @param registrar {User}. The identity of the registrar (i.e. who is performing the registration)
* @returns {Promise} The enrollment secret to use when this user enrolls
*/

	register(req, registrar) {
		if (typeof req === 'undefined' || req === null) {
			throw new Error('Missing required argument "request"');
		}

		if (typeof req.enrollmentID === 'undefined' || req.enrollmentID === null) {
			throw new Error('Missing required argument "request.enrollmentID"');
		}

		if (typeof req.maxEnrollments === 'undefined' || req.maxEnrollments === null) {
			// set maxEnrollments to 1
			req.maxEnrollments = 1;
		}

		checkRegistrar(registrar);

		return this._fabricCAClient.register(req.enrollmentID, req.enrollmentSecret, req.role, req.affiliation, req.maxEnrollments, req.attrs,
			registrar.getSigningIdentity(5)());

 * Register a new user and return the enrollment secret
	 * @param {string} enrollmentID ID which will be used for enrollment
	 * @param {string} enrollmentSecret Optional enrollment secret to set for the registered user.
	 *        If not provided, the server will generate one.
	 *        When not including, use a null for this parameter.
	 * @param {string} role Optional type of role for this user.
	 *        When not including, use a null for this parameter.
	 * @param {string} affiliation Affiliation with which this user will be associated
	 * @param {number} maxEnrollments The maximum number of times the user is permitted to enroll
	 * @param {KeyValueAttribute[]} attrs Array of key/value attributes to assign to the user
	 * @param {SigningIdentity} signingIdentity The instance of a SigningIdentity encapsulating the
	 * signing certificate, hash algorithm and signature algorithm
	 * @returns {Promise} The enrollment secret to use when this user enrolls
	 */
	register(enrollmentID, enrollmentSecret, role, affiliation, maxEnrollments, attrs, signingIdentity) {

		var self = this;
		//all arguments are required
		if (!enrollmentID || !affiliation || !signingIdentity) {
			throw new Error('Missing required parameters.  \'enrollmentID\', \'affiliation\', \
				and \'signingIdentity\' are all required.');
		} else if (!(typeof maxEnrollments === 'number')) {
			throw new Error('Missing required parameter. \'maxEnrollments\' must be a number');
		}

		return new Promise(function (resolve, reject) {
			var regRequest = {
				'id': enrollmentID,
				'affiliation': affiliation,
				'max_enrollments': maxEnrollments
			};

			if(role) {
				regRequest.type = role;
			}

			if(attrs) {
				regRequest.attrs = attrs;
			}

			if (typeof enrollmentSecret === 'string' && enrollmentSecret !== '') {
				regRequest.secret = enrollmentSecret;
			}

			return self.post('register', regRequest, signingIdentity)
			.then(function (response) {
				return resolve(response.result.secret);
			}).catch(function (err) {
				return reject(err);
			});
		});
	}

(3)
* @typedef {Object} EnrollmentRequest
* @property {string} enrollmentID - The registered ID to use for enrollment
* @property {string} enrollmentSecret - The secret associated with the enrollment ID
* @property {string} profile - The profile name. Specify the ‘tls’ profile for a TLS certificate;
* otherwise, an enrollment certificate is issued.
* @property {AttributeRequest[]} attr_reqs - An array of {@link AttributeRequest}
*/

	/**
	 * Enroll the member and return an opaque member object.
	 * @param req the {@link EnrollmentRequest}
	 * @returns Promise for an object with "key" for private key and "certificate" for the signed certificate
	 */
	 
	enroll(req) {
		var self = this;

		return new Promise(function (resolve, reject) {
			if (typeof req === 'undefined' || req === null) {
				logger.error('enroll() missing required argument "request"');
				return reject(new Error('Missing required argument "request"'));
			}
			if (!req.enrollmentID) {
				logger.error('Invalid enroll request, missing enrollmentID');
				return reject(new Error('req.enrollmentID is not set'));
			}

			if (!req.enrollmentSecret) {
				logger.error('Invalid enroll request, missing enrollmentSecret');
				return reject(new Error('req.enrollmentSecret is not set'));
			}

			if(req.attr_reqs) {
				if(!Array.isArray(req.attr_reqs)) {
					logger.error('Invalid enroll request, attr_reqs must be an array of AttributeRequest objects');
					return reject(new Error('req.attr_reqs is not an array'));
				} else {
					for(let i in req.attr_reqs) {
						let attr_req = req.attr_reqs[i];
						if(!attr_req.name) {
							logger.error('Invalid enroll request, attr_reqs object is missing the name of the attribute');
							return reject(new Error('req.att_regs is missing the attribute name'));
						}
					}
				}
			}

			//generate enrollment certificate pair for signing
			var opts;
			if (self.getCryptoSuite()._cryptoKeyStore) {
				opts = {ephemeral: false};
			} else {
				opts = {ephemeral: true};
			}
			self.getCryptoSuite().generateKey(opts)
				.then(
				function (privateKey) {
					//generate CSR using enrollmentID for the subject
					try {
						var csr = privateKey.generateCSR('CN=' + req.enrollmentID);
						self._fabricCAClient.enroll(req.enrollmentID, req.enrollmentSecret, csr, req.profile, req.attr_reqs)(4)
							.then(
							function (enrollResponse) {
								return resolve({
									key: privateKey,
									certificate: enrollResponse.enrollmentCert,
									rootCertificate: enrollResponse.caCertChain
								});
							},
							function (err) {
								return reject(err);
							}
							);

					} catch (err) {
						return reject(new Error(util.format('Failed to generate CSR for enrollmemnt due to error [%s]', err)));
					}
				},
				function (err) {
					return reject(new Error(util.format('Failed to generate key for enrollment due to error [%s]', err)));
				}
				);

		});
	}

(4)

 * Enroll a registered user in order to receive a signed X509 certificate
	 * @param {string} enrollmentID The registered ID to use for enrollment
	 * @param {string} enrollmentSecret The secret associated with the enrollment ID
	 * @param {string} csr PEM-encoded PKCS#10 certificate signing request
	 * @param {string} profile The profile name.  Specify the 'tls' profile for a TLS certificate; otherwise, an enrollment certificate is issued.
	 * @param {AttributeRequest[]} attr_reqs An array of {@link AttributeRequest}
	 * @returns {Promise} {@link EnrollmentResponse}
	 * @throws Will throw an error if all parameters are not provided
	 * @throws Will throw an error if calling the enroll API fails for any reason
	 */
	 
	enroll(enrollmentID, enrollmentSecret, csr, profile, attr_reqs) {

		var self = this;
		var numArgs = arguments.length;

		return new Promise(function (resolve, reject) {
			//check for required args
			if (numArgs < 3) {
				return reject(new Error('Missing required parameters.  \'enrollmentID\', \'enrollmentSecret\' and \'csr\' are all required.'));
			}

			var requestOptions = {
				hostname: self._hostname,
				port: self._port,
				path: self._baseAPI + 'enroll',
				method: 'POST',
				auth: enrollmentID + ':' + enrollmentSecret,
				ca: self._tlsOptions.trustedRoots,
				rejectUnauthorized: self._tlsOptions.verify
			};

			var enrollRequest = {
				caName: self._caName,
				certificate_request: csr
			};

			if(profile) {
				enrollRequest.profile = profile;
			}

			if(attr_reqs) {
				enrollRequest.attr_reqs = attr_reqs;
			}

			var request = self._httpClient.request(requestOptions, function (response) {

				const responseBody = [];
				response.on('data', function (chunk) {
					responseBody.push(chunk);
				});

				response.on('end', function () {

					var payload = responseBody.join('');

					if (!payload) {
						reject(new Error(
							util.format('Enrollment failed with HTTP status code ', response.statusCode)));
					}
					//response should be JSON
					try {
						var res = JSON.parse(payload);
						if (res.success) {
							//we want the result field which is Base64-encoded PEM
							var enrollResponse = new Object();
							// Cert field is Base64-encoded PEM
							enrollResponse.enrollmentCert = Buffer.from(res.result.Cert, 'base64').toString();
							enrollResponse.caCertChain = Buffer.from(res.result.ServerInfo.CAChain, 'base64').toString();
							return resolve(enrollResponse);
						} else {
							return reject(new Error(
								util.format('Enrollment failed with errors [%s]', JSON.stringify(res.errors))));
						}

					} catch (err) {
						reject(new Error(
							util.format('Could not parse enrollment response [%s] as JSON due to error [%s]', payload, err)));
					}
				});

			});

			request.on('error', function (err) {
				reject(new Error(util.format('Calling enrollment endpoint failed with error [%s]', err)));
			});

			let body = JSON.stringify(enrollRequest);
			request.write(body);
			request.end();

		});

(5)
_getSigningIdentity(admin) {
logger.debug(’_getSigningIdentity - admin parameter is %s :%s’,(typeof admin),admin);
if(admin && this._adminSigningIdentity) {
return this._adminSigningIdentity;
} else {
if(this._userContext) {
return this._userContext.getSigningIdentity();
} else {
throw new Error(‘No identity has been assigned to this client’);
}
}
}
* Set the admin signing identity object. This method will only assign a
* signing identity for use by this client instance and will not persist
* the identity.
* @param {string} private_key - the private key PEM string
* @param {string} certificate the PEM-encoded string of certificate
* @param {string} mspid The Member Service Provider id for the local signing identity
*/

	setAdminSigningIdentity(private_key, certificate, mspid) {
		logger.debug('setAdminSigningIdentity - start mspid:%s',mspid);
		if (typeof private_key === 'undefined' || private_key === null || private_key === '') {
			throw new Error('Invalid parameter. Must have a valid private key.');
		}
		if (typeof certificate === 'undefined' || certificate === null || certificate === '') {
			throw new Error('Invalid parameter. Must have a valid certificate.');
		}
		if (typeof mspid === 'undefined' || mspid === null || mspid === '') {
			throw new Error('Invalid parameter. Must have a valid mspid.');
		}
		let crypto_suite = this.getCryptoSuite();
		if(!crypto_suite) {
			crypto_suite = BaseClient.newCryptoSuite();
		}
		const key = crypto_suite.importKey(private_key, {ephemeral : true});
		const public_key = crypto_suite.importKey(certificate, {ephemeral: true});

		this._adminSigningIdentity = new SigningIdentity(certificate, public_key, mspid, crypto_suite, new Signer(crypto_suite, key));
	}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值