[ARVADOS] updated: 1.1.3-395-ge6c9fc6

Git user git at public.curoverse.com
Thu Apr 12 13:33:35 EDT 2018


Summary of changes:
 sdk/go/arvados/fs_base.go           |  4 ++++
 sdk/go/arvados/fs_collection.go     |  4 ++--
 sdk/go/arvados/fs_project.go        |  4 ++--
 sdk/go/arvados/fs_project_test.go   | 29 +++++++++++++++++++++++++++++
 sdk/go/arvados/group.go             | 11 ++++++++---
 sdk/go/httpserver/responsewriter.go |  3 +++
 services/keep-web/cadaver_test.go   | 16 ++++++++++++++++
 services/keep-web/doc.go            | 25 ++++++++++++++++++++-----
 services/keep-web/handler.go        | 23 +++++++++++++++++------
 services/keep-web/handler_test.go   | 15 ++++++++++++++-
 10 files changed, 115 insertions(+), 19 deletions(-)

       via  e6c9fc68cd6d4d281d81928729a2bd18007a96a4 (commit)
       via  3e16165a984135149ae9d87d29afa40e691c83b9 (commit)
       via  56d62dcc77f87af6d7f1403f510639740d87e6c2 (commit)
       via  57ecd452751d0f6efd2ecdb6add67890d2e36964 (commit)
       via  6ae864435a2c185b373703b3d6fc696211c3b79c (commit)
       via  cf79bd5e4f3cb2176a9d8939c720f95b26caea91 (commit)
      from  61a5f1cab58f4652a9f9bdd4f6bc26c887eae75b (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit e6c9fc68cd6d4d281d81928729a2bd18007a96a4
Author: Tom Clegg <tclegg at veritasgenetics.com>
Date:   Thu Apr 12 13:29:20 2018 -0400

    13111: Update docs.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tclegg at veritasgenetics.com>

diff --git a/services/keep-web/doc.go b/services/keep-web/doc.go
index b7da3b0..6c867f0 100644
--- a/services/keep-web/doc.go
+++ b/services/keep-web/doc.go
@@ -133,8 +133,21 @@
 //   http://zzzzz-4zz18-znfnqtbbv4spc3w.collections.example.com/foo/bar.txt
 //   http://zzzzz-4zz18-znfnqtbbv4spc3w.collections.example.com/_/foo/bar.txt
 //   http://zzzzz-4zz18-znfnqtbbv4spc3w--collections.example.com/_/foo/bar.txt
+//
+// The following URLs are read-only, but otherwise interchangeable
+// with the above:
+//
 //   http://1f4b0bc7583c2a7f9102c395f4ffc5e3-45--foo.example.com/foo/bar.txt
 //   http://1f4b0bc7583c2a7f9102c395f4ffc5e3-45--.invalid/foo/bar.txt
+//   http://collections.example.com/by_id/1f4b0bc7583c2a7f9102c395f4ffc5e3%2B45/foo/bar.txt
+//   http://collections.example.com/by_id/zzzzz-4zz18-znfnqtbbv4spc3w/foo/bar.txt
+//
+// If the collection is named "My Collection" and located in a project
+// called "My Project" which is in the home project of a user with
+// username is "bob", the following read-only URL is also available
+// when authenticating as bob:
+//
+//   http://collections.example.com/users/bob/My+Project/My+Collection/foo/bar.txt
 //
 // An additional form is supported specifically to make it more
 // convenient to maintain support for existing Workbench download
@@ -148,6 +161,9 @@
 //
 //   http://collections.example.com/collections/uuid_or_pdh/foo/bar.txt
 //
+// Collections can also be accessed (read-only) via "/by_id/X" where X
+// is a UUID or portable data hash.
+//
 // Authorization mechanisms
 //
 // A token can be provided in an Authorization header:
@@ -178,11 +194,10 @@
 //
 // Indexes
 //
-// Currently, keep-web does not generate HTML index listings, nor does
-// it serve a default file like "index.html" when a directory is
-// requested. These features are likely to be added in future
-// versions. Until then, keep-web responds with 404 if a directory
-// name (or any path ending with "/") is requested.
+// Keep-web returns a generic HTML index listing when a directory is
+// requested with the GET method. It does not serve a default file
+// like "index.html". Directory listings are also returned for WebDAV
+// PROPFIND requests.
 //
 // Compatibility
 //

commit 3e16165a984135149ae9d87d29afa40e691c83b9
Author: Tom Clegg <tclegg at veritasgenetics.com>
Date:   Thu Apr 12 13:28:31 2018 -0400

    13111: Follow attachment-only policy at /by_id/ and /users/ paths.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tclegg at veritasgenetics.com>

diff --git a/services/keep-web/handler.go b/services/keep-web/handler.go
index 0618588..8b61b54 100644
--- a/services/keep-web/handler.go
+++ b/services/keep-web/handler.go
@@ -14,6 +14,7 @@ import (
 	"net/http"
 	"net/url"
 	"os"
+	"path/filepath"
 	"sort"
 	"strconv"
 	"strings"
@@ -335,7 +336,7 @@ func (h *handler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) {
 	}
 
 	if useSiteFS {
-		h.serveSiteFS(w, r, tokens, credentialsOK)
+		h.serveSiteFS(w, r, tokens, credentialsOK, attachment)
 		return
 	}
 
@@ -505,7 +506,7 @@ func (h *handler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) {
 	}
 }
 
-func (h *handler) serveSiteFS(w http.ResponseWriter, r *http.Request, tokens []string, credentialsOK bool) {
+func (h *handler) serveSiteFS(w http.ResponseWriter, r *http.Request, tokens []string, credentialsOK, attachment bool) {
 	if len(tokens) == 0 {
 		w.Header().Add("WWW-Authenticate", "Basic realm=\"collections\"")
 		http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
@@ -551,6 +552,10 @@ func (h *handler) serveSiteFS(w http.ResponseWriter, r *http.Request, tokens []s
 		}
 		return
 	}
+	if r.Method == "GET" {
+		_, basename := filepath.Split(r.URL.Path)
+		applyContentDispositionHdr(w, r, basename, attachment)
+	}
 	wh := webdav.Handler{
 		Prefix: "/",
 		FileSystem: &webdavFS{
diff --git a/services/keep-web/handler_test.go b/services/keep-web/handler_test.go
index 15f32f1..4894ceb 100644
--- a/services/keep-web/handler_test.go
+++ b/services/keep-web/handler_test.go
@@ -333,7 +333,20 @@ func (s *IntegrationSuite) TestVhostRedirectQueryTokenRequestAttachment(c *check
 		http.StatusOK,
 		"foo",
 	)
-	c.Check(strings.Split(resp.Header().Get("Content-Disposition"), ";")[0], check.Equals, "attachment")
+	c.Check(resp.Header().Get("Content-Disposition"), check.Matches, "attachment(;.*)?")
+}
+
+func (s *IntegrationSuite) TestVhostRedirectQueryTokenSiteFS(c *check.C) {
+	s.testServer.Config.AttachmentOnlyHost = "download.example.com"
+	resp := s.testVhostRedirectTokenToCookie(c, "GET",
+		"download.example.com/by_id/"+arvadostest.FooCollection+"/foo",
+		"?api_token="+arvadostest.ActiveToken,
+		"",
+		"",
+		http.StatusOK,
+		"foo",
+	)
+	c.Check(resp.Header().Get("Content-Disposition"), check.Matches, "attachment(;.*)?")
 }
 
 func (s *IntegrationSuite) TestVhostRedirectQueryTokenTrustAllContent(c *check.C) {

commit 56d62dcc77f87af6d7f1403f510639740d87e6c2
Author: Tom Clegg <tclegg at veritasgenetics.com>
Date:   Thu Apr 12 10:14:31 2018 -0400

    13111: Serve /by_id/ dir.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tclegg at veritasgenetics.com>

diff --git a/services/keep-web/cadaver_test.go b/services/keep-web/cadaver_test.go
index 22ddd84..db5d373 100644
--- a/services/keep-web/cadaver_test.go
+++ b/services/keep-web/cadaver_test.go
@@ -265,6 +265,22 @@ func (s *IntegrationSuite) testCadaver(c *check.C, password string, pathFunc fun
 	}
 }
 
+func (s *IntegrationSuite) TestCadaverByID(c *check.C) {
+	for _, path := range []string{"/by_id", "/by_id/"} {
+		stdout := s.runCadaver(c, arvadostest.ActiveToken, path, "ls")
+		c.Check(stdout, check.Matches, `(?ms).*collection is empty.*`)
+	}
+	for _, path := range []string{
+		"/by_id/" + arvadostest.FooPdh,
+		"/by_id/" + arvadostest.FooPdh + "/",
+		"/by_id/" + arvadostest.FooCollection,
+		"/by_id/" + arvadostest.FooCollection + "/",
+	} {
+		stdout := s.runCadaver(c, arvadostest.ActiveToken, path, "ls")
+		c.Check(stdout, check.Matches, `(?ms).*\s+foo\s+3 .*`)
+	}
+}
+
 func (s *IntegrationSuite) TestCadaverUsersDir(c *check.C) {
 	for _, path := range []string{"/"} {
 		stdout := s.runCadaver(c, arvadostest.ActiveToken, path, "ls")
diff --git a/services/keep-web/handler.go b/services/keep-web/handler.go
index 389ab73..0618588 100644
--- a/services/keep-web/handler.go
+++ b/services/keep-web/handler.go
@@ -163,6 +163,12 @@ var (
 		"HEAD": true,
 		"POST": true,
 	}
+	// top-level dirs to serve with siteFS
+	siteFSDir = map[string]bool{
+		"":      true, // root directory
+		"by_id": true,
+		"users": true,
+	}
 )
 
 // ServeHTTP implements http.Handler.
@@ -250,7 +256,7 @@ func (h *handler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) {
 	} else if r.URL.Path == "/status.json" {
 		h.serveStatus(w, r)
 		return
-	} else if r.URL.Path == "/" || (len(pathParts) >= 1 && pathParts[0] == "users") {
+	} else if siteFSDir[pathParts[0]] {
 		useSiteFS = true
 	} else if len(pathParts) >= 1 && strings.HasPrefix(pathParts[0], "c=") {
 		// /c=ID[/PATH...]

commit 57ecd452751d0f6efd2ecdb6add67890d2e36964
Author: Tom Clegg <tclegg at veritasgenetics.com>
Date:   Thu Apr 12 09:14:52 2018 -0400

    13111: Fix skipped error check when Write called before WriteHeader.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tclegg at veritasgenetics.com>

diff --git a/services/keep-web/handler.go b/services/keep-web/handler.go
index 5e14cb4..389ab73 100644
--- a/services/keep-web/handler.go
+++ b/services/keep-web/handler.go
@@ -112,12 +112,12 @@ type updateOnSuccess struct {
 }
 
 func (uos *updateOnSuccess) Write(p []byte) (int, error) {
-	if uos.err != nil {
-		return 0, uos.err
-	}
 	if !uos.sentHeader {
 		uos.WriteHeader(http.StatusOK)
 	}
+	if uos.err != nil {
+		return 0, uos.err
+	}
 	return uos.ResponseWriter.Write(p)
 }
 

commit 6ae864435a2c185b373703b3d6fc696211c3b79c
Author: Tom Clegg <tclegg at veritasgenetics.com>
Date:   Wed Apr 11 19:59:18 2018 -0400

    13111: Avoid double WriteHeader after implicit 200 on first Write.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tclegg at veritasgenetics.com>

diff --git a/sdk/go/httpserver/responsewriter.go b/sdk/go/httpserver/responsewriter.go
index d37822f..8dea759 100644
--- a/sdk/go/httpserver/responsewriter.go
+++ b/sdk/go/httpserver/responsewriter.go
@@ -41,6 +41,9 @@ func (w *responseWriter) WriteHeader(s int) {
 }
 
 func (w *responseWriter) Write(data []byte) (n int, err error) {
+	if w.wroteStatus == 0 {
+		w.WriteHeader(http.StatusOK)
+	}
 	n, err = w.ResponseWriter.Write(data)
 	w.wroteBodyBytes += n
 	w.err = err

commit cf79bd5e4f3cb2176a9d8939c720f95b26caea91
Author: Tom Clegg <tclegg at veritasgenetics.com>
Date:   Wed Apr 11 09:07:09 2018 -0400

    13111: Ignore projects and collections with "/" in name.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tclegg at veritasgenetics.com>

diff --git a/sdk/go/arvados/fs_base.go b/sdk/go/arvados/fs_base.go
index 45beff6..3058a76 100644
--- a/sdk/go/arvados/fs_base.go
+++ b/sdk/go/arvados/fs_base.go
@@ -589,3 +589,7 @@ func rlookup(start inode, path string) (node inode, err error) {
 	}
 	return
 }
+
+func permittedName(name string) bool {
+	return name != "" && name != "." && name != ".." && !strings.Contains(name, "/")
+}
diff --git a/sdk/go/arvados/fs_collection.go b/sdk/go/arvados/fs_collection.go
index 923615b..7ce37aa 100644
--- a/sdk/go/arvados/fs_collection.go
+++ b/sdk/go/arvados/fs_collection.go
@@ -821,8 +821,8 @@ func (dn *dirnode) createFileAndParents(path string) (fn *filenode, err error) {
 	var node inode = dn
 	names := strings.Split(path, "/")
 	basename := names[len(names)-1]
-	if basename == "" || basename == "." || basename == ".." {
-		err = fmt.Errorf("invalid filename")
+	if !permittedName(basename) {
+		err = fmt.Errorf("invalid file part %q in path %q", basename, path)
 		return
 	}
 	for _, name := range names[:len(names)-1] {
diff --git a/sdk/go/arvados/fs_project.go b/sdk/go/arvados/fs_project.go
index 071cc0a..827a44b 100644
--- a/sdk/go/arvados/fs_project.go
+++ b/sdk/go/arvados/fs_project.go
@@ -63,7 +63,7 @@ func (pn *projectnode) load() {
 		}
 		for _, i := range resp.Items {
 			coll := i
-			if coll.Name == "" || coll.Name == "." || coll.Name == ".." {
+			if !permittedName(coll.Name) {
 				continue
 			}
 			pn.inode.Child(coll.Name, func(inode) (inode, error) {
@@ -85,7 +85,7 @@ func (pn *projectnode) load() {
 			break
 		}
 		for _, group := range resp.Items {
-			if group.Name == "" || group.Name == "." || group.Name == ".." {
+			if !permittedName(group.Name) {
 				continue
 			}
 			pn.inode.Child(group.Name, func(inode) (inode, error) {
diff --git a/sdk/go/arvados/fs_project_test.go b/sdk/go/arvados/fs_project_test.go
index 69bae89..058eb40 100644
--- a/sdk/go/arvados/fs_project_test.go
+++ b/sdk/go/arvados/fs_project_test.go
@@ -10,6 +10,7 @@ import (
 	"io"
 	"os"
 	"path/filepath"
+	"strings"
 
 	"git.curoverse.com/arvados.git/sdk/go/arvadostest"
 	check "gopkg.in/check.v1"
@@ -89,6 +90,34 @@ func (s *SiteFSSuite) testHomeProject(c *check.C, path string) {
 	}
 }
 
+func (s *SiteFSSuite) TestSlashInName(c *check.C) {
+	badCollection := Collection{
+		Name:      "bad/collection",
+		OwnerUUID: arvadostest.AProjectUUID,
+	}
+	err := s.client.RequestAndDecode(&badCollection, "POST", "arvados/v1/collections", s.client.UpdateBody(&badCollection), nil)
+	c.Assert(err, check.IsNil)
+	defer s.client.RequestAndDecode(nil, "DELETE", "arvados/v1/collections/"+badCollection.UUID, nil, nil)
+
+	badProject := Group{
+		Name:       "bad/project",
+		GroupClass: "project",
+		OwnerUUID:  arvadostest.AProjectUUID,
+	}
+	err = s.client.RequestAndDecode(&badProject, "POST", "arvados/v1/groups", s.client.UpdateBody(&badProject), nil)
+	c.Assert(err, check.IsNil)
+	defer s.client.RequestAndDecode(nil, "DELETE", "arvados/v1/groups/"+badProject.UUID, nil, nil)
+
+	dir, err := s.fs.Open("/users/active/A Project")
+	c.Check(err, check.IsNil)
+	fis, err := dir.Readdir(-1)
+	c.Check(err, check.IsNil)
+	for _, fi := range fis {
+		c.Logf("fi.Name() == %q", fi.Name())
+		c.Check(strings.Contains(fi.Name(), "/"), check.Equals, false)
+	}
+}
+
 func (s *SiteFSSuite) TestProjectUpdatedByOther(c *check.C) {
 	s.fs.MountProject("home", "")
 
diff --git a/sdk/go/arvados/group.go b/sdk/go/arvados/group.go
index b00809f..6b5718a 100644
--- a/sdk/go/arvados/group.go
+++ b/sdk/go/arvados/group.go
@@ -6,9 +6,10 @@ package arvados
 
 // Group is an arvados#group record
 type Group struct {
-	UUID      string `json:"uuid,omitempty"`
-	Name      string `json:"name,omitempty"`
-	OwnerUUID string `json:"owner_uuid,omitempty"`
+	UUID       string `json:"uuid,omitempty"`
+	Name       string `json:"name,omitempty"`
+	OwnerUUID  string `json:"owner_uuid,omitempty"`
+	GroupClass string `json:"group_class"`
 }
 
 // GroupList is an arvados#groupList resource.
@@ -18,3 +19,7 @@ type GroupList struct {
 	Offset         int     `json:"offset"`
 	Limit          int     `json:"limit"`
 }
+
+func (g Group) resourceName() string {
+	return "group"
+}

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list