mirror of https://github.com/dexidp/dex.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
261 lines
6.6 KiB
261 lines
6.6 KiB
package server |
|
|
|
import ( |
|
"errors" |
|
"net/http" |
|
"net/http/httptest" |
|
"net/url" |
|
"reflect" |
|
"testing" |
|
|
|
"github.com/coreos/go-oidc/oauth2" |
|
) |
|
|
|
func TestWriteAPIError(t *testing.T) { |
|
tests := []struct { |
|
err error |
|
code int |
|
wantCode int |
|
wantBody string |
|
}{ |
|
// standard |
|
{ |
|
err: newAPIError(errorInvalidRequest, "foo"), |
|
code: http.StatusBadRequest, |
|
wantCode: http.StatusBadRequest, |
|
wantBody: `{"error":"invalid_request","error_description":"foo"}`, |
|
}, |
|
// no description |
|
{ |
|
err: newAPIError(errorInvalidRequest, ""), |
|
code: http.StatusBadRequest, |
|
wantCode: http.StatusBadRequest, |
|
wantBody: `{"error":"invalid_request"}`, |
|
}, |
|
// no type |
|
{ |
|
err: newAPIError("", ""), |
|
code: http.StatusBadRequest, |
|
wantCode: http.StatusBadRequest, |
|
wantBody: `{"error":"server_error"}`, |
|
}, |
|
// generic error |
|
{ |
|
err: errors.New("generic failure"), |
|
code: http.StatusTeapot, |
|
wantCode: http.StatusTeapot, |
|
wantBody: `{"error":"server_error"}`, |
|
}, |
|
// nil error |
|
{ |
|
err: nil, |
|
code: http.StatusTeapot, |
|
wantCode: http.StatusTeapot, |
|
wantBody: `{"error":"server_error"}`, |
|
}, |
|
// empty code |
|
{ |
|
err: nil, |
|
code: 0, |
|
wantCode: http.StatusInternalServerError, |
|
wantBody: `{"error":"server_error"}`, |
|
}, |
|
} |
|
|
|
for i, tt := range tests { |
|
w := httptest.NewRecorder() |
|
writeAPIError(w, tt.code, tt.err) |
|
|
|
if tt.wantCode != w.Code { |
|
t.Errorf("case %d: incorrect HTTP status: want=%d got=%d", i, tt.wantCode, w.Code) |
|
} |
|
|
|
gotBody := w.Body.String() |
|
if tt.wantBody != gotBody { |
|
t.Errorf("case %d: incorrect HTTP body: want=%q got=%q", i, tt.wantBody, gotBody) |
|
} |
|
} |
|
} |
|
|
|
func TestWriteTokenError(t *testing.T) { |
|
tests := []struct { |
|
err error |
|
state string |
|
wantCode int |
|
wantHeader http.Header |
|
wantBody string |
|
}{ |
|
{ |
|
err: oauth2.NewError(oauth2.ErrorInvalidRequest), |
|
state: "bazinga", |
|
wantCode: http.StatusBadRequest, |
|
wantHeader: http.Header{ |
|
"Content-Type": []string{"application/json"}, |
|
}, |
|
wantBody: `{"error":"invalid_request","state":"bazinga"}`, |
|
}, |
|
{ |
|
err: oauth2.NewError(oauth2.ErrorInvalidRequest), |
|
wantCode: http.StatusBadRequest, |
|
wantHeader: http.Header{ |
|
"Content-Type": []string{"application/json"}, |
|
}, |
|
wantBody: `{"error":"invalid_request"}`, |
|
}, |
|
{ |
|
err: oauth2.NewError(oauth2.ErrorInvalidGrant), |
|
wantCode: http.StatusBadRequest, |
|
wantHeader: http.Header{ |
|
"Content-Type": []string{"application/json"}, |
|
}, |
|
wantBody: `{"error":"invalid_grant"}`, |
|
}, |
|
{ |
|
err: oauth2.NewError(oauth2.ErrorInvalidClient), |
|
wantCode: http.StatusUnauthorized, |
|
wantHeader: http.Header{ |
|
"Content-Type": []string{"application/json"}, |
|
"Www-Authenticate": []string{"Basic"}, |
|
}, |
|
wantBody: `{"error":"invalid_client"}`, |
|
}, |
|
{ |
|
err: oauth2.NewError(oauth2.ErrorServerError), |
|
wantCode: http.StatusBadRequest, |
|
wantHeader: http.Header{ |
|
"Content-Type": []string{"application/json"}, |
|
}, |
|
wantBody: `{"error":"server_error"}`, |
|
}, |
|
{ |
|
err: oauth2.NewError(oauth2.ErrorUnsupportedGrantType), |
|
wantCode: http.StatusBadRequest, |
|
wantHeader: http.Header{ |
|
"Content-Type": []string{"application/json"}, |
|
}, |
|
wantBody: `{"error":"unsupported_grant_type"}`, |
|
}, |
|
{ |
|
err: errors.New("generic failure"), |
|
wantCode: http.StatusBadRequest, |
|
wantHeader: http.Header{ |
|
"Content-Type": []string{"application/json"}, |
|
}, |
|
wantBody: `{"error":"server_error"}`, |
|
}, |
|
} |
|
|
|
for i, tt := range tests { |
|
w := httptest.NewRecorder() |
|
writeTokenError(w, tt.err, tt.state) |
|
|
|
if tt.wantCode != w.Code { |
|
t.Errorf("case %d: incorrect HTTP status: want=%d got=%d", i, tt.wantCode, w.Code) |
|
} |
|
|
|
gotHeader := w.Header() |
|
if !reflect.DeepEqual(tt.wantHeader, gotHeader) { |
|
t.Errorf("case %d: incorrect HTTP headers: want=%#v got=%#v", i, tt.wantHeader, gotHeader) |
|
} |
|
|
|
gotBody := w.Body.String() |
|
if tt.wantBody != gotBody { |
|
t.Errorf("case %d: incorrect HTTP body: want=%q got=%q", i, tt.wantBody, gotBody) |
|
} |
|
} |
|
} |
|
|
|
func TestWriteAuthError(t *testing.T) { |
|
wantCode := http.StatusBadRequest |
|
wantHeader := http.Header{"Content-Type": []string{"application/json"}} |
|
tests := []struct { |
|
err error |
|
state string |
|
wantBody string |
|
}{ |
|
{ |
|
err: errors.New("foobar"), |
|
state: "bazinga", |
|
wantBody: `{"error":"server_error","state":"bazinga"}`, |
|
}, |
|
{ |
|
err: oauth2.NewError(oauth2.ErrorInvalidRequest), |
|
state: "foo", |
|
wantBody: `{"error":"invalid_request","state":"foo"}`, |
|
}, |
|
{ |
|
err: oauth2.NewError(oauth2.ErrorUnsupportedResponseType), |
|
state: "bar", |
|
wantBody: `{"error":"unsupported_response_type","state":"bar"}`, |
|
}, |
|
} |
|
|
|
for i, tt := range tests { |
|
w := httptest.NewRecorder() |
|
writeAuthError(w, tt.err, tt.state) |
|
|
|
if wantCode != w.Code { |
|
t.Errorf("case %d: incorrect HTTP status: want=%d got=%d", i, wantCode, w.Code) |
|
} |
|
|
|
gotHeader := w.Header() |
|
if !reflect.DeepEqual(wantHeader, gotHeader) { |
|
t.Errorf("case %d: incorrect HTTP headers: want=%#v got=%#v", i, wantHeader, gotHeader) |
|
} |
|
|
|
gotBody := w.Body.String() |
|
if tt.wantBody != gotBody { |
|
t.Errorf("case %d: incorrect HTTP body: want=%q got=%q", i, tt.wantBody, gotBody) |
|
} |
|
} |
|
} |
|
|
|
func TestRedirectAuthError(t *testing.T) { |
|
wantCode := http.StatusFound |
|
|
|
tests := []struct { |
|
err error |
|
state string |
|
redirectURL url.URL |
|
wantLoc string |
|
}{ |
|
{ |
|
err: errors.New("foobar"), |
|
state: "bazinga", |
|
redirectURL: url.URL{Scheme: "http", Host: "server.example.com"}, |
|
wantLoc: "http://server.example.com?error=server_error&state=bazinga", |
|
}, |
|
{ |
|
err: oauth2.NewError(oauth2.ErrorInvalidRequest), |
|
state: "foo", |
|
redirectURL: url.URL{Scheme: "http", Host: "server.example.com"}, |
|
wantLoc: "http://server.example.com?error=invalid_request&state=foo", |
|
}, |
|
{ |
|
err: oauth2.NewError(oauth2.ErrorUnsupportedResponseType), |
|
state: "bar", |
|
redirectURL: url.URL{Scheme: "http", Host: "server.example.com"}, |
|
wantLoc: "http://server.example.com?error=unsupported_response_type&state=bar", |
|
}, |
|
} |
|
|
|
for i, tt := range tests { |
|
w := httptest.NewRecorder() |
|
redirectAuthError(w, tt.err, tt.state, tt.redirectURL) |
|
|
|
if wantCode != w.Code { |
|
t.Errorf("case %d: incorrect HTTP status: want=%d got=%d", i, wantCode, w.Code) |
|
} |
|
|
|
wantHeader := http.Header{"Location": []string{tt.wantLoc}} |
|
gotHeader := w.Header() |
|
if !reflect.DeepEqual(wantHeader, gotHeader) { |
|
t.Errorf("case %d: incorrect HTTP headers: want=%#v got=%#v", i, wantHeader, gotHeader) |
|
} |
|
|
|
gotBody := w.Body.String() |
|
if gotBody != "" { |
|
t.Errorf("case %d: incorrect empty HTTP body, got=%q", i, gotBody) |
|
} |
|
} |
|
}
|
|
|