Skip to content

chore: improve fake IDP script #11602

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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jan 15, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add logging
  • Loading branch information
Emyrk committed Jan 12, 2024
commit 978601cc3a2126c3efe6a936aafc8f0416c071f7
5 changes: 5 additions & 0 deletions coderd/coderdtest/oidctest/idp.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ func (f *FakeIDP) updateIssuerURL(t testing.TB, issuer string) {
Algorithms: []string{
"RS256",
},
ExternalAuthURL: u.ResolveReference(&url.URL{Path: fmt.Sprintf("/external-auth-validate/%s", f.externalProviderID)}).String(),
}
}

Expand Down Expand Up @@ -529,6 +530,8 @@ type ProviderJSON struct {
JWKSURL string `json:"jwks_uri"`
UserInfoURL string `json:"userinfo_endpoint"`
Algorithms []string `json:"id_token_signing_alg_values_supported"`
// This is custom
ExternalAuthURL string `json:"exteral_auth_url"`
}

// newCode enforces the code exchanged is actually a valid code
Expand Down Expand Up @@ -999,6 +1002,7 @@ func (f *FakeIDP) ExternalAuthConfig(t testing.TB, id string, custom *ExternalAu
}
instrumentF := promoauth.NewFactory(prometheus.NewRegistry())
cfg := &externalauth.Config{
DisplayName: id,
InstrumentedOAuth2Config: instrumentF.New(f.clientID, f.OIDCConfig(t, nil)),
ID: id,
// No defaults for these fields by omitting the type
Expand All @@ -1011,6 +1015,7 @@ func (f *FakeIDP) ExternalAuthConfig(t testing.TB, id string, custom *ExternalAu
for _, opt := range opts {
opt(cfg)
}
f.updateIssuerURL(t, f.issuer)
return cfg
}

Expand Down
48 changes: 45 additions & 3 deletions scripts/testidp/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"encoding/json"
"flag"
"log"
"os"
Expand All @@ -9,15 +10,21 @@ import (
"time"

"github.com/golang-jwt/jwt/v4"
"github.com/stretchr/testify/require"

"cdr.dev/slog"
"cdr.dev/slog/sloggers/sloghuman"
"github.com/coder/coder/v2/coderd/coderdtest/oidctest"
"github.com/coder/coder/v2/codersdk"
)

// Flags
var (
expiry = flag.Duration("expiry", time.Minute*5, "Token expiry")
clientID = flag.String("client-id", "static-client-id", "Client ID, set empty to be random")
clientSecret = flag.String("client-sec", "static-client-secret", "Client Secret, set empty to be random")
// By default, no regex means it will never match anything. So at least default to matching something.
extRegex = flag.String("ext-regex", `^(https?://)?example\.com(/.*)?$`, "External auth regex")
)

func main() {
Expand All @@ -37,6 +44,12 @@ func main() {
}, nil, nil)
}

type withClientSecret struct {
// We never unmarshal this in prod, but we need this field for testing.
ClientSecret string `json:"client_secret"`
codersdk.ExternalAuthConfig
}

// RunIDP needs the testing.T because our oidctest package requires the
// testing.T.
func RunIDP() func(t *testing.T) {
Expand All @@ -48,15 +61,44 @@ func RunIDP() func(t *testing.T) {
oidctest.WithDefaultExpire(*expiry),
oidctest.WithStaticCredentials(*clientID, *clientSecret),
oidctest.WithIssuer("http://localhost:4500"),
oidctest.WithLogger(slog.Make(sloghuman.Sink(os.Stderr))),
)
id, sec := idp.AppCredentials()
prov := idp.WellknownConfig()
const appID = "fake"
coderCfg := idp.ExternalAuthConfig(t, appID, nil)

log.Println("IDP Issuer URL", idp.IssuerURL())
log.Println("Coderd Flags")
log.Printf(`--external-auth-providers='[{"type":"fake","client_id":"%s","client_secret":"%s","auth_url":"%s","token_url":"%s","validate_url":"%s","scopes":["openid","email","profile"]}]'`,
id, sec, prov.AuthURL, prov.TokenURL, prov.UserInfoURL,
)
deviceCodeURL := ""
if coderCfg.DeviceAuth != nil {
deviceCodeURL = coderCfg.DeviceAuth.CodeURL
}
cfg := withClientSecret{
ClientSecret: sec,
ExternalAuthConfig: codersdk.ExternalAuthConfig{
Type: appID,
ClientID: id,
ClientSecret: sec,
ID: appID,
AuthURL: prov.AuthURL,
TokenURL: prov.TokenURL,
ValidateURL: prov.ExternalAuthURL,
AppInstallURL: coderCfg.AppInstallURL,
AppInstallationsURL: coderCfg.AppInstallationsURL,
NoRefresh: false,
Scopes: []string{"openid", "email", "profile"},
ExtraTokenKeys: coderCfg.ExtraTokenKeys,
DeviceFlow: coderCfg.DeviceAuth != nil,
DeviceCodeURL: deviceCodeURL,
Regex: *extRegex,
DisplayName: coderCfg.DisplayName,
DisplayIcon: coderCfg.DisplayIcon,
},
}
data, err := json.Marshal([]withClientSecret{cfg})
require.NoError(t, err)
log.Printf(`--external-auth-providers='%s'`, string(data))

log.Println("Press Ctrl+C to exit")
c := make(chan os.Signal, 1)
Expand Down