Skip to content

Commit

Permalink
Layout fix (bringing back pw) (#493)
Browse files Browse the repository at this point in the history
  • Loading branch information
madsi1m authored Feb 10, 2020
1 parent 9ac9004 commit 77bbd09
Show file tree
Hide file tree
Showing 6 changed files with 197 additions and 0 deletions.
1 change: 1 addition & 0 deletions cmd/revad/runtime/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
_ "github.com/cs3org/reva/pkg/publicshare/manager/loader"
_ "github.com/cs3org/reva/pkg/share/manager/loader"
_ "github.com/cs3org/reva/pkg/storage/fs/loader"
_ "github.com/cs3org/reva/pkg/storage/pw/loader"
_ "github.com/cs3org/reva/pkg/storage/registry/loader"
_ "github.com/cs3org/reva/pkg/token/manager/loader"
_ "github.com/cs3org/reva/pkg/user/manager/loader"
Expand Down
5 changes: 5 additions & 0 deletions examples/separate/storage-home.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,18 @@ 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 = "{{.UsernamePrefixCount.1}}/{{.UsernameLower}}"

[grpc.services.storageprovider.path_wrappers.context]
prefix = ""
layout = "{{.UsernamePrefixCount.1}}/{{.UsernameLower}}"

[http]
address = "0.0.0.0:12001"

Expand Down
33 changes: 33 additions & 0 deletions internal/grpc/services/storageprovider/storageprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"github.com/cs3org/reva/pkg/rgrpc/status"
"github.com/cs3org/reva/pkg/storage"
"github.com/cs3org/reva/pkg/storage/fs/registry"
pwregistry "github.com/cs3org/reva/pkg/storage/pw/registry"
"github.com/mitchellh/mapstructure"
"github.com/pkg/errors"
"go.opencensus.io/trace"
Expand Down Expand Up @@ -61,6 +62,7 @@ type config struct {
type service struct {
conf *config
storage storage.FS
pathWrapper storage.PathWrapper
mountPath, mountID string
tmpFolder string
dataServerURL *url.URL
Expand Down Expand Up @@ -132,6 +134,10 @@ func New(m map[string]interface{}, ss *grpc.Server) (rgrpc.Service, error) {
if err != nil {
return nil, err
}
pw, err := getPW(c)
if err != nil {
return nil, err
}

// parse data server url
u, err := url.Parse(c.DataServerURL)
Expand All @@ -152,6 +158,7 @@ func New(m map[string]interface{}, ss *grpc.Server) (rgrpc.Service, error) {
service := &service{
conf: c,
storage: fs,
pathWrapper: pw,
tmpFolder: tmpFolder,
mountPath: mountPath,
mountID: mountID,
Expand Down Expand Up @@ -782,6 +789,16 @@ func getFS(c *config) (storage.FS, error) {
return nil, fmt.Errorf("driver not found: %s", c.Driver)
}

func getPW(c *config) (storage.PathWrapper, error) {
if c.PathWrapper == "" {
return nil, nil
}
if f, ok := pwregistry.NewFuncs[c.PathWrapper]; ok {
return f(c.PathWrappers[c.PathWrapper])
}
return nil, fmt.Errorf("path wrapper not found: %s", c.Driver)
}

func (s *service) unwrap(ctx context.Context, ref *provider.Reference) (*provider.Reference, error) {
if ref.GetId() != nil {
idRef := &provider.Reference{
Expand All @@ -807,6 +824,13 @@ func (s *service) unwrap(ctx context.Context, ref *provider.Reference) (*provide
return nil, err
}

if s.pathWrapper != nil {
fsfn, err = s.pathWrapper.Unwrap(ctx, fsfn)
if err != nil {
return nil, err
}
}

pathRef := &provider.Reference{
Spec: &provider.Reference_Path{
Path: fsfn,
Expand All @@ -825,6 +849,15 @@ func (s *service) trimMountPrefix(fn string) (string, error) {

func (s *service) wrap(ctx context.Context, ri *provider.ResourceInfo) error {
ri.Id.StorageId = s.mountID

if s.pathWrapper != nil {
var err error
ri.Path, err = s.pathWrapper.Wrap(ctx, ri.Path)
if err != nil {
return err
}
}

ri.Path = path.Join(s.mountPath, ri.Path)
return nil
}
99 changes: 99 additions & 0 deletions pkg/storage/pw/context/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Copyright 2018-2019 CERN
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// In applying this license, CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

package context

import (
"context"
"fmt"
"path"
"strings"

"github.com/cs3org/reva/pkg/errtypes"
"github.com/cs3org/reva/pkg/storage"
"github.com/cs3org/reva/pkg/storage/helper"
"github.com/cs3org/reva/pkg/storage/pw/registry"
"github.com/cs3org/reva/pkg/user"
"github.com/mitchellh/mapstructure"
"github.com/pkg/errors"
)

func init() {
registry.Register("context", New)
}

type config struct {
Prefix string `mapstructure:"prefix"`
Layout string `mapstructure:"layout"`
}

func parseConfig(m map[string]interface{}) (*config, error) {
c := &config{Layout: "{{.Username}}"}
if err := mapstructure.Decode(m, c); err != nil {
err = errors.Wrap(err, "error decoding conf")
return nil, err
}
return c, nil
}

// New returns an implementation to of the storage.PathWrapper interface that
// is used to wrap and unwrap storage paths
func New(m map[string]interface{}) (storage.PathWrapper, error) {
c, err := parseConfig(m)
if err != nil {
return nil, err
}
return &pw{prefix: c.Prefix, layout: c.Layout}, nil
}

type pw struct {
prefix string
layout string
}

// Only works when a user is in context
func (pw *pw) Unwrap(ctx context.Context, rp string) (string, error) {

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")
}
userhome, err := helper.GetUserHomePath(u, pw.layout)
if err != nil {
return "", errors.Wrap(errtypes.UserRequired("userrequired"), fmt.Sprintf("template error: %s", err.Error()))
}
return path.Join("/", pw.prefix, userhome, rp), nil
}

func (pw *pw) Wrap(ctx context.Context, rp string) (string, error) {
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")
}
userhome, err := helper.GetUserHomePath(u, pw.layout)
if err != nil {
return "", errors.Wrap(errtypes.UserRequired("userrequired"), fmt.Sprintf("template error: %s", err.Error()))
}
return strings.TrimPrefix(rp, path.Join("/", userhome)), nil
}
25 changes: 25 additions & 0 deletions pkg/storage/pw/loader/loader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2018-2019 CERN
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// In applying this license, CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

package loader

import (
// Load core storage path wrapper backends.
_ "github.com/cs3org/reva/pkg/storage/pw/context"
// Add your own here
)
34 changes: 34 additions & 0 deletions pkg/storage/pw/registry/registry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2018-2019 CERN
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// In applying this license, CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

package registry

import "github.com/cs3org/reva/pkg/storage"

// NewFunc is the function that storage implementations
// should register at init time.
type NewFunc func(map[string]interface{}) (storage.PathWrapper, error)

// NewFuncs is a map containing all the registered storage backends.
var NewFuncs = map[string]NewFunc{}

// Register registers a new storage backend new function.
// Not safe for concurrent use. Safe for use from package init.
func Register(name string, f NewFunc) {
NewFuncs[name] = f
}

0 comments on commit 77bbd09

Please sign in to comment.