-
Notifications
You must be signed in to change notification settings - Fork 221
/
token.go
83 lines (72 loc) · 2.11 KB
/
token.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
package metrics
import (
"context"
"errors"
"fmt"
"github.com/superfly/flyctl/client"
"github.com/superfly/flyctl/gql"
"github.com/superfly/flyctl/internal/config"
"github.com/superfly/flyctl/internal/state"
"github.com/superfly/flyctl/terminal"
)
func queryMetricsToken(ctx context.Context) (string, error) {
// Manually construct an API client with the user's access token.
// We use this over the context API client because we're trying to
// authenticate the human user, not the specific credentials they're using.
cfg := config.FromContext(ctx)
apiClient := client.FromTokens(cfg.Tokens).API()
personal, err := apiClient.GetOrganizationBySlug(ctx, "personal")
if err != nil {
return "", err
}
if personal == nil {
return "", errors.New("no personal organization found")
}
resp, err := gql.CreateLimitedAccessToken(
ctx,
apiClient.GenqClient,
"flyctl-metrics",
personal.ID,
"identity",
struct{}{},
"",
)
if err != nil {
return "", fmt.Errorf("failed creating identity token: %w", err)
}
return resp.CreateLimitedAccessToken.LimitedAccessToken.TokenHeader, nil
}
func GetMetricsToken(parentCtx context.Context) (token string, err error) {
// Prevent metrics panics from bubbling up to the user.
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("panic: %v", r)
}
}()
cfg := config.FromContext(parentCtx)
if cfg.MetricsToken != "" {
terminal.Debugf("Config has metrics token\n")
return cfg.MetricsToken, nil
}
if cfg.MetricsToken == "" && cfg.Tokens.GraphQL() != "" {
terminal.Debugf("Querying metrics token from web\n")
token, err := queryMetricsToken(parentCtx)
if err != nil {
return "", err
}
if err = persistMetricsToken(parentCtx, token); err != nil {
return "", err
}
cfg.MetricsToken = token
return token, nil
}
return "", errors.New("no metrics token in config")
}
func persistMetricsToken(ctx context.Context, token string) error {
path := state.ConfigFile(ctx)
if err := config.SetMetricsToken(path, token); err != nil {
return fmt.Errorf("failed persisting %s in %s: %w\n",
config.MetricsTokenFileKey, path, err)
}
return nil
}