/
bridge_type.go
140 lines (121 loc) · 4.59 KB
/
bridge_type.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
138
139
140
package models
import (
"crypto/subtle"
"fmt"
"github.com/smartcontractkit/chainlink/core/store/assets"
"github.com/smartcontractkit/chainlink/core/utils"
)
// BridgeTypeRequest is the incoming record used to create a BridgeType
type BridgeTypeRequest struct {
Name TaskType `json:"name"`
URL WebURL `json:"url"`
Confirmations uint32 `json:"confirmations"`
MinimumContractPayment *assets.Link `json:"minimumContractPayment"`
}
// GetID returns the ID of this structure for jsonapi serialization.
func (bt BridgeTypeRequest) GetID() string {
return bt.Name.String()
}
// GetName returns the pluralized "type" of this structure for jsonapi serialization.
func (bt BridgeTypeRequest) GetName() string {
return "bridges"
}
// SetID is used to set the ID of this structure when deserializing from jsonapi documents.
func (bt *BridgeTypeRequest) SetID(value string) error {
name, err := NewTaskType(value)
bt.Name = name
return err
}
// BridgeTypeAuthentication is the record returned in response to a request to create a BridgeType
type BridgeTypeAuthentication struct {
Name TaskType `json:"name"`
URL WebURL `json:"url"`
Confirmations uint32 `json:"confirmations"`
IncomingToken string `json:"incomingToken"`
OutgoingToken string `json:"outgoingToken"`
MinimumContractPayment *assets.Link `json:"minimumContractPayment"`
}
// GetID returns the ID of this structure for jsonapi serialization.
func (bt BridgeTypeAuthentication) GetID() string {
return bt.Name.String()
}
// GetName returns the pluralized "type" of this structure for jsonapi serialization.
func (bt BridgeTypeAuthentication) GetName() string {
return "bridges"
}
// SetID is used to set the ID of this structure when deserializing from jsonapi documents.
func (bt *BridgeTypeAuthentication) SetID(value string) error {
name, err := NewTaskType(value)
bt.Name = name
return err
}
// BridgeType is used for external adapters and has fields for
// the name of the adapter and its URL.
type BridgeType struct {
Name TaskType `json:"name" gorm:"primary_key"`
URL WebURL `json:"url"`
Confirmations uint32 `json:"confirmations"`
IncomingTokenHash string `json:"-"`
Salt string `json:"-"`
OutgoingToken string `json:"outgoingToken"`
MinimumContractPayment *assets.Link `json:"minimumContractPayment" gorm:"type:varchar(255)"`
}
// GetID returns the ID of this structure for jsonapi serialization.
func (bt BridgeType) GetID() string {
return bt.Name.String()
}
// GetName returns the pluralized "type" of this structure for jsonapi serialization.
func (bt BridgeType) GetName() string {
return "bridges"
}
// SetID is used to set the ID of this structure when deserializing from jsonapi documents.
func (bt *BridgeType) SetID(value string) error {
name, err := NewTaskType(value)
bt.Name = name
return err
}
// NewBridgeType returns a bridge bridge type authentication (with plaintext
// password) and a bridge type (with hashed password, for persisting)
func NewBridgeType(btr *BridgeTypeRequest) (*BridgeTypeAuthentication,
*BridgeType, error) {
incomingToken := utils.NewBytes32ID()
outgoingToken := utils.NewBytes32ID()
salt := utils.NewBytes32ID()
hash, err := incomingTokenHash(incomingToken, salt)
if err != nil {
return nil, nil, err
}
return &BridgeTypeAuthentication{
Name: btr.Name,
URL: btr.URL,
Confirmations: btr.Confirmations,
IncomingToken: incomingToken,
OutgoingToken: outgoingToken,
MinimumContractPayment: btr.MinimumContractPayment,
}, &BridgeType{
Name: btr.Name,
URL: btr.URL,
Confirmations: btr.Confirmations,
IncomingTokenHash: hash,
Salt: salt,
OutgoingToken: outgoingToken,
MinimumContractPayment: btr.MinimumContractPayment,
}, nil
}
// AuthenticateBridgeType returns true if the passed token matches its
// IncomingToken, or returns false with an error.
func AuthenticateBridgeType(bt *BridgeType, token string) (bool, error) {
hash, err := incomingTokenHash(token, bt.Salt)
if err != nil {
return false, err
}
return subtle.ConstantTimeCompare([]byte(hash), []byte(bt.IncomingTokenHash)) == 1, nil
}
func incomingTokenHash(token, salt string) (string, error) {
input := fmt.Sprintf("%s-%s", token, salt)
hash, err := utils.Sha256(input)
if err != nil {
return "", err
}
return hash, nil
}