Skip to content

Commit

Permalink
set public storage ids for publicly shared resources
Browse files Browse the repository at this point in the history
  • Loading branch information
David Christofas committed Oct 27, 2021
1 parent 51bd3ec commit f1bba51
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 8 deletions.
8 changes: 8 additions & 0 deletions changelog/unreleased/fix-view-only-wopi.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Bugfix: Enforce permissions in public share apps

A receiver of a read-only public share could still edit files via apps like Collabora.
These changes enforce the share permissions in apps used on publicly shared resources.

https://github.com/owncloud/web/issues/5776
https://github.com/owncloud/ocis/issues/2479
https://github.com/cs3org/reva/pull/22142214
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,14 @@ func init() {

type config struct {
MountPath string `mapstructure:"mount_path"`
MountID string `mapstructure:"mount_id"`
GatewayAddr string `mapstructure:"gateway_addr"`
}

type service struct {
conf *config
mountPath string
mountID string
gateway gateway.GatewayAPIClient
}

Expand Down Expand Up @@ -88,6 +90,7 @@ func New(m map[string]interface{}, ss *grpc.Server) (rgrpc.Service, error) {
}

mountPath := c.MountPath
mountID := c.MountID

gateway, err := pool.GetGatewayServiceClient(c.GatewayAddr)
if err != nil {
Expand All @@ -97,6 +100,7 @@ func New(m map[string]interface{}, ss *grpc.Server) (rgrpc.Service, error) {
service := &service{
conf: c,
mountPath: mountPath,
mountID: mountID,
gateway: gateway,
}

Expand Down Expand Up @@ -458,9 +462,22 @@ func (s *service) Stat(ctx context.Context, req *provider.StatRequest) (*provide
Value: attribute.StringValue(req.Ref.String()),
})

tkn, relativePath, err := s.unwrap(ctx, req.Ref)
if err != nil {
return nil, err
var (
tkn string
relativePath string
nodeID string
)

if req.Ref.ResourceId != nil {
parts := strings.Split(req.Ref.ResourceId.OpaqueId, "/")
tkn = parts[0]
nodeID = parts[1]
} else if req.Ref.Path != "" {
var err error
tkn, relativePath, err = s.unwrap(ctx, req.Ref)
if err != nil {
return nil, err
}
}

originalPath, ls, ri, st, err := s.resolveToken(ctx, tkn)
Expand All @@ -477,13 +494,23 @@ func (s *service) Stat(ctx context.Context, req *provider.StatRequest) (*provide
}, nil
}

p := originalPath
if ri.Type == provider.ResourceType_RESOURCE_TYPE_CONTAINER {
p = path.Join("/", p, relativePath)
var ref *provider.Reference
if req.Ref.ResourceId != nil {
ref = &provider.Reference{ResourceId: &provider.ResourceId{
StorageId: ls.ResourceId.StorageId,
OpaqueId: nodeID,
}}
} else if req.Ref.Path != "" {
p := originalPath
if ri.Type == provider.ResourceType_RESOURCE_TYPE_CONTAINER {
p = path.Join("/", p, relativePath)
}
ref = &provider.Reference{Path: p}
}

var statResponse *provider.StatResponse
// the call has to be made to the gateway instead of the storage.
statResponse, err = s.gateway.Stat(ctx, &provider.StatRequest{Ref: &provider.Reference{Path: p}})
statResponse, err = s.gateway.Stat(ctx, &provider.StatRequest{Ref: ref})
if err != nil {
return &provider.StatResponse{
Status: status.NewInternal(ctx, err, "gateway: error calling Stat for ref:"+req.Ref.String()),
Expand All @@ -495,13 +522,19 @@ func (s *service) Stat(ctx context.Context, req *provider.StatRequest) (*provide
if err := addShare(statResponse.Info, ls); err != nil {
appctx.GetLogger(ctx).Error().Err(err).Interface("share", ls).Interface("info", statResponse.Info).Msg("error when adding share")
}
statResponse.Info.Path = path.Join(s.mountPath, "/", tkn, relativePath)
statResponse.Info.Path = path.Join(s.mountPath, "/", tkn, strings.TrimPrefix(statResponse.Info.Path, ri.Path))
s.setPublicStorageId(statResponse.Info, tkn)
filterPermissions(statResponse.Info.PermissionSet, ls.GetPermissions().Permissions)
}

return statResponse, nil
}

func (s *service) setPublicStorageId(info *provider.ResourceInfo, shareToken string) {
info.Id.StorageId = s.mountID
info.Id.OpaqueId = shareToken + "/" + info.Id.OpaqueId
}

func addShare(i *provider.ResourceInfo, ls *link.PublicShare) error {
if i.Opaque == nil {
i.Opaque = &typesv1beta1.Opaque{}
Expand Down Expand Up @@ -555,6 +588,7 @@ func (s *service) ListContainer(ctx context.Context, req *provider.ListContainer
for i := range listContainerR.Infos {
filterPermissions(listContainerR.Infos[i].PermissionSet, ls.GetPermissions().Permissions)
listContainerR.Infos[i].Path = path.Join(s.mountPath, "/", tkn, relativePath, path.Base(listContainerR.Infos[i].Path))
s.setPublicStorageId(listContainerR.Infos[i], tkn)
if err := addShare(listContainerR.Infos[i], ls); err != nil {
appctx.GetLogger(ctx).Error().Err(err).Interface("share", ls).Interface("info", listContainerR.Infos[i]).Msg("error when adding share")
}
Expand Down
1 change: 1 addition & 0 deletions tests/oc-integration-tests/drone/gateway.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ home_provider = "/home"
# another mount point might be "/projects/"

"/public" = {"address" = "localhost:13000"}
"e1a73ede-549b-4226-abdf-40e69ca8230d" = {"address" = "localhost:13000"}

[http]
address = "0.0.0.0:19001"
Expand Down
1 change: 1 addition & 0 deletions tests/oc-integration-tests/local/gateway.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ home_provider = "/home"
# another mount point might be "/projects/"

"/public" = {"address" = "localhost:13000"}
"e1a73ede-549b-4226-abdf-40e69ca8230d" = {"address" = "localhost:13000"}

[http]
address = "0.0.0.0:19001"
Expand Down
1 change: 1 addition & 0 deletions tests/oc-integration-tests/local/storage-publiclink.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ address = "0.0.0.0:13000"
# we have a locally running dataprovider
[grpc.services.publicstorageprovider]
mount_path = "/public/"
mount_id = "e1a73ede-549b-4226-abdf-40e69ca8230d"
gateway_addr = "0.0.0.0:19000"

0 comments on commit f1bba51

Please sign in to comment.