forked from keys-pub/keys
-
Notifications
You must be signed in to change notification settings - Fork 0
/
request.go
105 lines (90 loc) · 2.77 KB
/
request.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
package http
import (
"bytes"
"encoding/json"
"io"
"net/http"
"time"
"github.com/burlingtonbertie99/mykeys"
)
// NewRequest alias.
var NewRequest = http.NewRequest
// NewRequestWithContext alias.
var NewRequestWithContext = http.NewRequestWithContext
// NewAuthRequest returns new authorized/signed HTTP request using auth key.
func NewAuthRequest(method string, urs string, body io.Reader, contentHash string, ts time.Time, key *keys.EdX25519Key) (*http.Request, error) {
auths := []AuthHeader{{Header: "Authorization", Key: key}}
return NewAuthsRequest(method, urs, body, contentHash, ts, auths)
}
type AuthHeader struct {
Header string
Key *keys.EdX25519Key
}
func NewAuthsRequest(method string, urs string, body io.Reader, contentHash string, ts time.Time, auths []AuthHeader) (*http.Request, error) {
return newAuthsRequest(method, urs, body, contentHash, ts, keys.RandBytes(24), auths)
}
func newAuthRequest(method string, urs string, body io.Reader, contentHash string, ts time.Time, nonce []byte, key *keys.EdX25519Key) (*http.Request, error) {
auths := []AuthHeader{{Header: "Authorization", Key: key}}
return newAuthsRequest(method, urs, body, contentHash, ts, nonce, auths)
}
func newAuthsRequest(method string, urs string, body io.Reader, contentHash string, ts time.Time, nonce []byte, auths []AuthHeader) (*http.Request, error) {
ur, err := authURL(urs, ts, nonce)
if err != nil {
return nil, err
}
req, err := http.NewRequest(method, ur.String(), body)
if err != nil {
return nil, err
}
for _, auth := range auths {
a, err := newAuthWithURL(method, ur, contentHash, auth.Key)
if err != nil {
return nil, err
}
req.Header.Set(auth.Header, a.Header())
}
return req, nil
}
// NewJSONRequest ...
func NewJSONRequest(method string, urs string, i interface{}, opt ...RequestOption) (*http.Request, error) {
opts := NewRequestOptions(opt...)
b, err := json.Marshal(i)
if err != nil {
return nil, err
}
if opts.Key != nil {
ts := opts.Timestamp
if ts.IsZero() {
ts = time.Now()
}
return NewAuthRequest(method, urs, bytes.NewReader(b), ContentHash(b), ts, opts.Key)
}
return NewRequest(method, urs, bytes.NewReader(b))
}
// RequestOptions ...
type RequestOptions struct {
Timestamp time.Time
Key *keys.EdX25519Key
}
// RequestOption ...
type RequestOption func(*RequestOptions)
// NewRequestOptions parses RequestOption.
func NewRequestOptions(opts ...RequestOption) RequestOptions {
var options RequestOptions
for _, o := range opts {
o(&options)
}
return options
}
// WithTimestamp to overwride timestamp.
func WithTimestamp(ts time.Time) RequestOption {
return func(o *RequestOptions) {
o.Timestamp = ts
}
}
// SignedWith key.
func SignedWith(key *keys.EdX25519Key) RequestOption {
return func(o *RequestOptions) {
o.Key = key
}
}