Skip to content

Commit

Permalink
Merge pull request #2 from VRamakrishna/fabric-cli-iin-upgrade
Browse files Browse the repository at this point in the history
Fabric CLI Upgrade to handle IIN Agents and Counter Attested Foreign Memberships
  • Loading branch information
VRamakrishna authored Sep 22, 2022
2 parents c5d1001 + abe84d4 commit f6fa692
Show file tree
Hide file tree
Showing 14 changed files with 390 additions and 163 deletions.
15 changes: 10 additions & 5 deletions core/network/fabric-interop-cc/contracts/interop/decoders.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@
package main

import (
"encoding/base64"
"encoding/json"
"strings"
"fmt"

"github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go/common"
"github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go/identity"
protoV2 "google.golang.org/protobuf/proto"
)

func decodeMembership(jsonBytes []byte) (*common.Membership, error) {
Expand All @@ -30,13 +33,15 @@ func decodeMembership(jsonBytes []byte) (*common.Membership, error) {
return &decodeObj, nil
}

func decodeCounterAttestedMembership(jsonBytes []byte) (*identity.CounterAttestedMembership, error) {
func decodeCounterAttestedMembership(protoBytesBase64 string) (*identity.CounterAttestedMembership, error) {
var decodeObj identity.CounterAttestedMembership
dec := json.NewDecoder(strings.NewReader(string(jsonBytes)))
dec.DisallowUnknownFields()
err := dec.Decode(&decodeObj)
protoBytes, err := base64.StdEncoding.DecodeString(protoBytesBase64)
if err != nil {
return nil, err
return nil, fmt.Errorf("Counter attested membership could not be decoded from base64: %s", err.Error())
}
err = protoV2.Unmarshal(protoBytes, &decodeObj)
if err != nil {
return nil, fmt.Errorf("Unable to unmarshal counter attested membership: %s", err.Error())
}
return &decodeObj, nil
}
Expand Down
74 changes: 33 additions & 41 deletions core/network/fabric-interop-cc/contracts/interop/membership.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ func (s *SmartContract) UpdateLocalMembership(ctx contractapi.TransactionContext
}

membershipLocalKey, err := ctx.GetStub().CreateCompositeKey(membershipObjectType, []string{membershipLocalSecurityDomain})
_, getErr := s.GetMembershipBySecurityDomain(ctx, membership.SecurityDomain)
_, getErr := s.GetMembershipBySecurityDomain(ctx, membershipLocalSecurityDomain)
if getErr != nil {
return getErr
}
Expand All @@ -176,14 +176,20 @@ func (s *SmartContract) UpdateLocalMembership(ctx contractapi.TransactionContext

}

// CreateMembershipIIN cc is used to store a Membership in the ledger
// TODO: Replace 'CreateMembership' with this function after updating the Fabric CLI.
func (s *SmartContract) CreateMembershipIIN(ctx contractapi.TransactionContextInterface, counterAttestedMembershipJSON string) error {
// CreateMembership cc is used to store a Membership in the ledger
// TODO: Remove call to 'createMembership' after creating Corda IIN Agents.
func (s *SmartContract) CreateMembership(ctx contractapi.TransactionContextInterface, counterAttestedMembershipSerialized string) error {
// Check if the caller has IIN agent privileges
if isIINAgent, err := isClientIINAgent(ctx); err != nil {
return fmt.Errorf("IIN Agent client check error: %s", err)
} else if !isIINAgent {
return fmt.Errorf("Caller not an IIN Agent; access denied")
// Check if the caller has network admin privileges
if isAdmin, err := isClientNetworkAdmin(ctx); err != nil {
return fmt.Errorf("Admin client check error: %s", err)
} else if !isAdmin {
return fmt.Errorf("Caller neither a network admin nor an IIN Agent; access denied")
}
return s.createMembership(ctx, counterAttestedMembershipSerialized) // HACK to handle unattested memberships (for Corda) for backward compatibility
}

// Check if caller is one of the authorized IIN agents
Expand All @@ -205,7 +211,7 @@ func (s *SmartContract) CreateMembershipIIN(ctx contractapi.TransactionContextIn
return fmt.Errorf("Caller with identity %+v is not a designated IIN Agent: %+v", callerId, err)
}

counterAttestedMembership, err := decodeCounterAttestedMembership([]byte(counterAttestedMembershipJSON))
counterAttestedMembership, err := decodeCounterAttestedMembership(counterAttestedMembershipSerialized)
if err != nil {
return fmt.Errorf("Counter Attested Membership Unmarshal error: %s", err)
}
Expand Down Expand Up @@ -304,16 +310,16 @@ func (s *SmartContract) CreateMembershipIIN(ctx contractapi.TransactionContextIn
return fmt.Errorf("Membership already exists for membership id: %s. Use 'UpdateMembership' to update.", foreignMembership.SecurityDomain)
}

membershipBytes, err := json.Marshal(attestedMembershipSet.Membership)
membershipBytes, err := json.Marshal(foreignMembership)
if err != nil {
return fmt.Errorf("Marshal error: %s", err)
}
return ctx.GetStub().PutState(membershipKey, membershipBytes)
}

// CreateMembership cc is used to store a Membership in the ledger
// TODO: Replace this function with 'CreateMembership' after updating the Fabric CLI. Retaining this temporarily for backward compatibility.
func (s *SmartContract) CreateMembership(ctx contractapi.TransactionContextInterface, membershipJSON string) error {
// createMembership is used by a network admin to store a Membership in the ledger with an unattested membership
// TODO: Remove this function after creating Corda IIN Agents. Retaining this temporarily for backward compatibility.
func (s *SmartContract) createMembership(ctx contractapi.TransactionContextInterface, membershipJSON string) error {
membership, err := decodeMembership([]byte(membershipJSON))
if err != nil {
return fmt.Errorf("Unmarshal error: %s", err)
Expand All @@ -340,14 +346,20 @@ func (s *SmartContract) CreateMembership(ctx contractapi.TransactionContextInter
return ctx.GetStub().PutState(membershipKey, membershipBytes)
}

// UpdateMembershipIIN cc is used to update an existing Membership in the ledger
// TODO: Replace 'UpdateMembership' with this function after updating the Fabric CLI.
func (s *SmartContract) UpdateMembershipIIN(ctx contractapi.TransactionContextInterface, counterAttestedMembershipJSON string) error {
// UpdateMembership cc is used to update an existing Membership in the ledger
// TODO: Remove call to 'updateMembership' after creating Corda IIN Agents.
func (s *SmartContract) UpdateMembership(ctx contractapi.TransactionContextInterface, counterAttestedMembershipSerialized string) error {
// Check if the caller has IIN agent privileges
if isIINAgent, err := isClientIINAgent(ctx); err != nil {
return fmt.Errorf("IIN Agent client check error: %s", err)
} else if !isIINAgent {
return fmt.Errorf("Caller not an IIN Agent; access denied")
// Check if the caller has network admin privileges
if isAdmin, err := isClientNetworkAdmin(ctx); err != nil {
return fmt.Errorf("Admin client check error: %s", err)
} else if !isAdmin {
return fmt.Errorf("Caller neither a network admin nor an IIN Agent; access denied")
}
return s.updateMembership(ctx, counterAttestedMembershipSerialized) // HACK to handle unattested memberships (for Corda) for backward compatibility
}

// Check if caller is one of the authorized IIN agents
Expand All @@ -369,7 +381,7 @@ func (s *SmartContract) UpdateMembershipIIN(ctx contractapi.TransactionContextIn
return fmt.Errorf("Caller with identity %+v is not a designated IIN Agent: %+v", callerId, err)
}

counterAttestedMembership, err := decodeCounterAttestedMembership([]byte(counterAttestedMembershipJSON))
counterAttestedMembership, err := decodeCounterAttestedMembership(counterAttestedMembershipSerialized)
if err != nil {
return fmt.Errorf("Counter Attested Membership Unmarshal error: %s", err)
}
Expand Down Expand Up @@ -465,17 +477,17 @@ func (s *SmartContract) UpdateMembershipIIN(ctx contractapi.TransactionContextIn
return getErr
}

membershipBytes, err := json.Marshal(attestedMembershipSet.Membership)
membershipBytes, err := json.Marshal(foreignMembership)
if err != nil {
return fmt.Errorf("Marshal error: %s", err)
}
return ctx.GetStub().PutState(membershipKey, membershipBytes)

}

// UpdateMembership cc is used to update an existing Membership in the ledger
// TODO: Replace this function with 'UpdateMembership' after updating the Fabric CLI. Retaining this temporarily for backward compatibility.
func (s *SmartContract) UpdateMembership(ctx contractapi.TransactionContextInterface, membershipJSON string) error {
// updateMembership is used by a network admin to update an existing Membership in the ledger with an unattested membership
// TODO: Remove this function after creating Corda IIN Agents. Retaining this temporarily for backward compatibility.
func (s *SmartContract) updateMembership(ctx contractapi.TransactionContextInterface, membershipJSON string) error {
membership, err := decodeMembership([]byte(membershipJSON))
if err != nil {
return fmt.Errorf("Unmarshal error: %s", err)
Expand Down Expand Up @@ -525,9 +537,8 @@ func (s *SmartContract) DeleteLocalMembership(ctx contractapi.TransactionContext
return nil
}

// DeleteMembershipIIN cc is used to delete an existing Membership in the ledger
// TODO: Replace 'DeleteMembership' with this function after updating the Fabric CLI.
func (s *SmartContract) DeleteMembershipIIN(ctx contractapi.TransactionContextInterface, membershipID string) error {
// DeleteMembership cc is used to delete an existing Membership in the ledger
func (s *SmartContract) DeleteMembership(ctx contractapi.TransactionContextInterface, membershipID string) error {
// Check if the caller has IIN agent privileges
if isIINAgent, err := isClientIINAgent(ctx); err != nil {
return fmt.Errorf("IIN Agent client check error: %s", err)
Expand All @@ -551,25 +562,6 @@ func (s *SmartContract) DeleteMembershipIIN(ctx contractapi.TransactionContextIn
return nil
}

// DeleteMembership cc is used to delete an existing Membership in the ledger
// TODO: Replace this function with 'DeleteMembership' after updating the Fabric CLI. Retaining this temporarily for backward compatibility.
func (s *SmartContract) DeleteMembership(ctx contractapi.TransactionContextInterface, membershipID string) error {
membershipKey, err := ctx.GetStub().CreateCompositeKey(membershipObjectType, []string{membershipID})
bytes, err := ctx.GetStub().GetState(membershipKey)
if err != nil {
return err
}
if bytes == nil {
return fmt.Errorf("Membership with id: %s does not exist", membershipID)
}
err = ctx.GetStub().DelState(membershipKey)
if err != nil {
return fmt.Errorf("failed to delete asset %s: %v", membershipKey, err)
}

return nil
}

// GetMembershipBySecurityDomain cc gets the Membership for the provided id
func (s *SmartContract) GetMembershipBySecurityDomain(ctx contractapi.TransactionContextInterface, securityDomain string) (string, error) {
membershipKey, err := ctx.GetStub().CreateCompositeKey(membershipObjectType, []string{securityDomain})
Expand Down
Loading

0 comments on commit f6fa692

Please sign in to comment.