-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathorgs.go
More file actions
122 lines (99 loc) · 2.98 KB
/
orgs.go
File metadata and controls
122 lines (99 loc) · 2.98 KB
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
package hyperacc
import (
"fmt"
"slices"
"github.com/hyperledger/fabric-contract-api-go/v2/contractapi"
)
// MSPIDRule checks the caller's MSPID
type MSPIDRule struct {
mspid string
}
// RequireMSPID creates a rule to check for a specific MSPID
func RequireMSPID(mspid string) *MSPIDRule {
return &MSPIDRule{mspid: mspid}
}
// Check checks the caller's MSPID
func (r *MSPIDRule) Check(ctx contractapi.TransactionContextInterface) error {
mspid, err := ctx.GetClientIdentity().GetMSPID()
if err != nil {
return fmt.Errorf("failed to get MSPID: %w", err)
}
if mspid != r.mspid {
return NewAccessError(fmt.Sprintf("required MSPID '%s', got '%s'", r.mspid, mspid))
}
return nil
}
// AnyMSPIDRule checks for one of the specified MSPIDs
type AnyMSPIDRule struct {
mspids []string
}
// RequireAnyMSPID creates a rule to check for one of the MSPIDs
func RequireAnyMSPID(mspids ...string) *AnyMSPIDRule {
return &AnyMSPIDRule{mspids: mspids}
}
// Check checks if the caller has one of the MSPIDs
func (r *AnyMSPIDRule) Check(ctx contractapi.TransactionContextInterface) error {
mspid, err := ctx.GetClientIdentity().GetMSPID()
if err != nil {
return fmt.Errorf("failed to get MSPID: %w", err)
}
if slices.Contains(r.mspids, mspid) {
return nil
}
return NewAccessError(fmt.Sprintf("required one of MSPIDs %v, got '%s'", r.mspids, mspid))
}
// OURule checks the caller's Organizational Unit
type OURule struct {
ou string
}
// RequireOU creates a rule to check for a specific OU
func RequireOU(ou string) *OURule {
return &OURule{ou: ou}
}
// Check checks the caller's OU
func (r *OURule) Check(ctx contractapi.TransactionContextInterface) error {
identity := ctx.GetClientIdentity()
// Get MSPID
mspid, err := identity.GetMSPID()
if err != nil {
return fmt.Errorf("failed to get MSPID: %w", err)
}
// Parse certificate to get OU
cert, err := identity.GetX509Certificate()
if err != nil {
return fmt.Errorf("failed to get X509 certificate: %w", err)
}
found := slices.Contains(cert.Subject.OrganizationalUnit, r.ou)
if !found {
return NewAccessError(fmt.Sprintf("required OU '%s', MSP: %s", r.ou, mspid))
}
return nil
}
// AnyOURule checks for one of the specified OUs
type AnyOURule struct {
ous []string
}
// RequireAnyOU creates a rule to check for one of the OUs
func RequireAnyOU(ous ...string) *AnyOURule {
return &AnyOURule{ous: ous}
}
// Check checks if the caller has one of the OUs
func (r *AnyOURule) Check(ctx contractapi.TransactionContextInterface) error {
identity := ctx.GetClientIdentity()
// Get MSPID
mspid, err := identity.GetMSPID()
if err != nil {
return fmt.Errorf("failed to get MSPID: %w", err)
}
// Parse certificate to get OU
cert, err := identity.GetX509Certificate()
if err != nil {
return fmt.Errorf("failed to get X509 certificate: %w", err)
}
for _, certOU := range cert.Subject.OrganizationalUnit {
if slices.Contains(r.ous, certOU) {
return nil
}
}
return NewAccessError(fmt.Sprintf("required one of OUs %v, MSP: %s", r.ous, mspid))
}