tokens.go raw
1 package vegadns
2
3 import (
4 "context"
5 "encoding/json"
6 "errors"
7 "fmt"
8 "io"
9 "net/http"
10 "net/url"
11 "strings"
12 "time"
13 )
14
15 // Token struct to hold token information.
16 type Token struct {
17 Token string `json:"access_token"`
18 TokenType string `json:"token_type"`
19 ExpiresIn int `json:"expires_in"`
20 ExpiresAt time.Time `json:"-"`
21 }
22
23 func (t Token) valid() error {
24 if t.ExpiresAt.IsZero() || time.Now().UTC().After(t.ExpiresAt) {
25 return errors.New("token expired")
26 }
27
28 return nil
29 }
30
31 func (t Token) formatBearer() string {
32 return "Bearer " + t.Token
33 }
34
35 func (c *Client) getAuthToken(ctx context.Context) (Token, error) {
36 data := url.Values{}
37 data.Set("grant_type", "client_credentials")
38
39 req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.baseURL.JoinPath("token").String(), strings.NewReader(data.Encode()))
40 if err != nil {
41 return Token{}, fmt.Errorf("get auth token: %w", err)
42 }
43
44 req.SetBasicAuth(c.apiKey, c.apiSecret)
45
46 req.Header.Set("Content-Type", contentType)
47
48 issueTime := time.Now().UTC()
49
50 resp, err := c.httpClient.Do(req)
51 if err != nil {
52 return Token{}, fmt.Errorf("get auth token: %w", err)
53 }
54
55 defer resp.Body.Close()
56
57 if resp.StatusCode != http.StatusOK {
58 body, _ := io.ReadAll(resp.Body)
59
60 return Token{}, fmt.Errorf("get auth token: bad answer from VegaDNS (code: %d, message: %s)", resp.StatusCode, string(body))
61 }
62
63 body, err := io.ReadAll(resp.Body)
64 if err != nil {
65 return Token{}, fmt.Errorf("get auth token: response: %w", err)
66 }
67
68 tok := Token{}
69
70 if err := json.Unmarshal(body, &tok); err != nil {
71 return Token{}, fmt.Errorf("get auth token: unmarshalling body: %w", err)
72 }
73
74 if tok.TokenType != "bearer" {
75 return Token{}, fmt.Errorf("get auth token: don't support anything except bearer tokens (token type: %s)", c.token.TokenType)
76 }
77
78 tok.ExpiresAt = issueTime.Add(time.Duration(tok.ExpiresIn) * time.Second)
79
80 return tok, nil
81 }
82