- Notifications
You must be signed in to change notification settings - Fork925
chore: implement yaml parsing for external auth configs#11268
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,16 @@ | ||
package codersdk_test | ||
import ( | ||
"bytes" | ||
"embed" | ||
"fmt" | ||
"runtime" | ||
"strings" | ||
"testing" | ||
"time" | ||
"github.com/stretchr/testify/require" | ||
"gopkg.in/yaml.v3" | ||
"github.com/coder/coder/v2/cli/clibase" | ||
"github.com/coder/coder/v2/codersdk" | ||
@@ -277,3 +282,78 @@ func TestDeploymentValues_DurationFormatNanoseconds(t *testing.T) { | ||
t.FailNow() | ||
} | ||
} | ||
//go:embed testdata/* | ||
var testData embed.FS | ||
func TestExternalAuthYAMLConfig(t *testing.T) { | ||
t.Parallel() | ||
if runtime.GOOS == "windows" { | ||
// The windows marshal function uses different line endings. | ||
// Not worth the effort getting this to work on windows. | ||
t.SkipNow() | ||
} | ||
file := func(t *testing.T, name string) string { | ||
data, err := testData.ReadFile(fmt.Sprintf("testdata/%s", name)) | ||
require.NoError(t, err, "read testdata file %q", name) | ||
return string(data) | ||
} | ||
githubCfg := codersdk.ExternalAuthConfig{ | ||
Type: "github", | ||
ClientID: "client_id", | ||
ClientSecret: "client_secret", | ||
ID: "id", | ||
AuthURL: "https://example.com/auth", | ||
TokenURL: "https://example.com/token", | ||
ValidateURL: "https://example.com/validate", | ||
AppInstallURL: "https://example.com/install", | ||
AppInstallationsURL: "https://example.com/installations", | ||
NoRefresh: true, | ||
Scopes: []string{"user:email", "read:org"}, | ||
ExtraTokenKeys: []string{"extra", "token"}, | ||
DeviceFlow: true, | ||
DeviceCodeURL: "https://example.com/device", | ||
Regex: "^https://example.com/.*$", | ||
DisplayName: "GitHub", | ||
DisplayIcon: "/static/icons/github.svg", | ||
} | ||
Comment on lines +303 to +321 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Instead of hard-coding this and having to keep it in sync with the golden file, how about marshalling and unmarshalling the config to/from YAML and asserting that the two are the same byte-for-byte? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. I can do both, but I should still have the golden file imo. The actual struct is | ||
// Input the github section twice for testing a slice of configs. | ||
inputYAML := func() string { | ||
f := file(t, "githubcfg.yaml") | ||
lines := strings.SplitN(f, "\n", 2) | ||
// Append github config twice | ||
return f + lines[1] | ||
}() | ||
expected := []codersdk.ExternalAuthConfig{ | ||
githubCfg, githubCfg, | ||
} | ||
dv := codersdk.DeploymentValues{} | ||
opts := dv.Options() | ||
// replace any tabs with the proper space indentation | ||
inputYAML = strings.ReplaceAll(inputYAML, "\t", " ") | ||
// This is the order things are done in the cli, so just | ||
// keep it the same. | ||
var n yaml.Node | ||
err := yaml.Unmarshal([]byte(inputYAML), &n) | ||
require.NoError(t, err) | ||
err = n.Decode(&opts) | ||
require.NoError(t, err) | ||
require.ElementsMatchf(t, expected, dv.ExternalAuthConfigs.Value, "from yaml") | ||
var out bytes.Buffer | ||
enc := yaml.NewEncoder(&out) | ||
enc.SetIndent(2) | ||
err = enc.Encode(dv.ExternalAuthConfigs) | ||
require.NoError(t, err) | ||
// Because we only marshal the 1 section, the correct section name is not applied. | ||
output := strings.Replace(out.String(), "value:", "externalAuthProviders:", 1) | ||
require.Equal(t, inputYAML, output, "re-marshaled is the same as input") | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
externalAuthProviders: | ||
- type: github | ||
client_id: client_id | ||
client_secret: client_secret | ||
id: id | ||
auth_url: https://example.com/auth | ||
token_url: https://example.com/token | ||
validate_url: https://example.com/validate | ||
app_install_url: https://example.com/install | ||
app_installations_url: https://example.com/installations | ||
no_refresh: true | ||
scopes: | ||
- user:email | ||
- read:org | ||
extra_token_keys: | ||
- extra | ||
- token | ||
device_flow: true | ||
device_code_url: https://example.com/device | ||
regex: ^https://example.com/.*$ | ||
display_name: GitHub | ||
display_icon: /static/icons/github.svg |