forked from hyperledger/fabric-sdk-go
/
opts.go
137 lines (113 loc) · 5 KB
/
opts.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
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package msp
import (
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/msp"
"github.com/pkg/errors"
)
// IdentityConfigOptions represents IdentityConfig interface with overridable interface functions
// if a function is not overridden, the default IdentityConfig implementation will be used.
type IdentityConfigOptions struct {
client
caConfig
caServerCerts
caClientKey
caClientCert
caKeyStorePath
credentialStorePath
}
type applier func()
type predicate func() bool
type setter struct{ isSet bool }
// client interface allows to uniquely override IdentityConfig interface's Client() function
type client interface {
Client() *msp.ClientConfig
}
// caConfig interface allows to uniquely override IdentityConfig interface's CAConfig() function
type caConfig interface {
CAConfig(org string) (*msp.CAConfig, bool)
}
// caServerCerts interface allows to uniquely override IdentityConfig interface's CAServerCerts() function
type caServerCerts interface {
CAServerCerts(org string) ([][]byte, bool)
}
// caClientKey interface allows to uniquely override IdentityConfig interface's CAClientKey() function
type caClientKey interface {
CAClientKey(org string) ([]byte, bool)
}
// caClientCert interface allows to uniquely override IdentityConfig interface's CAClientCert() function
type caClientCert interface {
CAClientCert(org string) ([]byte, bool)
}
// caKeyStorePath interface allows to uniquely override IdentityConfig interface's CAKeyStorePath() function
type caKeyStorePath interface {
CAKeyStorePath() string
}
// credentialStorePath interface allows to uniquely override IdentityConfig interface's CredentialStorePath() function
type credentialStorePath interface {
CredentialStorePath() string
}
// BuildIdentityConfigFromOptions will return an IdentityConfig instance pre-built with Optional interfaces
// provided in fabsdk's WithConfigIdentity(opts...) call
func BuildIdentityConfigFromOptions(opts ...interface{}) (msp.IdentityConfig, error) {
// build a new IdentityConfig with overridden function implementations
c := &IdentityConfigOptions{}
for _, option := range opts {
err := setIdentityConfigWithOptionInterface(c, option)
if err != nil {
return nil, err
}
}
return c, nil
}
// UpdateMissingOptsWithDefaultConfig will verify if any functions of the IdentityConfig were not updated with fabsdk's
// WithConfigIdentity(opts...) call, then use default IdentityConfig interface for these functions instead
func UpdateMissingOptsWithDefaultConfig(c *IdentityConfigOptions, d msp.IdentityConfig) msp.IdentityConfig {
s := &setter{}
s.set(c.client, nil, func() { c.client = d })
s.set(c.caConfig, nil, func() { c.caConfig = d })
s.set(c.caServerCerts, nil, func() { c.caServerCerts = d })
s.set(c.caClientKey, nil, func() { c.caClientKey = d })
s.set(c.caClientCert, nil, func() { c.caClientCert = d })
s.set(c.caKeyStorePath, nil, func() { c.caKeyStorePath = d })
s.set(c.credentialStorePath, nil, func() { c.credentialStorePath = d })
return c
}
// IsIdentityConfigFullyOverridden will return true if all of the argument's sub interfaces is not nil
// (ie IdentityConfig interface not fully overridden)
func IsIdentityConfigFullyOverridden(c *IdentityConfigOptions) bool {
return !anyNil(c.client, c.caConfig, c.caServerCerts, c.caClientKey, c.caClientCert, c.caKeyStorePath, c.credentialStorePath)
}
// will override IdentityConfig interface with functions provided by o (option)
func setIdentityConfigWithOptionInterface(c *IdentityConfigOptions, o interface{}) error {
s := &setter{}
s.set(c.client, func() bool { _, ok := o.(client); return ok }, func() { c.client = o.(client) })
s.set(c.caConfig, func() bool { _, ok := o.(caConfig); return ok }, func() { c.caConfig = o.(caConfig) })
s.set(c.caServerCerts, func() bool { _, ok := o.(caServerCerts); return ok }, func() { c.caServerCerts = o.(caServerCerts) })
s.set(c.caClientKey, func() bool { _, ok := o.(caClientKey); return ok }, func() { c.caClientKey = o.(caClientKey) })
s.set(c.caClientCert, func() bool { _, ok := o.(caClientCert); return ok }, func() { c.caClientCert = o.(caClientCert) })
s.set(c.caKeyStorePath, func() bool { _, ok := o.(caKeyStorePath); return ok }, func() { c.caKeyStorePath = o.(caKeyStorePath) })
s.set(c.credentialStorePath, func() bool { _, ok := o.(credentialStorePath); return ok }, func() { c.credentialStorePath = o.(credentialStorePath) })
if !s.isSet {
return errors.Errorf("option %#v is not a sub interface of IdentityConfig, at least one of its functions must be implemented.", o)
}
return nil
}
// needed to avoid meta-linter errors (too many if conditions)
func (o *setter) set(current interface{}, check predicate, apply applier) {
if current == nil && (check == nil || check()) {
apply()
o.isSet = true
}
}
// will verify if any of objs element is nil, also needed to avoid meta-linter errors
func anyNil(objs ...interface{}) bool {
for _, p := range objs {
if p == nil {
return true
}
}
return false
}