...
1
21
22 package clients
23
24 import (
25 "context"
26 "encoding/json"
27 "io/ioutil"
28 "net/http"
29 "net/url"
30 "strings"
31 )
32
33 type IntrospectForm struct {
34 Token string
35 Scopes []string
36 }
37
38 type IntrospectResponse struct {
39 Active bool `json:"active"`
40 ClientID string `json:"client_id,omitempty"`
41 Scope string `json:"scope,omitempty"`
42 Audience []string `json:"aud,omitempty"`
43 ExpiresAt int64 `json:"exp,omitempty"`
44 IssuedAt int64 `json:"iat,omitempty"`
45 Subject string `json:"sub,omitempty"`
46 Username string `json:"username,omitempty"`
47 }
48
49 type Introspect struct {
50 endpointURL string
51 client *http.Client
52 }
53
54 func (c *Introspect) IntrospectToken(
55 ctx context.Context,
56 form IntrospectForm,
57 header map[string]string,
58 ) (*IntrospectResponse, error) {
59 data := url.Values{}
60 data.Set("token", form.Token)
61 data.Set("scope", strings.Join(form.Scopes, " "))
62
63 request, err := c.getRequest(ctx, data, header)
64 if err != nil {
65 return nil, err
66 }
67
68 response, err := c.client.Do(request)
69 if err != nil {
70 return nil, err
71 }
72
73 defer response.Body.Close()
74
75 body, err := ioutil.ReadAll(response.Body)
76 if err != nil {
77 return nil, err
78 }
79
80 if c := response.StatusCode; c < 200 || c > 299 {
81 return nil, &RequestError{
82 Response: response,
83 Body: body,
84 }
85 }
86
87 result := &IntrospectResponse{}
88
89 if err := json.Unmarshal(body, result); err != nil {
90 return nil, err
91 }
92
93 return result, nil
94 }
95
96 func (c *Introspect) getRequest(
97 ctx context.Context,
98 data url.Values,
99 header map[string]string,
100 ) (*http.Request, error) {
101 request, err := http.NewRequestWithContext(ctx, "POST", c.endpointURL, strings.NewReader(data.Encode()))
102 if err != nil {
103 return nil, err
104 }
105
106 request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
107
108 for header, value := range header {
109 request.Header.Set(header, value)
110 }
111
112 return request, nil
113 }
114
115 func NewIntrospectClient(endpointURL string) *Introspect {
116 return &Introspect{
117 endpointURL: endpointURL,
118 client: &http.Client{},
119 }
120 }
121
View as plain text