137 lines
3.0 KiB
Go
137 lines
3.0 KiB
Go
package auth_test
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"chat-switchboard/auth"
|
|
)
|
|
|
|
func TestOIDCProvider_Discovery(t *testing.T) {
|
|
idp := newMockIdP()
|
|
defer idp.Close()
|
|
|
|
p, err := auth.NewOIDCProvider(auth.OIDCConfig{
|
|
IssuerURL: idp.IssuerURL(),
|
|
ClientID: "switchboard",
|
|
ClientSecret: "secret",
|
|
AutoActivate: true,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("NewOIDCProvider: %v", err)
|
|
}
|
|
|
|
disc := p.Discovery()
|
|
if disc == nil {
|
|
t.Fatal("discovery should not be nil")
|
|
}
|
|
if disc.JWKSUri == "" {
|
|
t.Error("JWKS URI should not be empty")
|
|
}
|
|
if disc.TokenEndpoint == "" {
|
|
t.Error("token endpoint should not be empty")
|
|
}
|
|
}
|
|
|
|
func TestOIDCProvider_Mode(t *testing.T) {
|
|
idp := newMockIdP()
|
|
defer idp.Close()
|
|
|
|
p, err := auth.NewOIDCProvider(auth.OIDCConfig{
|
|
IssuerURL: idp.IssuerURL(),
|
|
ClientID: "switchboard",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("NewOIDCProvider: %v", err)
|
|
}
|
|
|
|
if p.Mode() != auth.ModeOIDC {
|
|
t.Errorf("Mode() = %q, want %q", p.Mode(), auth.ModeOIDC)
|
|
}
|
|
}
|
|
|
|
func TestOIDCProvider_NoRegistration(t *testing.T) {
|
|
idp := newMockIdP()
|
|
defer idp.Close()
|
|
|
|
p, err := auth.NewOIDCProvider(auth.OIDCConfig{
|
|
IssuerURL: idp.IssuerURL(),
|
|
ClientID: "switchboard",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("NewOIDCProvider: %v", err)
|
|
}
|
|
|
|
if p.SupportsRegistration() {
|
|
t.Error("OIDC should not support registration")
|
|
}
|
|
}
|
|
|
|
func TestOIDCProvider_MissingIssuer(t *testing.T) {
|
|
_, err := auth.NewOIDCProvider(auth.OIDCConfig{
|
|
ClientID: "switchboard",
|
|
})
|
|
if err == nil {
|
|
t.Error("expected error for missing issuer URL")
|
|
}
|
|
}
|
|
|
|
func TestOIDCProvider_MissingClientID(t *testing.T) {
|
|
idp := newMockIdP()
|
|
defer idp.Close()
|
|
|
|
_, err := auth.NewOIDCProvider(auth.OIDCConfig{
|
|
IssuerURL: idp.IssuerURL(),
|
|
})
|
|
if err == nil {
|
|
t.Error("expected error for missing client ID")
|
|
}
|
|
}
|
|
|
|
func TestOIDCProvider_AuthorizationURL(t *testing.T) {
|
|
idp := newMockIdP()
|
|
defer idp.Close()
|
|
|
|
p, err := auth.NewOIDCProvider(auth.OIDCConfig{
|
|
IssuerURL: idp.IssuerURL(),
|
|
ClientID: "switchboard",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("NewOIDCProvider: %v", err)
|
|
}
|
|
|
|
url := p.AuthorizationURL("test-state", "test-nonce", "http://localhost/callback")
|
|
if url == "" {
|
|
t.Fatal("AuthorizationURL should not be empty")
|
|
}
|
|
|
|
// Should contain the required OIDC parameters
|
|
for _, want := range []string{"response_type=code", "client_id=switchboard", "state=test-state", "nonce=test-nonce"} {
|
|
if !containsStr(url, want) {
|
|
t.Errorf("AuthorizationURL missing %q in %q", want, url)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestOIDCProvider_UnreachableIssuer(t *testing.T) {
|
|
_, err := auth.NewOIDCProvider(auth.OIDCConfig{
|
|
IssuerURL: "http://127.0.0.1:1/unreachable",
|
|
ClientID: "switchboard",
|
|
})
|
|
if err == nil {
|
|
t.Error("expected error for unreachable issuer")
|
|
}
|
|
}
|
|
|
|
func containsStr(s, substr string) bool {
|
|
return len(s) >= len(substr) && (s == substr || len(s) > 0 && containsSubstring(s, substr))
|
|
}
|
|
|
|
func containsSubstring(s, sub string) bool {
|
|
for i := 0; i <= len(s)-len(sub); i++ {
|
|
if s[i:i+len(sub)] == sub {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|