Skip to content

Commit

Permalink
Fix linter and hound issues
Browse files Browse the repository at this point in the history
  • Loading branch information
aduffeck committed Jan 12, 2022
1 parent c29667f commit 148c89e
Show file tree
Hide file tree
Showing 14 changed files with 130 additions and 42 deletions.
5 changes: 5 additions & 0 deletions internal/http/services/owncloud/ocdav/errors/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ var (
}
)

// Exception represents a ocdav exception
type Exception struct {
Code code
Message string
Expand All @@ -80,6 +81,7 @@ func Marshal(code code, message string, header string) ([]byte, error) {
return []byte(xml.Header + string(xmlstring)), err
}

// ErrorXML holds the xml representation of an error
// http://www.webdav.org/specs/rfc4918.html#ELEMENT_error
type ErrorXML struct {
XMLName xml.Name `xml:"d:error"`
Expand All @@ -92,7 +94,10 @@ type ErrorXML struct {
Header string `xml:"s:header,omitempty"`
}

// ErrorInvalidPropfind is an invalid propfind error
var ErrorInvalidPropfind = errors.New("webdav: invalid propfind")

// ErrInvalidProppatch is an invalid proppatch error
var ErrInvalidProppatch = errors.New("webdav: invalid proppatch")

// HandleErrorStatus checks the status code, logs a Debug or Error level message
Expand Down
2 changes: 1 addition & 1 deletion internal/http/services/owncloud/ocdav/net/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (
ctxpkg "github.com/cs3org/reva/pkg/ctx"
)

// a file is only yours if you are the owner
// IsCurrentUserOwner returns whether the context user is the given owner or not
func IsCurrentUserOwner(ctx context.Context, owner *userv1beta1.UserId) bool {
contextUser, ok := ctxpkg.ContextGetUser(ctx)
if ok && contextUser.Id != nil && owner != nil &&
Expand Down
14 changes: 10 additions & 4 deletions internal/http/services/owncloud/ocdav/net/net.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,23 @@ import (
type ctxKey int

const (
// CtxKeyBaseURI is the key of the base URI context field
CtxKeyBaseURI ctxKey = iota

NsDav = "DAV:"
// NsDav is the Dav ns
NsDav = "DAV:"
// NsOwncloud is the owncloud ns
NsOwncloud = "http://owncloud.org/ns"
NsOCS = "http://open-collaboration-services.org/ns"
// NsOCS is the OCS ns
NsOCS = "http://open-collaboration-services.org/ns"

// RFC1123 time that mimics oc10. time.RFC1123 would end in "UTC", see https://github.com/golang/go/issues/13781
RFC1123 = "Mon, 02 Jan 2006 15:04:05 GMT"

// PropQuotaUnknown is the quota unknown property
PropQuotaUnknown = "-2"
PropOcFavorite = "http://owncloud.org/ns/favorite"
// PropOcFavorite is the favorite ns property
PropOcFavorite = "http://owncloud.org/ns/favorite"
)

// replaceAllStringSubmatchFunc is taken from 'Go: Replace String with Regular Expression Callback'
Expand All @@ -58,7 +64,7 @@ func replaceAllStringSubmatchFunc(re *regexp.Regexp, str string, repl func([]str

var hrefre = regexp.MustCompile(`([^A-Za-z0-9_\-.~()/:@!$])`)

// encodePath encodes the path of a url.
// EncodePath encodes the path of a url.
//
// slashes (/) are treated as path-separators.
// ported from https://github.com/sabre-io/http/blob/bb27d1a8c92217b34e778ee09dcf79d9a2936e84/lib/functions.php#L369-L379
Expand Down
18 changes: 18 additions & 0 deletions internal/http/services/owncloud/ocdav/ocdav_suite_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
// Copyright 2018-2021 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 ocdav_test

import (
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

66 changes: 41 additions & 25 deletions internal/http/services/owncloud/ocdav/propfind/propfind.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,20 +63,24 @@ type GatewayClient interface {

// GetGatewayServiceClientFunc is a callback used to pass in a StorageProviderClient during testing
type GetGatewayServiceClientFunc func() (GatewayClient, error)
type PropfindHandler struct {

// Handler handles propfind requests
type Handler struct {
PublicURL string
getClient GetGatewayServiceClientFunc
}

func NewPropfindHandler(publicURL string, getClientFunc GetGatewayServiceClientFunc) *PropfindHandler {
return &PropfindHandler{
// NewHandler returns a new PropfindHandler instance
func NewHandler(publicURL string, getClientFunc GetGatewayServiceClientFunc) *Handler {
return &Handler{
PublicURL: publicURL,
getClient: getClientFunc,
}
}

// HandlePathPropfind handles a path based propfind request
// ns is the namespace that is prefixed to the path in the cs3 namespace
func (p *PropfindHandler) HandlePathPropfind(w http.ResponseWriter, r *http.Request, ns string) {
func (p *Handler) HandlePathPropfind(w http.ResponseWriter, r *http.Request, ns string) {
ctx, span := rtrace.Provider.Tracer("reva").Start(r.Context(), fmt.Sprintf("%s %v", r.Method, r.URL.Path))
defer span.End()

Expand Down Expand Up @@ -121,7 +125,8 @@ func (p *PropfindHandler) HandlePathPropfind(w http.ResponseWriter, r *http.Requ
p.propfindResponse(ctx, w, r, ns, pf, sendTusHeaders, resourceInfos, sublog)
}

func (p *PropfindHandler) HandleSpacesPropfind(w http.ResponseWriter, r *http.Request, spaceID string) {
// HandleSpacesPropfind handles a spaces based propfind request
func (p *Handler) HandleSpacesPropfind(w http.ResponseWriter, r *http.Request, spaceID string) {
ctx, span := rtrace.Provider.Tracer("ocdav").Start(r.Context(), "spaces_propfind")
defer span.End()

Expand All @@ -142,6 +147,11 @@ func (p *PropfindHandler) HandleSpacesPropfind(w http.ResponseWriter, r *http.Re

// retrieve a specific storage space
space, rpcStatus, err := spacelookup.LookUpStorageSpaceByID(ctx, client.(gateway.GatewayAPIClient), spaceID)
if err != nil {
sublog.Error().Err(err).Msg("error looking up the space by id")
w.WriteHeader(http.StatusInternalServerError)
return
}

if rpcStatus.Code != rpc.Code_CODE_OK {
errors.HandleErrorStatus(&sublog, w, rpcStatus)
Expand All @@ -163,7 +173,7 @@ func (p *PropfindHandler) HandleSpacesPropfind(w http.ResponseWriter, r *http.Re

}

func (p *PropfindHandler) propfindResponse(ctx context.Context, w http.ResponseWriter, r *http.Request, namespace string, pf PropfindXML, sendTusHeaders bool, resourceInfos []*provider.ResourceInfo, log zerolog.Logger) {
func (p *Handler) propfindResponse(ctx context.Context, w http.ResponseWriter, r *http.Request, namespace string, pf XML, sendTusHeaders bool, resourceInfos []*provider.ResourceInfo, log zerolog.Logger) {
ctx, span := rtrace.Provider.Tracer("ocdav").Start(ctx, "propfind_response")
defer span.End()

Expand Down Expand Up @@ -214,7 +224,7 @@ func (p *PropfindHandler) propfindResponse(ctx context.Context, w http.ResponseW
}

// TODO this is just a stat -> rename
func (p *PropfindHandler) statSpace(ctx context.Context, client gateway.GatewayAPIClient, space *provider.StorageSpace, ref *provider.Reference, metadataKeys []string) (*provider.ResourceInfo, *rpc.Status, error) {
func (p *Handler) statSpace(ctx context.Context, client gateway.GatewayAPIClient, space *provider.StorageSpace, ref *provider.Reference, metadataKeys []string) (*provider.ResourceInfo, *rpc.Status, error) {
req := &provider.StatRequest{
Ref: ref,
ArbitraryMetadataKeys: metadataKeys,
Expand All @@ -226,7 +236,7 @@ func (p *PropfindHandler) statSpace(ctx context.Context, client gateway.GatewayA
return res.Info, res.Status, nil
}

func (p *PropfindHandler) getResourceInfos(ctx context.Context, w http.ResponseWriter, r *http.Request, pf PropfindXML, spaces []*provider.StorageSpace, requestPath string, spacesPropfind bool, log zerolog.Logger) ([]*provider.ResourceInfo, bool, bool) {
func (p *Handler) getResourceInfos(ctx context.Context, w http.ResponseWriter, r *http.Request, pf XML, spaces []*provider.StorageSpace, requestPath string, spacesPropfind bool, log zerolog.Logger) ([]*provider.ResourceInfo, bool, bool) {
depth := r.Header.Get(net.HeaderDepth)
if depth == "" {
depth = "1"
Expand Down Expand Up @@ -503,38 +513,40 @@ func requiresExplicitFetching(n *xml.Name) bool {
return true
}

// ReadPropfind extracts and parses the propfind XML information from a Reader
// from https://github.com/golang/net/blob/e514e69ffb8bc3c76a71ae40de0118d794855992/webdav/xml.go#L178-L205
func ReadPropfind(r io.Reader) (pf PropfindXML, status int, err error) {
func ReadPropfind(r io.Reader) (pf XML, status int, err error) {
c := countingReader{r: r}
if err = xml.NewDecoder(&c).Decode(&pf); err != nil {
if err == io.EOF {
if c.n == 0 {
// An empty body means to propfind allprop.
// http://www.webdav.org/specs/rfc4918.html#METHOD_PROPFIND
return PropfindXML{Allprop: new(struct{})}, 0, nil
return XML{Allprop: new(struct{})}, 0, nil
}
err = errors.ErrorInvalidPropfind
}
return PropfindXML{}, http.StatusBadRequest, err
return XML{}, http.StatusBadRequest, err
}

if pf.Allprop == nil && pf.Include != nil {
return PropfindXML{}, http.StatusBadRequest, errors.ErrorInvalidPropfind
return XML{}, http.StatusBadRequest, errors.ErrorInvalidPropfind
}
if pf.Allprop != nil && (pf.Prop != nil || pf.Propname != nil) {
return PropfindXML{}, http.StatusBadRequest, errors.ErrorInvalidPropfind
return XML{}, http.StatusBadRequest, errors.ErrorInvalidPropfind
}
if pf.Prop != nil && pf.Propname != nil {
return PropfindXML{}, http.StatusBadRequest, errors.ErrorInvalidPropfind
return XML{}, http.StatusBadRequest, errors.ErrorInvalidPropfind
}
if pf.Propname == nil && pf.Allprop == nil && pf.Prop == nil {
// jfd: I think <d:prop></d:prop> is perfectly valid ... treat it as allprop
return PropfindXML{Allprop: new(struct{})}, 0, nil
return XML{Allprop: new(struct{})}, 0, nil
}
return pf, 0, nil
}

func MultistatusResponse(ctx context.Context, pf *PropfindXML, mds []*provider.ResourceInfo, publicURL, ns string, linkshares map[string]struct{}) (string, error) {
// MultistatusResponse converts a list of resource infos into a multistatus response string
func MultistatusResponse(ctx context.Context, pf *XML, mds []*provider.ResourceInfo, publicURL, ns string, linkshares map[string]struct{}) (string, error) {
responses := make([]*ResponseXML, 0, len(mds))
for i := range mds {
res, err := mdToPropResponse(ctx, pf, mds[i], publicURL, ns, linkshares)
Expand All @@ -557,7 +569,7 @@ func MultistatusResponse(ctx context.Context, pf *PropfindXML, mds []*provider.R
// mdToPropResponse converts the CS3 metadata into a webdav PropResponse
// ns is the CS3 namespace that needs to be removed from the CS3 path before
// prefixing it with the baseURI
func mdToPropResponse(ctx context.Context, pf *PropfindXML, md *provider.ResourceInfo, publicURL, ns string, linkshares map[string]struct{}) (*ResponseXML, error) {
func mdToPropResponse(ctx context.Context, pf *XML, md *provider.ResourceInfo, publicURL, ns string, linkshares map[string]struct{}) (*ResponseXML, error) {
sublog := appctx.GetLogger(ctx).With().Interface("md", md).Str("ns", ns).Logger()
md.Path = strings.TrimPrefix(md.Path, ns)

Expand Down Expand Up @@ -1090,14 +1102,15 @@ func metadataKeyOf(n *xml.Name) string {
}
}

// Props represents properties related to a resource
// http://www.webdav.org/specs/rfc4918.html#ELEMENT_prop (for propfind)
type PropfindProps []xml.Name
type Props []xml.Name

// UnmarshalXML appends the property names enclosed within start to pn.
//
// It returns an error if start does not contain any properties or if
// properties contain values. Character data between properties is ignored.
func (pn *PropfindProps) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
func (pn *Props) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
for {
t, err := props.Next(d)
if err != nil {
Expand Down Expand Up @@ -1125,15 +1138,17 @@ func (pn *PropfindProps) UnmarshalXML(d *xml.Decoder, start xml.StartElement) er
}
}

// XML holds the xml representation of a propfind
// http://www.webdav.org/specs/rfc4918.html#ELEMENT_propfind
type PropfindXML struct {
XMLName xml.Name `xml:"DAV: propfind"`
Allprop *struct{} `xml:"DAV: allprop"`
Propname *struct{} `xml:"DAV: propname"`
Prop PropfindProps `xml:"DAV: prop"`
Include PropfindProps `xml:"DAV: include"`
type XML struct {
XMLName xml.Name `xml:"DAV: propfind"`
Allprop *struct{} `xml:"DAV: allprop"`
Propname *struct{} `xml:"DAV: propname"`
Prop Props `xml:"DAV: prop"`
Include Props `xml:"DAV: include"`
}

// ResponseXML holds the xml representation of a propfind response
type ResponseXML struct {
XMLName xml.Name `xml:"d:response"`
Href string `xml:"d:href"`
Expand All @@ -1143,6 +1158,7 @@ type ResponseXML struct {
ResponseDescription string `xml:"d:responsedescription,omitempty"`
}

// PropstatXML holds the xml representation of a propfind response
// http://www.webdav.org/specs/rfc4918.html#ELEMENT_propstat
type PropstatXML struct {
// Prop requires DAV: to be the default namespace in the enclosing
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
// Copyright 2018-2021 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 propfind_test

import (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,21 @@ import (

var _ = Describe("Propfind", func() {
var (
handler *propfind.PropfindHandler
handler *propfind.Handler
client *mocks.GatewayClient
ctx context.Context
)

JustBeforeEach(func() {
ctx = context.Background()
client = &mocks.GatewayClient{}
handler = propfind.NewPropfindHandler("127.0.0.1:3000", func() (propfind.GatewayClient, error) {
handler = propfind.NewHandler("127.0.0.1:3000", func() (propfind.GatewayClient, error) {
return client, nil
})
})

Describe("NewPropfindHandler", func() {
It("returns a hanlder", func() {
Describe("NewHandler", func() {
It("returns a handler", func() {
Expect(handler).ToNot(BeNil())
})
})
Expand Down
5 changes: 4 additions & 1 deletion internal/http/services/owncloud/ocdav/props/props.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
"encoding/xml"
)

// Property represents a single DAV resource property as defined in RFC 4918.
// PropertyXML represents a single DAV resource property as defined in RFC 4918.
// http://www.webdav.org/specs/rfc4918.html#data.model.for.resource.properties
type PropertyXML struct {
// XMLName is the fully qualified name that identifies this property.
Expand All @@ -49,6 +49,7 @@ func xmlEscaped(val string) []byte {
return buf.Bytes()
}

// NewPropNS returns a new PropertyXML instance
func NewPropNS(namespace string, local string, val string) *PropertyXML {
return &PropertyXML{
XMLName: xml.Name{Space: namespace, Local: local},
Expand All @@ -57,6 +58,7 @@ func NewPropNS(namespace string, local string, val string) *PropertyXML {
}
}

// NewProp returns a new PropertyXML instance while xml-escaping the value
// TODO properly use the space
func NewProp(key, val string) *PropertyXML {
return &PropertyXML{
Expand All @@ -66,6 +68,7 @@ func NewProp(key, val string) *PropertyXML {
}
}

// NewPropRaw returns a new PropertyXML instance for the given key/value pair
// TODO properly use the space
func NewPropRaw(key, val string) *PropertyXML {
return &PropertyXML{
Expand Down
Loading

0 comments on commit 148c89e

Please sign in to comment.