package login
import (
"errors"
"io/ioutil"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
"k8s.io/kubernetes/pkg/auth/user"
"github.com/openshift/origin/pkg/auth/server/csrf"
)
type testImplicit struct {
Request *http.Request
User user.Info
Success bool
Err error
Then string
Called bool
}
func (t *testImplicit) AuthenticateRequest(req *http.Request) (user.Info, bool, error) {
t.Request = req
return t.User, t.Success, t.Err
}
func (t *testImplicit) AuthenticationSucceeded(user user.Info, then string, w http.ResponseWriter, req *http.Request) (bool, error) {
t.Called = true
t.User = user
t.Then = then
return false, nil
}
func TestImplicit(t *testing.T) {
testCases := map[string]struct {
CSRF csrf.CSRF
Implicit *testImplicit
Path string
PostValues url.Values
ExpectStatusCode int
ExpectRedirect string
ExpectContains []string
ExpectThen string
}{
"display confirm form": {
CSRF: &csrf.FakeCSRF{Token: "test", Err: nil},
Implicit: &testImplicit{Success: true, User: &user.DefaultInfo{Name: "user"}},
Path: "/login",
ExpectContains: []string{
`action="/login"`,
`You are now logged in as`,
},
},
"successful POST redirects": {
CSRF: &csrf.FakeCSRF{Token: "test", Err: nil},
Implicit: &testImplicit{Success: true, User: &user.DefaultInfo{Name: "user"}},
Path: "/login?then=%2Ffoo",
PostValues: url.Values{"csrf": []string{"test"}},
ExpectThen: "/foo",
},
"redirect when POST fails CSRF": {
CSRF: &csrf.FakeCSRF{Token: "test", Err: nil},
Implicit: &testImplicit{Success: true, User: &user.DefaultInfo{Name: "user"}},
Path: "/login",
PostValues: url.Values{"csrf": []string{"wrong"}},
ExpectRedirect: "/login?reason=token+expired",
},
"redirect when not authenticated": {
CSRF: &csrf.FakeCSRF{Token: "test", Err: nil},
Implicit: &testImplicit{Success: false},
Path: "/login",
PostValues: url.Values{"csrf": []string{"test"}},
ExpectRedirect: "/login?reason=access+denied",
},
"redirect on auth failure": {
CSRF: &csrf.FakeCSRF{Token: "test", Err: nil},
Implicit: &testImplicit{Err: errors.New("failed")},
Path: "/login",
PostValues: url.Values{"csrf": []string{"test"}},
ExpectRedirect: "/login?reason=access+denied",
},
"expect GET error": {
CSRF: &csrf.FakeCSRF{Token: "test", Err: nil},
Implicit: &testImplicit{Err: errors.New("failed")},
ExpectContains: []string{`"message">An unknown error has occurred. Contact your administrator`},
},
}
for k, testCase := range testCases {
server := httptest.NewServer(NewConfirm(testCase.CSRF, testCase.Implicit, DefaultConfirmFormRenderer))
var resp *http.Response
if testCase.PostValues != nil {
r, err := postForm(server.URL+testCase.Path, testCase.PostValues)
if err != nil {
t.Errorf("%s: unexpected error: %v", k, err)
continue
}
resp = r
} else {
r, err := getURL(server.URL + testCase.Path)
if err != nil {
t.Errorf("%s: unexpected error: %v", k, err)
continue
}
resp = r
}
defer resp.Body.Close()
if testCase.ExpectStatusCode != 0 && testCase.ExpectStatusCode != resp.StatusCode {
t.Errorf("%s: unexpected response: %#v", k, resp)
continue
}
if testCase.ExpectRedirect != "" {
uri, err := resp.Location()
if err != nil {
t.Errorf("%s: unexpected error: %v", testCase.ExpectRedirect, err)
continue
}
if uri.String() != server.URL+testCase.ExpectRedirect {
t.Errorf("%s: unexpected redirect: %s", testCase.ExpectRedirect, uri.String())
}
}
if testCase.ExpectThen != "" && (!testCase.Implicit.Called || testCase.Implicit.Then != testCase.ExpectThen) {
t.Errorf("%s: did not find expected 'then' value: %#v", k, testCase.Implicit)
}
if len(testCase.ExpectContains) > 0 {
data, _ := ioutil.ReadAll(resp.Body)
body := string(data)
for i := range testCase.ExpectContains {
if !strings.Contains(body, testCase.ExpectContains[i]) {
t.Errorf("%s: did not find expected value %s: %s", k, testCase.ExpectContains[i], body)
continue
}
}
}
}
}