chore: dynamically determine gitlab external auth defaults

Static defaults work for github cloud, but not self hosted.
Self hosted setups will now have sane defaults if omitted.
This commit is contained in:
Steven Masley 2024-04-29 14:19:02 -05:00
parent 47993e3fcf
commit 1e461b6a64
No known key found for this signature in database
2 changed files with 146 additions and 9 deletions

View File

@ -563,6 +563,9 @@ func applyDefaultsToConfig(config *codersdk.ExternalAuthConfig) {
// Dynamic defaults
switch codersdk.EnhancedExternalAuthProvider(config.Type) {
case codersdk.EnhancedExternalAuthProviderGitLab:
copyDefaultSettings(config, gitlabDefaults(config))
return
case codersdk.EnhancedExternalAuthProviderBitBucketServer:
copyDefaultSettings(config, bitbucketServerDefaults(config))
return
@ -667,6 +670,44 @@ func bitbucketServerDefaults(config *codersdk.ExternalAuthConfig) codersdk.Exter
return defaults
}
// gitlabDefaults returns a static config if using the gitlab cloud offering.
// The values are dynamic if using a self-hosted gitlab.
// When the decision is not obvious, just defer to the cloud defaults.
// Any user specific fields will override this if provided.
func gitlabDefaults(config *codersdk.ExternalAuthConfig) codersdk.ExternalAuthConfig {
cloud := codersdk.ExternalAuthConfig{
AuthURL: "https://gitlab.com/oauth/authorize",
TokenURL: "https://gitlab.com/oauth/token",
ValidateURL: "https://gitlab.com/oauth/token/info",
DisplayName: "GitLab",
DisplayIcon: "/icon/gitlab.svg",
Regex: `^(https?://)?gitlab\.com(/.*)?$`,
Scopes: []string{"write_repository"},
}
if config.AuthURL == "" || config.AuthURL == cloud.AuthURL {
return cloud
}
au, err := url.Parse(config.AuthURL)
if err != nil || au.Host == "gitlab.com" {
// If the AuthURL is not a valid URL or is using the cloud,
// use the cloud static defaults.
return cloud
}
// At this point, assume it is self-hosted and use the AuthURL
return codersdk.ExternalAuthConfig{
DisplayName: cloud.DisplayName,
Scopes: cloud.Scopes,
DisplayIcon: cloud.DisplayIcon,
AuthURL: au.ResolveReference(&url.URL{Path: "/oauth/authorize"}).String(),
TokenURL: au.ResolveReference(&url.URL{Path: "/oauth/token"}).String(),
ValidateURL: au.ResolveReference(&url.URL{Path: "/oauth/token/info"}).String(),
Regex: fmt.Sprintf(`^(https?://)?%s(/.*)?$`, strings.ReplaceAll(au.Host, ".", `\.`)),
}
}
func jfrogArtifactoryDefaults(config *codersdk.ExternalAuthConfig) codersdk.ExternalAuthConfig {
defaults := codersdk.ExternalAuthConfig{
DisplayName: "JFrog Artifactory",
@ -789,15 +830,6 @@ var staticDefaults = map[codersdk.EnhancedExternalAuthProvider]codersdk.External
Regex: `^(https?://)?bitbucket\.org(/.*)?$`,
Scopes: []string{"account", "repository:write"},
},
codersdk.EnhancedExternalAuthProviderGitLab: {
AuthURL: "https://gitlab.com/oauth/authorize",
TokenURL: "https://gitlab.com/oauth/token",
ValidateURL: "https://gitlab.com/oauth/token/info",
DisplayName: "GitLab",
DisplayIcon: "/icon/gitlab.svg",
Regex: `^(https?://)?gitlab\.com(/.*)?$`,
Scopes: []string{"write_repository"},
},
codersdk.EnhancedExternalAuthProviderGitHub: {
AuthURL: xgithub.Endpoint.AuthURL,
TokenURL: xgithub.Endpoint.TokenURL,

View File

@ -8,6 +8,111 @@ import (
"github.com/coder/coder/v2/codersdk"
)
func TestGitlabDefaults(t *testing.T) {
t.Parallel()
// The default cloud setup. Copying this here as hard coded
// values.
cloud := codersdk.ExternalAuthConfig{
Type: string(codersdk.EnhancedExternalAuthProviderGitLab),
ID: string(codersdk.EnhancedExternalAuthProviderGitLab),
AuthURL: "https://gitlab.com/oauth/authorize",
TokenURL: "https://gitlab.com/oauth/token",
ValidateURL: "https://gitlab.com/oauth/token/info",
DisplayName: "GitLab",
DisplayIcon: "/icon/gitlab.svg",
Regex: `^(https?://)?gitlab\.com(/.*)?$`,
Scopes: []string{"write_repository"},
}
tests := []struct {
name string
input codersdk.ExternalAuthConfig
expected codersdk.ExternalAuthConfig
mutateExpected func(*codersdk.ExternalAuthConfig)
}{
// Cloud
{
name: "OnlyType",
input: codersdk.ExternalAuthConfig{
Type: string(codersdk.EnhancedExternalAuthProviderGitLab),
},
expected: cloud,
},
{
// If someone was to manually configure the gitlab cli.
name: "CloudByConfig",
input: codersdk.ExternalAuthConfig{
Type: string(codersdk.EnhancedExternalAuthProviderGitLab),
AuthURL: "https://gitlab.com/oauth/authorize",
},
expected: cloud,
},
{
// Changing some of the defaults of the cloud option
name: "CloudWithChanges",
input: codersdk.ExternalAuthConfig{
Type: string(codersdk.EnhancedExternalAuthProviderGitLab),
// Adding an extra query param intentionally to break simple
// string comparisons.
AuthURL: "https://gitlab.com/oauth/authorize?foo=bar",
DisplayName: "custom",
Regex: ".*",
},
expected: cloud,
mutateExpected: func(config *codersdk.ExternalAuthConfig) {
config.DisplayName = "custom"
config.Regex = ".*"
},
},
// Self-hosted
{
// Dynamically figures out the Validate, Token, and Regex fields.
name: "SelfHostedOnlyAuthURL",
input: codersdk.ExternalAuthConfig{
Type: string(codersdk.EnhancedExternalAuthProviderGitLab),
AuthURL: "https://gitlab.company.org/oauth/authorize?foo=bar",
},
expected: cloud,
mutateExpected: func(config *codersdk.ExternalAuthConfig) {
config.AuthURL = "https://gitlab.company.org/oauth/authorize?foo=bar"
config.ValidateURL = "https://gitlab.company.org/oauth/token/info"
config.TokenURL = "https://gitlab.company.org/oauth/token"
config.Regex = `^(https?://)?gitlab\.company\.org(/.*)?$`
},
},
{
// Strange values
name: "RandomValues",
input: codersdk.ExternalAuthConfig{
Type: string(codersdk.EnhancedExternalAuthProviderGitLab),
AuthURL: "https://auth.com/auth",
ValidateURL: "https://validate.com/validate",
TokenURL: "https://token.com/token",
Regex: "random",
},
expected: cloud,
mutateExpected: func(config *codersdk.ExternalAuthConfig) {
config.AuthURL = "https://auth.com/auth"
config.ValidateURL = "https://validate.com/validate"
config.TokenURL = "https://token.com/token"
config.Regex = `random`
},
},
}
for _, c := range tests {
c := c
t.Run(c.name, func(t *testing.T) {
t.Parallel()
applyDefaultsToConfig(&c.input)
if c.mutateExpected != nil {
c.mutateExpected(&c.expected)
}
require.Equal(t, c.input, c.expected)
})
}
}
func Test_bitbucketServerConfigDefaults(t *testing.T) {
t.Parallel()