Skip to content

Commit 56ef00f

Browse files
committed
chore: yaml parsing for external auth configs
1 parent a6901ae commit 56ef00f

File tree

3 files changed

+109
-17
lines changed

3 files changed

+109
-17
lines changed

codersdk/deployment.go

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -329,33 +329,33 @@ type TraceConfig struct {
329329

330330
type ExternalAuthConfig struct {
331331
// Type is the type of external auth config.
332-
Type string `json:"type"`
333-
ClientID string `json:"client_id"`
332+
Type string `json:"type" yaml:"type"`
333+
ClientID string `json:"client_id" yaml:"client_id"`
334334
ClientSecret string `json:"-" yaml:"client_secret"`
335335
// ID is a unique identifier for the auth config.
336336
// It defaults to `type` when not provided.
337-
ID string `json:"id"`
338-
AuthURL string `json:"auth_url"`
339-
TokenURL string `json:"token_url"`
340-
ValidateURL string `json:"validate_url"`
341-
AppInstallURL string `json:"app_install_url"`
342-
AppInstallationsURL string `json:"app_installations_url"`
343-
NoRefresh bool `json:"no_refresh"`
344-
Scopes []string `json:"scopes"`
345-
ExtraTokenKeys []string `json:"extra_token_keys"`
346-
DeviceFlow bool `json:"device_flow"`
347-
DeviceCodeURL string `json:"device_code_url"`
337+
ID string `json:"id" yaml:"id"`
338+
AuthURL string `json:"auth_url" yaml:"auth_url"`
339+
TokenURL string `json:"token_url" yaml:"token_url"`
340+
ValidateURL string `json:"validate_url" yaml:"validate_url"`
341+
AppInstallURL string `json:"app_install_url" yaml:"app_install_url"`
342+
AppInstallationsURL string `json:"app_installations_url" yaml:"app_installations_url"`
343+
NoRefresh bool `json:"no_refresh" yaml:"no_refresh"`
344+
Scopes []string `json:"scopes" yaml:"scopes"`
345+
ExtraTokenKeys []string `json:"extra_token_keys" yaml:"extra_token_keys"`
346+
DeviceFlow bool `json:"device_flow" yaml:"device_flow"`
347+
DeviceCodeURL string `json:"device_code_url" yaml:"device_code_url"`
348348
// Regex allows API requesters to match an auth config by
349349
// a string (e.g. coder.com) instead of by it's type.
350350
//
351351
// Git clone makes use of this by parsing the URL from:
352352
// 'Username for "https://github.com":'
353353
// And sending it to the Coder server to match against the Regex.
354-
Regex string `json:"regex"`
354+
Regex string `json:"regex" yaml:"regex"`
355355
// DisplayName is shown in the UI to identify the auth config.
356-
DisplayName string `json:"display_name"`
356+
DisplayName string `json:"display_name" yaml:"display_name"`
357357
// DisplayIcon is a URL to an icon to display in the UI.
358-
DisplayIcon string `json:"display_icon"`
358+
DisplayIcon string `json:"display_icon" yaml:"display_icon"`
359359
}
360360

361361
type ProvisionerConfig struct {
@@ -1788,7 +1788,7 @@ Write out the current server config as YAML to stdout.`,
17881788
Description: "External Authentication providers.",
17891789
// We need extra scrutiny to ensure this works, is documented, and
17901790
// tested before enabling.
1791-
// YAML: "gitAuthProviders",
1791+
YAML: "externalAuthProviders",
17921792
Value: &c.ExternalAuthConfigs,
17931793
Hidden: true,
17941794
},

codersdk/deployment_test.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package codersdk_test
22

33
import (
4+
"embed"
5+
"fmt"
46
"strings"
57
"testing"
68
"time"
79

810
"github.com/stretchr/testify/require"
11+
"gopkg.in/yaml.v3"
912

1013
"github.com/coder/coder/v2/cli/clibase"
1114
"github.com/coder/coder/v2/codersdk"
@@ -277,3 +280,69 @@ func TestDeploymentValues_DurationFormatNanoseconds(t *testing.T) {
277280
t.FailNow()
278281
}
279282
}
283+
284+
//go:embed testdata/*
285+
var testData embed.FS
286+
287+
func TestExternalAuthYAMLConfig(t *testing.T) {
288+
t.Parallel()
289+
290+
file := func(t *testing.T, name string) string {
291+
data, err := testData.ReadFile(fmt.Sprintf("testdata/%s", name))
292+
require.NoError(t, err, "read testdata file %q", name)
293+
return string(data)
294+
}
295+
296+
testCases := []struct {
297+
Name string
298+
YAML string
299+
Expected []codersdk.ExternalAuthConfig
300+
}{
301+
{
302+
Name: "GitHub",
303+
YAML: file(t, "githubcfg.yaml"),
304+
Expected: []codersdk.ExternalAuthConfig{
305+
{
306+
Type: "github",
307+
ClientID: "client_id",
308+
ClientSecret: "client_secret",
309+
ID: "id",
310+
AuthURL: "https://example.com/auth",
311+
TokenURL: "https://example.com/token",
312+
ValidateURL: "https://example.com/validate",
313+
AppInstallURL: "https://example.com/install",
314+
AppInstallationsURL: "https://example.com/installations",
315+
NoRefresh: true,
316+
Scopes: []string{"user:email", "read:org"},
317+
ExtraTokenKeys: []string{"extra", "token"},
318+
DeviceFlow: true,
319+
DeviceCodeURL: "https://example.com/device",
320+
Regex: "^https://example.com/.*$",
321+
DisplayName: "GitHub",
322+
DisplayIcon: "/static/icons/github.svg",
323+
},
324+
},
325+
},
326+
}
327+
328+
for _, c := range testCases {
329+
c := c
330+
t.Run(c.Name, func(t *testing.T) {
331+
t.Parallel()
332+
333+
dv := codersdk.DeploymentValues{}
334+
opts := dv.Options()
335+
c.YAML = strings.ReplaceAll(c.YAML, "\t", " ")
336+
337+
// This is the order things are done in the cli, so just
338+
// keep it the same.
339+
var n yaml.Node
340+
err := yaml.Unmarshal([]byte(c.YAML), &n)
341+
require.NoError(t, err)
342+
343+
err = n.Decode(&opts)
344+
require.NoError(t, err)
345+
require.ElementsMatchf(t, c.Expected, dv.ExternalAuthConfigs.Value, "from yaml")
346+
})
347+
}
348+
}

codersdk/testdata/githubcfg.yaml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
externalAuthProviders:
2+
- type: github
3+
client_id: client_id
4+
client_secret: client_secret
5+
id: id
6+
auth_url: https://example.com/auth
7+
token_url: https://example.com/token
8+
validate_url: https://example.com/validate
9+
app_install_url: https://example.com/install
10+
app_installations_url: https://example.com/installations
11+
no_refresh: true
12+
scopes:
13+
- user:email
14+
- read:org
15+
extra_token_keys:
16+
- extra
17+
- token
18+
device_flow: true
19+
device_code_url: https://example.com/device
20+
regex: ^https://example.com/.*$
21+
display_name: GitHub
22+
display_icon: /static/icons/github.svg
23+

0 commit comments

Comments
 (0)