@ -18,6 +18,7 @@ import (
"github.com/coreos/dex/client"
"github.com/coreos/dex/db"
"github.com/coreos/dex/refresh/refreshtest"
"github.com/coreos/dex/scope"
"github.com/coreos/dex/session/manager"
"github.com/coreos/dex/user"
)
@ -490,117 +491,191 @@ func TestServerRefreshToken(t *testing.T) {
signer jose . Signer
createScopes [ ] string
refreshScopes [ ] string
expectedAud [ ] string
err error
} {
// Everything is good.
{
fmt . Sprintf ( "1/%s" , base64 . URLEncoding . EncodeToString ( [ ] byte ( "refresh-1" ) ) ) ,
testClientID ,
testClientCredentials ,
signerFixture ,
[ ] string { "openid" , "profile" } ,
[ ] string { "openid" , "profile" } ,
nil ,
token : fmt . Sprintf ( "1/%s" , base64 . URLEncoding . EncodeToString ( [ ] byte ( "refresh-1" ) ) ) ,
clientID : testClientID ,
creds : testClientCredentials ,
signer : signerFixture ,
createScopes : [ ] string { "openid" , "profile" } ,
refreshScopes : [ ] string { "openid" , "profile" } ,
} ,
// Asking for a scope not originally granted to you.
{
fmt . Sprintf ( "1/%s" , base64 . URLEncoding . EncodeToString ( [ ] byte ( "refresh-1" ) ) ) ,
testClientID ,
testClientCredentials ,
signerFixture ,
[ ] string { "openid" , "profile" } ,
[ ] string { "openid" , "profile" , "extra_scope" } ,
oauth2 . NewError ( oauth2 . ErrorInvalidRequest ) ,
token : fmt . Sprintf ( "1/%s" , base64 . URLEncoding . EncodeToString ( [ ] byte ( "refresh-1" ) ) ) ,
clientID : testClientID ,
creds : testClientCredentials ,
signer : signer Fixture,
createScopes : [ ] string { "openid" , "profile" } ,
refreshScopes : [ ] string { "openid" , "profile" , "extra_scope" } ,
err : oauth2 . NewError ( oauth2 . ErrorInvalidRequest ) ,
} ,
// Invalid refresh token(malformatted).
{
"invalid-token" ,
testClientID ,
testClientCredentials ,
signerFixture ,
[ ] string { "openid" , "profile" } ,
[ ] string { "openid" , "profile" } ,
oauth2 . NewError ( oauth2 . ErrorInvalidRequest ) ,
token : "invalid-token" ,
clientID : testClientID ,
creds : testClientCredentials ,
signer : signer Fixture,
createScopes : [ ] string { "openid" , "profile" } ,
refreshScopes : [ ] string { "openid" , "profile" } ,
err : oauth2 . NewError ( oauth2 . ErrorInvalidRequest ) ,
} ,
// Invalid refresh token(invalid payload content).
{
fmt . Sprintf ( "1/%s" , base64 . URLEncoding . EncodeToString ( [ ] byte ( "refresh-2" ) ) ) ,
testClientID ,
testClientCredentials ,
signerFixture ,
[ ] string { "openid" , "profile" } ,
[ ] string { "openid" , "profile" } ,
oauth2 . NewError ( oauth2 . ErrorInvalidRequest ) ,
token : fmt . Sprintf ( "1/%s" , base64 . URLEncoding . EncodeToString ( [ ] byte ( "refresh-2" ) ) ) ,
clientID : testClientID ,
creds : testClientCredentials ,
signer : signer Fixture,
createScopes : [ ] string { "openid" , "profile" } ,
refreshScopes : [ ] string { "openid" , "profile" } ,
err : oauth2 . NewError ( oauth2 . ErrorInvalidRequest ) ,
} ,
// Invalid refresh token(invalid ID content).
{
fmt . Sprintf ( "0/%s" , base64 . URLEncoding . EncodeToString ( [ ] byte ( "refresh-1" ) ) ) ,
testClientID ,
testClientCredentials ,
signerFixture ,
[ ] string { "openid" , "profile" } ,
[ ] string { "openid" , "profile" } ,
oauth2 . NewError ( oauth2 . ErrorInvalidRequest ) ,
token : fmt . Sprintf ( "0/%s" , base64 . URLEncoding . EncodeToString ( [ ] byte ( "refresh-1" ) ) ) ,
clientID : testClientID ,
creds : testClientCredentials ,
signer : signer Fixture,
createScopes : [ ] string { "openid" , "profile" } ,
refreshScopes : [ ] string { "openid" , "profile" } ,
err : oauth2 . NewError ( oauth2 . ErrorInvalidRequest ) ,
} ,
// Invalid client(client is not associated with the token).
{
fmt . Sprintf ( "1/%s" , base64 . URLEncoding . EncodeToString ( [ ] byte ( "refresh-1" ) ) ) ,
testClientID ,
clientB . Credentials ,
signerFixture ,
[ ] string { "openid" , "profile" } ,
[ ] string { "openid" , "profile" } ,
oauth2 . NewError ( oauth2 . ErrorInvalidClient ) ,
token : fmt . Sprintf ( "1/%s" , base64 . URLEncoding . EncodeToString ( [ ] byte ( "refresh-1" ) ) ) ,
clientID : testClientID ,
creds : c lientB . Credentials ,
signer : signer Fixture,
createScopes : [ ] string { "openid" , "profile" } ,
refreshScopes : [ ] string { "openid" , "profile" } ,
err : oauth2 . NewError ( oauth2 . ErrorInvalidClient ) ,
} ,
// Invalid client(no client ID).
{
fmt . Sprintf ( "1/%s" , base64 . URLEncoding . EncodeToString ( [ ] byte ( "refresh-1" ) ) ) ,
testClientID ,
oidc . ClientCredentials { ID : "" , Secret : "aaa" } ,
signerFixture ,
[ ] string { "openid" , "profile" } ,
[ ] string { "openid" , "profile" } ,
oauth2 . NewError ( oauth2 . ErrorInvalidClient ) ,
token : fmt . Sprintf ( "1/%s" , base64 . URLEncoding . EncodeToString ( [ ] byte ( "refresh-1" ) ) ) ,
clientID : testClientID ,
creds : oidc . ClientCredentials { ID : "" , Secret : "aaa" } ,
signer : signer Fixture,
createScopes : [ ] string { "openid" , "profile" } ,
refreshScopes : [ ] string { "openid" , "profile" } ,
err : oauth2 . NewError ( oauth2 . ErrorInvalidClient ) ,
} ,
// Invalid client(no such client).
{
fmt . Sprintf ( "1/%s" , base64 . URLEncoding . EncodeToString ( [ ] byte ( "refresh-1" ) ) ) ,
testClientID ,
oidc . ClientCredentials { ID : "AAA" , Secret : "aaa" } ,
signerFixture ,
[ ] string { "openid" , "profile" } ,
[ ] string { "openid" , "profile" } ,
oauth2 . NewError ( oauth2 . ErrorInvalidClient ) ,
token : fmt . Sprintf ( "1/%s" , base64 . URLEncoding . EncodeToString ( [ ] byte ( "refresh-1" ) ) ) ,
clientID : testClientID ,
creds : oidc . ClientCredentials { ID : "AAA" , Secret : "aaa" } ,
signer : signer Fixture,
createScopes : [ ] string { "openid" , "profile" } ,
refreshScopes : [ ] string { "openid" , "profile" } ,
err : oauth2 . NewError ( oauth2 . ErrorInvalidClient ) ,
} ,
// Invalid client(no secrets).
{
fmt . Sprintf ( "1/%s" , base64 . URLEncoding . EncodeToString ( [ ] byte ( "refresh-1" ) ) ) ,
testClientID ,
oidc . ClientCredentials { ID : testClientID } ,
signerFixture ,
[ ] string { "openid" , "profile" } ,
[ ] string { "openid" , "profile" } ,
oauth2 . NewError ( oauth2 . ErrorInvalidClient ) ,
token : fmt . Sprintf ( "1/%s" , base64 . URLEncoding . EncodeToString ( [ ] byte ( "refresh-1" ) ) ) ,
clientID : testClientID ,
creds : oidc . ClientCredentials { ID : testClientID } ,
signer : signer Fixture,
createScopes : [ ] string { "openid" , "profile" } ,
refreshScopes : [ ] string { "openid" , "profile" } ,
err : oauth2 . NewError ( oauth2 . ErrorInvalidClient ) ,
} ,
// Invalid client(invalid secret).
{
fmt . Sprintf ( "1/%s" , base64 . URLEncoding . EncodeToString ( [ ] byte ( "refresh-1" ) ) ) ,
testClientID ,
oidc . ClientCredentials { ID : "bad-id" , Secret : "bad-secret" } ,
signerFixture ,
[ ] string { "openid" , "profile" } ,
[ ] string { "openid" , "profile" } ,
oauth2 . NewError ( oauth2 . ErrorInvalidClient ) ,
token : fmt . Sprintf ( "1/%s" , base64 . URLEncoding . EncodeToString ( [ ] byte ( "refresh-1" ) ) ) ,
clientID : testClientID ,
creds : oidc . ClientCredentials { ID : "bad-id" , Secret : "bad-secret" } ,
signer : signer Fixture,
createScopes : [ ] string { "openid" , "profile" } ,
refreshScopes : [ ] string { "openid" , "profile" } ,
err : oauth2 . NewError ( oauth2 . ErrorInvalidClient ) ,
} ,
// Signing operation fails.
{
fmt . Sprintf ( "1/%s" , base64 . URLEncoding . EncodeToString ( [ ] byte ( "refresh-1" ) ) ) ,
testClientID ,
testClientCredentials ,
& StaticSigner { sig : nil , err : errors . New ( "fail" ) } ,
[ ] string { "openid" , "profile" } ,
[ ] string { "openid" , "profile" } ,
oauth2 . NewError ( oauth2 . ErrorServerError ) ,
token : fmt . Sprintf ( "1/%s" , base64 . URLEncoding . EncodeToString ( [ ] byte ( "refresh-1" ) ) ) ,
clientID : testClientID ,
creds : testClientCredentials ,
signer : & StaticSigner { sig : nil , err : errors . New ( "fail" ) } ,
createScopes : [ ] string { "openid" , "profile" } ,
refreshScopes : [ ] string { "openid" , "profile" } ,
err : oauth2 . NewError ( oauth2 . ErrorServerError ) ,
} ,
// Valid Cross-Client
{
token : fmt . Sprintf ( "1/%s" , base64 . URLEncoding . EncodeToString ( [ ] byte ( "refresh-1" ) ) ) ,
clientID : "client_a" ,
creds : oidc . ClientCredentials {
ID : "client_a" ,
Secret : base64 . URLEncoding . EncodeToString (
[ ] byte ( "client_a_secret" ) ) ,
} ,
signer : signerFixture ,
createScopes : [ ] string { "openid" , "profile" , scope . ScopeGoogleCrossClient + "client_b" } ,
refreshScopes : [ ] string { "openid" , "profile" , scope . ScopeGoogleCrossClient + "client_b" } ,
expectedAud : [ ] string { "client_b" } ,
} ,
// Valid Cross-Client - but this time we leave out the scopes in the
// refresh request, which should result in the original stored scopes
// being used.
{
token : fmt . Sprintf ( "1/%s" , base64 . URLEncoding . EncodeToString ( [ ] byte ( "refresh-1" ) ) ) ,
clientID : "client_a" ,
creds : oidc . ClientCredentials {
ID : "client_a" ,
Secret : base64 . URLEncoding . EncodeToString (
[ ] byte ( "client_a_secret" ) ) ,
} ,
signer : signerFixture ,
createScopes : [ ] string { "openid" , "profile" , scope . ScopeGoogleCrossClient + "client_b" } ,
refreshScopes : [ ] string { } ,
expectedAud : [ ] string { "client_b" } ,
} ,
// Valid Cross-Client - asking for fewer scopes than originally used
// when creating the refresh token, which is ok.
{
token : fmt . Sprintf ( "1/%s" , base64 . URLEncoding . EncodeToString ( [ ] byte ( "refresh-1" ) ) ) ,
clientID : "client_a" ,
creds : oidc . ClientCredentials {
ID : "client_a" ,
Secret : base64 . URLEncoding . EncodeToString (
[ ] byte ( "client_a_secret" ) ) ,
} ,
signer : signerFixture ,
createScopes : [ ] string { "openid" , "profile" , scope . ScopeGoogleCrossClient + "client_b" , scope . ScopeGoogleCrossClient + "client_c" } ,
refreshScopes : [ ] string { "openid" , "profile" , scope . ScopeGoogleCrossClient + "client_b" } ,
expectedAud : [ ] string { "client_b" } ,
} ,
// Valid Cross-Client - asking for multiple clients in the audience.
{
token : fmt . Sprintf ( "1/%s" , base64 . URLEncoding . EncodeToString ( [ ] byte ( "refresh-1" ) ) ) ,
clientID : "client_a" ,
creds : oidc . ClientCredentials {
ID : "client_a" ,
Secret : base64 . URLEncoding . EncodeToString (
[ ] byte ( "client_a_secret" ) ) ,
} ,
signer : signerFixture ,
createScopes : [ ] string { "openid" , "profile" , scope . ScopeGoogleCrossClient + "client_b" , scope . ScopeGoogleCrossClient + "client_c" } ,
refreshScopes : [ ] string { "openid" , "profile" , scope . ScopeGoogleCrossClient + "client_b" , scope . ScopeGoogleCrossClient + "client_c" } ,
expectedAud : [ ] string { "client_b" , "client_c" } ,
} ,
// Invalid Cross-Client - didn't orignally request cross-client when
// refresh token was created.
{
token : fmt . Sprintf ( "1/%s" , base64 . URLEncoding . EncodeToString ( [ ] byte ( "refresh-1" ) ) ) ,
clientID : "client_a" ,
creds : oidc . ClientCredentials {
ID : "client_a" ,
Secret : base64 . URLEncoding . EncodeToString (
[ ] byte ( "client_a_secret" ) ) ,
} ,
signer : signerFixture ,
createScopes : [ ] string { "openid" , "profile" } ,
refreshScopes : [ ] string { "openid" , "profile" , scope . ScopeGoogleCrossClient + "client_b" } ,
err : oauth2 . NewError ( oauth2 . ErrorInvalidRequest ) ,
} ,
}
@ -608,7 +683,7 @@ func TestServerRefreshToken(t *testing.T) {
km := & StaticKeyManager {
signer : tt . signer ,
}
f , err := makeTestFixtures ( )
f , err := makeCrossClient TestFixtures ( )
if err != nil {
t . Fatalf ( "error making test fixtures: %v" , err )
}
@ -637,8 +712,27 @@ func TestServerRefreshToken(t *testing.T) {
if err != nil {
t . Errorf ( "Case %d: unexpected error: %v" , i , err )
}
if claims [ "iss" ] != testIssuerURL . String ( ) || claims [ "sub" ] != testUserID1 || claims [ "aud" ] != testClientID {
t . Errorf ( "Case %d: invalid claims: %v" , i , claims )
var expectedAud interface { }
if tt . expectedAud == nil {
expectedAud = testClientID
} else if len ( tt . expectedAud ) == 1 {
expectedAud = tt . expectedAud [ 0 ]
} else {
expectedAud = tt . expectedAud
}
if claims [ "iss" ] != testIssuerURL . String ( ) {
t . Errorf ( "Case %d: want=%v, got=%v" , i ,
testIssuerURL . String ( ) , claims [ "iss" ] )
}
if claims [ "sub" ] != testUserID1 {
t . Errorf ( "Case %d: want=%v, got=%v" , i ,
testUserID1 , claims [ "sub" ] )
}
if diff := pretty . Compare ( claims [ "aud" ] , expectedAud ) ; diff != "" {
t . Errorf ( "Case %d: want=%v, got=%v" , i ,
expectedAud , claims [ "aud" ] )
}
}
}