2021-05-04 22:06:05 +00:00
package oidc
import (
2023-04-11 11:29:02 +00:00
"fmt"
2021-05-04 22:06:05 +00:00
"testing"
feat(oidc): add additional config options, accurate token times, and refactoring (#1991)
* This gives admins more control over their OIDC installation exposing options that had defaults before. Things like lifespans for authorize codes, access tokens, id tokens, refresh tokens, a option to enable the debug client messages, minimum parameter entropy. It also allows admins to configure the response modes.
* Additionally this records specific values about a users session indicating when they performed a specific authz factor so this is represented in the token accurately.
* Lastly we also implemented a OIDC key manager which calculates the kid for jwk's using the SHA1 digest instead of being static, or more specifically the first 7 chars. As per https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key#section-8.1.1 the kid should not exceed 8 chars. While it's allowed to exceed 8 chars, it must only be done so with a compelling reason, which we do not have.
2021-07-03 23:44:30 +00:00
"github.com/ory/fosite"
2021-05-04 22:06:05 +00:00
"github.com/stretchr/testify/assert"
feat(oidc): add additional config options, accurate token times, and refactoring (#1991)
* This gives admins more control over their OIDC installation exposing options that had defaults before. Things like lifespans for authorize codes, access tokens, id tokens, refresh tokens, a option to enable the debug client messages, minimum parameter entropy. It also allows admins to configure the response modes.
* Additionally this records specific values about a users session indicating when they performed a specific authz factor so this is represented in the token accurately.
* Lastly we also implemented a OIDC key manager which calculates the kid for jwk's using the SHA1 digest instead of being static, or more specifically the first 7 chars. As per https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key#section-8.1.1 the kid should not exceed 8 chars. While it's allowed to exceed 8 chars, it must only be done so with a compelling reason, which we do not have.
2021-07-03 23:44:30 +00:00
"github.com/stretchr/testify/require"
2021-05-04 22:06:05 +00:00
2021-08-11 01:04:35 +00:00
"github.com/authelia/authelia/v4/internal/authentication"
"github.com/authelia/authelia/v4/internal/authorization"
"github.com/authelia/authelia/v4/internal/configuration/schema"
2022-04-01 11:18:58 +00:00
"github.com/authelia/authelia/v4/internal/model"
2021-05-04 22:06:05 +00:00
)
feat(oidc): add additional config options, accurate token times, and refactoring (#1991)
* This gives admins more control over their OIDC installation exposing options that had defaults before. Things like lifespans for authorize codes, access tokens, id tokens, refresh tokens, a option to enable the debug client messages, minimum parameter entropy. It also allows admins to configure the response modes.
* Additionally this records specific values about a users session indicating when they performed a specific authz factor so this is represented in the token accurately.
* Lastly we also implemented a OIDC key manager which calculates the kid for jwk's using the SHA1 digest instead of being static, or more specifically the first 7 chars. As per https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key#section-8.1.1 the kid should not exceed 8 chars. While it's allowed to exceed 8 chars, it must only be done so with a compelling reason, which we do not have.
2021-07-03 23:44:30 +00:00
func TestNewClient ( t * testing . T ) {
blankConfig := schema . OpenIDConnectClientConfiguration { }
blankClient := NewClient ( blankConfig )
assert . Equal ( t , "" , blankClient . ID )
assert . Equal ( t , "" , blankClient . Description )
assert . Equal ( t , "" , blankClient . Description )
2023-04-11 11:29:02 +00:00
assert . Len ( t , blankClient . ResponseModes , 0 )
feat(oidc): add additional config options, accurate token times, and refactoring (#1991)
* This gives admins more control over their OIDC installation exposing options that had defaults before. Things like lifespans for authorize codes, access tokens, id tokens, refresh tokens, a option to enable the debug client messages, minimum parameter entropy. It also allows admins to configure the response modes.
* Additionally this records specific values about a users session indicating when they performed a specific authz factor so this is represented in the token accurately.
* Lastly we also implemented a OIDC key manager which calculates the kid for jwk's using the SHA1 digest instead of being static, or more specifically the first 7 chars. As per https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key#section-8.1.1 the kid should not exceed 8 chars. While it's allowed to exceed 8 chars, it must only be done so with a compelling reason, which we do not have.
2021-07-03 23:44:30 +00:00
exampleConfig := schema . OpenIDConnectClientConfiguration {
ID : "myapp" ,
Description : "My App" ,
Policy : "two_factor" ,
2022-10-20 03:21:45 +00:00
Secret : MustDecodeSecret ( "$plaintext$abcdef" ) ,
feat(oidc): add additional config options, accurate token times, and refactoring (#1991)
* This gives admins more control over their OIDC installation exposing options that had defaults before. Things like lifespans for authorize codes, access tokens, id tokens, refresh tokens, a option to enable the debug client messages, minimum parameter entropy. It also allows admins to configure the response modes.
* Additionally this records specific values about a users session indicating when they performed a specific authz factor so this is represented in the token accurately.
* Lastly we also implemented a OIDC key manager which calculates the kid for jwk's using the SHA1 digest instead of being static, or more specifically the first 7 chars. As per https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key#section-8.1.1 the kid should not exceed 8 chars. While it's allowed to exceed 8 chars, it must only be done so with a compelling reason, which we do not have.
2021-07-03 23:44:30 +00:00
RedirectURIs : [ ] string { "https://google.com/callback" } ,
Scopes : schema . DefaultOpenIDConnectClientConfiguration . Scopes ,
ResponseTypes : schema . DefaultOpenIDConnectClientConfiguration . ResponseTypes ,
GrantTypes : schema . DefaultOpenIDConnectClientConfiguration . GrantTypes ,
ResponseModes : schema . DefaultOpenIDConnectClientConfiguration . ResponseModes ,
}
exampleClient := NewClient ( exampleConfig )
assert . Equal ( t , "myapp" , exampleClient . ID )
2023-04-11 11:29:02 +00:00
require . Len ( t , exampleClient . ResponseModes , 3 )
assert . Equal ( t , fosite . ResponseModeFormPost , exampleClient . ResponseModes [ 0 ] )
assert . Equal ( t , fosite . ResponseModeQuery , exampleClient . ResponseModes [ 1 ] )
assert . Equal ( t , fosite . ResponseModeFragment , exampleClient . ResponseModes [ 2 ] )
2022-06-14 05:17:11 +00:00
assert . Equal ( t , authorization . TwoFactor , exampleClient . Policy )
feat(oidc): add additional config options, accurate token times, and refactoring (#1991)
* This gives admins more control over their OIDC installation exposing options that had defaults before. Things like lifespans for authorize codes, access tokens, id tokens, refresh tokens, a option to enable the debug client messages, minimum parameter entropy. It also allows admins to configure the response modes.
* Additionally this records specific values about a users session indicating when they performed a specific authz factor so this is represented in the token accurately.
* Lastly we also implemented a OIDC key manager which calculates the kid for jwk's using the SHA1 digest instead of being static, or more specifically the first 7 chars. As per https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key#section-8.1.1 the kid should not exceed 8 chars. While it's allowed to exceed 8 chars, it must only be done so with a compelling reason, which we do not have.
2021-07-03 23:44:30 +00:00
}
2021-05-04 22:06:05 +00:00
func TestIsAuthenticationLevelSufficient ( t * testing . T ) {
2022-04-07 05:33:53 +00:00
c := Client { }
2021-05-04 22:06:05 +00:00
c . Policy = authorization . Bypass
2022-10-20 02:16:36 +00:00
assert . False ( t , c . IsAuthenticationLevelSufficient ( authentication . NotAuthenticated ) )
2021-05-04 22:06:05 +00:00
assert . True ( t , c . IsAuthenticationLevelSufficient ( authentication . OneFactor ) )
assert . True ( t , c . IsAuthenticationLevelSufficient ( authentication . TwoFactor ) )
c . Policy = authorization . OneFactor
assert . False ( t , c . IsAuthenticationLevelSufficient ( authentication . NotAuthenticated ) )
assert . True ( t , c . IsAuthenticationLevelSufficient ( authentication . OneFactor ) )
assert . True ( t , c . IsAuthenticationLevelSufficient ( authentication . TwoFactor ) )
c . Policy = authorization . TwoFactor
assert . False ( t , c . IsAuthenticationLevelSufficient ( authentication . NotAuthenticated ) )
assert . False ( t , c . IsAuthenticationLevelSufficient ( authentication . OneFactor ) )
assert . True ( t , c . IsAuthenticationLevelSufficient ( authentication . TwoFactor ) )
c . Policy = authorization . Denied
assert . False ( t , c . IsAuthenticationLevelSufficient ( authentication . NotAuthenticated ) )
assert . False ( t , c . IsAuthenticationLevelSufficient ( authentication . OneFactor ) )
assert . False ( t , c . IsAuthenticationLevelSufficient ( authentication . TwoFactor ) )
}
feat(oidc): add additional config options, accurate token times, and refactoring (#1991)
* This gives admins more control over their OIDC installation exposing options that had defaults before. Things like lifespans for authorize codes, access tokens, id tokens, refresh tokens, a option to enable the debug client messages, minimum parameter entropy. It also allows admins to configure the response modes.
* Additionally this records specific values about a users session indicating when they performed a specific authz factor so this is represented in the token accurately.
* Lastly we also implemented a OIDC key manager which calculates the kid for jwk's using the SHA1 digest instead of being static, or more specifically the first 7 chars. As per https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key#section-8.1.1 the kid should not exceed 8 chars. While it's allowed to exceed 8 chars, it must only be done so with a compelling reason, which we do not have.
2021-07-03 23:44:30 +00:00
2022-10-20 03:21:45 +00:00
func TestClient_GetConsentResponseBody ( t * testing . T ) {
2022-04-07 05:33:53 +00:00
c := Client { }
feat(oidc): add additional config options, accurate token times, and refactoring (#1991)
* This gives admins more control over their OIDC installation exposing options that had defaults before. Things like lifespans for authorize codes, access tokens, id tokens, refresh tokens, a option to enable the debug client messages, minimum parameter entropy. It also allows admins to configure the response modes.
* Additionally this records specific values about a users session indicating when they performed a specific authz factor so this is represented in the token accurately.
* Lastly we also implemented a OIDC key manager which calculates the kid for jwk's using the SHA1 digest instead of being static, or more specifically the first 7 chars. As per https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key#section-8.1.1 the kid should not exceed 8 chars. While it's allowed to exceed 8 chars, it must only be done so with a compelling reason, which we do not have.
2021-07-03 23:44:30 +00:00
consentRequestBody := c . GetConsentResponseBody ( nil )
assert . Equal ( t , "" , consentRequestBody . ClientID )
assert . Equal ( t , "" , consentRequestBody . ClientDescription )
2022-02-07 14:18:16 +00:00
assert . Equal ( t , [ ] string ( nil ) , consentRequestBody . Scopes )
assert . Equal ( t , [ ] string ( nil ) , consentRequestBody . Audience )
feat(oidc): add additional config options, accurate token times, and refactoring (#1991)
* This gives admins more control over their OIDC installation exposing options that had defaults before. Things like lifespans for authorize codes, access tokens, id tokens, refresh tokens, a option to enable the debug client messages, minimum parameter entropy. It also allows admins to configure the response modes.
* Additionally this records specific values about a users session indicating when they performed a specific authz factor so this is represented in the token accurately.
* Lastly we also implemented a OIDC key manager which calculates the kid for jwk's using the SHA1 digest instead of being static, or more specifically the first 7 chars. As per https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key#section-8.1.1 the kid should not exceed 8 chars. While it's allowed to exceed 8 chars, it must only be done so with a compelling reason, which we do not have.
2021-07-03 23:44:30 +00:00
c . ID = "myclient"
c . Description = "My Client"
2022-04-07 05:33:53 +00:00
consent := & model . OAuth2ConsentSession {
feat(oidc): add additional config options, accurate token times, and refactoring (#1991)
* This gives admins more control over their OIDC installation exposing options that had defaults before. Things like lifespans for authorize codes, access tokens, id tokens, refresh tokens, a option to enable the debug client messages, minimum parameter entropy. It also allows admins to configure the response modes.
* Additionally this records specific values about a users session indicating when they performed a specific authz factor so this is represented in the token accurately.
* Lastly we also implemented a OIDC key manager which calculates the kid for jwk's using the SHA1 digest instead of being static, or more specifically the first 7 chars. As per https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key#section-8.1.1 the kid should not exceed 8 chars. While it's allowed to exceed 8 chars, it must only be done so with a compelling reason, which we do not have.
2021-07-03 23:44:30 +00:00
RequestedAudience : [ ] string { "https://example.com" } ,
RequestedScopes : [ ] string { "openid" , "groups" } ,
}
2022-02-07 14:18:16 +00:00
expectedScopes := [ ] string { "openid" , "groups" }
expectedAudiences := [ ] string { "https://example.com" }
feat(oidc): add additional config options, accurate token times, and refactoring (#1991)
* This gives admins more control over their OIDC installation exposing options that had defaults before. Things like lifespans for authorize codes, access tokens, id tokens, refresh tokens, a option to enable the debug client messages, minimum parameter entropy. It also allows admins to configure the response modes.
* Additionally this records specific values about a users session indicating when they performed a specific authz factor so this is represented in the token accurately.
* Lastly we also implemented a OIDC key manager which calculates the kid for jwk's using the SHA1 digest instead of being static, or more specifically the first 7 chars. As per https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key#section-8.1.1 the kid should not exceed 8 chars. While it's allowed to exceed 8 chars, it must only be done so with a compelling reason, which we do not have.
2021-07-03 23:44:30 +00:00
2022-04-07 05:33:53 +00:00
consentRequestBody = c . GetConsentResponseBody ( consent )
feat(oidc): add additional config options, accurate token times, and refactoring (#1991)
* This gives admins more control over their OIDC installation exposing options that had defaults before. Things like lifespans for authorize codes, access tokens, id tokens, refresh tokens, a option to enable the debug client messages, minimum parameter entropy. It also allows admins to configure the response modes.
* Additionally this records specific values about a users session indicating when they performed a specific authz factor so this is represented in the token accurately.
* Lastly we also implemented a OIDC key manager which calculates the kid for jwk's using the SHA1 digest instead of being static, or more specifically the first 7 chars. As per https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key#section-8.1.1 the kid should not exceed 8 chars. While it's allowed to exceed 8 chars, it must only be done so with a compelling reason, which we do not have.
2021-07-03 23:44:30 +00:00
assert . Equal ( t , "myclient" , consentRequestBody . ClientID )
assert . Equal ( t , "My Client" , consentRequestBody . ClientDescription )
assert . Equal ( t , expectedScopes , consentRequestBody . Scopes )
assert . Equal ( t , expectedAudiences , consentRequestBody . Audience )
}
2022-10-20 03:21:45 +00:00
func TestClient_GetAudience ( t * testing . T ) {
2022-04-07 05:33:53 +00:00
c := Client { }
feat(oidc): add additional config options, accurate token times, and refactoring (#1991)
* This gives admins more control over their OIDC installation exposing options that had defaults before. Things like lifespans for authorize codes, access tokens, id tokens, refresh tokens, a option to enable the debug client messages, minimum parameter entropy. It also allows admins to configure the response modes.
* Additionally this records specific values about a users session indicating when they performed a specific authz factor so this is represented in the token accurately.
* Lastly we also implemented a OIDC key manager which calculates the kid for jwk's using the SHA1 digest instead of being static, or more specifically the first 7 chars. As per https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key#section-8.1.1 the kid should not exceed 8 chars. While it's allowed to exceed 8 chars, it must only be done so with a compelling reason, which we do not have.
2021-07-03 23:44:30 +00:00
audience := c . GetAudience ( )
assert . Len ( t , audience , 0 )
c . Audience = [ ] string { "https://example.com" }
audience = c . GetAudience ( )
require . Len ( t , audience , 1 )
assert . Equal ( t , "https://example.com" , audience [ 0 ] )
}
2022-10-20 03:21:45 +00:00
func TestClient_GetScopes ( t * testing . T ) {
2022-04-07 05:33:53 +00:00
c := Client { }
feat(oidc): add additional config options, accurate token times, and refactoring (#1991)
* This gives admins more control over their OIDC installation exposing options that had defaults before. Things like lifespans for authorize codes, access tokens, id tokens, refresh tokens, a option to enable the debug client messages, minimum parameter entropy. It also allows admins to configure the response modes.
* Additionally this records specific values about a users session indicating when they performed a specific authz factor so this is represented in the token accurately.
* Lastly we also implemented a OIDC key manager which calculates the kid for jwk's using the SHA1 digest instead of being static, or more specifically the first 7 chars. As per https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key#section-8.1.1 the kid should not exceed 8 chars. While it's allowed to exceed 8 chars, it must only be done so with a compelling reason, which we do not have.
2021-07-03 23:44:30 +00:00
scopes := c . GetScopes ( )
assert . Len ( t , scopes , 0 )
c . Scopes = [ ] string { "openid" }
scopes = c . GetScopes ( )
require . Len ( t , scopes , 1 )
assert . Equal ( t , "openid" , scopes [ 0 ] )
}
2022-10-20 03:21:45 +00:00
func TestClient_GetGrantTypes ( t * testing . T ) {
2022-04-07 05:33:53 +00:00
c := Client { }
feat(oidc): add additional config options, accurate token times, and refactoring (#1991)
* This gives admins more control over their OIDC installation exposing options that had defaults before. Things like lifespans for authorize codes, access tokens, id tokens, refresh tokens, a option to enable the debug client messages, minimum parameter entropy. It also allows admins to configure the response modes.
* Additionally this records specific values about a users session indicating when they performed a specific authz factor so this is represented in the token accurately.
* Lastly we also implemented a OIDC key manager which calculates the kid for jwk's using the SHA1 digest instead of being static, or more specifically the first 7 chars. As per https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key#section-8.1.1 the kid should not exceed 8 chars. While it's allowed to exceed 8 chars, it must only be done so with a compelling reason, which we do not have.
2021-07-03 23:44:30 +00:00
grantTypes := c . GetGrantTypes ( )
require . Len ( t , grantTypes , 1 )
assert . Equal ( t , "authorization_code" , grantTypes [ 0 ] )
c . GrantTypes = [ ] string { "device_code" }
grantTypes = c . GetGrantTypes ( )
require . Len ( t , grantTypes , 1 )
assert . Equal ( t , "device_code" , grantTypes [ 0 ] )
}
2022-10-20 03:21:45 +00:00
func TestClient_Hashing ( t * testing . T ) {
2022-04-07 05:33:53 +00:00
c := Client { }
feat(oidc): add additional config options, accurate token times, and refactoring (#1991)
* This gives admins more control over their OIDC installation exposing options that had defaults before. Things like lifespans for authorize codes, access tokens, id tokens, refresh tokens, a option to enable the debug client messages, minimum parameter entropy. It also allows admins to configure the response modes.
* Additionally this records specific values about a users session indicating when they performed a specific authz factor so this is represented in the token accurately.
* Lastly we also implemented a OIDC key manager which calculates the kid for jwk's using the SHA1 digest instead of being static, or more specifically the first 7 chars. As per https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key#section-8.1.1 the kid should not exceed 8 chars. While it's allowed to exceed 8 chars, it must only be done so with a compelling reason, which we do not have.
2021-07-03 23:44:30 +00:00
hashedSecret := c . GetHashedSecret ( )
assert . Equal ( t , [ ] byte ( nil ) , hashedSecret )
2022-10-20 03:21:45 +00:00
c . Secret = MustDecodeSecret ( "$plaintext$a_bad_secret" )
assert . True ( t , c . Secret . MatchBytes ( [ ] byte ( "a_bad_secret" ) ) )
}
func TestClient_GetHashedSecret ( t * testing . T ) {
c := Client { }
hashedSecret := c . GetHashedSecret ( )
assert . Equal ( t , [ ] byte ( nil ) , hashedSecret )
c . Secret = MustDecodeSecret ( "$plaintext$a_bad_secret" )
feat(oidc): add additional config options, accurate token times, and refactoring (#1991)
* This gives admins more control over their OIDC installation exposing options that had defaults before. Things like lifespans for authorize codes, access tokens, id tokens, refresh tokens, a option to enable the debug client messages, minimum parameter entropy. It also allows admins to configure the response modes.
* Additionally this records specific values about a users session indicating when they performed a specific authz factor so this is represented in the token accurately.
* Lastly we also implemented a OIDC key manager which calculates the kid for jwk's using the SHA1 digest instead of being static, or more specifically the first 7 chars. As per https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key#section-8.1.1 the kid should not exceed 8 chars. While it's allowed to exceed 8 chars, it must only be done so with a compelling reason, which we do not have.
2021-07-03 23:44:30 +00:00
hashedSecret = c . GetHashedSecret ( )
2022-10-20 03:21:45 +00:00
assert . Equal ( t , [ ] byte ( "$plaintext$a_bad_secret" ) , hashedSecret )
feat(oidc): add additional config options, accurate token times, and refactoring (#1991)
* This gives admins more control over their OIDC installation exposing options that had defaults before. Things like lifespans for authorize codes, access tokens, id tokens, refresh tokens, a option to enable the debug client messages, minimum parameter entropy. It also allows admins to configure the response modes.
* Additionally this records specific values about a users session indicating when they performed a specific authz factor so this is represented in the token accurately.
* Lastly we also implemented a OIDC key manager which calculates the kid for jwk's using the SHA1 digest instead of being static, or more specifically the first 7 chars. As per https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key#section-8.1.1 the kid should not exceed 8 chars. While it's allowed to exceed 8 chars, it must only be done so with a compelling reason, which we do not have.
2021-07-03 23:44:30 +00:00
}
2022-10-20 03:21:45 +00:00
func TestClient_GetID ( t * testing . T ) {
2022-04-07 05:33:53 +00:00
c := Client { }
feat(oidc): add additional config options, accurate token times, and refactoring (#1991)
* This gives admins more control over their OIDC installation exposing options that had defaults before. Things like lifespans for authorize codes, access tokens, id tokens, refresh tokens, a option to enable the debug client messages, minimum parameter entropy. It also allows admins to configure the response modes.
* Additionally this records specific values about a users session indicating when they performed a specific authz factor so this is represented in the token accurately.
* Lastly we also implemented a OIDC key manager which calculates the kid for jwk's using the SHA1 digest instead of being static, or more specifically the first 7 chars. As per https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key#section-8.1.1 the kid should not exceed 8 chars. While it's allowed to exceed 8 chars, it must only be done so with a compelling reason, which we do not have.
2021-07-03 23:44:30 +00:00
id := c . GetID ( )
assert . Equal ( t , "" , id )
c . ID = "myid"
id = c . GetID ( )
assert . Equal ( t , "myid" , id )
}
2022-10-20 03:21:45 +00:00
func TestClient_GetRedirectURIs ( t * testing . T ) {
2022-04-07 05:33:53 +00:00
c := Client { }
feat(oidc): add additional config options, accurate token times, and refactoring (#1991)
* This gives admins more control over their OIDC installation exposing options that had defaults before. Things like lifespans for authorize codes, access tokens, id tokens, refresh tokens, a option to enable the debug client messages, minimum parameter entropy. It also allows admins to configure the response modes.
* Additionally this records specific values about a users session indicating when they performed a specific authz factor so this is represented in the token accurately.
* Lastly we also implemented a OIDC key manager which calculates the kid for jwk's using the SHA1 digest instead of being static, or more specifically the first 7 chars. As per https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key#section-8.1.1 the kid should not exceed 8 chars. While it's allowed to exceed 8 chars, it must only be done so with a compelling reason, which we do not have.
2021-07-03 23:44:30 +00:00
redirectURIs := c . GetRedirectURIs ( )
require . Len ( t , redirectURIs , 0 )
c . RedirectURIs = [ ] string { "https://example.com/oauth2/callback" }
redirectURIs = c . GetRedirectURIs ( )
require . Len ( t , redirectURIs , 1 )
assert . Equal ( t , "https://example.com/oauth2/callback" , redirectURIs [ 0 ] )
}
2022-10-20 03:21:45 +00:00
func TestClient_GetResponseModes ( t * testing . T ) {
2022-04-07 05:33:53 +00:00
c := Client { }
feat(oidc): add additional config options, accurate token times, and refactoring (#1991)
* This gives admins more control over their OIDC installation exposing options that had defaults before. Things like lifespans for authorize codes, access tokens, id tokens, refresh tokens, a option to enable the debug client messages, minimum parameter entropy. It also allows admins to configure the response modes.
* Additionally this records specific values about a users session indicating when they performed a specific authz factor so this is represented in the token accurately.
* Lastly we also implemented a OIDC key manager which calculates the kid for jwk's using the SHA1 digest instead of being static, or more specifically the first 7 chars. As per https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key#section-8.1.1 the kid should not exceed 8 chars. While it's allowed to exceed 8 chars, it must only be done so with a compelling reason, which we do not have.
2021-07-03 23:44:30 +00:00
responseModes := c . GetResponseModes ( )
require . Len ( t , responseModes , 0 )
c . ResponseModes = [ ] fosite . ResponseModeType {
fosite . ResponseModeDefault , fosite . ResponseModeFormPost ,
fosite . ResponseModeQuery , fosite . ResponseModeFragment ,
}
responseModes = c . GetResponseModes ( )
require . Len ( t , responseModes , 4 )
assert . Equal ( t , fosite . ResponseModeDefault , responseModes [ 0 ] )
assert . Equal ( t , fosite . ResponseModeFormPost , responseModes [ 1 ] )
assert . Equal ( t , fosite . ResponseModeQuery , responseModes [ 2 ] )
assert . Equal ( t , fosite . ResponseModeFragment , responseModes [ 3 ] )
}
2022-10-20 03:21:45 +00:00
func TestClient_GetResponseTypes ( t * testing . T ) {
2022-04-07 05:33:53 +00:00
c := Client { }
feat(oidc): add additional config options, accurate token times, and refactoring (#1991)
* This gives admins more control over their OIDC installation exposing options that had defaults before. Things like lifespans for authorize codes, access tokens, id tokens, refresh tokens, a option to enable the debug client messages, minimum parameter entropy. It also allows admins to configure the response modes.
* Additionally this records specific values about a users session indicating when they performed a specific authz factor so this is represented in the token accurately.
* Lastly we also implemented a OIDC key manager which calculates the kid for jwk's using the SHA1 digest instead of being static, or more specifically the first 7 chars. As per https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key#section-8.1.1 the kid should not exceed 8 chars. While it's allowed to exceed 8 chars, it must only be done so with a compelling reason, which we do not have.
2021-07-03 23:44:30 +00:00
responseTypes := c . GetResponseTypes ( )
require . Len ( t , responseTypes , 1 )
assert . Equal ( t , "code" , responseTypes [ 0 ] )
c . ResponseTypes = [ ] string { "code" , "id_token" }
responseTypes = c . GetResponseTypes ( )
require . Len ( t , responseTypes , 2 )
assert . Equal ( t , "code" , responseTypes [ 0 ] )
assert . Equal ( t , "id_token" , responseTypes [ 1 ] )
}
2023-01-03 15:03:23 +00:00
func TestNewClientPKCE ( t * testing . T ) {
testCases := [ ] struct {
name string
have schema . OpenIDConnectClientConfiguration
expectedEnforcePKCE bool
expectedEnforcePKCEChallengeMethod bool
expected string
2023-03-06 03:58:50 +00:00
r * fosite . Request
2023-01-03 15:03:23 +00:00
err string
2023-04-11 11:29:02 +00:00
desc string
2023-01-03 15:03:23 +00:00
} {
{
"ShouldNotEnforcePKCEAndNotErrorOnNonPKCERequest" ,
schema . OpenIDConnectClientConfiguration { } ,
false ,
false ,
"" ,
& fosite . Request { } ,
"" ,
2023-04-11 11:29:02 +00:00
"" ,
2023-01-03 15:03:23 +00:00
} ,
{
"ShouldEnforcePKCEAndErrorOnNonPKCERequest" ,
schema . OpenIDConnectClientConfiguration { EnforcePKCE : true } ,
true ,
false ,
"" ,
& fosite . Request { } ,
"invalid_request" ,
2023-04-11 11:29:02 +00:00
"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Clients must include a code_challenge when performing the authorize code flow, but it is missing. The server is configured in a way that enforces PKCE for this client." ,
2023-01-03 15:03:23 +00:00
} ,
{
"ShouldEnforcePKCEAndNotErrorOnPKCERequest" ,
schema . OpenIDConnectClientConfiguration { EnforcePKCE : true } ,
true ,
false ,
"" ,
& fosite . Request { Form : map [ string ] [ ] string { "code_challenge" : { "abc" } } } ,
"" ,
2023-04-11 11:29:02 +00:00
"" ,
2023-01-03 15:03:23 +00:00
} ,
{ "ShouldEnforcePKCEFromChallengeMethodAndErrorOnNonPKCERequest" ,
schema . OpenIDConnectClientConfiguration { PKCEChallengeMethod : "S256" } ,
true ,
true ,
"S256" ,
& fosite . Request { } ,
"invalid_request" ,
2023-04-11 11:29:02 +00:00
"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Clients must include a code_challenge when performing the authorize code flow, but it is missing. The server is configured in a way that enforces PKCE for this client." ,
2023-01-03 15:03:23 +00:00
} ,
{ "ShouldEnforcePKCEFromChallengeMethodAndErrorOnInvalidChallengeMethod" ,
schema . OpenIDConnectClientConfiguration { PKCEChallengeMethod : "S256" } ,
true ,
true ,
"S256" ,
& fosite . Request { Form : map [ string ] [ ] string { "code_challenge" : { "abc" } } } ,
"invalid_request" ,
2023-04-11 11:29:02 +00:00
"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Client must use code_challenge_method=S256, is not allowed. The server is configured in a way that enforces PKCE S256 as challenge method for this client." ,
2023-01-03 15:03:23 +00:00
} ,
{ "ShouldEnforcePKCEFromChallengeMethodAndNotErrorOnValidRequest" ,
schema . OpenIDConnectClientConfiguration { PKCEChallengeMethod : "S256" } ,
true ,
true ,
"S256" ,
& fosite . Request { Form : map [ string ] [ ] string { "code_challenge" : { "abc" } , "code_challenge_method" : { "S256" } } } ,
"" ,
2023-04-11 11:29:02 +00:00
"" ,
2023-01-03 15:03:23 +00:00
} ,
}
for _ , tc := range testCases {
t . Run ( tc . name , func ( t * testing . T ) {
client := NewClient ( tc . have )
assert . Equal ( t , tc . expectedEnforcePKCE , client . EnforcePKCE )
assert . Equal ( t , tc . expectedEnforcePKCEChallengeMethod , client . EnforcePKCEChallengeMethod )
assert . Equal ( t , tc . expected , client . PKCEChallengeMethod )
2023-03-06 03:58:50 +00:00
if tc . r != nil {
err := client . ValidatePKCEPolicy ( tc . r )
2023-01-03 15:03:23 +00:00
if tc . err != "" {
2023-04-11 11:29:02 +00:00
require . NotNil ( t , err )
assert . EqualError ( t , err , tc . err )
assert . Equal ( t , tc . desc , fosite . ErrorToRFC6749Error ( err ) . WithExposeDebug ( true ) . GetDescription ( ) )
} else {
assert . NoError ( t , err )
}
}
} )
}
}
func TestNewClientPAR ( t * testing . T ) {
testCases := [ ] struct {
name string
have schema . OpenIDConnectClientConfiguration
expected bool
r * fosite . Request
err string
desc string
} {
{
"ShouldNotEnforcEPARAndNotErrorOnNonPARRequest" ,
schema . OpenIDConnectClientConfiguration { } ,
false ,
& fosite . Request { } ,
"" ,
"" ,
} ,
{
"ShouldEnforcePARAndErrorOnNonPARRequest" ,
schema . OpenIDConnectClientConfiguration { EnforcePAR : true } ,
true ,
& fosite . Request { } ,
"invalid_request" ,
"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Pushed Authorization Requests are enforced for this client but no such request was sent. The request_uri parameter was empty." ,
} ,
{
"ShouldEnforcePARAndErrorOnNonPARRequest" ,
schema . OpenIDConnectClientConfiguration { EnforcePAR : true } ,
true ,
& fosite . Request { Form : map [ string ] [ ] string { FormParameterRequestURI : { "https://example.com" } } } ,
"invalid_request" ,
"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Pushed Authorization Requests are enforced for this client but no such request was sent. The request_uri parameter 'https://example.com' is malformed." } ,
{
"ShouldEnforcePARAndNotErrorOnPARRequest" ,
schema . OpenIDConnectClientConfiguration { EnforcePAR : true } ,
true ,
& fosite . Request { Form : map [ string ] [ ] string { FormParameterRequestURI : { fmt . Sprintf ( "%sabc" , urnPARPrefix ) } } } ,
"" ,
"" ,
} ,
}
for _ , tc := range testCases {
t . Run ( tc . name , func ( t * testing . T ) {
client := NewClient ( tc . have )
assert . Equal ( t , tc . expected , client . EnforcePAR )
if tc . r != nil {
err := client . ValidatePARPolicy ( tc . r , urnPARPrefix )
if tc . err != "" {
require . NotNil ( t , err )
assert . EqualError ( t , err , tc . err )
assert . Equal ( t , tc . desc , fosite . ErrorToRFC6749Error ( err ) . WithExposeDebug ( true ) . GetDescription ( ) )
} else {
assert . NoError ( t , err )
}
}
} )
}
}
func TestNewClientResponseModes ( t * testing . T ) {
testCases := [ ] struct {
name string
have schema . OpenIDConnectClientConfiguration
expected [ ] fosite . ResponseModeType
r * fosite . AuthorizeRequest
err string
desc string
} {
{
"ShouldEnforceResponseModePolicyAndAllowDefaultModeQuery" ,
schema . OpenIDConnectClientConfiguration { ResponseModes : [ ] string { ResponseModeQuery } } ,
[ ] fosite . ResponseModeType { fosite . ResponseModeQuery } ,
& fosite . AuthorizeRequest { DefaultResponseMode : fosite . ResponseModeQuery , ResponseMode : fosite . ResponseModeDefault , Request : fosite . Request { Form : map [ string ] [ ] string { FormParameterResponseMode : nil } } } ,
"" ,
"" ,
} ,
{
"ShouldEnforceResponseModePolicyAndFailOnDefaultMode" ,
schema . OpenIDConnectClientConfiguration { ResponseModes : [ ] string { ResponseModeFormPost } } ,
[ ] fosite . ResponseModeType { fosite . ResponseModeFormPost } ,
& fosite . AuthorizeRequest { DefaultResponseMode : fosite . ResponseModeQuery , ResponseMode : fosite . ResponseModeDefault , Request : fosite . Request { Form : map [ string ] [ ] string { FormParameterResponseMode : nil } } } ,
"unsupported_response_mode" ,
"The authorization server does not support obtaining a response using this response mode. The request omitted the response_mode making the default response_mode 'query' based on the other authorization request parameters but registered OAuth 2.0 client doesn't support this response_mode" ,
} ,
{
"ShouldNotEnforceConfiguredResponseMode" ,
schema . OpenIDConnectClientConfiguration { ResponseModes : [ ] string { ResponseModeFormPost } } ,
[ ] fosite . ResponseModeType { fosite . ResponseModeFormPost } ,
& fosite . AuthorizeRequest { DefaultResponseMode : fosite . ResponseModeQuery , ResponseMode : fosite . ResponseModeQuery , Request : fosite . Request { Form : map [ string ] [ ] string { FormParameterResponseMode : { ResponseModeQuery } } } } ,
"" ,
"" ,
} ,
{
"ShouldNotEnforceUnconfiguredResponseMode" ,
schema . OpenIDConnectClientConfiguration { ResponseModes : [ ] string { } } ,
[ ] fosite . ResponseModeType { } ,
& fosite . AuthorizeRequest { DefaultResponseMode : fosite . ResponseModeQuery , ResponseMode : fosite . ResponseModeDefault , Request : fosite . Request { Form : map [ string ] [ ] string { FormParameterResponseMode : { ResponseModeQuery } } } } ,
"" ,
"" ,
} ,
}
for _ , tc := range testCases {
t . Run ( tc . name , func ( t * testing . T ) {
client := NewClient ( tc . have )
assert . Equal ( t , tc . expected , client . GetResponseModes ( ) )
if tc . r != nil {
err := client . ValidateResponseModePolicy ( tc . r )
if tc . err != "" {
require . NotNil ( t , err )
2023-01-03 15:03:23 +00:00
assert . EqualError ( t , err , tc . err )
2023-04-11 11:29:02 +00:00
assert . Equal ( t , tc . desc , fosite . ErrorToRFC6749Error ( err ) . WithExposeDebug ( true ) . GetDescription ( ) )
2023-01-03 15:03:23 +00:00
} else {
assert . NoError ( t , err )
}
}
} )
}
}
2022-10-20 03:21:45 +00:00
func TestClient_IsPublic ( t * testing . T ) {
2022-04-07 05:33:53 +00:00
c := Client { }
feat(oidc): add additional config options, accurate token times, and refactoring (#1991)
* This gives admins more control over their OIDC installation exposing options that had defaults before. Things like lifespans for authorize codes, access tokens, id tokens, refresh tokens, a option to enable the debug client messages, minimum parameter entropy. It also allows admins to configure the response modes.
* Additionally this records specific values about a users session indicating when they performed a specific authz factor so this is represented in the token accurately.
* Lastly we also implemented a OIDC key manager which calculates the kid for jwk's using the SHA1 digest instead of being static, or more specifically the first 7 chars. As per https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key#section-8.1.1 the kid should not exceed 8 chars. While it's allowed to exceed 8 chars, it must only be done so with a compelling reason, which we do not have.
2021-07-03 23:44:30 +00:00
assert . False ( t , c . IsPublic ( ) )
c . Public = true
assert . True ( t , c . IsPublic ( ) )
}
2022-10-20 03:21:45 +00:00
func MustDecodeSecret ( value string ) * schema . PasswordDigest {
2022-12-04 22:37:08 +00:00
if secret , err := schema . DecodePasswordDigest ( value ) ; err != nil {
2022-10-20 03:21:45 +00:00
panic ( err )
} else {
return secret
}
}