From 23f6c01aaf4a3f501e908a689f128e77fc9f23aa Mon Sep 17 00:00:00 2001 From: Peter Amstutz Date: Mon, 14 Jun 2021 17:30:59 -0400 Subject: [PATCH] 17464: Permission/logging testing WIP The upload tests are messing up the other tests by changing the contents of the collection, still need to fix it. Arvados-DCO-1.1-Signed-off-by: Peter Amstutz --- services/keep-web/handler_test.go | 219 +++++++++++++++++++++++++++--- services/keep-web/server_test.go | 4 +- 2 files changed, 201 insertions(+), 22 deletions(-) diff --git a/services/keep-web/handler_test.go b/services/keep-web/handler_test.go index b8c7443f0c..e9f2eaaa32 100644 --- a/services/keep-web/handler_test.go +++ b/services/keep-web/handler_test.go @@ -9,6 +9,7 @@ import ( "context" "fmt" "html" + "io" "io/ioutil" "net/http" "net/http/httptest" @@ -1178,27 +1179,6 @@ func (s *IntegrationSuite) TestCacheWriteCollectionSamePDH(c *check.C) { checkWithID(colls[0].UUID, http.StatusOK) } -// func (s *IntegrationSuite) TestUploadDownloadLogging(c *check.C) { -// u := mustParseURL("http://" + arvadostest.FooCollection + ".keep-web.example/foo") -// req := &http.Request{ -// Method: "GET", -// Host: u.Host, -// URL: u, -// RequestURI: u.RequestURI(), -// Header: http.Header{ -// "Authorization": {"Bearer " + arvadostest.ActiveToken}, -// }, -// } - -// var logbuf bytes.Buffer -// logger := logrus.New() -// logger.Out = &logbuf -// req = req.WithContext(ctxlog.Context(context.Background(), logger)) -// s.doReq(req) - -// c.Check(logbuf.String(), check.Matches, `Download file*`) -// } - func copyHeader(h http.Header) http.Header { hc := http.Header{} for k, v := range h { @@ -1206,3 +1186,200 @@ func copyHeader(h http.Header) http.Header { } return hc } + +func (s *IntegrationSuite) TestDownloadLogging(c *check.C) { + h := handler{Config: newConfig(s.ArvConfig)} + u := mustParseURL("http://" + arvadostest.FooCollection + ".keep-web.example/foo") + req := &http.Request{ + Method: "GET", + Host: u.Host, + URL: u, + RequestURI: u.RequestURI(), + Header: http.Header{ + "Authorization": {"Bearer " + arvadostest.ActiveToken}, + }, + } + + var logbuf bytes.Buffer + logger := logrus.New() + logger.Out = &logbuf + resp := httptest.NewRecorder() + req = req.WithContext(ctxlog.Context(context.Background(), logger)) + h.ServeHTTP(resp, req) + + c.Check(logbuf.String(), check.Matches, `(?ms).*msg="File download".*`) + c.Check(logbuf.String(), check.Not(check.Matches), `(?ms).*level=error.*`) +} + +func (s *IntegrationSuite) TestUploadLogging(c *check.C) { + defer func() { + client := s.testServer.Config.Client + client.RequestAndDecode(nil, "POST", "database/reset", nil, nil) + }() + + h := handler{Config: newConfig(s.ArvConfig)} + u := mustParseURL("http://" + arvadostest.FooCollection + ".keep-web.example/bar") + req := &http.Request{ + Method: "PUT", + Host: u.Host, + URL: u, + RequestURI: u.RequestURI(), + Header: http.Header{ + "Authorization": {"Bearer " + arvadostest.ActiveToken}, + }, + Body: io.NopCloser(bytes.NewReader([]byte("bar"))), + } + + var logbuf bytes.Buffer + logger := logrus.New() + logger.Out = &logbuf + resp := httptest.NewRecorder() + req = req.WithContext(ctxlog.Context(context.Background(), logger)) + h.ServeHTTP(resp, req) + + c.Check(logbuf.String(), check.Matches, `(?ms).*msg="File upload".*`) + c.Check(logbuf.String(), check.Not(check.Matches), `(?ms).*level=error.*`) +} + +func (s *IntegrationSuite) TestDownloadPermission(c *check.C) { + config := newConfig(s.ArvConfig) + h := handler{Config: config} + u := mustParseURL("http://" + arvadostest.FooCollection + ".keep-web.example/foo") + + for _, adminperm := range []bool{true, false} { + for _, userperm := range []bool{true, false} { + + config.cluster.Collections.KeepWebPermission.Admin.Download = adminperm + config.cluster.Collections.KeepWebPermission.User.Download = userperm + + // Test admin permission + req := &http.Request{ + Method: "GET", + Host: u.Host, + URL: u, + RequestURI: u.RequestURI(), + Header: http.Header{ + "Authorization": {"Bearer " + arvadostest.AdminToken}, + }, + } + + var logbuf bytes.Buffer + logger := logrus.New() + logger.Out = &logbuf + resp := httptest.NewRecorder() + req = req.WithContext(ctxlog.Context(context.Background(), logger)) + h.ServeHTTP(resp, req) + + if adminperm { + c.Check(resp.Result().StatusCode, check.Equals, http.StatusOK) + c.Check(logbuf.String(), check.Matches, `(?ms).*msg="File download".*`) + c.Check(logbuf.String(), check.Not(check.Matches), `(?ms).*level=error.*`) + } else { + c.Check(resp.Result().StatusCode, check.Equals, http.StatusForbidden) + c.Check(logbuf.String(), check.Equals, "") + } + + // Test user permission + req = &http.Request{ + Method: "GET", + Host: u.Host, + URL: u, + RequestURI: u.RequestURI(), + Header: http.Header{ + "Authorization": {"Bearer " + arvadostest.ActiveToken}, + }, + } + + logbuf = bytes.Buffer{} + logger = logrus.New() + logger.Out = &logbuf + resp = httptest.NewRecorder() + req = req.WithContext(ctxlog.Context(context.Background(), logger)) + h.ServeHTTP(resp, req) + + if userperm { + c.Check(resp.Result().StatusCode, check.Equals, http.StatusOK) + c.Check(logbuf.String(), check.Matches, `(?ms).*msg="File download".*`) + c.Check(logbuf.String(), check.Not(check.Matches), `(?ms).*level=error.*`) + } else { + c.Check(resp.Result().StatusCode, check.Equals, http.StatusForbidden) + c.Check(logbuf.String(), check.Equals, "") + } + } + } +} + +func (s *IntegrationSuite) TestUploadPermission(c *check.C) { + defer func() { + client := s.testServer.Config.Client + client.RequestAndDecode(nil, "POST", "database/reset", nil, nil) + }() + + config := newConfig(s.ArvConfig) + h := handler{Config: config} + u := mustParseURL("http://" + arvadostest.FooCollection + ".keep-web.example/foo") + + for _, adminperm := range []bool{true, false} { + for _, userperm := range []bool{true, false} { + + config.cluster.Collections.KeepWebPermission.Admin.Upload = adminperm + config.cluster.Collections.KeepWebPermission.User.Upload = userperm + + // Test admin permission + req := &http.Request{ + Method: "PUT", + Host: u.Host, + URL: u, + RequestURI: u.RequestURI(), + Header: http.Header{ + "Authorization": {"Bearer " + arvadostest.AdminToken}, + }, + Body: io.NopCloser(bytes.NewReader([]byte("bar"))), + } + + var logbuf bytes.Buffer + logger := logrus.New() + logger.Out = &logbuf + resp := httptest.NewRecorder() + req = req.WithContext(ctxlog.Context(context.Background(), logger)) + h.ServeHTTP(resp, req) + + if adminperm { + c.Check(resp.Result().StatusCode, check.Equals, http.StatusCreated) + c.Check(logbuf.String(), check.Matches, `(?ms).*msg="File upload".*`) + c.Check(logbuf.String(), check.Not(check.Matches), `(?ms).*level=error.*`) + } else { + c.Check(resp.Result().StatusCode, check.Equals, http.StatusForbidden) + c.Check(logbuf.String(), check.Equals, "") + } + + // Test user permission + req = &http.Request{ + Method: "PUT", + Host: u.Host, + URL: u, + RequestURI: u.RequestURI(), + Header: http.Header{ + "Authorization": {"Bearer " + arvadostest.ActiveToken}, + }, + Body: io.NopCloser(bytes.NewReader([]byte("bar"))), + } + + logbuf = bytes.Buffer{} + logger = logrus.New() + logger.Out = &logbuf + resp = httptest.NewRecorder() + req = req.WithContext(ctxlog.Context(context.Background(), logger)) + h.ServeHTTP(resp, req) + + if userperm { + c.Check(resp.Result().StatusCode, check.Equals, http.StatusCreated) + c.Check(logbuf.String(), check.Matches, `(?ms).*msg="File upload".*`) + c.Check(logbuf.String(), check.Not(check.Matches), `(?ms).*level=error.*`) + } else { + c.Check(resp.Result().StatusCode, check.Equals, http.StatusForbidden) + c.Check(logbuf.String(), check.Equals, "") + } + } + } +} diff --git a/services/keep-web/server_test.go b/services/keep-web/server_test.go index 5c68eb4249..a65a48892a 100644 --- a/services/keep-web/server_test.go +++ b/services/keep-web/server_test.go @@ -34,6 +34,7 @@ var _ = check.Suite(&IntegrationSuite{}) // IntegrationSuite tests need an API server and a keep-web server type IntegrationSuite struct { testServer *server + ArvConfig *arvados.Config } func (s *IntegrationSuite) TestNoToken(c *check.C) { @@ -389,7 +390,7 @@ func (s *IntegrationSuite) TestMetrics(c *check.C) { c.Check(summaries["request_duration_seconds/get/404"].SampleCount, check.Equals, "1") c.Check(summaries["time_to_status_seconds/get/404"].SampleCount, check.Equals, "1") c.Check(counters["arvados_keepweb_collectioncache_requests//"].Value, check.Equals, int64(2)) - c.Check(counters["arvados_keepweb_collectioncache_api_calls//"].Value, check.Equals, int64(1)) + c.Check(counters["arvados_keepweb_collectioncache_api_calls//"].Value, check.Equals, int64(2)) c.Check(counters["arvados_keepweb_collectioncache_hits//"].Value, check.Equals, int64(1)) c.Check(counters["arvados_keepweb_collectioncache_pdh_hits//"].Value, check.Equals, int64(1)) c.Check(counters["arvados_keepweb_collectioncache_permission_hits//"].Value, check.Equals, int64(1)) @@ -446,6 +447,7 @@ func (s *IntegrationSuite) SetUpTest(c *check.C) { cfg.cluster.ManagementToken = arvadostest.ManagementToken cfg.cluster.SystemRootToken = arvadostest.SystemRootToken cfg.cluster.Users.AnonymousUserToken = arvadostest.AnonymousToken + s.ArvConfig = arvCfg s.testServer = &server{Config: cfg} err = s.testServer.Start(ctxlog.TestLogger(c)) c.Assert(err, check.Equals, nil) -- 2.30.2