Merge branch 'master' into scopes

# Conflicts:
#	pkg/op/authrequest.go
#	pkg/op/authrequest_test.go
This commit is contained in:
Livio Amstutz 2020-09-07 09:39:28 +02:00
commit 007a68d861
20 changed files with 298 additions and 209 deletions

View file

@ -158,27 +158,27 @@ func TestValidateAuthRequest(t *testing.T) {
// }
{
"scope missing fails",
args{&oidc.AuthRequest{}, nil, nil},
args{&oidc.AuthRequest{}, mock.NewMockStorageExpectValidClientID(t), nil},
true,
},
{
"scope openid missing fails",
args{&oidc.AuthRequest{Scopes: []string{"profile"}}, nil, nil},
args{&oidc.AuthRequest{Scopes: []string{"profile"}}, mock.NewMockStorageExpectValidClientID(t), nil},
true,
},
{
"response_type missing fails",
args{&oidc.AuthRequest{Scopes: []string{"openid"}}, nil, nil},
args{&oidc.AuthRequest{Scopes: []string{"openid"}}, mock.NewMockStorageExpectValidClientID(t), nil},
true,
},
{
"client_id missing fails",
args{&oidc.AuthRequest{Scopes: []string{"openid"}, ResponseType: oidc.ResponseTypeCode}, nil, nil},
args{&oidc.AuthRequest{Scopes: []string{"openid"}, ResponseType: oidc.ResponseTypeCode}, mock.NewMockStorageExpectValidClientID(t), nil},
true,
},
{
"redirect_uri missing fails",
args{&oidc.AuthRequest{Scopes: []string{"openid"}, ResponseType: oidc.ResponseTypeCode, ClientID: "client_id"}, nil, nil},
args{&oidc.AuthRequest{Scopes: []string{"openid"}, ResponseType: oidc.ResponseTypeCode, ClientID: "client_id"}, mock.NewMockStorageExpectValidClientID(t), nil},
true,
},
}
@ -223,9 +223,8 @@ func TestValidateAuthReqScopes(t *testing.T) {
func TestValidateAuthReqRedirectURI(t *testing.T) {
type args struct {
uri string
clientID string
client op.Client
responseType oidc.ResponseType
storage op.OPStorage
}
tests := []struct {
name string
@ -234,68 +233,106 @@ func TestValidateAuthReqRedirectURI(t *testing.T) {
}{
{
"empty fails",
args{"", "", oidc.ResponseTypeCode, nil},
args{"",
mock.NewClientWithConfig(t, []string{"https://registered.com/callback"}, op.ApplicationTypeWeb, nil, false),
oidc.ResponseTypeCode},
true,
},
{
"unregistered fails",
args{"https://unregistered.com/callback", "web_client", oidc.ResponseTypeCode, mock.NewMockStorageExpectValidClientID(t)},
true,
},
{
"storage error fails",
args{"https://registered.com/callback", "non_client", oidc.ResponseTypeIDToken, mock.NewMockStorageExpectInvalidClientID(t)},
args{"https://unregistered.com/callback",
mock.NewClientWithConfig(t, []string{"https://registered.com/callback"}, op.ApplicationTypeWeb, nil, false),
oidc.ResponseTypeCode},
true,
},
{
"code flow registered http not confidential fails",
args{"http://registered.com/callback", "useragent_client", oidc.ResponseTypeCode, mock.NewMockStorageExpectValidClientID(t)},
args{"http://registered.com/callback",
mock.NewClientWithConfig(t, []string{"http://registered.com/callback"}, op.ApplicationTypeUserAgent, nil, false),
oidc.ResponseTypeCode},
true,
},
{
"code flow registered http confidential ok",
args{"http://registered.com/callback", "web_client", oidc.ResponseTypeCode, mock.NewMockStorageExpectValidClientID(t)},
args{"http://registered.com/callback",
mock.NewClientWithConfig(t, []string{"http://registered.com/callback"}, op.ApplicationTypeWeb, nil, false),
oidc.ResponseTypeCode},
false,
},
{
"code flow registered custom not native fails",
args{"custom://callback", "useragent_client", oidc.ResponseTypeCode, mock.NewMockStorageExpectValidClientID(t)},
args{"custom://callback",
mock.NewClientWithConfig(t, []string{"custom://callback"}, op.ApplicationTypeUserAgent, nil, false),
oidc.ResponseTypeCode},
true,
},
{
"code flow registered custom native ok",
args{"http://registered.com/callback", "native_client", oidc.ResponseTypeCode, mock.NewMockStorageExpectValidClientID(t)},
args{"custom://callback",
mock.NewClientWithConfig(t, []string{"custom://callback"}, op.ApplicationTypeNative, nil, false),
oidc.ResponseTypeCode},
false,
},
{
"code flow dev mode http ok",
args{"http://registered.com/callback",
mock.NewClientWithConfig(t, []string{"http://registered.com/callback"}, op.ApplicationTypeNative, nil, true),
oidc.ResponseTypeCode},
false,
},
{
"implicit flow registered ok",
args{"https://registered.com/callback", "useragent_client", oidc.ResponseTypeIDToken, mock.NewMockStorageExpectValidClientID(t)},
args{"https://registered.com/callback",
mock.NewClientWithConfig(t, []string{"https://registered.com/callback"}, op.ApplicationTypeUserAgent, nil, false),
oidc.ResponseTypeIDToken},
false,
},
{
"implicit flow unregistered fails",
args{"https://unregistered.com/callback",
mock.NewClientWithConfig(t, []string{"https://registered.com/callback"}, op.ApplicationTypeUserAgent, nil, false),
oidc.ResponseTypeIDToken},
true,
},
{
"implicit flow registered http localhost native ok",
args{"http://localhost:9999/callback", "native_client", oidc.ResponseTypeIDToken, mock.NewMockStorageExpectValidClientID(t)},
args{"http://localhost:9999/callback",
mock.NewClientWithConfig(t, []string{"http://localhost:9999/callback"}, op.ApplicationTypeNative, nil, false),
oidc.ResponseTypeIDToken},
false,
},
{
"implicit flow registered http localhost user agent fails",
args{"http://localhost:9999/callback", "useragent_client", oidc.ResponseTypeIDToken, mock.NewMockStorageExpectValidClientID(t)},
args{"http://localhost:9999/callback",
mock.NewClientWithConfig(t, []string{"http://localhost:9999/callback"}, op.ApplicationTypeUserAgent, nil, false),
oidc.ResponseTypeIDToken},
true,
},
{
"implicit flow http non localhost fails",
args{"http://registered.com/callback", "native_client", oidc.ResponseTypeIDToken, mock.NewMockStorageExpectValidClientID(t)},
args{"http://registered.com/callback",
mock.NewClientWithConfig(t, []string{"http://registered.com/callback"}, op.ApplicationTypeNative, nil, false),
oidc.ResponseTypeIDToken},
true,
},
{
"implicit flow custom fails",
args{"custom://callback", "native_client", oidc.ResponseTypeIDToken, mock.NewMockStorageExpectValidClientID(t)},
args{"custom://callback",
mock.NewClientWithConfig(t, []string{"custom://callback"}, op.ApplicationTypeNative, nil, false),
oidc.ResponseTypeIDToken},
true,
},
{
"implicit flow dev mode http ok",
args{"http://registered.com/callback",
mock.NewClientWithConfig(t, []string{"http://registered.com/callback"}, op.ApplicationTypeNative, nil, true),
oidc.ResponseTypeIDToken},
false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := op.ValidateAuthReqRedirectURI(nil, tt.args.uri, tt.args.clientID, tt.args.responseType, tt.args.storage); (err != nil) != tt.wantErr {
if err := op.ValidateAuthReqRedirectURI(tt.args.client, tt.args.uri, tt.args.responseType); (err != nil) != tt.wantErr {
t.Errorf("ValidateRedirectURI() error = %v, wantErr %v", err.Error(), tt.wantErr)
}
})
@ -305,107 +342,36 @@ func TestValidateAuthReqRedirectURI(t *testing.T) {
func TestValidateAuthReqResponseType(t *testing.T) {
type args struct {
responseType oidc.ResponseType
}
type res struct {
err bool
client op.Client
}
tests := []struct {
name string
args args
res res
name string
args args
wantErr bool
}{
{
"code no error",
args{"code"},
res{false},
"empty response type",
args{"",
mock.NewClientWithConfig(t, nil, op.ApplicationTypeNative, []oidc.ResponseType{oidc.ResponseTypeCode}, true)},
true,
},
{
"id_token token no error",
args{"id_token token"},
res{false},
"response type missing in client config",
args{oidc.ResponseTypeIDToken,
mock.NewClientWithConfig(t, nil, op.ApplicationTypeNative, []oidc.ResponseType{oidc.ResponseTypeCode}, true)},
true,
},
{
"id_token no error",
args{"id_token"},
res{false},
},
{
"no response_type error",
args{},
res{true},
},
{
"invalid response_type error",
args{"invalid"},
res{true},
"valid response type",
args{oidc.ResponseTypeCode,
mock.NewClientWithConfig(t, nil, op.ApplicationTypeNative, []oidc.ResponseType{oidc.ResponseTypeCode}, true)},
false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := op.ValidateAuthReqResponseType(tt.args.responseType); (err != nil) != tt.res.err {
t.Errorf("ValidateAuthReqResponseType() error = %v, wantErr %v", err, tt.res.err)
}
})
}
}
func TestValidateAuthReqIDTokenHint(t *testing.T) {
type args struct {
idTokenHint string
verifier rp.Verifier
}
type res struct {
userID string
err bool
}
tests := []struct {
name string
args args
res res
}{
{
"no id_token_hint, no id and ok",
args{
"",
nil,
},
res{
"",
false,
},
},
{
"invalid id_token_hint, no id and error",
args{
"invalid",
rp_mock.NewMockVerifierExpectInvalid(t),
},
res{
"",
true,
},
},
{
"no id_token_hint ok",
args{
"valid",
rp_mock.NewMockVerifierExpectValid(t),
},
res{
"id",
false,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := op.ValidateAuthReqIDTokenHint(nil, tt.args.idTokenHint, tt.args.verifier)
if (err != nil) != tt.res.err {
t.Errorf("ValidateAuthReqIDTokenHint() error = %v, wantErr %v", err, tt.res.err)
return
}
if got != tt.res.userID {
t.Errorf("ValidateAuthReqIDTokenHint() got = %v, want %v", got, tt.res.userID)
if err := op.ValidateAuthReqResponseType(tt.args.client, tt.args.responseType); (err != nil) != tt.wantErr {
t.Errorf("ValidateAuthReqScopes() error = %v, wantErr %v", err, tt.wantErr)
}
})
}