X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/21e9b0c724c06df630d01ccfedf1312d07f751a0..b9c5339d113c63ffc3d8a7c6bf1019616bb3f89a:/services/keep-web/s3.go diff --git a/services/keep-web/s3.go b/services/keep-web/s3.go index 6ea9bf9f7a..e6262374d6 100644 --- a/services/keep-web/s3.go +++ b/services/keep-web/s3.go @@ -24,7 +24,9 @@ import ( "time" "git.arvados.org/arvados.git/sdk/go/arvados" + "git.arvados.org/arvados.git/sdk/go/arvadosclient" "git.arvados.org/arvados.git/sdk/go/ctxlog" + "git.arvados.org/arvados.git/sdk/go/keepclient" "github.com/AdRoll/goamz/s3" ) @@ -309,19 +311,25 @@ func (h *handler) serveS3(w http.ResponseWriter, r *http.Request) bool { var err error var fs arvados.CustomFileSystem + var arvclient *arvadosclient.ArvadosClient if r.Method == http.MethodGet || r.Method == http.MethodHead { // Use a single session (cached FileSystem) across // multiple read requests. - fs, err = h.Config.Cache.GetSession(token) + var sess *cachedSession + fs, sess, err = h.Config.Cache.GetSession(token) if err != nil { s3ErrorResponse(w, InternalError, err.Error(), r.URL.Path, http.StatusInternalServerError) return true } + arvclient = sess.arvadosclient } else { // Create a FileSystem for this request, to avoid // exposing incomplete write operations to concurrent // requests. - _, kc, client, release, err := h.getClients(r.Header.Get("X-Request-Id"), token) + var kc *keepclient.KeepClient + var release func() + var client *arvados.Client + arvclient, kc, client, release, err = h.getClients(r.Header.Get("X-Request-Id"), token) if err != nil { s3ErrorResponse(w, InternalError, err.Error(), r.URL.Path, http.StatusInternalServerError) return true @@ -396,6 +404,14 @@ func (h *handler) serveS3(w http.ResponseWriter, r *http.Request) bool { s3ErrorResponse(w, NoSuchKey, "The specified key does not exist.", r.URL.Path, http.StatusNotFound) return true } + + tokenUser, err := h.Config.Cache.GetTokenUser(token) + if !h.userPermittedToUploadOrDownload(r.Method, tokenUser) { + http.Error(w, "Not permitted", http.StatusForbidden) + return true + } + h.logUploadOrDownload(r, arvclient, fs, fspath, nil, tokenUser) + // shallow copy r, and change URL path r := *r r.URL.Path = fspath @@ -479,6 +495,14 @@ func (h *handler) serveS3(w http.ResponseWriter, r *http.Request) bool { return true } defer f.Close() + + tokenUser, err := h.Config.Cache.GetTokenUser(token) + if !h.userPermittedToUploadOrDownload(r.Method, tokenUser) { + http.Error(w, "Not permitted", http.StatusForbidden) + return true + } + h.logUploadOrDownload(r, arvclient, fs, fspath, nil, tokenUser) + _, err = io.Copy(f, r.Body) if err != nil { err = fmt.Errorf("write to %q failed: %w", r.URL.Path, err)