Skip to content

Commit 02ae074

Browse files
authored
Add preferred login method (#382)
1 parent cb004ca commit 02ae074

File tree

1 file changed

+64
-12
lines changed

1 file changed

+64
-12
lines changed

client/session/from_environment.go

Lines changed: 64 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"net/http"
77
"os"
88
"strings"
9+
10+
"github.com/pkg/errors"
911
)
1012

1113
const (
@@ -34,6 +36,17 @@ const (
3436
// EnvSpaceliftAPIGitHubToken represents the name of the environment variable
3537
// pointing to the GitHub access token used to get the Spacelift API token.
3638
EnvSpaceliftAPIGitHubToken = "SPACELIFT_API_GITHUB_TOKEN" // #nosec G101
39+
40+
// EnvSpaceliftAPIPreferredMethod represents the name of the environment variable
41+
// that specifies the preferred authentication method. Valid values: AuthMethodToken, AuthMethodGitHub, AuthMethodAPIKey.
42+
// If not set, the default priority is: token -> github -> apikey.
43+
EnvSpaceliftAPIPreferredMethod = "SPACELIFT_API_PREFERRED_METHOD"
44+
)
45+
46+
const (
47+
authMethodToken = "token"
48+
authMethodGitHub = "github"
49+
authMethodAPIKey = "apikey"
3750
)
3851

3952
var (
@@ -49,35 +62,74 @@ func FromEnvironment(ctx context.Context, client *http.Client) func(func(string)
4962
lookup = os.LookupEnv
5063
}
5164

52-
if token, ok := lookup(EnvSpaceliftAPIToken); ok && token != "" {
53-
return FromAPIToken(ctx, client)("", token)
65+
preferredMethod, _ := lookup(EnvSpaceliftAPIPreferredMethod)
66+
preferredMethod = strings.ToLower(strings.TrimSpace(preferredMethod))
67+
68+
if preferredMethod != "" {
69+
return tryAuthMethod(ctx, client, preferredMethod, lookup)
5470
}
5571

56-
endpoint, ok := lookup(EnvSpaceliftAPIKeyEndpoint)
57-
if !ok || endpoint == "" {
58-
// Keep backwards compatibility with older version of spacectl.
59-
endpoint, ok = lookup(EnvSpaceliftAPIEndpoint)
60-
if !ok {
61-
return nil, errEnvSpaceliftAPIKeyEndpoint
72+
var lastErr error
73+
for _, method := range []string{authMethodToken, authMethodGitHub, authMethodAPIKey} {
74+
session, err := tryAuthMethod(ctx, client, method, lookup)
75+
if err != nil {
76+
lastErr = err
77+
}
78+
if session != nil {
79+
return session, nil
6280
}
63-
fmt.Printf("Environment variable %q is deprecated, please use %q\n", EnvSpaceliftAPIEndpoint, EnvSpaceliftAPIKeyEndpoint)
6481
}
65-
endpoint = strings.TrimSuffix(endpoint, "/")
82+
return nil, lastErr
83+
}
84+
}
85+
86+
func tryAuthMethod(ctx context.Context, client *http.Client, method string, lookup func(string) (string, bool)) (Session, error) {
87+
switch method {
88+
case authMethodToken:
89+
if token, ok := lookup(EnvSpaceliftAPIToken); ok && token != "" {
90+
return FromAPIToken(ctx, client)("", token)
91+
}
92+
return nil, errors.New("SPACELIFT_API_TOKEN not set in environment")
6693

94+
case authMethodGitHub:
95+
endpoint, err := getEndpoint(lookup)
96+
if err != nil {
97+
return nil, err
98+
}
6799
if gitHubToken, ok := lookup(EnvSpaceliftAPIGitHubToken); ok && gitHubToken != "" {
68100
return FromGitHubToken(ctx, client)(endpoint, gitHubToken)
69101
}
102+
return nil, errors.New("SPACELIFT_API_GITHUB_TOKEN not set in environment")
70103

104+
case authMethodAPIKey:
105+
endpoint, err := getEndpoint(lookup)
106+
if err != nil {
107+
return nil, err
108+
}
71109
keyID, ok := lookup(EnvSpaceliftAPIKeyID)
72110
if !ok || keyID == "" {
73111
return nil, errEnvSpaceliftAPIKeyID
74112
}
75-
76113
keySecret, ok := lookup(EnvSpaceliftAPIKeySecret)
77114
if !ok || keySecret == "" {
78115
return nil, errEnvSpaceliftAPIKeySecret
79116
}
80-
81117
return FromAPIKey(ctx, client)(endpoint, keyID, keySecret)
118+
119+
default:
120+
return nil, fmt.Errorf("no such method %q", method)
121+
}
122+
}
123+
124+
func getEndpoint(lookup func(string) (string, bool)) (string, error) {
125+
endpoint, ok := lookup(EnvSpaceliftAPIKeyEndpoint)
126+
if !ok || endpoint == "" {
127+
// Keep backwards compatibility with older version of spacectl.
128+
endpoint, ok = lookup(EnvSpaceliftAPIEndpoint)
129+
if !ok {
130+
return "", errEnvSpaceliftAPIKeyEndpoint
131+
}
132+
fmt.Printf("Environment variable %q is deprecated, please use %q\n", EnvSpaceliftAPIEndpoint, EnvSpaceliftAPIKeyEndpoint)
82133
}
134+
return strings.TrimSuffix(endpoint, "/"), nil
83135
}

0 commit comments

Comments
 (0)