forked from hyperledger/fabric
-
Notifications
You must be signed in to change notification settings - Fork 0
/
simplecollection.go
154 lines (133 loc) · 4.96 KB
/
simplecollection.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package privdata
import (
"fmt"
"github.com/golang/protobuf/proto"
m "github.com/hyperledger/fabric-protos-go/msp"
"github.com/hyperledger/fabric-protos-go/peer"
"github.com/hyperledger/fabric/common/policies"
"github.com/hyperledger/fabric/msp"
"github.com/hyperledger/fabric/protoutil"
"github.com/pkg/errors"
)
// SimpleCollection implements a collection with static properties
// and a public member set
type SimpleCollection struct {
name string
accessPolicy policies.Policy
memberOrgs []string
conf peer.StaticCollectionConfig
}
type SimpleCollectionPersistenceConfigs struct {
blockToLive uint64
}
// NewSimpleCollection returns a simple collection object based on a given
// StaticCollectionConfig proto that has all the necessary information
func NewSimpleCollection(collectionConfig *peer.StaticCollectionConfig, deserializer msp.IdentityDeserializer) (*SimpleCollection, error) {
sc := &SimpleCollection{}
err := sc.Setup(collectionConfig, deserializer)
return sc, err
}
// CollectionID returns the collection's ID
func (sc *SimpleCollection) CollectionID() string {
return sc.name
}
// MemberOrgs returns the MSP IDs that are part of this collection
func (sc *SimpleCollection) MemberOrgs() []string {
return sc.memberOrgs
}
// RequiredPeerCount returns the minimum number of peers
// required to send private data to
func (sc *SimpleCollection) RequiredPeerCount() int {
return int(sc.conf.RequiredPeerCount)
}
// MaximumPeerCount returns the maximum number of peers
// to which the private data will be sent
func (sc *SimpleCollection) MaximumPeerCount() int {
return int(sc.conf.MaximumPeerCount)
}
// AccessFilter returns the member filter function that evaluates signed data
// against the member access policy of this collection
func (sc *SimpleCollection) AccessFilter() Filter {
return func(sd protoutil.SignedData) bool {
if err := sc.accessPolicy.EvaluateSignedData([]*protoutil.SignedData{&sd}); err != nil {
return false
}
return true
}
}
// IsMemberOnlyRead returns whether only collection member
// has the read permission
func (sc *SimpleCollection) IsMemberOnlyRead() bool {
return sc.conf.MemberOnlyRead
}
// IsMemberOnlyWrite returns whether only collection member
// has the write permission
func (sc *SimpleCollection) IsMemberOnlyWrite() bool {
return sc.conf.MemberOnlyWrite
}
// Setup configures a simple collection object based on a given
// StaticCollectionConfig proto that has all the necessary information
func (sc *SimpleCollection) Setup(collectionConfig *peer.StaticCollectionConfig, deserializer msp.IdentityDeserializer) error {
if collectionConfig == nil {
return errors.New("Nil config passed to collection setup")
}
sc.conf = *collectionConfig
sc.name = collectionConfig.GetName()
// get the access signature policy envelope
collectionPolicyConfig := collectionConfig.GetMemberOrgsPolicy()
if collectionPolicyConfig == nil {
return errors.New("Collection config policy is nil")
}
accessPolicyEnvelope := collectionPolicyConfig.GetSignaturePolicy()
if accessPolicyEnvelope == nil {
return errors.New("Collection config access policy is nil")
}
err := sc.setupAccessPolicy(collectionPolicyConfig, deserializer)
if err != nil {
return err
}
// get member org MSP IDs from the envelope
for _, principal := range accessPolicyEnvelope.Identities {
switch principal.PrincipalClassification {
case m.MSPPrincipal_ROLE:
// Principal contains the msp role
mspRole := &m.MSPRole{}
err := proto.Unmarshal(principal.Principal, mspRole)
if err != nil {
return errors.Wrap(err, "Could not unmarshal MSPRole from principal")
}
sc.memberOrgs = append(sc.memberOrgs, mspRole.MspIdentifier)
case m.MSPPrincipal_IDENTITY:
principalId, err := deserializer.DeserializeIdentity(principal.Principal)
if err != nil {
return errors.Wrap(err, "Invalid identity principal, not a certificate")
}
sc.memberOrgs = append(sc.memberOrgs, principalId.GetMSPIdentifier())
case m.MSPPrincipal_ORGANIZATION_UNIT:
OU := &m.OrganizationUnit{}
err := proto.Unmarshal(principal.Principal, OU)
if err != nil {
return errors.Wrap(err, "Could not unmarshal OrganizationUnit from principal")
}
sc.memberOrgs = append(sc.memberOrgs, OU.MspIdentifier)
default:
return errors.New(fmt.Sprintf("Invalid principal type %d", int32(principal.PrincipalClassification)))
}
}
return nil
}
// setupAccessPolicy configures a simple collection object based on a given
// StaticCollectionConfig proto that has all the necessary information
func (sc *SimpleCollection) setupAccessPolicy(collectionPolicyConfig *peer.CollectionPolicyConfig, deserializer msp.IdentityDeserializer) error {
var err error
sc.accessPolicy, err = getPolicy(collectionPolicyConfig, deserializer)
return err
}
// BlockToLive return collection's block to live configuration
func (s *SimpleCollectionPersistenceConfigs) BlockToLive() uint64 {
return s.blockToLive
}