From e0273d5e99e2494271687d5d51abbdc8c955f169 Mon Sep 17 00:00:00 2001 From: ale <ale@incal.net> Date: Sat, 8 Feb 2020 11:55:32 +0000 Subject: [PATCH] Factor out common strings in tests --- server/http_test.go | 158 ++++++++++++++++++++----------------- server/integration_test.go | 8 +- 2 files changed, 89 insertions(+), 77 deletions(-) diff --git a/server/http_test.go b/server/http_test.go index 3c932a5..c15b78c 100644 --- a/server/http_test.go +++ b/server/http_test.go @@ -25,6 +25,18 @@ import ( "git.autistici.org/id/keystore" ) +// Common strings used throughout the various tests. +const ( + testService = "service.example.com/" + testDestination = "https://service.example.com/admin/" + testNonce = "averysecretnonce" + + testUser = "testuser" + testPassword = "abcdefgh" + testUser2FA = "test2fa" + testOTP = "123456" +) + type fakeAuthClient struct{} func (c *fakeAuthClient) Authenticate(_ context.Context, req *auth.Request) (*auth.Response, error) { @@ -34,11 +46,11 @@ func (c *fakeAuthClient) Authenticate(_ context.Context, req *auth.Request) (*au Groups: []string{"users"}, } switch { - case req.Username == "testuser" && p == "password": + case req.Username == testUser && p == testPassword: return &auth.Response{Status: auth.StatusOK, UserInfo: info}, nil - case req.Username == "test2fa" && p == "password" && req.OTP == "123456": + case req.Username == testUser2FA && p == testPassword && req.OTP == testOTP: return &auth.Response{Status: auth.StatusOK, UserInfo: info}, nil - case req.Username == "test2fa" && p == "password": + case req.Username == testUser2FA && p == testPassword: return &auth.Response{ Status: auth.StatusInsufficientCredentials, TFAMethods: []auth.TFAMethod{auth.TFAMethodOTP}, @@ -74,7 +86,7 @@ func startTestHTTPServer(t testing.TB) (string, *httptest.Server) { } func startTestHTTPServerWithKeyStore(t testing.TB) (string, *httptest.Server, *fakeKeyStore) { - ks := createFakeKeyStore(t, "testuser", "password") + ks := createFakeKeyStore(t, testUser, testPassword) tmpdir, _ := ioutil.TempDir("", "") config := testConfig(t, tmpdir, ks.URL) @@ -195,7 +207,7 @@ func checkRedirectToTargetService(t testing.TB, resp *http.Response) { if resp.StatusCode != 302 { t.Fatalf("expected status 302, got %s", resp.Status) } - if !strings.HasPrefix(resp.Header.Get("Location"), "https://service.example.com/sso_login?") { + if !strings.HasPrefix(resp.Header.Get("Location"), "https://"+testService+"sso_login?") { t.Fatalf("redirect is not to target service: %v", resp.Header.Get("Location")) } } @@ -214,7 +226,7 @@ func checkTargetSSOTicket(config *Config) func(testing.TB, *http.Response) { if err != nil { t.Fatalf("newValidatorFromConfig: %v", err) } - ticket, err := v.Validate(tstr, nonce, "service.example.com/", nil) + ticket, err := v.Validate(tstr, nonce, testService, nil) if err != nil { t.Fatalf("sso.Validate(%s): %v", tstr, err) } @@ -290,7 +302,7 @@ func checkLogoutPage(t testing.TB, resp *http.Response) { t.Fatalf("not the logout page:\n%s", s) } // Check presence of fallback service logout URL. - if !strings.Contains(s, "<img src=\"https://service.example.com/sso_logout\"") { + if !strings.Contains(s, "<img src=\"https://"+testService+"sso_logout\"") { t.Fatalf("logout page does not contain fallback service logout URL:\n%s", s) } // Parse the JSON in the services div. @@ -305,7 +317,7 @@ func checkLogoutPage(t testing.TB, resp *http.Response) { if len(svcs) != 1 { t.Fatalf("expected 1 service, got %d: %v", len(svcs), svcs) } - if svcs[0].URL != "https://service.example.com/sso_logout" { + if svcs[0].URL != "https://"+testService+"sso_logout" { t.Fatalf("bad service logout URL: %s", svcs[0].URL) } } @@ -330,17 +342,17 @@ func TestHTTP_Login(t *testing.T) { // 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") + v.Set("s", testService) + v.Set("d", testDestination) + v.Set("n", testNonce) v.Set("g", "users") doGet(t, c, httpSrv.URL+"/?"+v.Encode(), checkTemplateError, 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") + v.Set("username", testUser) + v.Set("password", testPassword) doPostForm(t, c, httpSrv.URL+"/login", v, checkRedirectToTargetService, checkTargetSSOTicket(config)) } @@ -354,22 +366,22 @@ func TestHTTP_LoginOnSecondAttempt(t *testing.T) { // 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") + v.Set("s", testService) + v.Set("d", testDestination) + v.Set("n", testNonce) doGet(t, c, httpSrv.URL+"/?"+v.Encode(), checkTemplateError, checkStatusOk, checkLoginPageURL, checkLoginPasswordPage) // Attempt to login with wrong credentials. v = make(url.Values) - v.Set("username", "testuser") + v.Set("username", testUser) v.Set("password", "badpassword") doPostForm(t, c, httpSrv.URL+"/login", v, checkTemplateError, 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") + v.Set("username", testUser) + v.Set("password", testPassword) doPostForm(t, c, httpSrv.URL+"/login", v, checkRedirectToTargetService) } @@ -383,16 +395,16 @@ func TestHTTP_LoginAndLogout(t *testing.T) { // 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") + v.Set("s", testService) + v.Set("d", testDestination) + v.Set("n", testNonce) doGet(t, c, httpSrv.URL+"/?"+v.Encode(), checkTemplateError, 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") + v.Set("username", testUser) + v.Set("password", testPassword) doPostForm(t, c, httpSrv.URL+"/login", v, checkRedirectToTargetService) // Make a logout request. @@ -400,9 +412,9 @@ func TestHTTP_LoginAndLogout(t *testing.T) { // This new authorization request should send us to 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") + v.Set("s", testService) + v.Set("d", testDestination) + v.Set("n", testNonce) doGet(t, c, httpSrv.URL+"/?"+v.Encode(), checkTemplateError, checkStatusOk, checkLoginPageURL, checkLoginPasswordPage) } @@ -416,21 +428,21 @@ func TestHTTP_LoginOTP(t *testing.T) { // 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") + v.Set("s", testService) + v.Set("d", testDestination) + v.Set("n", testNonce) doGet(t, c, httpSrv.URL+"/?"+v.Encode(), checkTemplateError, checkStatusOk, checkLoginPageURL, checkLoginPasswordPage) // Attempt to login by submitting the form. We should see the OTP page. v = make(url.Values) - v.Set("username", "test2fa") - v.Set("password", "password") + v.Set("username", testUser2FA) + v.Set("password", testPassword) doPostForm(t, c, httpSrv.URL+"/login", v, checkTemplateError, checkStatusOk, checkLoginOTPPage) // Submit the correct OTP token. We expect the result to be a // 302 redirect to the target service. v = make(url.Values) - v.Set("otp", "123456") + v.Set("otp", testOTP) doPostForm(t, c, httpSrv.URL+"/login/otp", v, checkRedirectToTargetService) } @@ -444,15 +456,15 @@ func TestHTTP_LoginOTP_Fail(t *testing.T) { // 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") + v.Set("s", testService) + v.Set("d", testDestination) + v.Set("n", testNonce) doGet(t, c, httpSrv.URL+"/?"+v.Encode(), checkTemplateError, checkStatusOk, checkLoginPageURL, checkLoginPasswordPage) // Attempt to login by submitting the form. We should see the OTP page. v = make(url.Values) - v.Set("username", "test2fa") - v.Set("password", "password") + v.Set("username", testUser2FA) + v.Set("password", testPassword) doPostForm(t, c, httpSrv.URL+"/login", v, checkTemplateError, checkStatusOk, checkLoginOTPPage) // Submit a bad OTP token, test for failure. @@ -475,15 +487,15 @@ func TestHTTP_LoginOTP_Intermediate404(t *testing.T) { // 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") + v.Set("s", testService) + v.Set("d", testDestination) + v.Set("n", testNonce) doGet(t, c, httpSrv.URL+"/?"+v.Encode(), checkTemplateError, checkStatusOk, checkLoginPageURL, checkLoginPasswordPage) // Attempt to login by submitting the form. We should see the OTP page. v = make(url.Values) - v.Set("username", "test2fa") - v.Set("password", "password") + v.Set("username", testUser2FA) + v.Set("password", testPassword) doPostForm(t, c, httpSrv.URL+"/login", v, checkTemplateError, checkStatusOk, checkLoginOTPPage) // Make a request for a URL that does not exist, browsers might do this @@ -493,7 +505,7 @@ func TestHTTP_LoginOTP_Intermediate404(t *testing.T) { // Submit the correct OTP token. We expect the result to be a // 302 redirect to the target service. v = make(url.Values) - v.Set("otp", "123456") + v.Set("otp", testOTP) doPostForm(t, c, httpSrv.URL+"/login/otp", v, checkRedirectToTargetService) } @@ -534,20 +546,20 @@ func TestHTTP_LoginWithKeyStore(t *testing.T) { // 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") + v.Set("s", testService) + v.Set("d", testDestination) + v.Set("n", testNonce) 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") + v.Set("username", testUser) + v.Set("password", testPassword) doPostForm(t, c, httpSrv.URL+"/login", v, checkRedirectToTargetService) // Verify that the keystore has been called. - if v := ks.values["testuser"]; v != "password" { + if v := ks.values[testUser]; v != testPassword { t.Fatalf("keystore not called as expected: ks_values=%+v", ks.values) } } @@ -563,23 +575,23 @@ func TestHTTP_CORS(t *testing.T) { // 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") + v.Set("s", testService) + v.Set("d", testDestination) + v.Set("n", testNonce) 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") + v.Set("username", testUser) + v.Set("password", testPassword) doPostForm(t, c, httpSrv.URL+"/login", v, checkRedirectToTargetService) // Simulate a CORS preflight request. v = make(url.Values) - v.Set("s", "service.example.com/") - v.Set("d", "https://service.example.com/admin/") - v.Set("n", "averysecretnonce") + v.Set("s", testService) + v.Set("d", testDestination) + v.Set("n", testNonce) req, err := http.NewRequest("OPTIONS", httpSrv.URL+"/?"+v.Encode(), nil) if err != nil { t.Fatalf("NewRequest(): %v", err) @@ -607,24 +619,24 @@ func TestHTTP_LoginAndExchange(t *testing.T) { // 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") + v.Set("s", testService) + v.Set("d", testDestination) + v.Set("n", testNonce) 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") + v.Set("username", testUser) + v.Set("password", testPassword) 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("cur_svc", testService) + v.Set("cur_nonce", testNonce) v.Set("new_svc", "service2.example.com/") v.Set("new_nonce", "anothernonce") doPostForm(t, c, httpSrv.URL+"/exchange", v, checkStatusOk) @@ -632,8 +644,8 @@ func TestHTTP_LoginAndExchange(t *testing.T) { // 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("cur_svc", testService) + v.Set("cur_nonce", testNonce) v.Set("new_svc", "service3.example.com/") v.Set("new_nonce", "anothernonce") doPostForm(t, c, httpSrv.URL+"/exchange", v, checkStatusForbidden) @@ -659,9 +671,9 @@ func TestHTTP_SRI(t *testing.T) { // 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") + v.Set("s", testService) + v.Set("d", testDestination) + v.Set("n", testNonce) v.Set("g", "users") doGet(t, c, httpSrv.URL+"/?"+v.Encode(), checkStatusOk, checkSRI) } @@ -716,9 +728,9 @@ template_dir: "%s/templates" // see the login page. Verify that the page contains our // custom logo, from our template override. v := make(url.Values) - v.Set("s", "service.example.com/") - v.Set("d", "https://service.example.com/admin/") - v.Set("n", "averysecretnonce") + v.Set("s", testService) + v.Set("d", testDestination) + v.Set("n", testNonce) v.Set("g", "users") doGet(t, c, httpSrv.URL+"/?"+v.Encode(), checkStatusOk, checkCustomLogo) } diff --git a/server/integration_test.go b/server/integration_test.go index d1cbace..46d4e8d 100644 --- a/server/integration_test.go +++ b/server/integration_test.go @@ -109,8 +109,8 @@ func TestIntegration(t *testing.T) { doGet(t, c, "https://service.example.com/", checkStatusOk, checkLoginPageURL, checkLoginPasswordPage) v := make(url.Values) - v.Set("username", "testuser") - v.Set("password", "password") + v.Set("username", testUser) + v.Set("password", testPassword) doPostForm(t, c, "https://login.example.com/login", v, checkStatusOk, checkIsProtectedService) // Now attempt to logout, and verify that we can't access the service anymore. @@ -134,8 +134,8 @@ func TestIntegration_WithURLPrefix(t *testing.T) { doGet(t, c, "https://service.example.com/", checkStatusOk, checkLoginPageURLWithPrefix, checkLoginPasswordPage) v := make(url.Values) - v.Set("username", "testuser") - v.Set("password", "password") + v.Set("username", testUser) + v.Set("password", testPassword) doPostForm(t, c, "https://login.example.com/sso/login", v, checkStatusOk, checkIsProtectedService) // Now attempt to logout, and verify that we can't access the service anymore. -- GitLab