How to add attribute values to the admin on Hyperledger fabric? - hyperledger-fabric

Based on fabcar-sample (v1.4) I developed an app in which I want to use attribute values for the admin and for the users. I face an issue about how to add attribute values while I enroll in the admin. I do not know if it is possible to add attribute values for the admin. In the examples that I have seen are only added from the registered users. In the fabcar sample looks like the admin is just enrolled and not registered in contrast to the users.
registerUser.js
const gateway = new Gateway();
await gateway.connect(ccpPath, { wallet, identity: 'admin', discovery: { enabled: true, asLocalhost: true } });
console.log('Create a new gateway for connecting to our peer node');
// Get the CA client object from the gateway for interacting with the CA.
const ca = gateway.getClient().getCertificateAuthority();
const adminIdentity = gateway.getCurrentIdentity();
console.log('Get the CA client object from the gateway for interacting with the CA');
const aff = adminIdentity.getAffiliation();
const secret = await ca.register({ affiliation: aff, enrollmentID: username, role: 'client', attrs: [ {"name": "email", "value": "myemail#test.com", "ecert": true} ] }, adminIdentity);
const enrollment = await ca.enroll({ enrollmentID: username, enrollmentSecret: secret, attr_reqs: [{ name: "email", optional: false }]});
enrollAdmin.js
const caInfo = ccp.certificateAuthorities[ca_info];
const caTLSCACerts = caInfo.tlsCACerts.pem;
const ca = new FabricCAServices(caInfo.url, { trustedRoots: caTLSCACerts, verify: false }, caInfo.caName);
// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), wallet_info);
const wallet = new FileSystemWallet(walletPath);
const enrollment = await ca.enroll({ enrollmentID: username, enrollmentSecret:'adminpw'});
const identity = X509WalletMixin.createIdentity(MSP, enrollment.certificate, enrollment.key.toBytes());
await wallet.import(username, identity);
smartcontract.go
func (c *SmartContract) getEmail(stub shim.ChaincodeStubInterface) (string, error) {
email, ok, err := cid.GetAttributeValue(stub, "email")
if err != nil {
return "", err
}
if !ok {
return "", errors.New("email attribute is missing")
}
return email, nil
}
Any idea how to add attribute values on the admin while in this process in not registered the admin like the users?

In the case of the admin client, when the fabric-ca-server is executed, the value can be set in the configuration. Most of the examples work only with the ID and password by using the -b option. like fabric-ca-server start -b admin:adminpw -d
default configuration can be changed in fabric-ca-server-config.yaml file.
fabric-ca-server-config.yaml link is fabric-samples v2.0, but fabric-ca has no changes(v1.4) and the configuration form is the same.
You can add admin's attr in this file.
[EDIT] I wrote it according to the guide document, but I confirmed that it does not work. After deepdive analysis of the code, I confirmed and corrected that the regular expression did not work properly.
hf.Registrar.Attributes: "*"
to
hf.Registrar.Attributes: "email,hf.Registrar.Roles,hf.Registrar.DelegateRoles,hf.Revoker,hf.IntermediateCA,hf.GenCRL,hf.Registrar.Attributes,hf.AffiliationMgr"
in fabric-ca-server-config.yaml
Here is example.
docker-compose-ca.yaml
version: '3'
services:
ca.org1.example.com:
image: hyperledger/fabric-ca:1.4
environment:
- FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
- FABRIC_CA_SERVER_CA_NAME=ca.org1.example.com
- FABRIC_CA_SERVER_TLS_ENABLED=true
- FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem
- FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/<your_ca_org1_private_key>
- FABRIC_CA_SERVER_PORT=7054
ports:
- "7054:7054"
command: sh -c 'fabric-ca-server start -d'
volumes:
# mounting fabric-ca-server-config.yaml file
- ./fabric-ca-server-config.yaml:/etc/hyperledger/fabric-ca-server/fabric-ca-server-config.yaml
- ./crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config
container_name: ca.org1.example.com
fabric-ca-server-config.yaml
...
registry:
maxenrollments: -1
identities:
- name: test
pass: testpw
type: client
affiliation: ""
attrs:
# <add_your_attrs>
email: "myemail#test.com"
hf.Registrar.Roles: "*"
hf.Registrar.DelegateRoles: "*"
hf.Revoker: true
hf.IntermediateCA: true
hf.GenCRL: true
hf.Registrar.Attributes: "email,hf.Registrar.Roles,hf.Registrar.DelegateRoles,hf.Revoker,hf.IntermediateCA,hf.GenCRL,hf.Registrar.Attributes,hf.AffiliationMgr"
hf.AffiliationMgr: true
...
enrollAdmin.js
...
// Enroll the admin user, and import the new identity into the wallet.
// with attrs
const enrollment = await ca.enroll({ enrollmentID: 'test', enrollmentSecret: 'testpw',
attr_reqs: [{ name: "email", optional: false }] });
const x509Identity = {
credentials: {
certificate: enrollment.certificate,
privateKey: enrollment.key.toBytes(),
},
mspId: 'Org1MSP',
type: 'X.509',
};
await wallet.put('admin', x509Identity);
console.log('Successfully enrolled admin user "admin" and imported it into the wallet');
...
node enrollAdmin.js
Successfully enrolled admin user "admin" and imported it into the wallet
it works!
[NOTE] If you don't want to touch the docker or configuration it's okay to add another admin to work.
registerAndEnrollAdmin.js
...
// Register the user, enroll the user, and import the new identity into the wallet.
const adminUser = await provider.getUserContext(adminIdentity, 'admin');
const secret = await ca.register({
affiliation: 'org1.department1',
enrollmentID: 'admin2',
role: 'client',
attrs: [ {"name": "hf.Registrar.Roles", "value": "client,orderer,peer"}, {"name": "hf.Registrar.DelegateRoles", "value": "client,orderer,peer"}, {"name": "hf.Revoker", "value": "true"},
{"name": "email", "value": "test#example.com"}, {"name": "hf.Registrar.Attributes", "value": "email, hf.Registrar.Roles, hf.Registrar.DelegateRoles, hf.Revoker, hf.Registrar.Attributes"} ] }
, adminUser);
const enrollment = await ca.enroll({
enrollmentID: 'admin2',
enrollmentSecret: secret,
attr_reqs: [{ name: "email", optional: false }]
});
...
then you can register users using admin2

Related

Octokit.js github base url setup

I am trying to authenticate with my enterprise github through App in octokit.js but I couldn't find any parameter to change gihub url. Can someone please help?
const {Octokit, App} = require('octokit')
// below points to github.com
const app = new App({ appId: appId1, privateKey: privateKey1 })
// below does not work
//const app = new App({ appId: appId1, privateKey: privateKey1 , baseUrl: mygitHub })
app.octokit.rest.apps.getAuthenticated();
Using nodejs.
Found answer at https://github.com/octokit/app.js/#constructor
const { Octokit } = require("#octokit/core");
new App({
appId: 123,
privateKey: "-----BEGIN PRIVATE KEY-----\n...",
oauth: {
clientId: 123,
clientSecret: "secret",
},
webhooks: {
secret: "secret",
},
Octokit: Octokit.defaults({
baseUrl: "https://ghe.my-company.com/api/v3",
}),
});

Hyperledger CA ignore TLS certificate from Fabric SDK for Node

I have the CA for my organization. This is setting for CA's docker container:
version: '2'
services:
ca.org1.example.com:
container_name: ca.org1.example.com
image: hyperledger/fabric-ca
command: /bin/bash -c 'fabric-ca-server start -b rca-org-admin:rca-org-adminpw --port 6053'
environment:
- FABRIC_CA_SERVER_HOME=/tmp/hyperledger/fabric-ca/crypto
- FABRIC_CA_SERVER_TLS_ENABLED=true
- FABRIC_CA_SERVER_CSR_CN=ca.org1.example.com
- FABRIC_CA_SERVER_CSR_HOSTS=0.0.0.0
- FABRIC_CA_SERVER_DEBUG=true
- ADMIN_CREDS=rca-org-admin:rca-org-adminpw
- PORT=6053
volumes:
- /home/user/go/src/network/crypto-config/org1/ca/server:/tmp/hyperledger/fabric-ca
ports:
- 6053:6053
networks:
- basic
networks:
basic:
I have a connectionProfile.yaml with url and TLS certificate of my CA:
certificateAuthorities:
ca.org1.examlple.com:
url: https://localhost:6053
tlsCACerts:
pem: |
-----BEGIN CERTIFICATE-----
MIICMzCCAdqgAwIBAgIUYj0f4V+ms+xjSSx73MYurypAwGUwCgYIKoZIzj0EAwIw
bjELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMRQwEgYDVQQK
EwtIeXBlcmxlZGdlcjEPMA0GA1UECxMGRmFicmljMR8wHQYDVQQDExZjYS5xcHIu
Zm9vdGJhbGxuZXQuY29tMB4XDTIwMDUwNjA5NTgwMFoXDTM1MDUwMzA5NTgwMFow
bjELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMRQwEgYDVQQK
EwtIeXBlcmxlZGdlcjEPMA0GA1UECxMGRmFicmljMR8wHQYDVQQDExZjYS5xcHIu
Zm9vdGJhbGxuZXQuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2q06YuK7
L6K2kwl5HPwW1exdxBoEwiQ+denvNtoq1hvo4f6zwtlD6+aVwfnu9CvLlriPEJy3
KSbM8/IuszlKyqNWMFQwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8C
AQEwHQYDVR0OBBYEFG4G17iqYS0wCNskmsFC8pUtXf8zMA8GA1UdEQQIMAaHBAAA
AAAwCgYIKoZIzj0EAwIDRwAwRAIgZMIAjEyB9aeqSJuvBqPBkJAddOCTEdsPwbzb
Bql46DICIAl998KlBM23r4iRYPoZTX8/8njPfXpi5a8lX85Skpme
-----END CERTIFICATE-----
httpOptions:
verify: false
I load this connectionProfile.yaml to my nodeJS application and try to enroll user. See code below:
const caInfo = ccp.certificateAuthorities['ca.org1.example.com'];
const caTLSCACerts = caInfo.tlsCACerts.pem;
const ca = new FabricCAServices(caInfo.url, { trustedRoots: caTLSCACerts, verify: false }, caInfo.caName);
​
// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), 'wallet');
const wallet = new FileSystemWallet(`${__dirname}/../hyperledger/wallet`);
console.log(`Wallet path: ${walletPath}`);
​
// Check to see if we've already enrolled the admin user.
const identityLabel = 'admin.org1.example.com'
const identity = await wallet.exists(identityLabel);
if (!identity) {
// Enroll the admin user, and import the new identity into the wallet.
const enrollment = await ca.enroll({ enrollmentID: 'rca-org-admin', enrollmentSecret: 'rca-org-adminpw' });
const x509Identity = {
certificate: enrollment.certificate,
privateKey: enrollment.key.toBytes(),
mspId: 'org1MSP',
type: 'X.509',
};​
await wallet.import('admin.org1.example.com', x509Identity);
console.log('Successfully enrolled admin user "admin" and imported it into the wallet');
}
I guess tlsCACerts.pem needs for TLS connection with CA. User enroll was successful by this code. But if I change this certificate(tlsCACerts.pem) to some other one(any certificate, even randomly generated) and clean my wallet and try to make an enroll, it will still succeed. Logs of the container CA confirm this. It seems to me that it does not use this TLS certificate, but why, if the TLS certification is turned on on the CA server.
Version of fabric-ca-server is 1.4.6
Version of Fabric SDK for Node is 1.4.8
Maybe someone has thoughts on this issue. Maybe I'm doing something wrong?
Despite the fact that the question is 4 months old and you probably found the solution I try to answer.
I think the problem is on the line 3 of your code:
const ca = new FabricCAServices(caInfo.url, { trustedRoots: caTLSCACerts, verify: false }, caInfo.caName);
TLS option verify is false, so certificate is not actually verifying.
Try to set verify to true, I think this should work:
const ca = new FabricCAServices(caInfo.url, { trustedRoots: caTLSCACerts, verify: true }, caInfo.caName);

Calling register endpoint failed with error [Error: self signed certificate]

I am trying to follow the hyperledger fabric tutorials [1] and get the Node.js SDK running with my network. I have already successfully enrolled the admin on my ca server, however, when trying the next step (registering a new user), I get an error about using a self-signed certificate.
I don't even understand which certificate the error is referring to.
The ones in use by the CA server are obviously self-signed, since they are root certs. The certificate of the adminIdentity comes from the CA server itself, obtained in the previous enrollment step.
The logs on my ca-server container don't contain any errors, firing off the request does not even produce any log entries there.
The (unaltered) sample code from fabric-samples/fabcar and fabric-samples/basic-network obviously work just fine. As far as I can tell the SDK code is functionally identical to the samples, so I suspect the error to hide somewhere in the configuration.
This is my registerUser.js file:
/*
* SPDX-License-Identifier: Apache-2.0
*/
'use strict';
const FabricCAServices = require('fabric-ca-client');
const { FileSystemWallet, X509WalletMixin } = require('fabric-network');
const fs = require('fs');
const path = require('path');
const ccpPath = path.resolve(__dirname, '..', '..', 'fabric-network', 'connection.json');
const ccpJSON = fs.readFileSync(ccpPath, 'utf8');
const ccp = JSON.parse(ccpJSON);
async function main() {
try {
// Create a new CA client for interacting with the CA.
const caURL = ccp.certificateAuthorities['ca.org1.org'].url;
const ca = new FabricCAServices(caURL);
// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), 'org1', 'wallet');
const wallet = new FileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);
// Check to see if we've already enrolled the admin user.
const adminExists = await wallet.exists('admin');
if (adminExists) {
console.log('An identity for the admin user "admin" already exists in the wallet');
return;
}
// Enroll the admin user, and import the new identity into the wallet.
const enrollment = await ca.enroll({ enrollmentID: 'admin', enrollmentSecret: 'adminpw' });
const identity = X509WalletMixin.createIdentity('Org1MSP', enrollment.certificate, enrollment.key.toBytes());
wallet.import('admin', identity);
console.log('Successfully enrolled admin user "admin" and imported it into the wallet');
} catch (error) {
console.error(`Failed to enroll admin user "admin": ${error}`);
process.exit(1);
}
}
main();
...and my connection.json file:
{
"name": "OrganisationOne",
"version": "1.0.0",
"client": {
"organization": "Org1",
"connection": {
"timeout": {
"peer": {
"endorser": "300"
}
}
}
},
"organizations": {
"Org1": {
"mspid": "Org1MSP",
"peers": [
"peer0.org1.org",
"peer1.org1.org"
],
"certificateAuthorities": [
"ca.org1.org"
]
}
},
"peers": {
"peer0.org1.org": {
"url": "grpcs://localhost:7051",
"tlsCACerts": {
"path": "crypto-config/peerOrganizations/org1.org/tlsca/tlsca.org1.org-cert.pem"
},
"grpcOptions": {
"ssl-target-name-override": "peer0.org1.org"
}
},
"peer1.org1.org": {
"url": "grpcs://localhost:8051",
"tlsCACerts": {
"path": "crypto-config/peerOrganizations/org1.org/tlsca/tlsca.org1.org-cert.pem"
},
"grpcOptions": {
"ssl-target-name-override": "peer1.org1.org"
}
}
},
"certificateAuthorities": {
"ca.org1.org": {
"url": "https://localhost:7054",
"caName": "ca.org1.org"
}
}
}
I expected the user to be successfully registered, instead I receive the following error:
Failed to register user "user1": Error: Calling register endpoint failed with error [Error: self signed certificate]
What can I do to fix this error or even get more helpful information about it?
Specify this inside connection.json file in certificateAuthorities properties
"httpOptions": {
"verify": false
}
it worked for me
Hit it myself recently, and I should know better;)
The error is because the CLI enrolling the user doesn't like receiving back a self-signed cert from the CA. In many environments this is the default, so it's helpful to hear that the default changes to false in 1.4.10.

How to assign identity to fabric-client instance?

I am unable to install node chaincode using fabric-node-sdk.
I am getting the following error:
installChaincode error No identity has been assigned to this client
I am using following script
const Client = require("fabric-client");
const path = require("path");
const os = require("os");
const client = new Client();
const deploy = async () => {
const connectionOpts = {
name: "peer1",
"request-timeout": 7000,
pem: path.resolve(
os.homedir,
"/fabric-samples/chaincode-docker-devmode/msp/signcerts/peer.pem"
),
"ssl-target-name-override": "peer"
};
const peer = client.newPeer("grpc://172.18.0.3:7052", connectionOpts);
const request = {
targets: peer,
chaincodePath: path.resolve(
os.homedir + "/fabric-samples/chaincode/chaincode_example02/node"
),
chaincodeId: "myc",
chaincodeVersion: "v0",
chaincodeType: "node"
};
const result = await client.installChaincode(request, 6000);
console.log(await result);
};
deploy();
How do I assign identity to client?
In the documentation, it is not demonstrated what arguments it required and how to assign identity.
Peer node want to know who is making the transaction. Try using this method before the install chincode transaction:
client.setAdminSigningIdentity(private_key, certificate, mspid)
Where:
private_key: the private key PEM string
certificate: the PEM-encoded string of certificate
mspid: The Member Service Provider id for the local signing identity (i.e 'Org1MSP')
In the chaincode install request, you need the txId:
client.setAdminSigningIdentity(private_key, certificate, mspid)
const request = {
targets: peer,
chaincodePath: path.resolve(
os.homedir + "/fabric-samples/chaincode/chaincode_example02/node"
),
chaincodeId: "myc",
chaincodeVersion: "v0",
chaincodeType: "node",
txId: client.newTransactionID(true)
};
const result = await client.installChaincode(request, 6000);
console.log(await result);
I faced the same issue as well and it is resolved after adding the below line, i.e., channel initialization.
await channel.initialize({ discover: true });
source: https://fabric-sdk-node.github.io/master/tutorial-discovery.html

Node js ACL export issue

I have recently started development of a Node js application with user authentication and authorization. I have successfully implemented the user authentication with passport js but having an issue with the user authorization using node acl.
security.js file looks like this
var node_acl = require('acl'),
acl;
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017/claim_app', function (err, db) {
var mongoBackend = new node_acl.mongodbBackend(db, 'acl');
acl = new node_acl(mongoBackend);
console.log(acl);
set_roles();
});
function set_roles() {
acl.allow([{
roles: 'admin',
allows: [{
resources: '/api/conf',
permissions: '*'
}
]
}, {
roles: 'user',
allows: [{
resources: 'photos',
permissions: ['view', 'edit', 'delete']
}]
}, {
roles: 'guest',
allows: []
}]);
}
module.exports = acl;
but when I try to use above with require('./src/config/security'), always getting as undefined. what is the reason for this behaviour.
Thanks.

Resources