diff --git a/api/apifabca/user.go b/api/apifabca/user.go index e697902285..8d81e82486 100644 --- a/api/apifabca/user.go +++ b/api/apifabca/user.go @@ -33,6 +33,8 @@ type User interface { EnrollmentCertificate() []byte PrivateKey() bccsp.Key + Identity() ([]byte, error) + // TODO: TCerts //GenerateTcerts(count int, attributes []string) } diff --git a/api/apifabclient/fabricclient.go b/api/apifabclient/fabricclient.go index 73719e082d..1da4984bf5 100644 --- a/api/apifabclient/fabricclient.go +++ b/api/apifabclient/fabricclient.go @@ -47,7 +47,6 @@ type FabricClient interface { InstallChaincode(chaincodeName string, chaincodePath string, chaincodeVersion string, chaincodePackage []byte, targets []Peer) ([]*txn.TransactionProposalResponse, string, error) QueryChannels(peer Peer) (*pb.ChannelQueryResponse, error) QueryInstalledChaincodes(peer Peer) (*pb.ChaincodeQueryResponse, error) - GetIdentity() ([]byte, error) GetUserContext() User SetUserContext(user User) GetConfig() config.Config // TODO: refactor to a fab client config interface diff --git a/api/apifabclient/msp.go b/api/apifabclient/identity.go similarity index 97% rename from api/apifabclient/msp.go rename to api/apifabclient/identity.go index db8265fe0d..9db1b25631 100644 --- a/api/apifabclient/msp.go +++ b/api/apifabclient/identity.go @@ -30,4 +30,5 @@ type User interface { EnrollmentCertificate() []byte PrivateKey() bccsp.Key Roles() []string + Identity() ([]byte, error) } diff --git a/def/fabapi/fabapi.go b/def/fabapi/fabapi.go index 12c73a3c51..11cf654e62 100644 --- a/def/fabapi/fabapi.go +++ b/def/fabapi/fabapi.go @@ -18,8 +18,8 @@ import ( fabricCAClient "github.com/hyperledger/fabric-sdk-go/pkg/fabric-ca-client" clientImpl "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client" eventsImpl "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/events" + identityImpl "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/identity" kvs "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/keyvaluestore" - mspImpl "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/msp" ordererImpl "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/orderer" peerImpl "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/peer" bccsp "github.com/hyperledger/fabric/bccsp" @@ -119,7 +119,7 @@ func NewUser(config config.Config, msp fabca.FabricCAClient, name string, pwd st if err != nil { return nil, fmt.Errorf("Enroll returned error: %v", err) } - user := mspImpl.NewUser(name, mspID) + user := identityImpl.NewUser(name, mspID) user.SetPrivateKey(key) user.SetEnrollmentCertificate(cert) @@ -139,7 +139,7 @@ func NewPreEnrolledUser(config config.Config, privateKeyPath string, return nil, fmt.Errorf("Error reading from the enrollment cert path: %v", err) } - user := mspImpl.NewUser(username, mspID) + user := identityImpl.NewUser(username, mspID) user.SetEnrollmentCertificate(enrollmentCert) user.SetPrivateKey(privateKey) diff --git a/pkg/fabric-ca-client/mocks/mockuser.go b/pkg/fabric-ca-client/mocks/mockuser.go index a31d73f5e4..95ca86e150 100644 --- a/pkg/fabric-ca-client/mocks/mockuser.go +++ b/pkg/fabric-ca-client/mocks/mockuser.go @@ -98,6 +98,11 @@ func (u *MockUser) MspID() string { return u.mspID } +// Identity returns MockUser's serialized identity +func (u *MockUser) Identity() ([]byte, error) { + return []byte("test"), nil +} + // GenerateTcerts ... /** * Gets a batch of TCerts to use for transaction. there is a 1-to-1 relationship between diff --git a/pkg/fabric-client/channel/block.go b/pkg/fabric-client/channel/block.go index 147455fbb0..d656627f17 100644 --- a/pkg/fabric-client/channel/block.go +++ b/pkg/fabric-client/channel/block.go @@ -42,7 +42,10 @@ func (c *Channel) GenesisBlock(request *fab.GenesisBlockRequest) (*common.Block, return nil, fmt.Errorf("GenesisBlock - error: Missing nonce input parameter with the required single use number") } - creator, err := c.clientContext.GetIdentity() + if c.clientContext.GetUserContext() == nil { + return nil, fmt.Errorf("User context needs to be set") + } + creator, err := c.clientContext.GetUserContext().Identity() if err != nil { return nil, fmt.Errorf("Error getting creator: %v", err) } @@ -90,7 +93,10 @@ func (c *Channel) block(pos *ab.SeekPosition) (*common.Block, error) { return nil, fmt.Errorf("error when generating nonce: %v", err) } - creator, err := c.clientContext.GetIdentity() + if c.clientContext.GetUserContext() == nil { + return nil, fmt.Errorf("User context needs to be set") + } + creator, err := c.clientContext.GetUserContext().Identity() if err != nil { return nil, fmt.Errorf("error when serializing identity: %v", err) } diff --git a/pkg/fabric-client/channel/channel.go b/pkg/fabric-client/channel/channel.go index 8563a90f3a..903c66fd83 100644 --- a/pkg/fabric-client/channel/channel.go +++ b/pkg/fabric-client/channel/channel.go @@ -35,7 +35,6 @@ type Channel struct { // ClientContext ... type ClientContext interface { GetUserContext() fab.User - GetIdentity() ([]byte, error) GetCryptoSuite() bccsp.BCCSP NewTxnID() (apitxn.TransactionID, error) // TODO: ClientContext.IsSecurityEnabled() diff --git a/pkg/fabric-client/channel/txnproposer.go b/pkg/fabric-client/channel/txnproposer.go index efdeecf7c2..1b30d0c4fb 100644 --- a/pkg/fabric-client/channel/txnproposer.go +++ b/pkg/fabric-client/channel/txnproposer.go @@ -113,7 +113,10 @@ func newTransactionProposal(channelID string, request apitxn.ChaincodeInvokeRequ Input: &pb.ChaincodeInput{Args: argsArray}}} // create a proposal from a ChaincodeInvocationSpec - creator, err := clientContext.GetIdentity() + if clientContext.GetUserContext() == nil { + return nil, fmt.Errorf("User context needs to be set") + } + creator, err := clientContext.GetUserContext().Identity() if err != nil { return nil, fmt.Errorf("Error getting creator: %v", err) } @@ -229,7 +232,10 @@ func (c *Channel) JoinChannel(request *fab.JoinChannelRequest) error { return fmt.Errorf("JoinChannel - error: Missing block input parameter with the required genesis block") } - creator, err := c.clientContext.GetIdentity() + if c.clientContext.GetUserContext() == nil { + return fmt.Errorf("User context needs to be set") + } + creator, err := c.clientContext.GetUserContext().Identity() if err != nil { return fmt.Errorf("Error getting creator ID: %v", err) } diff --git a/pkg/fabric-client/channel/txnsender.go b/pkg/fabric-client/channel/txnsender.go index 07518f6b8d..0d1a3da505 100644 --- a/pkg/fabric-client/channel/txnsender.go +++ b/pkg/fabric-client/channel/txnsender.go @@ -185,7 +185,10 @@ func (c *Channel) SendInstantiateProposal(chaincodeName string, Type: pb.ChaincodeSpec_GOLANG, ChaincodeId: &pb.ChaincodeID{Name: chaincodeName, Path: chaincodePath, Version: chaincodeVersion}, Input: &pb.ChaincodeInput{Args: argsArray}}} - creator, err := c.clientContext.GetIdentity() + if c.clientContext.GetUserContext() == nil { + return nil, apitxn.TransactionID{}, fmt.Errorf("User context needs to be set") + } + creator, err := c.clientContext.GetUserContext().Identity() if err != nil { return nil, apitxn.TransactionID{}, fmt.Errorf("Error getting creator: %v", err) } diff --git a/pkg/fabric-client/client.go b/pkg/fabric-client/client.go index bfe7b048bd..f0eef1e302 100644 --- a/pkg/fabric-client/client.go +++ b/pkg/fabric-client/client.go @@ -17,9 +17,9 @@ import ( fab "github.com/hyperledger/fabric-sdk-go/api/apifabclient" "github.com/hyperledger/fabric-sdk-go/api/apitxn" channel "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/channel" + "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/identity" fc "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/internal" "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/internal/txnproc" - "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/msp" packager "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/packager" peer "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/peer" @@ -29,7 +29,6 @@ import ( "github.com/hyperledger/fabric/common/crypto" fcutils "github.com/hyperledger/fabric/common/util" "github.com/hyperledger/fabric/protos/common" - pb_msp "github.com/hyperledger/fabric/protos/msp" pb "github.com/hyperledger/fabric/protos/peer" protos_utils "github.com/hyperledger/fabric/protos/utils" ) @@ -153,7 +152,7 @@ func (c *Client) SaveUserToStateStore(user fab.User, skipPersistence bool) error if c.stateStore == nil { return fmt.Errorf("stateStore is nil") } - userJSON := &msp.JSON{ + userJSON := &identity.JSON{ MspID: user.MspID(), Roles: user.Roles(), PrivateKeySKI: user.PrivateKey().SKI(), @@ -195,12 +194,12 @@ func (c *Client) LoadUserFromStateStore(name string) (fab.User, error) { if err != nil { return nil, nil } - var userJSON msp.JSON + var userJSON identity.JSON err = json.Unmarshal(value, &userJSON) if err != nil { return nil, fmt.Errorf("stateStore GetValue return error: %v", err) } - user := msp.NewUser(name, userJSON.MspID) + user := identity.NewUser(name, userJSON.MspID) user.SetRoles(userJSON.Roles) user.SetEnrollmentCertificate(userJSON.EnrollmentCertificate) key, err := c.cryptoSuite.GetKey(userJSON.PrivateKeySKI) @@ -259,7 +258,10 @@ func (c *Client) SignChannelConfig(config []byte) (*common.ConfigSignature, erro return nil, fmt.Errorf("Channel configuration parameter is required") } - creator, err := c.GetIdentity() + if c.userContext == nil { + return nil, fmt.Errorf("User context needs to be set") + } + creator, err := c.userContext.Identity() if err != nil { return nil, fmt.Errorf("Error getting creator: %v", err) } @@ -389,7 +391,10 @@ func (c *Client) createOrUpdateChannel(request fab.CreateChannelRequest, haveEnv if err != nil { return fmt.Errorf("error when building channel header: %v", err) } - creator, err := c.GetIdentity() + if c.userContext == nil { + return fmt.Errorf("User context needs to be set") + } + creator, err := c.userContext.Identity() if err != nil { return fmt.Errorf("Error getting creator: %v", err) } @@ -496,7 +501,10 @@ func (c *Client) InstallChaincode(chaincodeName string, chaincodePath string, ch Type: pb.ChaincodeSpec_GOLANG, ChaincodeId: &pb.ChaincodeID{Name: chaincodeName, Path: chaincodePath, Version: chaincodeVersion}}, CodePackage: chaincodePackage, EffectiveDate: &google_protobuf.Timestamp{Seconds: int64(now.Second()), Nanos: int32(now.Nanosecond())}} - creator, err := c.GetIdentity() + if c.userContext == nil { + return nil, "", fmt.Errorf("User context needs to be set") + } + creator, err := c.userContext.Identity() if err != nil { return nil, "", fmt.Errorf("Error getting creator: %v", err) } @@ -532,21 +540,6 @@ func (c *Client) InstallChaincode(chaincodeName string, chaincodePath string, ch return transactionProposalResponse, txID, err } -// GetIdentity returns client's serialized identity -func (c *Client) GetIdentity() ([]byte, error) { - - if c.userContext == nil { - return nil, fmt.Errorf("User is nil") - } - serializedIdentity := &pb_msp.SerializedIdentity{Mspid: c.userContext.MspID(), - IdBytes: c.userContext.EnrollmentCertificate()} - identity, err := proto.Marshal(serializedIdentity) - if err != nil { - return nil, fmt.Errorf("Could not Marshal serializedIdentity, err %s", err) - } - return identity, nil -} - // GetUserContext ... func (c *Client) GetUserContext() fab.User { return c.userContext @@ -565,7 +558,10 @@ func (c *Client) NewTxnID() (apitxn.TransactionID, error) { return apitxn.TransactionID{}, err } - creator, err := c.GetIdentity() + if c.userContext == nil { + return apitxn.TransactionID{}, fmt.Errorf("User context needs to be set") + } + creator, err := c.userContext.Identity() if err != nil { return apitxn.TransactionID{}, err } diff --git a/pkg/fabric-client/client_test.go b/pkg/fabric-client/client_test.go index 46e1581c51..b873c323ea 100644 --- a/pkg/fabric-client/client_test.go +++ b/pkg/fabric-client/client_test.go @@ -13,8 +13,8 @@ import ( "time" fab "github.com/hyperledger/fabric-sdk-go/api/apifabclient" + "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/identity" mocks "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/mocks" - msp "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/msp" kvs "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/keyvaluestore" bccspFactory "github.com/hyperledger/fabric/bccsp/factory" @@ -66,7 +66,7 @@ func TestClientMethods(t *testing.T) { } //Client tests: successfully SaveUserToStateStore with skipPersistence true - user = msp.NewUser("someUser", testMsp) + user = identity.NewUser("someUser", testMsp) err = client.SaveUserToStateStore(user, true) if err != nil { t.Fatalf("client.SaveUserToStateStore return error[%s]", err) diff --git a/pkg/fabric-client/events/consumer/consumer.go b/pkg/fabric-client/events/consumer/consumer.go index bb1d876e69..4434f5f7f8 100644 --- a/pkg/fabric-client/events/consumer/consumer.go +++ b/pkg/fabric-client/events/consumer/consumer.go @@ -101,7 +101,10 @@ func (ec *eventsClient) send(emsg *ehpb.Event) error { // RegisterAsync - registers interest in a event and doesn't wait for a response func (ec *eventsClient) RegisterAsync(ies []*ehpb.Interest) error { - creator, err := ec.client.GetIdentity() + if ec.client.GetUserContext() == nil { + return fmt.Errorf("User context needs to be set") + } + creator, err := ec.client.GetUserContext().Identity() if err != nil { return fmt.Errorf("Error getting creator: %v", err) } diff --git a/pkg/fabric-client/msp/user.go b/pkg/fabric-client/identity/identity.go similarity index 83% rename from pkg/fabric-client/msp/user.go rename to pkg/fabric-client/identity/identity.go index 99e8eb0b19..8b7e8e0fee 100644 --- a/pkg/fabric-client/msp/user.go +++ b/pkg/fabric-client/identity/identity.go @@ -4,10 +4,14 @@ Copyright SecureKey Technologies Inc. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 */ -package msp +package identity import ( + "fmt" + + "github.com/golang/protobuf/proto" "github.com/hyperledger/fabric/bccsp" + pb_msp "github.com/hyperledger/fabric/protos/msp" ) // User represents a Fabric user registered at an MSP @@ -84,6 +88,17 @@ func (u *User) MspID() string { return u.mspID } +// Identity returns client's serialized identity +func (u *User) Identity() ([]byte, error) { + serializedIdentity := &pb_msp.SerializedIdentity{Mspid: u.MspID(), + IdBytes: u.EnrollmentCertificate()} + identity, err := proto.Marshal(serializedIdentity) + if err != nil { + return nil, fmt.Errorf("Could not Marshal serializedIdentity, err %s", err) + } + return identity, nil +} + // GenerateTcerts Gets a batch of TCerts to use for transaction. there is a 1-to-1 relationship between // TCert and Transaction. The TCert can be generated locally by the SDK using the user’s crypto materials. // @param {int} count how many in the batch to obtain diff --git a/pkg/fabric-client/msp/user_test.go b/pkg/fabric-client/identity/identity_test.go similarity index 98% rename from pkg/fabric-client/msp/user_test.go rename to pkg/fabric-client/identity/identity_test.go index f0e3a9e14f..00ee39da45 100644 --- a/pkg/fabric-client/msp/user_test.go +++ b/pkg/fabric-client/identity/identity_test.go @@ -4,7 +4,7 @@ Copyright SecureKey Technologies Inc. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 */ -package msp +package identity import ( "testing" diff --git a/pkg/fabric-client/mocks/mockclient.go b/pkg/fabric-client/mocks/mockclient.go index 5513b71a1e..9bc5f8ee70 100644 --- a/pkg/fabric-client/mocks/mockclient.go +++ b/pkg/fabric-client/mocks/mockclient.go @@ -134,12 +134,6 @@ func (c *MockClient) InstallChaincode(chaincodeName string, chaincodePath string } -// GetIdentity returns MockClient's serialized identity -func (c *MockClient) GetIdentity() ([]byte, error) { - return []byte("test"), nil - -} - // GetUserContext ... func (c *MockClient) GetUserContext() fab.User { return c.userContext diff --git a/pkg/fabric-client/mocks/mockuser.go b/pkg/fabric-client/mocks/mockuser.go index 8bcfdc64b7..5fb881b30f 100644 --- a/pkg/fabric-client/mocks/mockuser.go +++ b/pkg/fabric-client/mocks/mockuser.go @@ -104,6 +104,11 @@ func (u *MockUser) MspID() string { return u.mspID } +// Identity returns MockUser's serialized identity +func (u *MockUser) Identity() ([]byte, error) { + return []byte("test"), nil +} + // GenerateTcerts ... /** * Gets a batch of TCerts to use for transaction. there is a 1-to-1 relationship between diff --git a/test/integration/fabric_ca_test.go b/test/integration/fabric_ca_test.go index a253d16595..a56fdb7a44 100644 --- a/test/integration/fabric_ca_test.go +++ b/test/integration/fabric_ca_test.go @@ -22,8 +22,8 @@ import ( config "github.com/hyperledger/fabric-sdk-go/api/apiconfig" client "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client" + "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/identity" kvs "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/keyvaluestore" - msp "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/msp" bccspFactory "github.com/hyperledger/fabric/bccsp/factory" fabricCAClient "github.com/hyperledger/fabric-sdk-go/pkg/fabric-ca-client" @@ -113,7 +113,7 @@ func TestRegisterEnrollRevoke(t *testing.T) { if cert509.Subject.CommonName != "admin" { t.Fatalf("CommonName in x509 cert is not the enrollmentID") } - adminUser2 := msp.NewUser("admin", mspID) + adminUser2 := identity.NewUser("admin", mspID) adminUser2.SetPrivateKey(key) adminUser2.SetEnrollmentCertificate(cert) err = client.SaveUserToStateStore(adminUser2, false) @@ -150,7 +150,7 @@ func TestRegisterEnrollRevoke(t *testing.T) { //re-enroll fmt.Printf("** Attempt to re-enrolled user: '%s'\n", userName) //create new user object and set certificate and private key of the previously enrolled user - enrolleduser := msp.NewUser(userName, mspID) + enrolleduser := identity.NewUser(userName, mspID) enrolleduser.SetEnrollmentCertificate(ecert) enrolleduser.SetPrivateKey(ekey) //reenroll