/
resourceprovider.go
187 lines (146 loc) · 4.96 KB
/
resourceprovider.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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
//<developer>
// <name>linapex 曹一峰</name>
// <email>linapex@163.com</email>
// <wx>superexc</wx>
// <qqgroup>128148617</qqgroup>
// <url>https://jsq.ink</url>
// <role>pku engineer</role>
// <date>2019-03-16 19:40:01</date>
//</624455976585531392>
/*
版权所有IBM公司。保留所有权利。
SPDX许可证标识符:Apache-2.0
**/
package aclmgmt
import (
"fmt"
"github.com/hyperledger/fabric/common/channelconfig"
"github.com/hyperledger/fabric/protos/common"
pb "github.com/hyperledger/fabric/protos/peer"
"github.com/hyperledger/fabric/protos/utils"
)
//-------错误------
//资源的PolicyNotFound缓存
type PolicyNotFound string
func (e PolicyNotFound) Error() string {
return fmt.Sprintf("policy %s not found", string(e))
}
//无效信息
type InvalidIdInfo string
func (e InvalidIdInfo) Error() string {
return fmt.Sprintf("Invalid id for policy [%s]", string(e))
}
//-------策略评估器------
//policyEvaluor接口为策略评估提供接口
type policyEvaluator interface {
PolicyRefForAPI(resName string) string
Evaluate(polName string, id []*common.SignedData) error
}
//PolicyEvaluator Impl实现PolicyEvaluator
type policyEvaluatorImpl struct {
bundle channelconfig.Resources
}
func (pe *policyEvaluatorImpl) PolicyRefForAPI(resName string) string {
app, exists := pe.bundle.ApplicationConfig()
if !exists {
return ""
}
pm := app.APIPolicyMapper()
if pm == nil {
return ""
}
return pm.PolicyRefForAPI(resName)
}
func (pe *policyEvaluatorImpl) Evaluate(polName string, sd []*common.SignedData) error {
policy, ok := pe.bundle.PolicyManager().GetPolicy(polName)
if !ok {
return PolicyNotFound(polName)
}
return policy.Evaluate(sd)
}
//------资源策略提供程序----------
//aclmgmtpolicyProvider是基于资源的acl实现的接口。
type aclmgmtPolicyProvider interface {
//GetPolicyName返回给定资源名称的策略名称
GetPolicyName(resName string) string
//checkacl备份aclprovider接口
CheckACL(polName string, idinfo interface{}) error
}
//aclmgmtpolicyproviderimpl保存来自分类帐状态的字节
type aclmgmtPolicyProviderImpl struct {
pEvaluator policyEvaluator
}
//GetPolicyName返回给定资源字符串的策略名称
func (rp *aclmgmtPolicyProviderImpl) GetPolicyName(resName string) string {
return rp.pEvaluator.PolicyRefForAPI(resName)
}
//checkacl实现aclprovider的checkacl接口,以便可以注册它
//作为具有aclmgmt的提供程序
func (rp *aclmgmtPolicyProviderImpl) CheckACL(polName string, idinfo interface{}) error {
aclLogger.Debugf("acl check(%s)", polName)
//我们将实现其他标识符。最后我们只需要一个签名数据
var sd []*common.SignedData
var err error
switch idinfo.(type) {
case *pb.SignedProposal:
signedProp, _ := idinfo.(*pb.SignedProposal)
//准备签名数据
proposal, err := utils.GetProposal(signedProp.ProposalBytes)
if err != nil {
return fmt.Errorf("Failing extracting proposal during check policy with policy [%s]: [%s]", polName, err)
}
header, err := utils.GetHeader(proposal.Header)
if err != nil {
return fmt.Errorf("Failing extracting header during check policy [%s]: [%s]", polName, err)
}
shdr, err := utils.GetSignatureHeader(header.SignatureHeader)
if err != nil {
return fmt.Errorf("Invalid Proposal's SignatureHeader during check policy [%s]: [%s]", polName, err)
}
sd = []*common.SignedData{{
Data: signedProp.ProposalBytes,
Identity: shdr.Creator,
Signature: signedProp.Signature,
}}
case *common.Envelope:
sd, err = idinfo.(*common.Envelope).AsSignedData()
if err != nil {
return err
}
default:
return InvalidIdInfo(polName)
}
err = rp.pEvaluator.Evaluate(polName, sd)
if err != nil {
return fmt.Errorf("failed evaluating policy on signed data during check policy [%s]: [%s]", polName, err)
}
return nil
}
//--------资源提供程序-AclMgmtImpl用于执行基于资源的ACL的入口点API------
//资源getter获取channelconfig。给定通道ID的资源
type ResourceGetter func(channelID string) channelconfig.Resources
//使用资源配置信息提供ACL支持的资源提供程序
type resourceProvider struct {
//资源吸气剂
resGetter ResourceGetter
//用于未定义资源的默认提供程序
defaultProvider ACLProvider
}
//创建新的资源提供程序
func newResourceProvider(rg ResourceGetter, defprov ACLProvider) *resourceProvider {
return &resourceProvider{rg, defprov}
}
//checkacl实现acl
func (rp *resourceProvider) CheckACL(resName string, channelID string, idinfo interface{}) error {
resCfg := rp.resGetter(channelID)
if resCfg != nil {
pp := &aclmgmtPolicyProviderImpl{&policyEvaluatorImpl{resCfg}}
policyName := pp.GetPolicyName(resName)
if policyName != "" {
aclLogger.Debugf("acl policy %s found in config for resource %s", policyName, resName)
return pp.CheckACL(policyName, idinfo)
}
aclLogger.Debugf("acl policy not found in config for resource %s", resName)
}
return rp.defaultProvider.CheckACL(resName, channelID, idinfo)
}