fix(client/rs): do not error when issuer discovery has no introspection endpoint (#414)

* chore(tests): add basic unit tests for `pkg/client/rs/resource_server.go`
* fix: do not error when issuer discovery has no introspection endpoint
This commit is contained in:
Hugo Hromic 2023-06-23 08:19:58 +01:00 committed by GitHub
parent fb891d8281
commit 406153a4f4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 230 additions and 4 deletions

View file

@ -77,11 +77,15 @@ func newResourceServer(issuer string, authorizer func() (interface{}, error), op
if err != nil { if err != nil {
return nil, err return nil, err
} }
if rs.tokenURL == "" {
rs.tokenURL = config.TokenEndpoint rs.tokenURL = config.TokenEndpoint
}
if rs.introspectURL == "" {
rs.introspectURL = config.IntrospectionEndpoint rs.introspectURL = config.IntrospectionEndpoint
} }
if rs.introspectURL == "" || rs.tokenURL == "" { }
return nil, errors.New("introspectURL and/or tokenURL is empty: please provide with either `WithStaticEndpoints` or a discovery url") if rs.tokenURL == "" {
return nil, errors.New("tokenURL is empty: please provide with either `WithStaticEndpoints` or a discovery url")
} }
rs.authFn = authorizer rs.authFn = authorizer
return rs, nil return rs, nil
@ -113,6 +117,9 @@ func WithStaticEndpoints(tokenURL, introspectURL string) Option {
} }
func Introspect(ctx context.Context, rp ResourceServer, token string) (*oidc.IntrospectionResponse, error) { func Introspect(ctx context.Context, rp ResourceServer, token string) (*oidc.IntrospectionResponse, error) {
if rp.IntrospectionURL() == "" {
return nil, errors.New("resource server: introspection URL is empty")
}
authFn, err := rp.AuthFn() authFn, err := rp.AuthFn()
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -0,0 +1,219 @@
package rs
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestNewResourceServer(t *testing.T) {
type args struct {
issuer string
authorizer func() (interface{}, error)
options []Option
}
type wantFields struct {
issuer string
tokenURL string
introspectURL string
authFn func() (interface{}, error)
}
tests := []struct {
name string
args args
wantFields *wantFields
wantErr bool
}{
{
name: "spotify-full-discovery",
args: args{
issuer: "https://accounts.spotify.com",
authorizer: nil,
options: []Option{},
},
wantFields: &wantFields{
issuer: "https://accounts.spotify.com",
tokenURL: "https://accounts.spotify.com/api/token",
introspectURL: "",
authFn: nil,
},
wantErr: false,
},
{
name: "spotify-with-static-tokenurl",
args: args{
issuer: "https://accounts.spotify.com",
authorizer: nil,
options: []Option{
WithStaticEndpoints(
"https://some.host/token-url",
"",
),
},
},
wantFields: &wantFields{
issuer: "https://accounts.spotify.com",
tokenURL: "https://some.host/token-url",
introspectURL: "",
authFn: nil,
},
wantErr: false,
},
{
name: "spotify-with-static-introspecturl",
args: args{
issuer: "https://accounts.spotify.com",
authorizer: nil,
options: []Option{
WithStaticEndpoints(
"",
"https://some.host/instrospect-url",
),
},
},
wantFields: &wantFields{
issuer: "https://accounts.spotify.com",
tokenURL: "https://accounts.spotify.com/api/token",
introspectURL: "https://some.host/instrospect-url",
authFn: nil,
},
wantErr: false,
},
{
name: "spotify-with-all-static-endpoints",
args: args{
issuer: "https://accounts.spotify.com",
authorizer: nil,
options: []Option{
WithStaticEndpoints(
"https://some.host/token-url",
"https://some.host/instrospect-url",
),
},
},
wantFields: &wantFields{
issuer: "https://accounts.spotify.com",
tokenURL: "https://some.host/token-url",
introspectURL: "https://some.host/instrospect-url",
authFn: nil,
},
wantErr: false,
},
{
name: "bad-discovery",
args: args{
issuer: "https://127.0.0.1:65535",
authorizer: nil,
options: []Option{},
},
wantFields: nil,
wantErr: true,
},
{
name: "bad-discovery-with-static-tokenurl",
args: args{
issuer: "https://127.0.0.1:65535",
authorizer: nil,
options: []Option{
WithStaticEndpoints(
"https://some.host/token-url",
"",
),
},
},
wantFields: nil,
wantErr: true,
},
{
name: "bad-discovery-with-static-introspecturl",
args: args{
issuer: "https://127.0.0.1:65535",
authorizer: nil,
options: []Option{
WithStaticEndpoints(
"",
"https://some.host/instrospect-url",
),
},
},
wantFields: nil,
wantErr: true,
},
{
name: "bad-discovery-with-all-static-endpoints",
args: args{
issuer: "https://127.0.0.1:65535",
authorizer: nil,
options: []Option{
WithStaticEndpoints(
"https://some.host/token-url",
"https://some.host/instrospect-url",
),
},
},
wantFields: &wantFields{
issuer: "https://127.0.0.1:65535",
tokenURL: "https://some.host/token-url",
introspectURL: "https://some.host/instrospect-url",
authFn: nil,
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := newResourceServer(tt.args.issuer, tt.args.authorizer, tt.args.options...)
if tt.wantErr {
assert.Error(t, err)
return
}
require.NoError(t, err)
if tt.wantFields == nil {
return
}
assert.Equal(t, tt.wantFields.issuer, got.issuer)
assert.Equal(t, tt.wantFields.tokenURL, got.tokenURL)
assert.Equal(t, tt.wantFields.introspectURL, got.introspectURL)
})
}
}
func TestIntrospect(t *testing.T) {
type args struct {
ctx context.Context
rp ResourceServer
token string
}
rp, err := newResourceServer(
"https://accounts.spotify.com",
nil,
)
require.NoError(t, err)
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "missing-introspect-url",
args: args{
ctx: nil,
rp: rp,
token: "my-token",
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := Introspect(tt.args.ctx, tt.args.rp, tt.args.token)
if tt.wantErr {
assert.Error(t, err)
return
}
require.NoError(t, err)
})
}
}