From 674976af2f6bd933a5656d7a33751601688da2d3 Mon Sep 17 00:00:00 2001
From: Andre Duffeck <aduffeck@users.noreply.github.com>
Date: Fri, 13 Aug 2021 14:07:59 +0200
Subject: [PATCH] Make ownloudsql behave more like oc10 (#1990)

* Set proper permissions for base directories

* Do not use a . as the name for root entries

* Set the same fs permissions as oc10

* Add changelog
---
 .../owncloudsql-oc10-compatibility.md         |  5 ++++
 .../fs/owncloudsql/filecache/filecache.go     | 23 +++++++++++++------
 .../owncloudsql/filecache/filecache_test.go   | 17 ++++++++++++++
 pkg/storage/fs/owncloudsql/owncloudsql.go     |  9 ++++----
 4 files changed, 43 insertions(+), 11 deletions(-)
 create mode 100644 changelog/unreleased/owncloudsql-oc10-compatibility.md

diff --git a/changelog/unreleased/owncloudsql-oc10-compatibility.md b/changelog/unreleased/owncloudsql-oc10-compatibility.md
new file mode 100644
index 0000000000..aad92b9a69
--- /dev/null
+++ b/changelog/unreleased/owncloudsql-oc10-compatibility.md
@@ -0,0 +1,5 @@
+Bugfix: Increase oc10 compatibility of owncloudsql
+
+We added a few changes to the owncloudsql storage driver to behave more like oc10.
+
+https://github.com/cs3org/reva/pull/1990
diff --git a/pkg/storage/fs/owncloudsql/filecache/filecache.go b/pkg/storage/fs/owncloudsql/filecache/filecache.go
index 7408dd0480..6c431e950a 100644
--- a/pkg/storage/fs/owncloudsql/filecache/filecache.go
+++ b/pkg/storage/fs/owncloudsql/filecache/filecache.go
@@ -338,21 +338,30 @@ func (c *Cache) doInsertOrUpdate(tx *sql.Tx, storage interface{}, data map[strin
 	}
 
 	path := data["path"].(string)
+	data["name"] = filepath.Base(path)
+	if data["name"] == "." {
+		data["name"] = ""
+	}
+
 	parentPath := strings.TrimRight(filepath.Dir(path), "/")
 	if parentPath == "." {
 		parentPath = ""
 	}
-	parent, err := c.Get(storageID, parentPath)
-	if err == nil {
-		data["parent"] = parent.ID
+	if path == "" {
+		data["parent"] = -1
 	} else {
-		if allowEmptyParent {
-			data["parent"] = -1
+		parent, err := c.Get(storageID, parentPath)
+		if err == nil {
+			data["parent"] = parent.ID
 		} else {
-			return -1, fmt.Errorf("could not find parent %s, %s, %v, %w", parentPath, path, parent, err)
+			if allowEmptyParent {
+				data["parent"] = -1
+			} else {
+				return -1, fmt.Errorf("could not find parent %s, %s, %v, %w", parentPath, path, parent, err)
+			}
 		}
 	}
-	data["name"] = filepath.Base(path)
+
 	if _, exists := data["checksum"]; !exists {
 		data["checksum"] = ""
 	}
diff --git a/pkg/storage/fs/owncloudsql/filecache/filecache_test.go b/pkg/storage/fs/owncloudsql/filecache/filecache_test.go
index b00cc981c5..c1c383aa58 100644
--- a/pkg/storage/fs/owncloudsql/filecache/filecache_test.go
+++ b/pkg/storage/fs/owncloudsql/filecache/filecache_test.go
@@ -298,6 +298,23 @@ var _ = Describe("Filecache", func() {
 				Expect(entry.MimeType).To(Equal(9))
 				Expect(entry.MimePart).To(Equal(5))
 			})
+
+			It("does not add a . as the name for root entries", func() {
+				data := map[string]interface{}{
+					"path":     "",
+					"checksum": "SHA1: abcdefg",
+					"etag":     "abcdefg",
+					"mimetype": "image/tiff",
+				}
+
+				_, err := cache.InsertOrUpdate(1, data, false)
+				Expect(err).ToNot(HaveOccurred())
+
+				file, err := cache.Get(1, "")
+				Expect(err).ToNot(HaveOccurred())
+				Expect(file).ToNot(BeNil())
+				Expect(file.Name).To(Equal(""))
+			})
 		})
 
 		Context("when updating an existing record", func() {
diff --git a/pkg/storage/fs/owncloudsql/owncloudsql.go b/pkg/storage/fs/owncloudsql/owncloudsql.go
index e2a8539c63..c094744f45 100644
--- a/pkg/storage/fs/owncloudsql/owncloudsql.go
+++ b/pkg/storage/fs/owncloudsql/owncloudsql.go
@@ -670,7 +670,7 @@ func (fs *owncloudsqlfs) createHomeForUser(ctx context.Context, user string) err
 		return err
 	}
 	for _, v := range homePaths {
-		if err := os.MkdirAll(v, 0700); err != nil {
+		if err := os.MkdirAll(v, 0755); err != nil {
 			return errors.Wrap(err, "owncloudsql: error creating home path: "+v)
 		}
 
@@ -679,9 +679,10 @@ func (fs *owncloudsqlfs) createHomeForUser(ctx context.Context, user string) err
 			return err
 		}
 		data := map[string]interface{}{
-			"path":     fs.toDatabasePath(v),
-			"etag":     calcEtag(ctx, fi),
-			"mimetype": "httpd/unix-directory",
+			"path":        fs.toDatabasePath(v),
+			"etag":        calcEtag(ctx, fi),
+			"mimetype":    "httpd/unix-directory",
+			"permissions": 31, // 1: READ, 2: UPDATE, 4: CREATE, 8: DELETE, 16: SHARE
 		}
 
 		allowEmptyParent := v == filepath.Join(fs.c.DataDirectory, user) // the root doesn't have a parent