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