TestAuthCodeWithDefaultStrategy runs proper integration tests against in-memory and database connectors, specifically we test: - [x] If the flow - in general - works - [x] If `authenticatedAt` is properly managed across the lifecycle - [x] The value `authenticatedAt` should be an old time if no use
(t *testing.T)
| 168 | // - [x] If `id_token_hint` is handled properly |
| 169 | // - [x] What happens if `id_token_hint` does not match the value from the handled authentication request ("accept login") |
| 170 | func TestAuthCodeWithDefaultStrategy(t *testing.T) { |
| 171 | t.Parallel() |
| 172 | |
| 173 | ctx := context.Background() |
| 174 | |
| 175 | for dbName, reg := range testhelpers.ConnectDatabases(t, true, driver.WithConfigOptions(configx.WithValues(map[string]any{ |
| 176 | config.KeyAccessTokenStrategy: "opaque", |
| 177 | config.KeyRefreshTokenHook: "", |
| 178 | }))) { |
| 179 | t.Run("registry="+dbName, func(t *testing.T) { |
| 180 | t.Parallel() |
| 181 | |
| 182 | rng := rand.New(rand.NewSource(time.Now().UnixNano())) |
| 183 | |
| 184 | jwk.EnsureAsymmetricKeypairExists(t, reg, string(jose.ES256), x.OpenIDConnectKeyName) |
| 185 | jwk.EnsureAsymmetricKeypairExists(t, reg, string(jose.ES256), x.OAuth2JWTKeyName) |
| 186 | |
| 187 | publicTS, adminTS := testhelpers.NewOAuth2Server(ctx, t, reg) |
| 188 | |
| 189 | publicClient := hydra.NewAPIClient(hydra.NewConfiguration()) |
| 190 | publicClient.GetConfig().Servers = hydra.ServerConfigurations{{URL: publicTS.URL}} |
| 191 | adminClient := hydra.NewAPIClient(hydra.NewConfiguration()) |
| 192 | adminClient.GetConfig().Servers = hydra.ServerConfigurations{{URL: adminTS.URL}} |
| 193 | |
| 194 | assertRefreshToken := func(t *testing.T, token *oauth2.Token, c *oauth2.Config, expectedExp time.Time) gjson.Result { |
| 195 | introspect := testhelpers.IntrospectToken(t, token.RefreshToken, adminTS) |
| 196 | if !expectedExp.IsZero() { |
| 197 | require.WithinDuration(t, expectedExp, time.Unix(introspect.Get("exp").Int(), 0), time.Second*3) |
| 198 | } |
| 199 | return introspect |
| 200 | } |
| 201 | |
| 202 | assertIDToken := func(t *testing.T, token *oauth2.Token, c *oauth2.Config, expectedSubject, expectedNonce string, expectedExp time.Time) gjson.Result { |
| 203 | idt, ok := token.Extra("id_token").(string) |
| 204 | require.True(t, ok) |
| 205 | assert.NotEmpty(t, idt) |
| 206 | |
| 207 | claims := gjson.ParseBytes(testhelpers.InsecureDecodeJWT(t, idt)) |
| 208 | assert.Truef(t, time.Now().After(time.Unix(claims.Get("iat").Int(), 0)), "%s", claims) |
| 209 | assert.Truef(t, time.Now().After(time.Unix(claims.Get("nbf").Int(), 0)), "%s", claims) |
| 210 | assert.Truef(t, time.Now().Before(time.Unix(claims.Get("exp").Int(), 0)), "%s", claims) |
| 211 | if !expectedExp.IsZero() { |
| 212 | // 1.5s due to rounding |
| 213 | require.WithinDuration(t, expectedExp, time.Unix(claims.Get("exp").Int(), 0), 1*time.Second+500*time.Millisecond) |
| 214 | } |
| 215 | assert.NotEmptyf(t, claims.Get("jti").String(), "%s", claims) |
| 216 | assert.EqualValuesf(t, reg.Config().IssuerURL(ctx).String(), claims.Get("iss").String(), "%s", claims) |
| 217 | assert.NotEmptyf(t, claims.Get("sid").String(), "%s", claims) |
| 218 | assert.Equalf(t, "1", claims.Get("acr").String(), "%s", claims) |
| 219 | require.Lenf(t, claims.Get("amr").Array(), 1, "%s", claims) |
| 220 | assert.EqualValuesf(t, "pwd", claims.Get("amr.0").String(), "%s", claims) |
| 221 | |
| 222 | require.Lenf(t, claims.Get("aud").Array(), 1, "%s", claims) |
| 223 | assert.EqualValuesf(t, c.ClientID, claims.Get("aud.0").String(), "%s", claims) |
| 224 | assert.EqualValuesf(t, expectedSubject, claims.Get("sub").String(), "%s", claims) |
| 225 | assert.EqualValuesf(t, expectedNonce, claims.Get("nonce").String(), "%s", claims) |
| 226 | assert.EqualValuesf(t, `baz`, claims.Get("bar").String(), "%s", claims) |
| 227 | assert.EqualValuesf(t, `foo@bar.com`, claims.Get("email").String(), "%s", claims) |
nothing calls this directly
no test coverage detected