This repository has been archived by the owner on Mar 6, 2024. It is now read-only.
forked from s7techlab/hlf-sdk-go
-
Notifications
You must be signed in to change notification settings - Fork 2
/
core.go
128 lines (102 loc) · 3.12 KB
/
core.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
package ca
import (
"encoding/base64"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"github.com/golang/protobuf/proto"
mspPb "github.com/hyperledger/fabric-protos-go/msp"
"github.com/hyperledger/fabric/msp"
"github.com/pkg/errors"
"github.com/atomyze-ru/hlf-sdk-go/api"
"github.com/atomyze-ru/hlf-sdk-go/api/ca"
"github.com/atomyze-ru/hlf-sdk-go/api/config"
"github.com/atomyze-ru/hlf-sdk-go/crypto"
"github.com/atomyze-ru/hlf-sdk-go/crypto/ecdsa"
)
type core struct {
mspId string
cs api.CryptoSuite
config *config.CAConfig
client *http.Client
identity msp.SigningIdentity
}
func (c *core) createAuthToken(request []byte) (string, error) {
id, err := c.identity.Serialize()
if err != nil {
return ``, errors.Wrap(err, `failed to get serialized identity`)
}
var serId mspPb.SerializedIdentity
if err = proto.Unmarshal(id, &serId); err != nil {
return ``, errors.Wrap(err, `failed to unmarshal serialized identity`)
}
baseCert := base64.StdEncoding.EncodeToString(serId.IdBytes)
baseReq := base64.StdEncoding.EncodeToString(request)
if signature, err := c.identity.Sign([]byte(baseReq + `.` + baseCert)); err != nil {
return ``, errors.Wrap(err, `failed to sign data`)
} else {
return fmt.Sprintf("%s.%s", baseCert, base64.StdEncoding.EncodeToString(signature)), nil
}
}
func (c *core) setAuthToken(req *http.Request, body []byte) error {
if token, err := c.createAuthToken(body); err != nil {
return errors.Wrap(err, `failed to create auth token`)
} else {
req.Header.Add(`Authorization`, token)
}
return nil
}
func (c *core) processResponse(resp *http.Response, out interface{}, expectedHTTPStatuses ...int) error {
defer func() { _ = resp.Body.Close() }()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return errors.Wrap(err, `failed to read response body`)
}
if !c.expectedHTTPStatus(resp.StatusCode, expectedHTTPStatuses...) {
return api.ErrUnexpectedHTTPStatus{Status: resp.StatusCode, Body: body}
}
var caResp ca.Response
if err = json.Unmarshal(body, &caResp); err != nil {
return errors.Wrap(err, `failed to unmarshal JSON response`)
}
if !caResp.Success {
return ca.ResponseError{Errors: caResp.Errors}
}
if err = json.Unmarshal(caResp.Result, out); err != nil {
return errors.Wrap(err, `failed to unmarshal JSON`)
}
return nil
}
func (c *core) expectedHTTPStatus(status int, expected ...int) bool {
for _, s := range expected {
if s == status {
return true
}
}
return false
}
func NewCore(mspId string, identity api.Identity, opts ...opt) (ca.Core, error) {
var err error
c := &core{mspId: mspId}
// Applying user opts
for _, opt := range opts {
if err = opt(c); err != nil {
return nil, fmt.Errorf(`apply ca.core option: %w`, err)
}
}
if c.config == nil {
return nil, api.ErrEmptyConfig
}
if c.config.Crypto.Type == `` {
c.config.Crypto = ecdsa.DefaultConfig
}
if c.cs, err = crypto.GetSuite(c.config.Crypto.Type, c.config.Crypto.Options); err != nil {
return nil, fmt.Errorf(`initialize crypto suite: %w`, err)
}
if c.client == nil {
c.client = http.DefaultClient
}
c.identity = identity.GetSigningIdentity(c.cs)
return c, nil
}