From f011587d4e72bb7f9333194b2c0895f0b0c8a077 Mon Sep 17 00:00:00 2001 From: Samir Patel <48686912+54mir@users.noreply.github.com> Date: Tue, 21 Dec 2021 10:08:49 -0600 Subject: [PATCH 1/2] add tests --- http/handler_internal_test.go | 367 +++++++++++++++++++++++++--------- 1 file changed, 274 insertions(+), 93 deletions(-) diff --git a/http/handler_internal_test.go b/http/handler_internal_test.go index 5a59a2471..28b80ce07 100644 --- a/http/handler_internal_test.go +++ b/http/handler_internal_test.go @@ -186,6 +186,8 @@ func readResponse(w *httptest.ResponseRecorder) ([]byte, error) { } func TestAuth(t *testing.T) { + type evaluate func(w *httptest.ResponseRecorder, data []byte) + type endpoint func(w gohttp.ResponseWriter, r *gohttp.Request) var ( ClientId = "e9088663-eb08-41d7-8f65-efb5f54bbb71" ClientSecret = "DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF" @@ -222,6 +224,8 @@ func TestAuth(t *testing.T) { auth: a, } + hOff := Handler{} + validToken := oauth2.Token{ TokenType: "Bearer", RefreshToken: "abcdef", @@ -253,77 +257,280 @@ func TestAuth(t *testing.T) { HttpOnly: true, Expires: validToken.Expiry, } + expiredCookie := &gohttp.Cookie{ + Name: "molecula-chip", + Value: validEncodedCV, + Path: "/", + Secure: true, + HttpOnly: true, + Expires: time.Now().Add(time.Minute * -1), + } + emptyCookie := &gohttp.Cookie{ + Name: "molecula-chip", + Value: "", + Path: "/", + Secure: true, + HttpOnly: true, + Expires: validToken.Expiry, + } + unEncodedCookie := &gohttp.Cookie{ + Name: "molecula-chip", + Value: "The quick brown fox", + Path: "/", + Secure: true, + HttpOnly: true, + Expires: validToken.Expiry, + } - t.Run("Login", func(t *testing.T) { - r := httptest.NewRequest(gohttp.MethodGet, "/login", nil) - w := httptest.NewRecorder() + tests := []struct { + name string + path string + kind string + cookie *gohttp.Cookie + handler endpoint + fn evaluate + }{ + { + name: "Login", + path: "/login", + kind: "type1", + cookie: validCookie, + handler: func(w gohttp.ResponseWriter, r *gohttp.Request) { h.handleLogin(w, r) }, + fn: func(w *httptest.ResponseRecorder, data []byte) { + if strings.Index(string(data), AuthorizeURL) != 9 { + t.Errorf("incorrect redirect url: expected: %s, got: %s", AuthorizeURL, string(data)) + } + }, + }, + { + name: "Logout", + path: "/logout", + kind: "type1", + cookie: validCookie, + handler: func(w gohttp.ResponseWriter, r *gohttp.Request) { h.handleLogout(w, r) }, + fn: func(w *httptest.ResponseRecorder, data []byte) { + if w.Result().Cookies()[0].Value != "" { + t.Errorf("expected cookie to be cleared, got: %+v", w.Result().Cookies()[0].Value) + } + }, + }, + { + name: "Authenticate-Groups", + path: "/auth", + kind: "type1", + cookie: validCookie, + handler: func(w gohttp.ResponseWriter, r *gohttp.Request) { h.handleCheckAuthentication(w, r) }, + fn: func(w *httptest.ResponseRecorder, data []byte) { + fmt.Printf("w %+v \n\n", w) + }, + }, + { + name: "Authenticate-NoGroups", + path: "/auth", + kind: "type1", + cookie: validCookie, + handler: func(w gohttp.ResponseWriter, r *gohttp.Request) { h.handleCheckAuthentication(w, r) }, + fn: func(w *httptest.ResponseRecorder, data []byte) { + fmt.Printf("w %+v \n\n", w) + }, + }, + { + name: "Authenticate-BadCookie", + path: "/auth", + kind: "type1", + cookie: unEncodedCookie, + handler: func(w gohttp.ResponseWriter, r *gohttp.Request) { h.handleCheckAuthentication(w, r) }, + fn: func(w *httptest.ResponseRecorder, data []byte) { + fmt.Printf("w %+v \n\n", w) + }, + }, + { + name: "Authenticate-Expired", + path: "/auth", + kind: "type1", + cookie: expiredCookie, + handler: func(w gohttp.ResponseWriter, r *gohttp.Request) { h.handleCheckAuthentication(w, r) }, + fn: func(w *httptest.ResponseRecorder, data []byte) { + fmt.Printf("w %+v \n\n", w) + }, + }, + { + name: "Authenticate-NoCookie", + path: "/auth", + kind: "type1", + cookie: emptyCookie, + handler: func(w gohttp.ResponseWriter, r *gohttp.Request) { h.handleCheckAuthentication(w, r) }, + fn: func(w *httptest.ResponseRecorder, data []byte) { + fmt.Printf("w %+v \n\n", w) + }, + }, + { + name: "UserInfo", + path: "/userinfo", + kind: "type1", + cookie: validCookie, + handler: func(w gohttp.ResponseWriter, r *gohttp.Request) { h.handleUserInfo(w, r) }, + fn: func(w *httptest.ResponseRecorder, data []byte) { + uinfo := authn.UserInfo{} + err = json.Unmarshal(data, &uinfo) + if err != nil { + t.Errorf("unmarshalling userinfo") + } + if uinfo.UserID != "snowstorm" && uinfo.UserName != "J.M.W. Turner" { + t.Errorf("expected http code 400, got: %+v", uinfo) + } + }, + }, + { + name: "UserInfo-NoCookie", + path: "/userinfo", + kind: "type1", + cookie: emptyCookie, + handler: func(w gohttp.ResponseWriter, r *gohttp.Request) { h.handleUserInfo(w, r) }, + fn: func(w *httptest.ResponseRecorder, data []byte) { + uinfo := authn.UserInfo{} + err = json.Unmarshal(data, &uinfo) + if err != nil { + t.Errorf("unmarshalling userinfo") + } + if uinfo.UserID != "" && uinfo.UserName != "" { + t.Errorf("expected http code 400, got: %+v", uinfo) + } + }, + }, + + { + name: "Redirect-NoAuthCode", + path: "/redirect", + kind: "type1", + cookie: validCookie, + handler: func(w gohttp.ResponseWriter, r *gohttp.Request) { h.handleRedirect(w, r) }, + fn: func(w *httptest.ResponseRecorder, data []byte) { + if strings.Index(string(data), AuthorizeURL) != 9 { + if w.Result().StatusCode != 400 { + t.Errorf("expected http code 400, got: %+v", w.Result().StatusCode) + } + } + }, + }, + { + name: "Redirect-SomeAuthCode", + path: "/redirect", + kind: "type2", + cookie: validCookie, + handler: func(w gohttp.ResponseWriter, r *gohttp.Request) { h.handleRedirect(w, r) }, + fn: func(w *httptest.ResponseRecorder, data []byte) { + if strings.Index(string(data), AuthorizeURL) != 9 { + if w.Result().StatusCode != 400 { + t.Errorf("expected http code 400, got: %+v", w.Result().StatusCode) + } + } + }, + }, + { + name: "Login-AuthOff", + path: "/login", + kind: "type1", + cookie: validCookie, + handler: func(w gohttp.ResponseWriter, r *gohttp.Request) { hOff.handleLogin(w, r) }, + fn: func(w *httptest.ResponseRecorder, data []byte) { + if strings.Index(string(data), AuthorizeURL) != 9 { + if w.Result().StatusCode != 204 { + t.Errorf("expected http code 204, got: %+v", w.Result().StatusCode) + } + } + }, + }, + { + name: "Logout-AuthOff", + path: "/logout", + kind: "type1", + cookie: validCookie, + handler: func(w gohttp.ResponseWriter, r *gohttp.Request) { hOff.handleLogout(w, r) }, + fn: func(w *httptest.ResponseRecorder, data []byte) { + if strings.Index(string(data), AuthorizeURL) != 9 { + if w.Result().StatusCode != 204 { + t.Errorf("expected http code 204, got: %+v", w.Result().StatusCode) + } + } + }, + }, + { + name: "UserInfo-AuthOff", + path: "/userinfo", + kind: "type1", + cookie: validCookie, + handler: func(w gohttp.ResponseWriter, r *gohttp.Request) { hOff.handleUserInfo(w, r) }, + fn: func(w *httptest.ResponseRecorder, data []byte) { + if strings.Index(string(data), AuthorizeURL) != 9 { + if w.Result().StatusCode != 204 { + t.Errorf("expected http code 204, got: %+v", w.Result().StatusCode) + } + } + }, + }, + { + name: "Authenticate-AuthOff", + path: "/auth", + kind: "type1", + cookie: validCookie, + handler: func(w gohttp.ResponseWriter, r *gohttp.Request) { hOff.handleCheckAuthentication(w, r) }, + fn: func(w *httptest.ResponseRecorder, data []byte) { + if strings.Index(string(data), AuthorizeURL) != 9 { + if w.Result().StatusCode != 204 { + t.Errorf("expected http code 204, got: %+v", w.Result().StatusCode) + } + } + }, + }, + { + name: "Redirect-AuthOff", + path: "/redirect", + kind: "type1", + cookie: validCookie, + handler: func(w gohttp.ResponseWriter, r *gohttp.Request) { hOff.handleRedirect(w, r) }, + fn: func(w *httptest.ResponseRecorder, data []byte) { + if strings.Index(string(data), AuthorizeURL) != 9 { + if w.Result().StatusCode != 204 { + t.Errorf("expected http code 204, got: %+v", w.Result().StatusCode) + } + } + }, + }, + } + + for _, test := range tests { + switch test.kind { + case "type1": + t.Run(test.name, func(t *testing.T) { + r := httptest.NewRequest(gohttp.MethodGet, test.path, nil) + w := httptest.NewRecorder() + r.AddCookie(test.cookie) + test.handler(w, r) + data, err := readResponse(w) + if err != nil { + t.Errorf("expected no errors reading response, got: %+v", err) + } + test.fn(w, data) + }) + case "type2": + r := httptest.NewRequest(gohttp.MethodGet, test.path, nil) + w := httptest.NewRecorder() + r.Form = url.Values{} + r.Header.Set("Content-Type", "application/x-www-form-urlencoded") + r.Form.Add("code", "junk") + + test.handler(w, r) + data, err := readResponse(w) + if err != nil { + t.Errorf("expected no errors reading response, got: %+v", err) + } + + test.fn(w, data) - //login w/o cookie - h.handleLogin(w, r) - data, err := readResponse(w) - if err != nil { - t.Errorf("expected no errors reading response, got: %+v", err) } - if strings.Index(string(data), AuthorizeURL) != 9 { - t.Errorf("incorrect redirect url: expected: %s, got: %s", AuthorizeURL, string(data)) - } - }) - - t.Run("Logout", func(t *testing.T) { - r := httptest.NewRequest(gohttp.MethodGet, "/logout", nil) - w := httptest.NewRecorder() - r.AddCookie(validCookie) - - h.handleLogout(w, r) - - if w.Result().Cookies()[0].Value != "" { - t.Errorf("expected cookie to be cleared, got: %+v", w.Result().Cookies()[0].Value) - } - }) - - t.Run("Redirect-NoAuthCode", func(t *testing.T) { - r := httptest.NewRequest(gohttp.MethodGet, "/redirect", nil) - w := httptest.NewRecorder() - - h.handleRedirect(w, r) - - if w.Result().StatusCode != 400 { - t.Errorf("expected http code 400, got: %+v", w.Result().StatusCode) - } - - }) - - t.Run("Redirect-SomeAuthCode", func(t *testing.T) { - r := httptest.NewRequest(gohttp.MethodGet, "/redirect", nil) - w := httptest.NewRecorder() - - r.Form = url.Values{} - r.Header.Set("Content-Type", "application/x-www-form-urlencoded") - r.Form.Add("code", "junk") - - h.handleRedirect(w, r) - - if w.Result().StatusCode != 400 { - t.Errorf("expected http code 400, got: %+v", w.Result().StatusCode) - } - - }) - t.Run("Authenticate-Cookie", func(t *testing.T) { - r := httptest.NewRequest(gohttp.MethodGet, "/authenticate", nil) - w := httptest.NewRecorder() - r.AddCookie(validCookie) - - fmt.Printf("r %+v \n\n", r) - - h.handleCheckAuthentication(w, r) - - fmt.Printf("w %+v \n\n", w) - - //auth with cookie - //auth w/o cookie - - }) + } t.Run("GetUserInfo", func(t *testing.T) { r := httptest.NewRequest(gohttp.MethodGet, "/userinfo", nil) @@ -350,30 +557,4 @@ func TestAuth(t *testing.T) { }) - t.Run("GetUserInfo", func(t *testing.T) { - r := httptest.NewRequest(gohttp.MethodGet, "/userinfo", nil) - w := httptest.NewRecorder() - r.AddCookie(validCookie) - - h.handleUserInfo(w, r) - - data, err := readResponse(w) - if err != nil { - t.Errorf("expected no errors reading response, got: %+v", err) - } - - uinfo := authn.UserInfo{} - - err = json.Unmarshal(data, &uinfo) - if err != nil { - t.Errorf("unmarshalling userinfo") - } - - if uinfo.UserID != "snowstorm" && uinfo.UserName != "J.M.W. Turner" { - - t.Errorf("expected http code 400, got: %+v", uinfo) - } - - }) - } From fd7d905be255de650a6e5fd2bdb9129913d5b68b Mon Sep 17 00:00:00 2001 From: Samir Patel <48686912+54mir@users.noreply.github.com> Date: Tue, 21 Dec 2021 15:49:51 -0600 Subject: [PATCH 2/2] fix formatting issues --- authz/authorization_test.go | 21 ++++++++++++--------- server/server.go | 2 +- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/authz/authorization_test.go b/authz/authorization_test.go index 45718fe29..bfda894a9 100644 --- a/authz/authorization_test.go +++ b/authz/authorization_test.go @@ -109,12 +109,15 @@ admin: "ac97c9e2-346b-42a2-b6da-18bcb61a32fe"` groupName := "name" userId := "user-id" groupsList1 := []authn.Group{} - groupsList2 := []authn.Group{{userId, "fake-group", groupName}} + groupsList2 := []authn.Group{{ + UserID: userId, + GroupID: "fake-group", + GroupName: groupName}} groupsList3 := []authn.Group{ - {userId, "dca35310-ecda-4f23-86cd-876aee55906b", groupName}, - {userId, "dca35310-ecda-4f23-86cd-876aee559900", groupName}, + {UserID: userId, GroupID: "dca35310-ecda-4f23-86cd-876aee55906b", GroupName: groupName}, + {UserID: userId, GroupID: "dca35310-ecda-4f23-86cd-876aee559900", GroupName: groupName}, } - groupsList4 := []authn.Group{{userId, "ac97c9e2-346b-42a2-b6da-18bcb61a32fe", groupName}} + groupsList4 := []authn.Group{{UserID: userId, GroupID: "ac97c9e2-346b-42a2-b6da-18bcb61a32fe", GroupName: groupName}} tests := []struct { yamlData string @@ -203,11 +206,11 @@ admin: "ac97c9e2-346b-42a2-b6da-18bcb61a32fe"` func TestAuth_IsAdmin(t *testing.T) { group1 := []authn.Group{ - {"admin-user-id", "ac97c9e2-346b-42a2-b6da-18bcb61a32fe", "admin-group"}, + {UserID: "admin-user-id", GroupID: "ac97c9e2-346b-42a2-b6da-18bcb61a32fe", GroupName: "admin-group"}, } group2 := []authn.Group{ - {"user-id", "dca35310-ecda-4f23-86cd-876aee55906b", "group-name"}, + {UserID: "user-id", GroupID: "dca35310-ecda-4f23-86cd-876aee55906b", GroupName: "group-name"}, } groupPermissions := authz.GroupPermissions{ @@ -244,15 +247,15 @@ func TestAuth_IsAdmin(t *testing.T) { func TestAuth_GetAuthorizedIndexList(t *testing.T) { group1 := []authn.Group{ - {"user-id", "dca35310-ecda-4f23-86cd-876aee55906b", "group-name"}, + {UserID: "user-id", GroupID: "dca35310-ecda-4f23-86cd-876aee55906b", GroupName: "group-name"}, } group2 := []authn.Group{ - {"admin-user-id", "ac97c9e2-346b-42a2-b6da-18bcb61a32fe", "admin-group"}, + {UserID: "admin-user-id", GroupID: "ac97c9e2-346b-42a2-b6da-18bcb61a32fe", GroupName: "admin-group"}, } group3 := []authn.Group{ - {"user-id", "dca35310-ecda-4f23-86cd-876aee559900", "group-name"}, + {UserID: "user-id", GroupID: "dca35310-ecda-4f23-86cd-876aee559900", GroupName: "group-name"}, } p := authz.GroupPermissions{ diff --git a/server/server.go b/server/server.go index 911f82177..a2b963398 100644 --- a/server/server.go +++ b/server/server.go @@ -535,7 +535,7 @@ func (m *Command) SetupServer() error { if err = p.ReadPermissionsFile(permsFile); err != nil { return err } - + ac := m.Config.Auth m.auth, err = authn.NewAuth(m.logger, m.listenURI.String(), ac.Scopes, ac.AuthorizeURL, ac.TokenURL, ac.GroupEndpointURL, ac.LogoutURL, ac.ClientId, ac.ClientSecret, ac.HashKey, ac.BlockKey) if err != nil {