Skip to content

Commit

Permalink
Use the user in request for deciding the layout for non-home DAV requ…
Browse files Browse the repository at this point in the history
…ests (#1401)
  • Loading branch information
ishank011 authored Jan 15, 2021
1 parent bd7234e commit 47119be
Show file tree
Hide file tree
Showing 14 changed files with 54 additions and 42 deletions.
16 changes: 16 additions & 0 deletions changelog/unreleased/fix-dav-namespace.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Bugfix: Use the user in request for deciding the layout for non-home DAV requests

For the incoming /dav/files/userID requests, we have different namespaces
depending on whether the request is for the logged-in user's namespace or not.
Since in the storage drivers, we specify the layout depending only on the user
whose resources are to be accessed, this fails when a user wants to access
another user's namespace when the storage provider depends on the logged in
user's namespace. This PR fixes that.

For example, consider the following case. The owncloud fs uses a layout
{{substr 0 1 .Id.OpaqueId}}/{{.Id.OpaqueId}}. The user einstein sends a request
to access a resource shared with him, say /dav/files/marie/abcd, which should be
allowed. However, based on the way we applied the layout, there's no way in
which this can be translated to /m/marie/.

https://github.com/cs3org/reva/pull/1401
2 changes: 0 additions & 2 deletions internal/http/services/owncloud/ocdav/copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ func (s *svc) handleCopy(w http.ResponseWriter, r *http.Request, ns string) {
ctx, span := trace.StartSpan(ctx, "head")
defer span.End()

ns = applyLayout(ctx, ns)

src := path.Join(ns, r.URL.Path)
dstHeader := r.Header.Get("Destination")
overwrite := r.Header.Get("Overwrite")
Expand Down
6 changes: 3 additions & 3 deletions internal/http/services/owncloud/ocdav/dav.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ func (h *DavHandler) init(c *Config) error {
return err
}
h.FilesHandler = new(WebDavHandler)
if err := h.FilesHandler.init(c.FilesNamespace); err != nil {
if err := h.FilesHandler.init(c.FilesNamespace, false); err != nil {
return err
}
h.FilesHomeHandler = new(WebDavHandler)
if err := h.FilesHomeHandler.init(c.WebdavNamespace); err != nil {
if err := h.FilesHomeHandler.init(c.WebdavNamespace, true); err != nil {
return err
}
h.MetaHandler = new(MetaHandler)
Expand All @@ -71,7 +71,7 @@ func (h *DavHandler) init(c *Config) error {
h.TrashbinHandler = new(TrashbinHandler)

h.PublicFolderHandler = new(WebDavHandler)
if err := h.PublicFolderHandler.init("public"); err != nil { // jail public file requests to /public/ prefix
if err := h.PublicFolderHandler.init("public", true); err != nil { // jail public file requests to /public/ prefix
return err
}

Expand Down
2 changes: 0 additions & 2 deletions internal/http/services/owncloud/ocdav/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ func (s *svc) handleDelete(w http.ResponseWriter, r *http.Request, ns string) {
ctx, span := trace.StartSpan(ctx, "head")
defer span.End()

ns = applyLayout(ctx, ns)

fn := path.Join(ns, r.URL.Path)

sublog := appctx.GetLogger(ctx).With().Str("path", fn).Logger()
Expand Down
2 changes: 0 additions & 2 deletions internal/http/services/owncloud/ocdav/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ func (s *svc) handleGet(w http.ResponseWriter, r *http.Request, ns string) {
ctx, span := trace.StartSpan(ctx, "get")
defer span.End()

ns = applyLayout(ctx, ns)

fn := path.Join(ns, r.URL.Path)

sublog := appctx.GetLogger(ctx).With().Str("path", fn).Str("svc", "ocdav").Str("handler", "get").Logger()
Expand Down
2 changes: 0 additions & 2 deletions internal/http/services/owncloud/ocdav/head.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ func (s *svc) handleHead(w http.ResponseWriter, r *http.Request, ns string) {
ctx, span := trace.StartSpan(ctx, "head")
defer span.End()

ns = applyLayout(ctx, ns)

fn := path.Join(ns, r.URL.Path)

sublog := appctx.GetLogger(ctx).With().Str("path", fn).Logger()
Expand Down
2 changes: 0 additions & 2 deletions internal/http/services/owncloud/ocdav/mkcol.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ func (s *svc) handleMkcol(w http.ResponseWriter, r *http.Request, ns string) {
ctx, span := trace.StartSpan(ctx, "mkcol")
defer span.End()

ns = applyLayout(ctx, ns)

fn := path.Join(ns, r.URL.Path)

sublog := appctx.GetLogger(ctx).With().Str("path", fn).Logger()
Expand Down
2 changes: 0 additions & 2 deletions internal/http/services/owncloud/ocdav/move.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ func (s *svc) handleMove(w http.ResponseWriter, r *http.Request, ns string) {
ctx, span := trace.StartSpan(ctx, "move")
defer span.End()

ns = applyLayout(ctx, ns)

src := path.Join(ns, r.URL.Path)
dstHeader := r.Header.Get("Destination")
overwrite := r.Header.Get("Overwrite")
Expand Down
19 changes: 16 additions & 3 deletions internal/http/services/owncloud/ocdav/ocdav.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"time"

gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/cs3org/reva/pkg/appctx"
"github.com/cs3org/reva/pkg/rgrpc/todo/pool"
Expand Down Expand Up @@ -102,7 +103,7 @@ func New(m map[string]interface{}, log *zerolog.Logger) (global.Service, error)
),
}
// initialize handlers and set default configs
if err := s.webDavHandler.init(conf.WebdavNamespace); err != nil {
if err := s.webDavHandler.init(conf.WebdavNamespace, true); err != nil {
return nil, err
}
if err := s.davHandler.init(conf); err != nil {
Expand Down Expand Up @@ -186,8 +187,20 @@ func (s *svc) getClient() (gateway.GatewayAPIClient, error) {
return pool.GetGatewayServiceClient(s.c.GatewaySvc)
}

func applyLayout(ctx context.Context, ns string) string {
return templates.WithUser(ctxuser.ContextMustGetUser(ctx), ns)
func applyLayout(ctx context.Context, ns string, useLoggedInUserNS bool, requestPath string) string {
// If useLoggedInUserNS is false, that implies that the request is coming from
// the FilesHandler method invoked by a /dav/files/fileOwner where fileOwner
// is not the same as the logged in user. In that case, we'll treat fileOwner
// as the username whose files are to be accessed and use that in the
// namespace template.
u, ok := ctxuser.ContextGetUser(ctx)
if !ok || !useLoggedInUserNS {
requestUserID, _ := router.ShiftPath(requestPath)
u = &userpb.User{
Username: requestUserID,
}
}
return templates.WithUser(u, ns)
}

func wrapResourceID(r *provider.ResourceId) string {
Expand Down
2 changes: 0 additions & 2 deletions internal/http/services/owncloud/ocdav/propfind.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ func (s *svc) handlePropfind(w http.ResponseWriter, r *http.Request, ns string)
ctx, span := trace.StartSpan(ctx, "propfind")
defer span.End()

ns = applyLayout(ctx, ns)

fn := path.Join(ns, r.URL.Path)
depth := r.Header.Get("Depth")
if depth == "" {
Expand Down
2 changes: 0 additions & 2 deletions internal/http/services/owncloud/ocdav/proppatch.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ func (s *svc) handleProppatch(w http.ResponseWriter, r *http.Request, ns string)
acceptedProps := []xml.Name{}
removedProps := []xml.Name{}

ns = applyLayout(ctx, ns)

fn := path.Join(ns, r.URL.Path)

sublog := appctx.GetLogger(ctx).With().Str("path", fn).Logger()
Expand Down
2 changes: 0 additions & 2 deletions internal/http/services/owncloud/ocdav/put.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,6 @@ func isContentRange(r *http.Request) bool {

func (s *svc) handlePut(w http.ResponseWriter, r *http.Request, ns string) {
ctx := r.Context()

ns = applyLayout(ctx, ns)
fn := path.Join(ns, r.URL.Path)

sublog := appctx.GetLogger(ctx).With().Str("path", fn).Logger()
Expand Down
2 changes: 0 additions & 2 deletions internal/http/services/owncloud/ocdav/tus.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@ func (s *svc) handleTusPost(w http.ResponseWriter, r *http.Request, ns string) {
return
}

ns = applyLayout(ctx, ns)

// append filename to current dir
fn := path.Join(ns, r.URL.Path, meta["filename"])

Expand Down
35 changes: 19 additions & 16 deletions internal/http/services/owncloud/ocdav/webdav.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,46 +25,49 @@ import (

// WebDavHandler implements a dav endpoint
type WebDavHandler struct {
namespace string
namespace string
useLoggedInUserNS bool
}

func (h *WebDavHandler) init(ns string) error {
func (h *WebDavHandler) init(ns string, useLoggedInUserNS bool) error {
h.namespace = path.Join("/", ns)
h.useLoggedInUserNS = useLoggedInUserNS
return nil
}

// Handler handles requests
func (h *WebDavHandler) Handler(s *svc) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ns := applyLayout(r.Context(), h.namespace, h.useLoggedInUserNS, r.URL.Path)
switch r.Method {
case "PROPFIND":
s.handlePropfind(w, r, h.namespace)
s.handlePropfind(w, r, ns)
case "LOCK":
s.handleLock(w, r, h.namespace)
s.handleLock(w, r, ns)
case "UNLOCK":
s.handleUnlock(w, r, h.namespace)
s.handleUnlock(w, r, ns)
case "PROPPATCH":
s.handleProppatch(w, r, h.namespace)
s.handleProppatch(w, r, ns)
case "MKCOL":
s.handleMkcol(w, r, h.namespace)
s.handleMkcol(w, r, ns)
case "MOVE":
s.handleMove(w, r, h.namespace)
s.handleMove(w, r, ns)
case "COPY":
s.handleCopy(w, r, h.namespace)
s.handleCopy(w, r, ns)
case "REPORT":
s.handleReport(w, r, h.namespace)
s.handleReport(w, r, ns)
case http.MethodGet:
s.handleGet(w, r, h.namespace)
s.handleGet(w, r, ns)
case http.MethodPut:
s.handlePut(w, r, h.namespace)
s.handlePut(w, r, ns)
case http.MethodPost:
s.handleTusPost(w, r, h.namespace)
s.handleTusPost(w, r, ns)
case http.MethodOptions:
s.handleOptions(w, r, h.namespace)
s.handleOptions(w, r, ns)
case http.MethodHead:
s.handleHead(w, r, h.namespace)
s.handleHead(w, r, ns)
case http.MethodDelete:
s.handleDelete(w, r, h.namespace)
s.handleDelete(w, r, ns)
default:
w.WriteHeader(http.StatusNotFound)
}
Expand Down

0 comments on commit 47119be

Please sign in to comment.