77package oauthex
88
99import (
10+ "context"
1011 "encoding/json"
12+ "net/http"
13+ "net/http/httptest"
14+ "net/url"
1115 "os"
1216 "path/filepath"
17+ "strings"
1318 "testing"
1419)
1520
@@ -28,3 +33,88 @@ func TestAuthMetaParse(t *testing.T) {
2833 t .Errorf ("got %q, want %q" , g , w )
2934 }
3035}
36+
37+ func TestGetAuthServerMetaPKCESupport (t * testing.T ) {
38+ ctx := context .Background ()
39+ tests := []struct {
40+ name string
41+ hasPKCESupport bool
42+ wantError string
43+ }{
44+ {
45+ name : "server_with_pkce_support" ,
46+ hasPKCESupport : true ,
47+ },
48+ {
49+ name : "server_without_pkce_support" ,
50+ hasPKCESupport : false ,
51+ wantError : "does not implement PKCE" ,
52+ },
53+ }
54+
55+ for _ , tt := range tests {
56+ t .Run (tt .name , func (t * testing.T ) {
57+ // Start a fake OAuth 2.1 auth server
58+ wrapper := http .NewServeMux ()
59+ wrapper .HandleFunc ("/.well-known/oauth-authorization-server" , func (w http.ResponseWriter , r * http.Request ) {
60+ u , _ := url .Parse ("https://" + r .Host )
61+ issuer := "https://localhost:" + u .Port ()
62+ metadata := AuthServerMeta {
63+ Issuer : issuer ,
64+ AuthorizationEndpoint : issuer + "/authorize" ,
65+ TokenEndpoint : issuer + "/token" ,
66+ RegistrationEndpoint : issuer + "/register" ,
67+ JWKSURI : issuer + "/.well-known/jwks.json" ,
68+ ScopesSupported : []string {"openid" , "profile" , "email" },
69+ ResponseTypesSupported : []string {"code" },
70+ GrantTypesSupported : []string {"authorization_code" },
71+ TokenEndpointAuthMethodsSupported : []string {"none" },
72+ }
73+
74+ // Add PKCE support based on test case
75+ if tt .hasPKCESupport {
76+ metadata .CodeChallengeMethodsSupported = []string {"S256" }
77+ }
78+ // If hasPKCESupport is false, CodeChallengeMethodsSupported remains empty
79+
80+ w .Header ().Set ("Content-Type" , "application/json" )
81+ json .NewEncoder (w ).Encode (metadata )
82+ })
83+ ts := httptest .NewTLSServer (wrapper )
84+ defer ts .Close ()
85+
86+ // The fake server sets issuer to https://localhost:<port>, so compute that issuer.
87+ u , _ := url .Parse (ts .URL )
88+ issuer := "https://localhost:" + u .Port ()
89+
90+ // The fake server presents a cert for example.com; set ServerName accordingly.
91+ httpClient := ts .Client ()
92+ if tr , ok := httpClient .Transport .(* http.Transport ); ok {
93+ clone := tr .Clone ()
94+ clone .TLSClientConfig .ServerName = "example.com"
95+ httpClient .Transport = clone
96+ }
97+
98+ meta , err := GetAuthServerMeta (ctx , issuer , httpClient )
99+ if tt .wantError != "" {
100+ if err == nil {
101+ t .Fatal ("wanted error but got none" )
102+ }
103+ if ! strings .Contains (err .Error (), tt .wantError ) {
104+ t .Errorf ("wanted error to contain %q, but got: %v" , tt .wantError , err )
105+ }
106+ } else {
107+ if err != nil {
108+ t .Fatalf ("unwanted error: %v" , err )
109+ }
110+ if meta == nil {
111+ t .Fatal ("wanted metadata but got nil" )
112+ }
113+ // Verify PKCE support is present
114+ if len (meta .CodeChallengeMethodsSupported ) == 0 {
115+ t .Error ("wanted PKCE support but CodeChallengeMethodsSupported is empty" )
116+ }
117+ }
118+ })
119+ }
120+ }
0 commit comments