/
client.go
148 lines (121 loc) · 3.23 KB
/
client.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
141
142
143
144
145
146
147
148
package oauth2
import (
"net/http"
)
// ClientConfig is used to configure a client.
type ClientConfig struct {
BaseURI string
TokenEndpoint string
IntrospectionEndpoint string
RevocationEndpoint string
ResponseLimit int64
}
// Default will return a default configuration.
func Default(baseURI string) ClientConfig {
return ClientConfig{
BaseURI: baseURI,
TokenEndpoint: "/oauth2/token",
IntrospectionEndpoint: "/oauth2/introspect",
RevocationEndpoint: "/oauth2/revoke",
}
}
// Client is a low-level OAuth2 client.
type Client struct {
config ClientConfig
client *http.Client
}
// NewClient will create and return a new client.
func NewClient(config ClientConfig) *Client {
return NewClientWithClient(config, new(http.Client))
}
// NewClientWithClient will create and return a new client using the provided
// client.
func NewClientWithClient(config ClientConfig, client *http.Client) *Client {
// set default response limit
if config.ResponseLimit == 0 {
config.ResponseLimit = 2048
}
return &Client{
config: config,
client: client,
}
}
// Authenticate will send the provided token request and return the servers
// token response or an error if failed.
func (c *Client) Authenticate(trq TokenRequest) (*TokenResponse, error) {
// prepare endpoint
endpoint := c.config.BaseURI + c.config.TokenEndpoint
// build request
req, err := BuildTokenRequest(endpoint, trq)
if err != nil {
return nil, err
}
// perform request
res, err := c.client.Do(req)
if err != nil {
return nil, err
}
// ensure body is closed
defer res.Body.Close()
// check status
if res.StatusCode != http.StatusOK {
return nil, ParseRequestError(res, c.config.ResponseLimit)
}
// parse response
trs, err := ParseTokenResponse(res, c.config.ResponseLimit)
if err != nil {
return nil, err
}
return trs, nil
}
// Introspect will send the provided introspection request and return the server
// response or an error if failed.
func (c *Client) Introspect(irq IntrospectionRequest) (*IntrospectionResponse, error) {
// prepare endpoint
endpoint := c.config.BaseURI + c.config.IntrospectionEndpoint
// build request
req, err := BuildIntrospectionRequest(endpoint, irq)
if err != nil {
return nil, err
}
// perform request
res, err := c.client.Do(req)
if err != nil {
return nil, err
}
// ensure body is closed
defer res.Body.Close()
// check status
if res.StatusCode != http.StatusOK {
return nil, ParseRequestError(res, c.config.ResponseLimit)
}
// parse response
irs, err := ParseIntrospectionResponse(res, c.config.ResponseLimit)
if err != nil {
return nil, err
}
return irs, nil
}
// Revoke will send the provided revocation request and return and error if it
// failed.
func (c *Client) Revoke(rrq RevocationRequest) error {
// prepare endpoint
endpoint := c.config.BaseURI + c.config.RevocationEndpoint
// build request
req, err := BuildRevocationRequest(endpoint, rrq)
if err != nil {
return err
}
// perform request
res, err := c.client.Do(req)
if err != nil {
return err
}
// ensure body is closed
defer res.Body.Close()
// check status
if res.StatusCode != http.StatusOK {
return ParseRequestError(res, c.config.ResponseLimit)
}
return nil
}