Skip to content

Commit

Permalink
sort out namespaces, fake root storage (#358)
Browse files Browse the repository at this point in the history
Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
  • Loading branch information
butonic authored and labkode committed Nov 8, 2019
1 parent fb46ee7 commit 3d3e9a9
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 19 deletions.
21 changes: 19 additions & 2 deletions examples/separate/frontend.toml
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,26 @@ gateway = "localhost:19000"
# can prefix the path to jail the requests to the correct CS3 namespace.
# In this deployment we mounted the owncloud storage provider at /oc. It
# expects a username as the first path segment.
files_namespace = "/oc/"
files_namespace = "/"
# currently, only the desktop client will use this endpoint, but only if
# the dav.chunking capability is available
# TODO implement a path wrapper that rewrites `<username>` into the path
# layout for the users home?
# no, use GetHome?
# 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/<username> endpoint? what about migration? separate reva instance

# similar to the dav/files endpoint we can configure a prefix for the old webdav endpoint
webdav_namespace = "/home/"
# we use the old webdav endpoint to present the cs3 namespace
webdav_namespace = "/"
# note: this changes the tree that is rendered at remote.php/webdav from the users home to the cs3 namespace
# use webdav_namespace = "/home" to use the old namespace that only exposes the users files
# this endpoint should not affect the desktop client sync but will present different folders for the other clients:
# - the desktop clients use a hardcoded remote.php/dav/files/<username> if the dav.chunkung capability is present
# - the ios ios uses the core.webdav-root capability which points to remote.php/webdav in oc10
# - the oc js sdk is hardcoded to the remote.php/webdav so it will see the new tree
# - TODO android? no sync ... but will see different tree

[http.services.ocs]
# prefix = "ocs"
Expand Down
8 changes: 6 additions & 2 deletions examples/separate/gateway.toml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ bearer = "localhost:20099"
driver = "static"

[grpc.services.storageregistry.drivers.static.rules]
# this is the list of namespaces that build the cs3 namespace
# - every storage as mounted in the root

# mount a home storage provider that uses a context based path wrapper
# to jail users into their home dir
"/home" = "localhost:12000"
Expand All @@ -89,6 +92,8 @@ driver = "static"
# mount a storage provider without a path wrapper for direct access to files
"/oc" = "localhost:11000"
"123e4567-e89b-12d3-a456-426655440000" = "localhost:11000"
"/" = "localhost:11100"
"123e4567-e89b-12d3-a456-426655440001" = "localhost:11100"

# another mount point might be "/projects/"

Expand All @@ -104,8 +109,7 @@ transfer_shared_secret = "replace-me-with-a-transfer-secret"

[http.middlewares.auth]
gatewaysvc = "0.0.0.0:19000"
auth_type = "basic"
credential_strategy = "basic"
credential_chain = ["basic", "bearer"]
token_strategy = "header"
token_writer = "header"
token_manager = "jwt"
Expand Down
3 changes: 1 addition & 2 deletions examples/separate/storage-home.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ enabled_middlewares = ["auth"]

[http.middlewares.auth]
gatewaysvc = "localhost:19000"
auth_type = "basic"
credential_strategy = "basic"
credential_chain = ["basic", "bearer"]
token_strategy = "header"
token_writer = "header"
token_manager = "jwt"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ enabled_middlewares = ["auth"]

[http.middlewares.auth]
gatewaysvc = "localhost:19000"
auth_type = "basic"
credential_strategy = "basic"
credential_chain = ["basic", "bearer"]
token_strategy = "header"
token_writer = "header"
token_manager = "jwt"
Expand Down
49 changes: 49 additions & 0 deletions examples/separate/storage-root.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# This storage-root.toml config file will start a reva service that:
# - authenticates grpc storage provider requests using the internal jwt token
# - serves a root storage provider on grpc port 11100

# it is used to render the root namespace. you need to create a folder
# layout in "/var/tmp/reva/root" that matches the storage registry:
# tree /var/tmp/reva/root should give for this example
# /var/tmp/reva/root
# ├── home
# └── oc
# that will allow you to list the existing namespaces.
# TODO either make the gateway return a proper ListCollection for the root,
# TODO or implement a virtual storage that implements this

[core]
max_cpus = "2"
disable_http = true

[log]
level = "debug"

[grpc]
network = "tcp"
address = "0.0.0.0:11100"
enabled_services = ["storageprovider"]
enabled_interceptors = ["auth"]

# This is a storage proider that grants direct acces to the wrapped storage
[grpc.services.storageprovider]
driver = "local"
mount_path = "/"
# if we have an id, we can directly go to that storage, no need to wrap paths
mount_id = "123e4567-e89b-12d3-a456-426655440001"

[grpc.services.storageprovider.available_checksums]
md5 = 100
unset = 1000

[grpc.services.storageprovider.drivers.local]
root = "/var/tmp/reva/root"

[grpc.services.storageprovider.path_wrappers.context]
prefix = ""

[grpc.interceptors.auth]
token_manager = "jwt"

[grpc.interceptors.auth.token_managers.jwt]
secret = "Pive-Fumkiu4"
25 changes: 15 additions & 10 deletions pkg/storage/fs/owncloud/owncloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,19 +269,24 @@ func (fs *ocFS) scanFiles(ctx context.Context, conn redis.Conn) {
// and prefix the datadirectory
// TODO the path handed to a storage provider should not contain the username
func (fs *ocFS) getInternalPath(ctx context.Context, fn string) string {
// p = /<username> or
// p = /<username>/foo/bar.txt
parts := strings.SplitN(fn, "/", 3)
// trim all /
fn = strings.Trim(fn, "/")
// p = "" or
// p = <username> or
// p = <username>/foo/bar.txt
parts := strings.SplitN(fn, "/", 2)

switch len(parts) {
case 2:
// parts = "", "<username>"
return path.Join(fs.c.DataDirectory, parts[1], "files")
case 3:
// parts = "", "<username>", "foo/bar.txt"
return path.Join(fs.c.DataDirectory, parts[1], "files", parts[2])
case 1:
// parts = "" or "<username>"
if parts[0] == "" {
return fs.c.DataDirectory
}
// parts = "<username>"
return path.Join(fs.c.DataDirectory, parts[0], "files")
default:
return "" // TODO Must not happen?
// parts = "<username>", "foo/bar.txt"
return path.Join(fs.c.DataDirectory, parts[0], "files", parts[1])
}
}

Expand Down
10 changes: 9 additions & 1 deletion pkg/storage/pw/context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ package context
import (
"context"
"path"
"strings"

"github.com/cs3org/reva/pkg/errtypes"
"github.com/cs3org/reva/pkg/storage"
Expand Down Expand Up @@ -82,5 +83,12 @@ func (pw *pw) Unwrap(ctx context.Context, rp string) (string, error) {
return path.Join("/", pw.prefix, u.Username, rp), nil
}
func (pw *pw) Wrap(ctx context.Context, rp string) (string, error) {
return rp, nil
u, ok := user.ContextGetUser(ctx)
if !ok {
return "", errors.Wrap(errtypes.UserRequired("userrequired"), "error getting user from ctx")
}
if u.Username == "" {
return "", errors.Wrap(errtypes.UserRequired("userrequired"), "user has no username")
}
return strings.TrimPrefix(rp, path.Join("/", u.Username)), nil
}

0 comments on commit 3d3e9a9

Please sign in to comment.