Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent panic on /remote.php/dav/files/ #1320

Merged
merged 13 commits into from
Nov 25, 2020
Merged

Prevent panic on /remote.php/dav/files/ #1320

merged 13 commits into from
Nov 25, 2020

Conversation

refs
Copy link
Member

@refs refs commented Nov 13, 2020

Currently requests to /remote.php/dav/files/ result in panics since we cannot longer strip the user + destination from the url.

We're reproducing this issue on the ocis storage. I wanted to tackle this at the storage level but sadly the panic happens before reaching the stat call.

I wonder if there is a better way to achieve the same results but instead letting the storage handle the way it interprets paths. Open to suggestions 💃

@refs refs requested a review from labkode as a code owner November 13, 2020 11:14
@update-docs
Copy link

update-docs bot commented Nov 13, 2020

Thanks for opening this pull request! The maintainers of this repository would appreciate it if you would create a changelog item based on your changes.

@refs refs changed the title Avoid panic on /remote.php/dav/files/ Prevent panic on /remote.php/dav/files/ Nov 13, 2020
@labkode
Copy link
Member

labkode commented Nov 13, 2020

@refs can you provide info of the panic?

@phil-davis
Copy link
Contributor

https://cloud.drone.io/cs3org/reva/3145/13/6

runsh: Total unexpected passed scenarios throughout the test run:
apiWebdavOperations/propfind.feature:5

This does "a good thing" - that now-passing scenario should be deleted from the expected-failures files.

@phil-davis
Copy link
Contributor

And look at https://cloud.drone.io/cs3org/reva/3145/6/7 tests/acceptance/features/apiOcisSpecific/apiShareWebdavOperations-propfind.feature:6

  Scenario: PROPFIND to "/remote.php/dav/files"                                            # /drone/src/tests/acceptance/features/apiOcisSpecific/apiShareWebdavOperations-propfind.feature:6
    Given user "Alice" has been created with default attributes and without skeleton files # FeatureContext::userHasBeenCreatedWithDefaultAttributesAndWithoutSkeletonFiles()
    When user "Alice" requests "/remote.php/dav/files" with "PROPFIND" using basic auth    # AuthContext::userRequestsURLWithUsingBasicAuth()
    Then the HTTP status code should be "500"                                              # FeatureContext::thenTheHTTPStatusCodeShouldBe()
      HTTP status code 405 is not the expected value 500
      Failed asserting that 405 matches expected '500'.

That bug-demo scenario is now producing a good result. It can be deleted.

@refs
Copy link
Member Author

refs commented Nov 23, 2020

hi @labkode sorry for the radio silence, I was off sick the past week with some string children virus thing ...

The panic I was referring to happens here:

// validate that we have always at least two elements
if len(parts) < 2 {
panic(fmt.Sprintf("split: len(parts) < 2: path:%s parts:%+v", p, parts))
}

and it is triggered when the URL looks just like in the description of this pull request:

/remote.php/dav/files/

I'm open to better alternatives and not just patch this :)

@labkode
Copy link
Member

labkode commented Nov 23, 2020

@refs to trigger this condition one has to be on a "Shared folder" that must contain this structure.
If the path is outside the Shared folder (remote.php/dav/files) is not a shared folder this method should never be called.
Is it possible that your config is missing or has a different value for the Shares folder?

Anyways, the panic could have some nice logging to inform of the problem.

// webdav endpoint is called without a path. i.e: /remote.php/dav/files
if len(strings.Split(req.Ref.GetPath(), "/")) == 2 {
return &provider.StatResponse{
Status: status.NewUnimplemented(ctx, nil, "method not allowed"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A storage provider determines if the listing of the root folder is allowed based on permissions, not the gateway ...

@@ -95,6 +95,10 @@ func (s *svc) handlePropfind(w http.ResponseWriter, r *http.Request, ns string)
case rpc.Code_CODE_PERMISSION_DENIED:
log.Debug().Str("path", fn).Interface("status", res.Status).Msg("permission denied")
w.WriteHeader(http.StatusMultiStatus)
// TODO this is not a correct mapping. A new code SHOULD be added to the cs3apis.
case rpc.Code_CODE_UNIMPLEMENTED:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should check if the username is missing only in the ocs api. no need to push these quirks into storage providers or the cs3 api.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree, will contain the changes to ocdav only

@refs
Copy link
Member Author

refs commented Nov 24, 2020

@butonic changes are now contained to ocdav.go and its path handling magic 🌸 will put some effort into returning the correct XML and refactoring a little bit.

I thought of a middleware for not allowed methods to prevent from executing unnecessary logic but it might be an early optimization, but the fact that there is no way to catch this early on our router has some room for improvement 🚀

@labkode as per the behavior, it is captured here: https://github.com/owncloud/core/blob/18475dac812064b21dabcc50f25ef3ffe55691a5/tests/acceptance/features/apiWebdavOperations/propfind.feature

honestly that LoC on Reva was running regardless of being on a shared folder or not, the stack trace shed some light on the path taken, I recommend having a look at it. I will dig into my configuration to discard it but we're not having a very complex use case, but we need to be sure.

butonic
butonic previously approved these changes Nov 24, 2020
@micbar micbar requested a review from butonic November 24, 2020 14:00
@@ -6,4 +6,4 @@ Feature: PROPFIND
Scenario: PROPFIND to "/remote.php/dav/files"
Copy link
Contributor

@butonic butonic Nov 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you check the line above you should find the after fixing all issues delete this Scenario and use the one from oC10 core, meaning that AFAICT this complete feature file can be removed, as it is covered by the core tests.

  • remove tests/acceptance/features/apiOcisSpecific/apiShareWebdavOperations-propfind.feature

Copy link
Contributor

@phil-davis phil-davis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good from a test point of view - the related scenario in the core API tests now passes, and the local bug-demo scenario has been deleted.

@ishank011
Copy link
Contributor

@refs can we try to return false instead of raising a panic here?

// validate that we have always at least two elements
if len(parts) < 2 {
panic(fmt.Sprintf("split: len(parts) < 2: path:%s parts:%+v", p, parts))
}

The next step will be to find the storage provider and since it won't find any mapping for it, it will return the appropriate error. That's because this is raised a lot of other times when the user doesn't provide a correct path from any other clients.

@refs
Copy link
Member Author

refs commented Nov 25, 2020

@refs can we try to return false instead of raising a panic here?

// validate that we have always at least two elements
if len(parts) < 2 {
panic(fmt.Sprintf("split: len(parts) < 2: path:%s parts:%+v", p, parts))
}

The next step will be to find the storage provider and since it won't find any mapping for it, it will return the appropriate error. That's because this is raised a lot of other times when the user doesn't provide a correct path from any other clients.

I'd say that's out of the scope of this one :D

Copy link
Contributor

@ishank011 ishank011 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh okay. No worries!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants