package headerrequest import ( "net/http" "reflect" "testing" "github.com/openshift/origin/pkg/auth/api" "k8s.io/kubernetes/pkg/auth/user" ) type TestUserIdentityMapper struct { Identity api.UserIdentityInfo } func (m *TestUserIdentityMapper) UserFor(identityInfo api.UserIdentityInfo) (user.Info, error) { m.Identity = identityInfo username := identityInfo.GetProviderUserName() if preferredUsername := identityInfo.GetExtra()[api.IdentityPreferredUsernameKey]; len(preferredUsername) > 0 { username = preferredUsername } return &user.DefaultInfo{Name: username}, nil } func TestRequestHeader(t *testing.T) { testcases := map[string]struct { Config Config RequestHeaders http.Header ExpectedUsername string ExpectedIdentity api.UserIdentityInfo }{ "empty": { ExpectedUsername: "", }, "no match": { Config: Config{IDHeaders: []string{"X-Remote-User"}}, ExpectedUsername: "", }, "match": { Config: Config{IDHeaders: []string{"X-Remote-User"}}, RequestHeaders: http.Header{"X-Remote-User": {"Bob"}}, ExpectedUsername: "Bob", }, "exact match": { Config: Config{IDHeaders: []string{"X-Remote-User"}}, RequestHeaders: http.Header{ "Prefixed-X-Remote-User-With-Suffix": {"Bob"}, "X-Remote-User-With-Suffix": {"Bob"}, }, ExpectedUsername: "", }, "first match": { Config: Config{IDHeaders: []string{ "X-Remote-User", "A-Second-X-Remote-User", "Another-X-Remote-User", }}, RequestHeaders: http.Header{ "X-Remote-User": {"", "First header, second value"}, "A-Second-X-Remote-User": {"Second header, first value", "Second header, second value"}, "Another-X-Remote-User": {"Third header, first value"}}, ExpectedUsername: "Second header, first value", }, "case-insensitive": { Config: Config{IDHeaders: []string{"x-REMOTE-user"}}, // configured headers can be case-insensitive RequestHeaders: http.Header{"X-Remote-User": {"Bob"}}, // the parsed headers are normalized by the http package ExpectedUsername: "Bob", }, "extended attributes": { Config: Config{ IDHeaders: []string{"x-id", "x-id2"}, PreferredUsernameHeaders: []string{"x-preferred-username", "x-preferred-username2"}, EmailHeaders: []string{"x-email", "x-email2"}, NameHeaders: []string{"x-name", "x-name2"}, }, RequestHeaders: http.Header{ "X-Id2": {"12345"}, "X-Preferred-Username2": {"bob"}, "X-Email2": {"bob@example.com"}, "X-Name2": {"Bob"}, }, ExpectedUsername: "bob", ExpectedIdentity: &api.DefaultUserIdentityInfo{ ProviderName: "testprovider", ProviderUserName: "12345", Extra: map[string]string{ api.IdentityDisplayNameKey: "Bob", api.IdentityEmailKey: "bob@example.com", api.IdentityPreferredUsernameKey: "bob", }, }, }, } for k, testcase := range testcases { mapper := &TestUserIdentityMapper{} auth := NewAuthenticator("testprovider", &testcase.Config, mapper) req := &http.Request{Header: testcase.RequestHeaders} user, ok, err := auth.AuthenticateRequest(req) if testcase.ExpectedUsername == "" { if ok { t.Errorf("%s: Didn't expect user, authentication succeeded", k) continue } } if testcase.ExpectedUsername != "" { if err != nil { t.Errorf("%s: Expected user, got error: %v", k, err) continue } if !ok { t.Errorf("%s: Expected user, auth failed", k) continue } if testcase.ExpectedUsername != user.GetName() { t.Errorf("%s: Expected username %s, got %s", k, testcase.ExpectedUsername, user.GetName()) continue } } if testcase.ExpectedIdentity != nil { if !reflect.DeepEqual(testcase.ExpectedIdentity.GetExtra(), mapper.Identity.GetExtra()) { t.Errorf("%s: Expected %#v, got %#v", k, testcase.ExpectedIdentity.GetExtra(), mapper.Identity.GetExtra()) } if !reflect.DeepEqual(testcase.ExpectedIdentity.GetProviderUserName(), mapper.Identity.GetProviderUserName()) { t.Errorf("%s: Expected %#v, got %#v", k, testcase.ExpectedIdentity.GetProviderUserName(), mapper.Identity.GetProviderUserName()) } } } }