Skip to content

Commit c4b0fa0

Browse files
committed
Add support for new config properties
1 parent 614313b commit c4b0fa0

File tree

13 files changed

+541
-463
lines changed

13 files changed

+541
-463
lines changed

cli/server.go

Lines changed: 102 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -98,89 +98,6 @@ import (
9898
"github.com/coder/wgtunnel/tunnelsdk"
9999
)
100100

101-
// ReadGitAuthProvidersFromEnv is provided for compatibility purposes with the
102-
// viper CLI.
103-
// DEPRECATED
104-
func ReadGitAuthProvidersFromEnv(environ []string) ([]codersdk.ExternalAuthConfig, error) {
105-
// The index numbers must be in-order.
106-
sort.Strings(environ)
107-
108-
var providers []codersdk.ExternalAuthConfig
109-
for _, v := range clibase.ParseEnviron(environ, "CODER_GITAUTH_") {
110-
tokens := strings.SplitN(v.Name, "_", 2)
111-
if len(tokens) != 2 {
112-
return nil, xerrors.Errorf("invalid env var: %s", v.Name)
113-
}
114-
115-
providerNum, err := strconv.Atoi(tokens[0])
116-
if err != nil {
117-
return nil, xerrors.Errorf("parse number: %s", v.Name)
118-
}
119-
120-
var provider codersdk.ExternalAuthConfig
121-
switch {
122-
case len(providers) < providerNum:
123-
return nil, xerrors.Errorf(
124-
"provider num %v skipped: %s",
125-
len(providers),
126-
v.Name,
127-
)
128-
case len(providers) == providerNum:
129-
// At the next next provider.
130-
providers = append(providers, provider)
131-
case len(providers) == providerNum+1:
132-
// At the current provider.
133-
provider = providers[providerNum]
134-
}
135-
136-
key := tokens[1]
137-
switch key {
138-
case "ID":
139-
provider.ID = v.Value
140-
case "TYPE":
141-
provider.Type = v.Value
142-
case "CLIENT_ID":
143-
provider.ClientID = v.Value
144-
case "CLIENT_SECRET":
145-
provider.ClientSecret = v.Value
146-
case "AUTH_URL":
147-
provider.AuthURL = v.Value
148-
case "TOKEN_URL":
149-
provider.TokenURL = v.Value
150-
case "VALIDATE_URL":
151-
provider.ValidateURL = v.Value
152-
case "REGEX":
153-
provider.Regex = v.Value
154-
case "DEVICE_FLOW":
155-
b, err := strconv.ParseBool(v.Value)
156-
if err != nil {
157-
return nil, xerrors.Errorf("parse bool: %s", v.Value)
158-
}
159-
provider.DeviceFlow = b
160-
case "DEVICE_CODE_URL":
161-
provider.DeviceCodeURL = v.Value
162-
case "NO_REFRESH":
163-
b, err := strconv.ParseBool(v.Value)
164-
if err != nil {
165-
return nil, xerrors.Errorf("parse bool: %s", v.Value)
166-
}
167-
provider.NoRefresh = b
168-
case "SCOPES":
169-
provider.Scopes = strings.Split(v.Value, " ")
170-
case "APP_INSTALL_URL":
171-
provider.AppInstallURL = v.Value
172-
case "APP_INSTALLATIONS_URL":
173-
provider.AppInstallationsURL = v.Value
174-
case "DISPLAY_NAME":
175-
provider.DisplayName = v.Value
176-
case "DISPLAY_ICON":
177-
provider.DisplayIcon = v.Value
178-
}
179-
providers[providerNum] = provider
180-
}
181-
return providers, nil
182-
}
183-
184101
func createOIDCConfig(ctx context.Context, vals *codersdk.DeploymentValues) (*coderd.OIDCConfig, error) {
185102
if vals.OIDC.ClientID == "" {
186103
return nil, xerrors.Errorf("OIDC client ID must be set!")
@@ -572,14 +489,14 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
572489
}
573490
}
574491

575-
gitAuthEnv, err := ReadGitAuthProvidersFromEnv(os.Environ())
492+
extAuthEnv, err := ReadExternalAuthProvidersFromEnv(os.Environ())
576493
if err != nil {
577-
return xerrors.Errorf("read git auth providers from env: %w", err)
494+
return xerrors.Errorf("read external auth providers from env: %w", err)
578495
}
579496

580-
vals.GitAuthProviders.Value = append(vals.GitAuthProviders.Value, gitAuthEnv...)
497+
vals.ExternalAuthConfigs.Value = append(vals.ExternalAuthConfigs.Value, extAuthEnv...)
581498
externalAuthConfigs, err := externalauth.ConvertConfig(
582-
vals.GitAuthProviders.Value,
499+
vals.ExternalAuthConfigs.Value,
583500
vals.AccessURL.Value(),
584501
)
585502
if err != nil {
@@ -2246,3 +2163,101 @@ func ConfigureHTTPServers(inv *clibase.Invocation, cfg *codersdk.DeploymentValue
22462163

22472164
return httpServers, nil
22482165
}
2166+
2167+
// ReadExternalAuthProvidersFromEnv is provided for compatibility purposes with
2168+
// the viper CLI.
2169+
func ReadExternalAuthProvidersFromEnv(environ []string) ([]codersdk.ExternalAuthConfig, error) {
2170+
providers, err := readExternalAuthProvidersFromEnv("CODER_EXTERNAL_AUTH_", environ)
2171+
if err != nil {
2172+
return nil, err
2173+
}
2174+
// Deprecated: To support legacy git auth!
2175+
gitProviders, err := readExternalAuthProvidersFromEnv("CODER_GITAUTH_", environ)
2176+
if err != nil {
2177+
return nil, err
2178+
}
2179+
return append(providers, gitProviders...), nil
2180+
}
2181+
2182+
// readExternalAuthProvidersFromEnv consumes environment variables to parse
2183+
// external auth providers. A prefix is provided to support the legacy
2184+
// parsing of `GITAUTH` environment variables.
2185+
func readExternalAuthProvidersFromEnv(prefix string, environ []string) ([]codersdk.ExternalAuthConfig, error) {
2186+
// The index numbers must be in-order.
2187+
sort.Strings(environ)
2188+
2189+
var providers []codersdk.ExternalAuthConfig
2190+
for _, v := range clibase.ParseEnviron(environ, prefix) {
2191+
tokens := strings.SplitN(v.Name, "_", 2)
2192+
if len(tokens) != 2 {
2193+
return nil, xerrors.Errorf("invalid env var: %s", v.Name)
2194+
}
2195+
2196+
providerNum, err := strconv.Atoi(tokens[0])
2197+
if err != nil {
2198+
return nil, xerrors.Errorf("parse number: %s", v.Name)
2199+
}
2200+
2201+
var provider codersdk.ExternalAuthConfig
2202+
switch {
2203+
case len(providers) < providerNum:
2204+
return nil, xerrors.Errorf(
2205+
"provider num %v skipped: %s",
2206+
len(providers),
2207+
v.Name,
2208+
)
2209+
case len(providers) == providerNum:
2210+
// At the next next provider.
2211+
providers = append(providers, provider)
2212+
case len(providers) == providerNum+1:
2213+
// At the current provider.
2214+
provider = providers[providerNum]
2215+
}
2216+
2217+
key := tokens[1]
2218+
switch key {
2219+
case "ID":
2220+
provider.ID = v.Value
2221+
case "TYPE":
2222+
provider.Type = v.Value
2223+
case "CLIENT_ID":
2224+
provider.ClientID = v.Value
2225+
case "CLIENT_SECRET":
2226+
provider.ClientSecret = v.Value
2227+
case "AUTH_URL":
2228+
provider.AuthURL = v.Value
2229+
case "TOKEN_URL":
2230+
provider.TokenURL = v.Value
2231+
case "VALIDATE_URL":
2232+
provider.ValidateURL = v.Value
2233+
case "REGEX":
2234+
provider.Regex = v.Value
2235+
case "DEVICE_FLOW":
2236+
b, err := strconv.ParseBool(v.Value)
2237+
if err != nil {
2238+
return nil, xerrors.Errorf("parse bool: %s", v.Value)
2239+
}
2240+
provider.DeviceFlow = b
2241+
case "DEVICE_CODE_URL":
2242+
provider.DeviceCodeURL = v.Value
2243+
case "NO_REFRESH":
2244+
b, err := strconv.ParseBool(v.Value)
2245+
if err != nil {
2246+
return nil, xerrors.Errorf("parse bool: %s", v.Value)
2247+
}
2248+
provider.NoRefresh = b
2249+
case "SCOPES":
2250+
provider.Scopes = strings.Split(v.Value, " ")
2251+
case "APP_INSTALL_URL":
2252+
provider.AppInstallURL = v.Value
2253+
case "APP_INSTALLATIONS_URL":
2254+
provider.AppInstallationsURL = v.Value
2255+
case "DISPLAY_NAME":
2256+
provider.DisplayName = v.Value
2257+
case "DISPLAY_ICON":
2258+
provider.DisplayIcon = v.Value
2259+
}
2260+
providers[providerNum] = provider
2261+
}
2262+
return providers, nil
2263+
}

cli/server_test.go

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,27 +49,66 @@ import (
4949
"github.com/coder/coder/v2/testutil"
5050
)
5151

52+
func TestReadExternalAuthProvidersFromEnv(t *testing.T) {
53+
t.Parallel()
54+
t.Run("Valid", func(t *testing.T) {
55+
t.Parallel()
56+
providers, err := cli.ReadExternalAuthProvidersFromEnv([]string{
57+
"CODER_EXTERNAL_AUTH_0_ID=1",
58+
"CODER_EXTERNAL_AUTH_0_TYPE=gitlab",
59+
"CODER_EXTERNAL_AUTH_1_ID=2",
60+
"CODER_EXTERNAL_AUTH_1_CLIENT_ID=sid",
61+
"CODER_EXTERNAL_AUTH_1_CLIENT_SECRET=hunter12",
62+
"CODER_EXTERNAL_AUTH_1_TOKEN_URL=google.com",
63+
"CODER_EXTERNAL_AUTH_1_VALIDATE_URL=bing.com",
64+
"CODER_EXTERNAL_AUTH_1_SCOPES=repo:read repo:write",
65+
"CODER_EXTERNAL_AUTH_1_NO_REFRESH=true",
66+
"CODER_EXTERNAL_AUTH_1_DISPLAY_NAME=Google",
67+
"CODER_EXTERNAL_AUTH_1_DISPLAY_ICON=/icon/google.svg",
68+
})
69+
require.NoError(t, err)
70+
require.Len(t, providers, 2)
71+
72+
// Validate the first provider.
73+
assert.Equal(t, "1", providers[0].ID)
74+
assert.Equal(t, "gitlab", providers[0].Type)
75+
76+
// Validate the second provider.
77+
assert.Equal(t, "2", providers[1].ID)
78+
assert.Equal(t, "sid", providers[1].ClientID)
79+
assert.Equal(t, "hunter12", providers[1].ClientSecret)
80+
assert.Equal(t, "google.com", providers[1].TokenURL)
81+
assert.Equal(t, "bing.com", providers[1].ValidateURL)
82+
assert.Equal(t, []string{"repo:read", "repo:write"}, providers[1].Scopes)
83+
assert.Equal(t, true, providers[1].NoRefresh)
84+
assert.Equal(t, "Google", providers[1].DisplayName)
85+
assert.Equal(t, "/icon/google.svg", providers[1].DisplayIcon)
86+
})
87+
}
88+
89+
// TestReadGitAuthProvidersFromEnv ensures that the deprecated `CODER_GITAUTH_`
90+
// environment variables are still supported.
5291
func TestReadGitAuthProvidersFromEnv(t *testing.T) {
5392
t.Parallel()
5493
t.Run("Empty", func(t *testing.T) {
5594
t.Parallel()
56-
providers, err := cli.ReadGitAuthProvidersFromEnv([]string{
95+
providers, err := cli.ReadExternalAuthProvidersFromEnv([]string{
5796
"HOME=/home/frodo",
5897
})
5998
require.NoError(t, err)
6099
require.Empty(t, providers)
61100
})
62101
t.Run("InvalidKey", func(t *testing.T) {
63102
t.Parallel()
64-
providers, err := cli.ReadGitAuthProvidersFromEnv([]string{
103+
providers, err := cli.ReadExternalAuthProvidersFromEnv([]string{
65104
"CODER_GITAUTH_XXX=invalid",
66105
})
67106
require.Error(t, err, "providers: %+v", providers)
68107
require.Empty(t, providers)
69108
})
70109
t.Run("SkipKey", func(t *testing.T) {
71110
t.Parallel()
72-
providers, err := cli.ReadGitAuthProvidersFromEnv([]string{
111+
providers, err := cli.ReadExternalAuthProvidersFromEnv([]string{
73112
"CODER_GITAUTH_0_ID=invalid",
74113
"CODER_GITAUTH_2_ID=invalid",
75114
})
@@ -78,7 +117,7 @@ func TestReadGitAuthProvidersFromEnv(t *testing.T) {
78117
})
79118
t.Run("Valid", func(t *testing.T) {
80119
t.Parallel()
81-
providers, err := cli.ReadGitAuthProvidersFromEnv([]string{
120+
providers, err := cli.ReadExternalAuthProvidersFromEnv([]string{
82121
"CODER_GITAUTH_0_ID=1",
83122
"CODER_GITAUTH_0_TYPE=gitlab",
84123
"CODER_GITAUTH_1_ID=2",

0 commit comments

Comments
 (0)