Skip to content

Commit 77bbd09

Browse files
authored
Layout fix (bringing back pw) (#493)
1 parent 9ac9004 commit 77bbd09

File tree

6 files changed

+197
-0
lines changed

6 files changed

+197
-0
lines changed

cmd/revad/runtime/loader.go

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
_ "github.com/cs3org/reva/pkg/publicshare/manager/loader"
3333
_ "github.com/cs3org/reva/pkg/share/manager/loader"
3434
_ "github.com/cs3org/reva/pkg/storage/fs/loader"
35+
_ "github.com/cs3org/reva/pkg/storage/pw/loader"
3536
_ "github.com/cs3org/reva/pkg/storage/registry/loader"
3637
_ "github.com/cs3org/reva/pkg/token/manager/loader"
3738
_ "github.com/cs3org/reva/pkg/user/manager/loader"

examples/separate/storage-home.toml

+5
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,18 @@ driver = "owncloud"
2626
mount_path = "/home"
2727
mount_id = "123e4567-e89b-12d3-a456-426655440000"
2828
expose_data_server = true
29+
path_wrapper = "context"
2930
data_server_url = "http://localhost:12001/data"
3031
enable_home_creation = true
3132

3233
[grpc.services.storageprovider.drivers.owncloud]
3334
datadirectory = "/var/tmp/reva/data"
3435
layout = "{{.UsernamePrefixCount.1}}/{{.UsernameLower}}"
3536

37+
[grpc.services.storageprovider.path_wrappers.context]
38+
prefix = ""
39+
layout = "{{.UsernamePrefixCount.1}}/{{.UsernameLower}}"
40+
3641
[http]
3742
address = "0.0.0.0:12001"
3843

internal/grpc/services/storageprovider/storageprovider.go

+33
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import (
3434
"github.com/cs3org/reva/pkg/rgrpc/status"
3535
"github.com/cs3org/reva/pkg/storage"
3636
"github.com/cs3org/reva/pkg/storage/fs/registry"
37+
pwregistry "github.com/cs3org/reva/pkg/storage/pw/registry"
3738
"github.com/mitchellh/mapstructure"
3839
"github.com/pkg/errors"
3940
"go.opencensus.io/trace"
@@ -61,6 +62,7 @@ type config struct {
6162
type service struct {
6263
conf *config
6364
storage storage.FS
65+
pathWrapper storage.PathWrapper
6466
mountPath, mountID string
6567
tmpFolder string
6668
dataServerURL *url.URL
@@ -132,6 +134,10 @@ func New(m map[string]interface{}, ss *grpc.Server) (rgrpc.Service, error) {
132134
if err != nil {
133135
return nil, err
134136
}
137+
pw, err := getPW(c)
138+
if err != nil {
139+
return nil, err
140+
}
135141

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

792+
func getPW(c *config) (storage.PathWrapper, error) {
793+
if c.PathWrapper == "" {
794+
return nil, nil
795+
}
796+
if f, ok := pwregistry.NewFuncs[c.PathWrapper]; ok {
797+
return f(c.PathWrappers[c.PathWrapper])
798+
}
799+
return nil, fmt.Errorf("path wrapper not found: %s", c.Driver)
800+
}
801+
785802
func (s *service) unwrap(ctx context.Context, ref *provider.Reference) (*provider.Reference, error) {
786803
if ref.GetId() != nil {
787804
idRef := &provider.Reference{
@@ -807,6 +824,13 @@ func (s *service) unwrap(ctx context.Context, ref *provider.Reference) (*provide
807824
return nil, err
808825
}
809826

827+
if s.pathWrapper != nil {
828+
fsfn, err = s.pathWrapper.Unwrap(ctx, fsfn)
829+
if err != nil {
830+
return nil, err
831+
}
832+
}
833+
810834
pathRef := &provider.Reference{
811835
Spec: &provider.Reference_Path{
812836
Path: fsfn,
@@ -825,6 +849,15 @@ func (s *service) trimMountPrefix(fn string) (string, error) {
825849

826850
func (s *service) wrap(ctx context.Context, ri *provider.ResourceInfo) error {
827851
ri.Id.StorageId = s.mountID
852+
853+
if s.pathWrapper != nil {
854+
var err error
855+
ri.Path, err = s.pathWrapper.Wrap(ctx, ri.Path)
856+
if err != nil {
857+
return err
858+
}
859+
}
860+
828861
ri.Path = path.Join(s.mountPath, ri.Path)
829862
return nil
830863
}

pkg/storage/pw/context/context.go

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// Copyright 2018-2019 CERN
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
// In applying this license, CERN does not waive the privileges and immunities
16+
// granted to it by virtue of its status as an Intergovernmental Organization
17+
// or submit itself to any jurisdiction.
18+
19+
package context
20+
21+
import (
22+
"context"
23+
"fmt"
24+
"path"
25+
"strings"
26+
27+
"github.com/cs3org/reva/pkg/errtypes"
28+
"github.com/cs3org/reva/pkg/storage"
29+
"github.com/cs3org/reva/pkg/storage/helper"
30+
"github.com/cs3org/reva/pkg/storage/pw/registry"
31+
"github.com/cs3org/reva/pkg/user"
32+
"github.com/mitchellh/mapstructure"
33+
"github.com/pkg/errors"
34+
)
35+
36+
func init() {
37+
registry.Register("context", New)
38+
}
39+
40+
type config struct {
41+
Prefix string `mapstructure:"prefix"`
42+
Layout string `mapstructure:"layout"`
43+
}
44+
45+
func parseConfig(m map[string]interface{}) (*config, error) {
46+
c := &config{Layout: "{{.Username}}"}
47+
if err := mapstructure.Decode(m, c); err != nil {
48+
err = errors.Wrap(err, "error decoding conf")
49+
return nil, err
50+
}
51+
return c, nil
52+
}
53+
54+
// New returns an implementation to of the storage.PathWrapper interface that
55+
// is used to wrap and unwrap storage paths
56+
func New(m map[string]interface{}) (storage.PathWrapper, error) {
57+
c, err := parseConfig(m)
58+
if err != nil {
59+
return nil, err
60+
}
61+
return &pw{prefix: c.Prefix, layout: c.Layout}, nil
62+
}
63+
64+
type pw struct {
65+
prefix string
66+
layout string
67+
}
68+
69+
// Only works when a user is in context
70+
func (pw *pw) Unwrap(ctx context.Context, rp string) (string, error) {
71+
72+
u, ok := user.ContextGetUser(ctx)
73+
if !ok {
74+
return "", errors.Wrap(errtypes.UserRequired("userrequired"), "error getting user from ctx")
75+
}
76+
if u.Username == "" {
77+
return "", errors.Wrap(errtypes.UserRequired("userrequired"), "user has no username")
78+
}
79+
userhome, err := helper.GetUserHomePath(u, pw.layout)
80+
if err != nil {
81+
return "", errors.Wrap(errtypes.UserRequired("userrequired"), fmt.Sprintf("template error: %s", err.Error()))
82+
}
83+
return path.Join("/", pw.prefix, userhome, rp), nil
84+
}
85+
86+
func (pw *pw) Wrap(ctx context.Context, rp string) (string, error) {
87+
u, ok := user.ContextGetUser(ctx)
88+
if !ok {
89+
return "", errors.Wrap(errtypes.UserRequired("userrequired"), "error getting user from ctx")
90+
}
91+
if u.Username == "" {
92+
return "", errors.Wrap(errtypes.UserRequired("userrequired"), "user has no username")
93+
}
94+
userhome, err := helper.GetUserHomePath(u, pw.layout)
95+
if err != nil {
96+
return "", errors.Wrap(errtypes.UserRequired("userrequired"), fmt.Sprintf("template error: %s", err.Error()))
97+
}
98+
return strings.TrimPrefix(rp, path.Join("/", userhome)), nil
99+
}

pkg/storage/pw/loader/loader.go

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2018-2019 CERN
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
// In applying this license, CERN does not waive the privileges and immunities
16+
// granted to it by virtue of its status as an Intergovernmental Organization
17+
// or submit itself to any jurisdiction.
18+
19+
package loader
20+
21+
import (
22+
// Load core storage path wrapper backends.
23+
_ "github.com/cs3org/reva/pkg/storage/pw/context"
24+
// Add your own here
25+
)

pkg/storage/pw/registry/registry.go

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright 2018-2019 CERN
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
// In applying this license, CERN does not waive the privileges and immunities
16+
// granted to it by virtue of its status as an Intergovernmental Organization
17+
// or submit itself to any jurisdiction.
18+
19+
package registry
20+
21+
import "github.com/cs3org/reva/pkg/storage"
22+
23+
// NewFunc is the function that storage implementations
24+
// should register at init time.
25+
type NewFunc func(map[string]interface{}) (storage.PathWrapper, error)
26+
27+
// NewFuncs is a map containing all the registered storage backends.
28+
var NewFuncs = map[string]NewFunc{}
29+
30+
// Register registers a new storage backend new function.
31+
// Not safe for concurrent use. Safe for use from package init.
32+
func Register(name string, f NewFunc) {
33+
NewFuncs[name] = f
34+
}

0 commit comments

Comments
 (0)