From bdb361616f58a77ed494020f89c3a06cd8bd797f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Wed, 18 Mar 2020 12:06:09 +0100 Subject: [PATCH] Teach the owncloud storage driver home handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jörn Friedrich Dreyer --- examples/oc-phoenix/frontend.toml | 2 +- examples/oc-phoenix/storage-home.toml | 6 +- pkg/storage/fs/owncloud/owncloud.go | 105 +++++++++++++++----------- 3 files changed, 65 insertions(+), 48 deletions(-) diff --git a/examples/oc-phoenix/frontend.toml b/examples/oc-phoenix/frontend.toml index b91f5d40905..905a87e5d2f 100644 --- a/examples/oc-phoenix/frontend.toml +++ b/examples/oc-phoenix/frontend.toml @@ -67,7 +67,7 @@ chunk_folder = "/var/tmp/reva/chunks" # for eos we need to rewrite the path # TODO strip the username from the path so the CS3 namespace can be mounted # at the files/ endpoint? what about migration? separate reva instance -files_namespace = "/" +files_namespace = "/oc" # similar to the dav/files endpoint we can configure a prefix for the old webdav endpoint # we use the old webdav endpoint to present the cs3 namespace diff --git a/examples/oc-phoenix/storage-home.toml b/examples/oc-phoenix/storage-home.toml index 1184d47703a..a37a4bc673f 100644 --- a/examples/oc-phoenix/storage-home.toml +++ b/examples/oc-phoenix/storage-home.toml @@ -26,17 +26,13 @@ driver = "owncloud" mount_path = "/home" mount_id = "123e4567-e89b-12d3-a456-426655440000" expose_data_server = true -path_wrapper = "context" data_server_url = "http://localhost:12001/data" enable_home_creation = true [grpc.services.storageprovider.drivers.owncloud] datadirectory = "/var/tmp/reva/data" -layout = "{{.Username}}" +enable_home = true -[grpc.services.storageprovider.path_wrappers.context] -prefix = "" -layout = "{{.Username}}" [http] address = "0.0.0.0:12001" diff --git a/pkg/storage/fs/owncloud/owncloud.go b/pkg/storage/fs/owncloud/owncloud.go index dade30c7e49..e548394a9f7 100644 --- a/pkg/storage/fs/owncloud/owncloud.go +++ b/pkg/storage/fs/owncloud/owncloud.go @@ -154,7 +154,8 @@ type config struct { DataDirectory string `mapstructure:"datadirectory"` Scan bool `mapstructure:"scan"` Redis string `mapstructure:"redis"` - Layout string `mapstructure:"layout"` + EnableHome bool `mapstructure:"enable_home"` + UserLayout string `mapstructure:"user_layout"` } func parseConfig(m map[string]interface{}) (*config, error) { @@ -170,8 +171,8 @@ func (c *config) init(m map[string]interface{}) { if c.Redis == "" { c.Redis = ":6379" } - if c.Layout == "" { - c.Layout = "{{.Username}}" + if c.UserLayout == "" { + c.UserLayout = "{{.Username}}" } // default to scanning if not configured if _, ok := m["scan"]; !ok { @@ -270,26 +271,36 @@ func (fs *ocfs) scanFiles(ctx context.Context, conn redis.Conn) { // the incoming path starts with /, so we need to insert the files subfolder into the path // and prefix the datadirectory // TODO the path handed to a storage provider should not contain the username -func (fs *ocfs) wrap(ctx context.Context, fn string) string { - // trim all / - fn = strings.Trim(fn, "/") - // p = "" or - // p = or - // p = /foo/bar.txt - parts := strings.SplitN(fn, "/", 2) - - switch len(parts) { - case 1: - // parts = "" or "" - if parts[0] == "" { - return fs.c.DataDirectory +func (fs *ocfs) wrap(ctx context.Context, fn string) (internal string) { + if fs.c.EnableHome { + layout, err := fs.GetHome(ctx) + if err != nil { + panic(err) + } + internal = path.Join(fs.c.DataDirectory, layout, "files", fn) + } else { + // trim all / + fn = strings.Trim(fn, "/") + // p = "" or + // p = or + // p = /foo/bar.txt + parts := strings.SplitN(fn, "/", 2) + + switch len(parts) { + case 1: + // parts = "" or "" + if parts[0] == "" { + internal = fs.c.DataDirectory + return + } + // parts = "" + internal = path.Join(fs.c.DataDirectory, parts[0], "files") + default: + // parts = "", "foo/bar.txt" + internal = path.Join(fs.c.DataDirectory, parts[0], "files", parts[1]) } - // parts = "" - return path.Join(fs.c.DataDirectory, parts[0], "files") - default: - // parts = "", "foo/bar.txt" - return path.Join(fs.c.DataDirectory, parts[0], "files", parts[1]) } + return } // ownloud stores versions in the files_versions subfolder @@ -329,27 +340,37 @@ func (fs *ocfs) getRecyclePath(ctx context.Context) (string, error) { return path.Join(fs.c.DataDirectory, u.GetUsername(), "files_trashbin/files"), nil } -func (fs *ocfs) unwrap(ctx context.Context, np string) string { - // np = /data//files/foo/bar.txt - // remove data dir - if fs.c.DataDirectory != "/" { - // fs.c.DataDirectory is a clean puth, so it never ends in / - np = strings.TrimPrefix(np, fs.c.DataDirectory) - // np = //files/foo/bar.txt - } +func (fs *ocfs) unwrap(ctx context.Context, np string) (external string) { + if fs.c.EnableHome { + layout, err := fs.GetHome(ctx) + if err != nil { + panic(err) + } + trim := path.Join(fs.c.DataDirectory, layout, "files") + external = strings.TrimPrefix(np, trim) + } else { + // np = /data//files/foo/bar.txt + // remove data dir + if fs.c.DataDirectory != "/" { + // fs.c.DataDirectory is a clean path, so it never ends in / + np = strings.TrimPrefix(np, fs.c.DataDirectory) + // np = //files/foo/bar.txt + } - parts := strings.SplitN(np, "/", 4) - // parts = "", "", "files", "foo/bar.txt" - switch len(parts) { - case 1: - return "/" - case 2: - return path.Join("/", parts[1]) - case 3: - return path.Join("/", parts[1]) - default: - return path.Join("/", parts[1], parts[3]) + parts := strings.SplitN(np, "/", 4) + // parts = "", "", "files", "foo/bar.txt" + switch len(parts) { + case 1: + external = "/" + case 2: + external = path.Join("/", parts[1]) + case 3: + external = path.Join("/", parts[1]) + default: + external = path.Join("/", parts[1], parts[3]) + } } + return } func getOwner(fn string) string { @@ -851,7 +872,7 @@ func (fs *ocfs) CreateHome(ctx context.Context) error { err = errors.Wrap(err, "oc CreateHome: no user in ctx and home is enabled") panic(err) } - layout := templates.WithUser(u, fs.c.Layout) + layout := templates.WithUser(u, fs.c.UserLayout) homePaths := []string{ path.Join(fs.c.DataDirectory, layout, "files"), @@ -883,7 +904,7 @@ func (fs *ocfs) GetHome(ctx context.Context) (string, error) { err = errors.Wrap(err, "oc GetHome: no user in ctx and home is enabled") panic(err) } - relativeHome := templates.WithUser(u, fs.c.Layout) + relativeHome := templates.WithUser(u, fs.c.UserLayout) return relativeHome, nil }