-
Notifications
You must be signed in to change notification settings - Fork 8
/
tokens.go
156 lines (126 loc) · 3.77 KB
/
tokens.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
149
150
151
152
153
154
155
156
package scalingo
import (
"context"
"encoding/json"
"strconv"
"time"
"gopkg.in/errgo.v1"
"github.com/Scalingo/go-scalingo/v7/http"
)
type TokensService interface {
TokensList(context.Context) (Tokens, error)
TokenCreate(context.Context, TokenCreateParams) (Token, error)
TokenExchange(ctx context.Context, token string) (string, error)
TokenShow(ctx context.Context, id int) (Token, error)
}
var _ TokensService = (*Client)(nil)
// Deprecated: use http.ErrOTPRequired instead of this wrapper.
var ErrOTPRequired = http.ErrOTPRequired
// IsOTPRequired tests if the authentication backend return an OTP Required error
//
// Deprecated: use http.IsOTPRequired instead of this wrapper.
func IsOTPRequired(err error) bool {
return http.IsOTPRequired(err)
}
type Token struct {
ID string `json:"id"`
Name string `json:"name"`
CreatedAt time.Time `json:"created_at"`
LastUsedAt time.Time `json:"last_used_at"`
Token string `json:"token"`
}
type LoginParams struct {
Identifier string `json:"identifier"`
Password string `json:"password"`
OTP string `json:"otp"`
JWT string `json:"jwt"`
}
type TokenCreateParams struct {
Name string `json:"name"`
}
type Tokens []*Token
type TokensRes struct {
Tokens Tokens `json:"tokens"`
}
type BearerTokenRes struct {
Token string `json:"token"`
}
type TokenRes struct {
Token Token `json:"token"`
}
func (c *Client) TokensList(ctx context.Context) (Tokens, error) {
var tokensRes TokensRes
err := c.AuthAPI().ResourceList(ctx, "tokens", nil, &tokensRes)
if err != nil {
return nil, errgo.Notef(err, "fail to get tokens")
}
return tokensRes.Tokens, nil
}
func (c *Client) TokenExchange(ctx context.Context, token string) (string, error) {
req := &http.APIRequest{
NoAuth: true,
Method: "POST",
Endpoint: "/tokens/exchange",
Password: token,
}
res, err := c.AuthAPI().Do(ctx, req)
if err != nil {
return "", errgo.Notef(err, "fail to make request POST /v1/tokens/exchange")
}
defer res.Body.Close()
var btRes BearerTokenRes
err = json.NewDecoder(res.Body).Decode(&btRes)
if err != nil {
return "", errgo.Notef(err, "invalid response from authentication service")
}
return btRes.Token, nil
}
func (c *Client) TokenCreateWithLogin(ctx context.Context, params TokenCreateParams, login LoginParams) (Token, error) {
req := &http.APIRequest{
NoAuth: true,
Method: "POST",
Endpoint: "/tokens",
Expected: http.Statuses{201},
Username: login.Identifier,
Password: login.Password,
OTP: login.OTP,
Token: login.JWT,
Params: map[string]interface{}{"token": params},
}
resp, err := c.AuthAPI().Do(ctx, req)
if err != nil {
if http.IsOTPRequired(err) {
return Token{}, http.ErrOTPRequired
}
return Token{}, errgo.Notef(err, "request failed")
}
defer resp.Body.Close()
var tokenRes TokenRes
err = json.NewDecoder(resp.Body).Decode(&tokenRes)
if err != nil {
return Token{}, errgo.NoteMask(err, "invalid response from authentication service", errgo.Any)
}
return tokenRes.Token, nil
}
func (c *Client) TokenCreate(ctx context.Context, params TokenCreateParams) (Token, error) {
var tokenRes TokenRes
payload := map[string]TokenCreateParams{
"token": params,
}
err := c.AuthAPI().ResourceAdd(ctx, "tokens", payload, &tokenRes)
if err != nil {
return Token{}, errgo.Notef(err, "fail to create token")
}
return tokenRes.Token, nil
}
func (c *Client) TokenShow(ctx context.Context, id int) (Token, error) {
var tokenRes TokenRes
err := c.AuthAPI().ResourceGet(ctx, "tokens", strconv.Itoa(id), nil, &tokenRes)
if err != nil {
return Token{}, errgo.Notef(err, "fail to get token")
}
return tokenRes.Token, nil
}
func (c *Client) GetAccessToken(ctx context.Context) (string, error) {
return c.ScalingoAPI().TokenGenerator().GetAccessToken(ctx)
}