@@ -12,12 +12,15 @@ import (
12
12
"time"
13
13
14
14
"github.com/coreos/go-oidc/v3/oidc"
15
- "github.com/golang-jwt/jwt"
15
+ "github.com/golang-jwt/jwt/v4 "
16
16
"github.com/stretchr/testify/assert"
17
17
"github.com/stretchr/testify/require"
18
18
"golang.org/x/oauth2"
19
19
"golang.org/x/xerrors"
20
20
21
+ "github.com/coder/coder/v2/coderd"
22
+ "github.com/coder/coder/v2/coderd/coderdtest"
23
+ "github.com/coder/coder/v2/coderd/coderdtest/oidctest"
21
24
"github.com/coder/coder/v2/coderd/oauthpki"
22
25
"github.com/coder/coder/v2/testutil"
23
26
)
@@ -123,6 +126,57 @@ func TestAzureADPKIOIDC(t *testing.T) {
123
126
require .Error (t , err , "error expected" )
124
127
}
125
128
129
+ // TestAzureAKPKIWithCoderd uses a fake IDP and a real Coderd to test PKI auth.
130
+ func TestAzureAKPKIWithCoderd (t * testing.T ) {
131
+ t .Parallel ()
132
+
133
+ scopes := []string {"openid" , "email" , "profile" , "offline_access" }
134
+ fake := oidctest .NewFakeIDP (t ,
135
+ oidctest .WithIssuer ("https://login.microsoftonline.com/fake_app" ),
136
+ oidctest .WithCustomClientAuth (func (t testing.TB , req * http.Request ) (url.Values , error ) {
137
+ values := assertJWTAuth (t , req )
138
+ if values == nil {
139
+ return nil , xerrors .New ("authorizatin failed in request" )
140
+ }
141
+ return values , nil
142
+ }),
143
+ oidctest .WithServing (),
144
+ )
145
+ cfg := fake .OIDCConfig (t , scopes , func (cfg * coderd.OIDCConfig ) {
146
+ cfg .AllowSignups = true
147
+ })
148
+
149
+ oauthCfg := cfg .OAuth2Config .(* oauth2.Config )
150
+ // Create the oauthpki config
151
+ pki , err := oauthpki .NewOauth2PKIConfig (oauthpki.ConfigParams {
152
+ ClientID : oauthCfg .ClientID ,
153
+ TokenURL : oauthCfg .Endpoint .TokenURL ,
154
+ Scopes : scopes ,
155
+ PemEncodedKey : []byte (testClientKey ),
156
+ PemEncodedCert : []byte (testClientCert ),
157
+ Config : oauthCfg ,
158
+ })
159
+ require .NoError (t , err )
160
+ cfg .OAuth2Config = pki
161
+
162
+ owner , _ , api := coderdtest .NewWithAPI (t , & coderdtest.Options {
163
+ OIDCConfig : cfg ,
164
+ })
165
+
166
+ // Create a user and login
167
+ const email = "alice@coder.com"
168
+ claims := jwt.MapClaims {
169
+ "email" : email ,
170
+ }
171
+ helper := oidctest .NewLoginHelper (owner , fake )
172
+ user , _ := helper .Login (t , claims )
173
+
174
+ // Try refreshing the token more than once.
175
+ for i := 0 ; i < 2 ; i ++ {
176
+ helper .ForceRefresh (t , api .Database , user , claims )
177
+ }
178
+ }
179
+
126
180
// TestSavedAzureADPKIOIDC was created by capturing actual responses from an Azure
127
181
// AD instance and saving them to replay, removing some details.
128
182
// The reason this is done is that this is the only way to assert values
@@ -269,7 +323,7 @@ func (f fakeRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
269
323
270
324
// assertJWTAuth will assert the basic JWT auth assertions. It will return the
271
325
// url.Values from the request body for any additional assertions to be made.
272
- func assertJWTAuth (t * testing.T , r * http.Request ) url.Values {
326
+ func assertJWTAuth (t testing.TB , r * http.Request ) url.Values {
273
327
body , err := io .ReadAll (r .Body )
274
328
if ! assert .NoError (t , err ) {
275
329
return nil
0 commit comments