diff --git a/server/http_test.go b/server/http_test.go index b3a5e267f8ea748282089febbce4ebde411477a7..299623a5b603335511eb9c9e03b53c6938f1121d 100644 --- a/server/http_test.go +++ b/server/http_test.go @@ -158,12 +158,18 @@ func checkStatusOk(t testing.TB, resp *http.Response) { } } +func checkStatusForbidden(t testing.TB, resp *http.Response) { + if resp.StatusCode != 403 { + t.Fatalf("expected status 403, got %s", resp.Status) + } +} + func checkStatusNotFound(t testing.TB, resp *http.Response) { if resp.StatusCode != 404 { t.Fatalf("expected status 404, got %s", resp.Status) } - } + func checkRedirectToTargetService(t testing.TB, resp *http.Response) { if resp.StatusCode != 302 { t.Fatalf("expected status 302, got %s", resp.Status) @@ -260,6 +266,16 @@ func checkLogoutPage(t testing.TB, resp *http.Response) { } } +func extractSSOTicket(dest *string) func(testing.TB, *http.Response) { + return func(t testing.TB, resp *http.Response) { + u, err := url.Parse(resp.Header.Get("Location")) + if err != nil { + t.Fatalf("could not parse Location URL: %v", err) + } + *dest = u.Query().Get("t") + } +} + func TestHTTP_Login(t *testing.T) { tmpdir, httpSrv, config := startTestHTTPServerWithConfig(t) defer os.RemoveAll(tmpdir) @@ -527,3 +543,45 @@ func TestHTTP_CORS(t *testing.T) { t.Fatalf("Bad Access-Control-Allow-Origin returned to OPTIONS request: %s", s) } } + +func TestHTTP_LoginAndExchange(t *testing.T) { + tmpdir, httpSrv := startTestHTTPServer(t) + defer os.RemoveAll(tmpdir) + defer httpSrv.Close() + + c := newTestHTTPClient() + + // Simulate an authorization request from a service, expect to + // see the login page. + v := make(url.Values) + v.Set("s", "service.example.com/") + v.Set("d", "https://service.example.com/admin/") + v.Set("n", "averysecretnonce") + doGet(t, c, httpSrv.URL+"/?"+v.Encode(), checkStatusOk, checkLoginPageURL, checkLoginPasswordPage) + + // Attempt to login by submitting the form. We expect the + // result to be a 302 redirect to the target service. + v = make(url.Values) + v.Set("username", "testuser") + v.Set("password", "password") + var ssoTkt string + doPostForm(t, c, httpSrv.URL+"/login", v, checkRedirectToTargetService, extractSSOTicket(&ssoTkt)) + + // Make an exchange request for a new service. + v = make(url.Values) + v.Set("cur_tkt", ssoTkt) + v.Set("cur_svc", "service.example.com/") + v.Set("cur_nonce", "averysecretnonce") + v.Set("new_svc", "service2.example.com/") + v.Set("new_nonce", "anothernonce") + doPostForm(t, c, httpSrv.URL+"/exchange", v, checkStatusOk) + + // Make an exchange request for a forbidden service. + v = make(url.Values) + v.Set("cur_tkt", ssoTkt) + v.Set("cur_svc", "service.example.com/") + v.Set("cur_nonce", "averysecretnonce") + v.Set("new_svc", "service3.example.com/") + v.Set("new_nonce", "anothernonce") + doPostForm(t, c, httpSrv.URL+"/exchange", v, checkStatusForbidden) +} diff --git a/server/service_test.go b/server/service_test.go index 6829ff49f249bc0f9d115214cda40660ceafedec..f6a740fd591884416581f673dfcc015c3e9fc15a 100644 --- a/server/service_test.go +++ b/server/service_test.go @@ -39,9 +39,10 @@ domain: example.com allowed_services: - "^service\\.example\\.com/$" - "^service2\\.example\\.com/$" + - "^service3\\.example\\.com/$" allowed_exchanges: - src_regexp: "^service\\.example\\.com/$" - dst_regexp: "\\.example\\.com/.*$" + dst_regexp: "^service2\\.example\\.com/$" allowed_cors_origins: - "https://origin.example.com" service_ttls: @@ -139,9 +140,10 @@ func TestLoginService_Exchange(t *testing.T) { service, destination string ok bool }{ + {"service.example.com/", "service.example.com/", false}, {"service.example.com/", "service2.example.com/", true}, + {"service.example.com/", "service3.example.com/", false}, {"service.example.com/", "bad-service.another.com/", false}, - {"service.example.com/", "service.example.com/", true}, // self-exchange?? } for _, td := range testdata {