github.com/s7techlab/cckit@v0.10.5/extensions/owner/owner.go (about) 1 // Package owner provides method for storing in chaincode state information about chaincode owner 2 package owner 3 4 import ( 5 "errors" 6 "fmt" 7 8 "github.com/s7techlab/cckit/identity" 9 r "github.com/s7techlab/cckit/router" 10 ) 11 12 var ( 13 // ErrOwnerNotProvided occurs when providing owner identity in init arguments 14 ErrOwnerNotProvided = errors.New(`owner not provided`) 15 16 // ErrOwnerAlreadySet owner already set 17 ErrOwnerAlreadySet = errors.New(`owner already set`) 18 ) 19 20 func IsSet(c r.Context) (bool, error) { 21 return c.State().Exists(OwnerStateKey) 22 } 23 24 // Get returns current chaincode owner identity.Entry 25 // Service implementation recommended, see chaincode_owner.proto 26 func Get(c r.Context) (*identity.Entry, error) { 27 ownerEntry, err := c.State().Get(OwnerStateKey, &identity.Entry{}) 28 if err != nil { 29 return nil, err 30 } 31 32 o := ownerEntry.(identity.Entry) 33 return &o, nil 34 } 35 36 // SetFromCreator sets chain code owner from stub creator 37 // Service implementation recommended, see chaincode_owner.proto 38 func SetFromCreator(c r.Context) (*identity.Entry, error) { 39 if ownerSet, err := IsSet(c); err != nil { 40 return nil, err 41 } else if ownerSet { 42 return Get(c) 43 } 44 45 creator, err := identity.FromStub(c.Stub()) 46 if err != nil { 47 return nil, err 48 } 49 50 identityEntry, err := identity.CreateEntry(creator) 51 if err != nil { 52 return nil, err 53 } 54 55 return identityEntry, c.State().Insert(OwnerStateKey, identityEntry) 56 } 57 58 // SetFromArgs set owner from first args 59 func SetFromArgs(c r.Context) (*identity.Entry, error) { 60 args := c.Stub().GetArgs() 61 62 if len(args) == 2 { 63 return Insert(c, string(args[0]), args[1]) 64 } 65 66 if isSet, err := IsSet(c); err != nil { 67 return nil, err 68 } else if !isSet { 69 return nil, ErrOwnerNotProvided 70 } 71 72 return Get(c) 73 } 74 75 // Insert information about owner to chaincode state 76 func Insert(c r.Context, mspID string, cert []byte) (*identity.Entry, error) { 77 if ownerSet, err := IsSet(c); err != nil { 78 return nil, fmt.Errorf(`check owner is set: %w`, err) 79 } else if ownerSet { 80 return nil, ErrOwnerAlreadySet 81 } 82 83 id, err := identity.New(mspID, cert) 84 if err != nil { 85 return nil, err 86 } 87 88 identityEntry, err := identity.CreateEntry(id) 89 if err != nil { 90 return nil, fmt.Errorf(`create owner entry: %w`, err) 91 } 92 return identityEntry, c.State().Insert(OwnerStateKey, identityEntry) 93 } 94 95 // IsInvokerOr checks tx creator and compares with owner of another identity 96 // Service implementation recommended, see chaincode_owner.proto 97 func IsInvokerOr(c r.Context, allowedTo ...identity.Identity) (bool, error) { 98 if err := IsTxCreator(c); err == nil { 99 return true, nil 100 } 101 if len(allowedTo) == 0 { 102 return false, nil 103 } 104 invoker, err := identity.FromStub(c.Stub()) 105 if err != nil { 106 return false, err 107 } 108 for _, allowed := range allowedTo { 109 if allowed.GetMSPIdentifier() == invoker.GetMSPIdentifier() && 110 allowed.GetSubject() == invoker.GetSubject() { 111 return true, nil 112 } 113 } 114 return false, nil 115 } 116 117 // IdentityEntryFromState returns identity.Entry with chaincode owner certificate 118 // Service implementation recommended, see chaincode_owner.proto 119 func IdentityEntryFromState(c r.Context) (identity.Entry, error) { 120 res, err := c.State().Get(OwnerStateKey, &identity.Entry{}) 121 if err != nil { 122 return identity.Entry{}, err 123 } 124 125 return res.(identity.Entry), nil 126 } 127 128 // IsInvoker checks than tx creator is chain code owner 129 // Service implementation recommended, see chaincode_owner.proto 130 func IsInvoker(ctx r.Context) (bool, error) { 131 if err := IsTxCreator(ctx); err != nil { 132 return false, err 133 } 134 135 return true, nil 136 } 137 138 // IsTxCreator returns error if owner identity (msp_id + certificate) did not match tx creator identity 139 // Service implementation recommended, see chaincode_owner.proto 140 func IsTxCreator(ctx r.Context) error { 141 invoker, err := identity.FromStub(ctx.Stub()) 142 if err != nil { 143 return err 144 } 145 146 ownerEntry, err := IdentityEntryFromState(ctx) 147 if err != nil { 148 return err 149 } 150 151 if err = identity.Equal(invoker, ownerEntry); err != nil { 152 return fmt.Errorf(`%s : %w`, err, ErrOwnerOnly) 153 } 154 155 return nil 156 }