136 lines
2.7 kB
1
package state
2
3
import (
4
"bytes"
5
"crypto/hmac"
6
"crypto/sha256"
7
"encoding/hex"
8
"encoding/json"
9
"fmt"
10
"net/http"
11
"net/url"
12
"time"
13
)
14
15
type SignerTransport struct {
16
Secret string
17
}
18
19
func (s SignerTransport) RoundTrip(req *http.Request) (*http.Response, error) {
20
timestamp := time.Now().Format(time.RFC3339)
21
mac := hmac.New(sha256.New, []byte(s.Secret))
22
message := req.Method + req.URL.Path + timestamp
23
mac.Write([]byte(message))
24
signature := hex.EncodeToString(mac.Sum(nil))
25
req.Header.Set("X-Signature", signature)
26
req.Header.Set("X-Timestamp", timestamp)
27
return http.DefaultTransport.RoundTrip(req)
28
}
29
30
type SignedClient struct {
31
Secret string
32
Url *url.URL
33
client *http.Client
34
}
35
36
func NewSignedClient(domain, secret string) (*SignedClient, error) {
37
client := &http.Client{
38
Timeout: 5 * time.Second,
39
Transport: SignerTransport{
40
Secret: secret,
41
},
42
}
43
44
url, err := url.Parse(fmt.Sprintf("http://%s", domain))
45
if err != nil {
46
return nil, err
47
}
48
49
signedClient := &SignedClient{
50
Secret: secret,
51
client: client,
52
Url: url,
53
}
54
55
return signedClient, nil
56
}
57
58
func (s *SignedClient) newRequest(method, endpoint string, body []byte) (*http.Request, error) {
59
return http.NewRequest(method, s.Url.JoinPath(endpoint).String(), bytes.NewReader(body))
60
}
61
62
func (s *SignedClient) Init(did string) (*http.Response, error) {
63
const (
64
Method = "POST"
65
Endpoint = "/init"
66
)
67
68
body, _ := json.Marshal(map[string]interface{}{
69
"did": did,
70
})
71
72
req, err := s.newRequest(Method, Endpoint, body)
73
if err != nil {
74
return nil, err
75
}
76
77
return s.client.Do(req)
78
}
79
80
func (s *SignedClient) NewRepo(did, repoName, defaultBranch string) (*http.Response, error) {
81
const (
82
Method = "PUT"
83
Endpoint = "/repo/new"
84
)
85
86
body, _ := json.Marshal(map[string]interface{}{
87
"did": did,
88
"name": repoName,
89
"default_branch": defaultBranch,
90
})
91
92
fmt.Println(body)
93
94
req, err := s.newRequest(Method, Endpoint, body)
95
if err != nil {
96
return nil, err
97
}
98
99
return s.client.Do(req)
100
}
101
102
func (s *SignedClient) AddMember(did string) (*http.Response, error) {
103
const (
104
Method = "PUT"
105
Endpoint = "/member/add"
106
)
107
108
body, _ := json.Marshal(map[string]interface{}{
109
"did": did,
110
})
111
112
req, err := s.newRequest(Method, Endpoint, body)
113
if err != nil {
114
return nil, err
115
}
116
117
return s.client.Do(req)
118
}
119
120
func (s *SignedClient) AddCollaborator(ownerDid, repoName, memberDid string) (*http.Response, error) {
121
const (
122
Method = "POST"
123
)
124
endpoint := fmt.Sprintf("/%s/%s/collaborator/add", ownerDid, repoName)
125
126
body, _ := json.Marshal(map[string]interface{}{
127
"did": memberDid,
128
})
129
130
req, err := s.newRequest(Method, endpoint, body)
131
if err != nil {
132
return nil, err
133
}
134
135
return s.client.Do(req)
136
}
137