-
Notifications
You must be signed in to change notification settings - Fork 8
/
tokens.go
105 lines (82 loc) · 2.54 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
// Copyright 2022 Namespace Labs Inc; All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
package fnapi
import (
"context"
"os"
"time"
"namespacelabs.dev/foundation/internal/auth"
"namespacelabs.dev/foundation/internal/fnerrors"
"namespacelabs.dev/foundation/std/tasks"
)
type Token interface {
IsSessionToken() bool
Claims(context.Context) (*auth.TokenClaims, error)
PrimaryRegion(context.Context) (string, error)
IssueToken(context.Context, time.Duration, func(context.Context, string, time.Duration) (string, error), bool) (string, error)
}
func BearerToken(ctx context.Context, t Token, skipCache bool) (string, error) {
raw, err := t.IssueToken(ctx, 5*time.Minute, IssueTenantTokenFromSession, skipCache)
if err != nil {
return "", err
}
return raw, nil
}
type ResolvedToken struct {
BearerToken string
PrimaryRegion string // Only available in tenant tokens.
}
func FetchToken(ctx context.Context) (Token, error) {
return tasks.Return(ctx, tasks.Action("nsc.fetch-token").LogLevel(1), func(ctx context.Context) (*auth.Token, error) {
spec, err := ResolveSpec()
if err != nil {
return nil, err
}
if spec != "" {
return auth.FetchTokenFromSpec(ctx, spec)
}
if specified := os.Getenv("NSC_TOKEN_FILE"); specified != "" {
return auth.LoadTokenFromPath(ctx, specified, time.Now())
}
return auth.LoadTenantToken(ctx)
})
}
func IssueBearerToken(ctx context.Context) (ResolvedToken, error) {
tok, err := FetchToken(ctx)
if err != nil {
return ResolvedToken{}, err
}
return IssueBearerTokenFromToken(ctx, tok)
}
func IssueBearerTokenFromToken(ctx context.Context, tok Token) (ResolvedToken, error) {
primaryRegion, err := tok.PrimaryRegion(ctx)
if err != nil {
return ResolvedToken{}, err
}
bt, err := BearerToken(ctx, tok, false)
if err != nil {
return ResolvedToken{}, err
}
return ResolvedToken{BearerToken: bt, PrimaryRegion: primaryRegion}, nil
}
func IssueToken(ctx context.Context, minDur time.Duration) (string, error) {
t, err := FetchToken(ctx)
if err != nil {
return "", err
}
return t.IssueToken(ctx, minDur, IssueTenantTokenFromSession, false)
}
func ResolveSpec() (string, error) {
if spec := os.Getenv("NSC_TOKEN_SPEC"); spec != "" {
return spec, nil
}
if specFile := os.Getenv("NSC_TOKEN_SPEC_FILE"); specFile != "" {
contents, err := os.ReadFile(specFile)
if err != nil {
return "", fnerrors.New("failed to load spec: %w", err)
}
return string(contents), nil
}
return "", nil
}