forked from s7techlab/cckit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathowner.go
136 lines (113 loc) · 3.33 KB
/
owner.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
// Package owner provides method for storing in chaincode state information about chaincode owner
package owner
import (
"github.com/pkg/errors"
"github.com/s7techlab/cckit/identity"
r "github.com/s7techlab/cckit/router"
)
// OwnerStateKey key used to store owner grant struct in chain code state
const OwnerStateKey = `OWNER`
var (
// ErrOwnerNotProvided occurs when providing owner identity in init arguments
ErrOwnerNotProvided = errors.New(`owner not provided`)
// ErrOwnerAlreadySetted owner already setted
ErrOwnerAlreadySetted = errors.New(`owner already setted`)
)
func IsSetted(c r.Context) (bool, error) {
return c.State().Exists(OwnerStateKey)
}
func Get(c r.Context) (*identity.Entry, error) {
ownerEntry, err := c.State().Get(OwnerStateKey, &identity.Entry{})
if err != nil {
return nil, err
}
o := ownerEntry.(identity.Entry)
return &o, nil
}
// SetFromCreator sets chain code owner from stub creator
func SetFromCreator(c r.Context) (*identity.Entry, error) {
if ownerSetted, err := IsSetted(c); err != nil {
return nil, err
} else if ownerSetted {
return Get(c)
}
creator, err := identity.FromStub(c.Stub())
if err != nil {
return nil, err
}
identityEntry, err := identity.CreateEntry(creator)
if err != nil {
return nil, err
}
return identityEntry, c.State().Insert(OwnerStateKey, identityEntry)
}
// SetFromArgs set owner fron first args
func SetFromArgs(c r.Context) (*identity.Entry, error) {
args := c.Stub().GetArgs()
if len(args) == 2 {
return Insert(c, string(args[0]), args[1])
}
if isSetted, err := IsSetted(c); err != nil {
return nil, err
} else if !isSetted {
return nil, ErrOwnerNotProvided
}
return Get(c)
}
// Insert
func Insert(c r.Context, mspID string, cert []byte) (*identity.Entry, error) {
if ownerSetted, err := IsSetted(c); err != nil {
return nil, errors.Wrap(err, `check owner is set`)
} else if ownerSetted {
return nil, ErrOwnerAlreadySetted
}
id, err := identity.New(mspID, cert)
if err != nil {
return nil, err
}
identityEntry, err := identity.CreateEntry(id)
if err != nil {
return nil, errors.Wrap(err, `create owner entry`)
}
return identityEntry, c.State().Insert(OwnerStateKey, identityEntry)
}
// IsInvokerOr checks tx creator and compares with owner of another identity
func IsInvokerOr(c r.Context, allowedTo ...identity.Identity) (bool, error) {
if isOwner, err := IsInvoker(c); isOwner || err != nil {
return isOwner, err
}
if len(allowedTo) == 0 {
return false, nil
}
invoker, err := identity.FromStub(c.Stub())
if err != nil {
return false, err
}
for _, allowed := range allowedTo {
if allowed.GetMSPIdentifier() == invoker.GetMSPIdentifier() &&
allowed.GetSubject() == invoker.GetSubject() {
return true, nil
}
}
return false, nil
}
// IdentityFromState
func IdentityEntryFromState(c r.Context) (identity.Entry, error) {
res, err := c.State().Get(OwnerStateKey, &identity.Entry{})
if err != nil {
return identity.Entry{}, err
}
return res.(identity.Entry), nil
}
// IsInvoker checks than tx creator is chain code owner
func IsInvoker(c r.Context) (bool, error) {
invoker, err := identity.FromStub(c.Stub())
if err != nil {
return false, err
}
ownerEntry, err := IdentityEntryFromState(c)
if err != nil {
return false, err
}
return ownerEntry.MSPId == invoker.MspID && ownerEntry.Subject == invoker.GetSubject(), nil
}