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

Bugfix/owncloud/oauth2#103 #30365

Merged
merged 2 commits into from
Feb 13, 2018
Merged

Bugfix/owncloud/oauth2#103 #30365

merged 2 commits into from
Feb 13, 2018

Conversation

DeepDiver1975
Copy link
Member

@DeepDiver1975 DeepDiver1975 commented Feb 5, 2018

Description

Related Issue

fixes owncloud/oauth2#103

Motivation and Context

How Has This Been Tested?

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

@DeepDiver1975 DeepDiver1975 added this to the development milestone Feb 5, 2018
@DeepDiver1975 DeepDiver1975 self-assigned this Feb 5, 2018
@DeepDiver1975 DeepDiver1975 force-pushed the bugfix/owncloud/oauth2#103 branch from cadc772 to e838056 Compare February 6, 2018 14:12
@codecov
Copy link

codecov bot commented Feb 6, 2018

Codecov Report

Merging #30365 into master will increase coverage by 0.03%.
The diff coverage is 84.37%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master   #30365      +/-   ##
============================================
+ Coverage     60.86%   60.89%   +0.03%     
- Complexity    18584    18597      +13     
============================================
  Files          1093     1093              
  Lines         61371    61405      +34     
============================================
+ Hits          37351    37393      +42     
+ Misses        24020    24012       -8
Impacted Files Coverage Δ Complexity Δ
lib/private/Session/Internal.php 0% <0%> (ø) 19 <0> (ø) ⬇️
lib/private/User/Session.php 62.21% <75%> (+3.45%) 144 <5> (+4) ⬆️
lib/private/User/BasicAuthModule.php 95.45% <91.66%> (+1.7%) 11 <0> (+2) ⬆️
lib/private/User/TokenAuthModule.php 92.1% <92.59%> (+2.1%) 15 <9> (+7) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d5be225...80fe030. Read the comment docs.

$user = $this->manager->checkPassword($request->server['PHP_AUTH_USER'], $request->server['PHP_AUTH_PW']);
if ($user instanceof IUser) {
return $user;
// reuse logClientIn because this method
Copy link
Contributor

Choose a reason for hiding this comment

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

because this method... yes ?

@@ -66,6 +63,10 @@ public function getUserPassword(IRequest $request) {
return '';
}

if ($this->session->getSession()->exists('app_password')) {
// TODO: use proper password
throw new \Exception('Not implemented yet');
Copy link
Contributor

Choose a reason for hiding this comment

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

is this ever triggered ?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not at the moment - this is a safety exception which will punch us in the face as soon as we use it accidentally.

Actually the whole method should not yet be called ... we could just throw the exception right away

$user = $module->auth($request);
if ($user !== null) {
if ($this->isLoggedIn() && $this->getUser()->getUID() !== $user->getUID()) {
throw new Exception();
Copy link
Contributor

Choose a reason for hiding this comment

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

would be nice to have a message, especially if we don't have a proper type.

no more auto-logout of bad sessions ?

Copy link
Member Author

Choose a reason for hiding this comment

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

these exceptions are basically just to jump out of the loop and do the logout in the catch block - I'm not to happy with this .....

@PVince81
Copy link
Contributor

PVince81 commented Feb 6, 2018

As someone unfamiliar with this code, it would be nice to have a more detailed description that tells why you went to make the changes you made.

The commit says something about reordering auth modules but the PR does more than this: it seems to replace API calls with other ones and throw exceptions instead of returning. Are these latter changes part of the bugfix or are they more about cleaning up ?

@DeepDiver1975 DeepDiver1975 force-pushed the bugfix/owncloud/oauth2#103 branch from e838056 to 84d3242 Compare February 7, 2018 11:56
Copy link
Contributor

@PVince81 PVince81 left a comment

Choose a reason for hiding this comment

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

ok then 👍

@PVince81
Copy link
Contributor

PVince81 commented Feb 7, 2018

looks good, yes

@PVince81
Copy link
Contributor

PVince81 commented Feb 8, 2018

@SamuAlfageme can you retest auth issue with this ?

@PVince81
Copy link
Contributor

PVince81 commented Feb 8, 2018

CI fails ? :-/

@DeepDiver1975
Copy link
Member Author

CI fails ? :-/

drone has network issues

@DeepDiver1975
Copy link
Member Author

jenkins has failing integration tests

@PVince81
Copy link
Contributor

PVince81 commented Feb 8, 2018

the integration tests seem completely unrelated. trashbin ?! 🙈

@PVince81
Copy link
Contributor

PVince81 commented Feb 8, 2018

oh wait... trashbin result says Failed asserting that 401 matches expected '200'..

Either we broke something or the test was passing by chance before

@DeepDiver1975
Copy link
Member Author

I better have a look ....

@PVince81 PVince81 added the p1-urgent Critical issue, need to consider hotfix with just that issue label Feb 8, 2018
@DeepDiver1975
Copy link
Member Author

10:27:08     And logging in using web as "user1"                                                                   # FeatureContext::loggingInUsingWebAs()
10:27:08 [Thu Feb  8 10:27:08 2018] ::1:53702 [200]: /index.php/apps/files/
10:27:08 [Thu Feb  8 10:27:08 2018] ::1:53706 [401]: /index.php/apps/files_trashbin/ajax/list.php?dir=%2F
10:27:08     When as "user1" the file with original path "/renamed_shared/shared_file.txt" is restored             # FeatureContext::elementInTrashIsRestored()
10:27:08       Failed asserting that 401 matches expected '200'.
10:27:09     Then as "user1" the file with original path "/renamed_shared/shared_file.txt" does not exist in trash # FeatureContext::elementIsNotInTrashCheckingOriginalPath()
10:27:09     And user "user1" should see following elements                                                        # FeatureContext::checkElementList()
10:27:09       | /renamed_shared/                |
10:27:09       | /renamed_shared/shared_file.txt |

@DeepDiver1975
Copy link
Member Author

The requests as executed by the integration tests are not reusing the session cookies - which might have a side effect ...

@DeepDiver1975 DeepDiver1975 force-pushed the bugfix/owncloud/oauth2#103 branch 2 times, most recently from d4a9a90 to c90f461 Compare February 12, 2018 10:49
}
return $this->manager->checkPassword($users[0]->getUID(), $request->server['PHP_AUTH_PW']);
throw new \Exception('Invalid credentials');
Copy link
Contributor

Choose a reason for hiding this comment

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

return false ? Throwing could cause other side effects...

Copy link
Contributor

Choose a reason for hiding this comment

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

in TokenAuthModule we return null, let's stay consistent

Copy link
Member Author

Choose a reason for hiding this comment

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

null is returned if there is no authentication header to be evaluated aka handled by this module.
exception is throws if credentials are wrong
user object is returned if creds are valid

Copy link
Contributor

Choose a reason for hiding this comment

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

okay

Copy link
Member Author

Choose a reason for hiding this comment

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

But you are right - this logic seems to be missing in the token auch module ....

* @return null|IToken
*/
private function getTokenForAppPassword(IRequest $request, &$token) {
if (empty($request->server['PHP_AUTH_USER']) || empty($request->server['PHP_AUTH_PW'])) {
Copy link
Contributor

Choose a reason for hiding this comment

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

not afraid of "0" users ?

Copy link
Member Author

Choose a reason for hiding this comment

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

@PVince81 as requested: fuck php

Copy link
Contributor

@PVince81 PVince81 left a comment

Choose a reason for hiding this comment

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

see comments

@DeepDiver1975 DeepDiver1975 force-pushed the bugfix/owncloud/oauth2#103 branch 2 times, most recently from bbf4193 to ee3c057 Compare February 13, 2018 07:13
…over all modules and allow each of them

to verify the headers and in case something is terribly wrong the user will be logged out and the session will be destroyed.

The BasicAuthModule now handles app passwords as well - this was missing before and caused users being locked out of ldap.

Solves OAuth token expiry issue - fixes owncloud/oauth2#103
@SamuAlfageme
Copy link

@DeepDiver1975 initial tests suggest the problem no longer reproduces with this + owncloud/oauth2#112; great news! 🎉

  1. Reduced drastically AccessToken's resetExpires() to bump expires every 20s
  2. Authorized the Desktop client
  3. Close the client during access_token validity period and wait 20s
  4. Replay any successful request the client made previously
  5. Observe 401 "Unauthorized" reply on the replayed request

Would a traversal unit test like this one make sense to be included in the OAuth2 test pool?

Will focus now on trying to reproduce owncloud/oauth2#103 on the mobile apps; with and without these patches.

@SamuAlfageme
Copy link

SamuAlfageme commented Feb 13, 2018

@DeepDiver1975 can you check if the scope of this patch can be extended to the old WebDAV endpoint?

After some more tests, I believe the original cause of owncloud/oauth2#103 is the logic for the old endpoint. Take these 2 PROPFINDs using OAuth2 as the auth8n mechanism:

Replaying the iOS request any number of times results on 2XX, while desktop gets the correct 401 (after the token is expired; as described in my previous #30365 (comment))

@SamuAlfageme
Copy link

SamuAlfageme commented Feb 13, 2018

Hm. Forcing the use of the old endpoint on the Desktop client (setting env. OWNCLOUD_CHUNKING_NG=0) still results on 401 & token refresh.

Appart from the endpoints there are a few apparent (but not relevant) differences between iOS and Desktop PROPFINDS 😕

Desktop:

curl \
    -H 'Depth:0' \
    -H 'Authorization:Bearer VBvulBvRbhOpaA5BLkaLl7H7AdeatO5kwGyDNqfwYf2XRnsJTz0sEagLwgSuT3U3' \
    -H 'User-Agent:Mozilla/5.0 (Macintosh) mirall/2.4.0 (build 8836)' \
    -H 'Accept:*/*' \
    -H 'Content-Type:text/xml; charset=utf-8' \
    -H 'X-Request-ID:83fd38fa-395b-429e-a1be-80aad5fc9c32' \
    -H 'Cookie:oc_sessionPassphrase=fnebJi6XYVoOIsvNDYO9KMec7ZI8qYbD3m0D0kYi5UJhoXh%2FviUkj7hqrvuPkXpaFgzSW0UqemP4JIOjFUMjmR2tWh%2Bt1DjRkr8uXnypprsGZvRoy7EGWdSwGemssovV; oc3kizzp7f7d=plgcob981he5sjek79r7avjqp1' \
    -H 'Content-Length:147' \
    -H 'Connection:Keep-Alive' \
    -H 'Accept-Encoding:gzip, deflate' \
    -H 'Accept-Language:en-US,*' \
    -H 'Host:alfageme.solidgear.prv:4443' \
    -X PROPFIND 'https://alfageme.solidgear.prv:4443/remote.php/webdav/' \
    --data-binary '<?xml version="1.0" ?>
<d:propfind xmlns:d="DAV:">
  <d:prop>
    <d:quota-available-bytes />
    <d:quota-used-bytes />
  </d:prop>
</d:propfind>
'

iOS:

curl \
    -H 'Host:alfageme.solidgear.prv:4443' \
    -H 'Content-Type:application/xml' \
    -H 'Depth:1' \
    -H 'Accept:*/*' \
    -H 'Accept-Encoding:gzip, deflate' \
    -H 'Connection:keep-alive' \
    -H 'Cookie:oc3kizzp7f7d=6ds6rnc8mcl5jg31dkmdnpqli6; oc_sessionPassphrase=9sWpKyFrO8B59uXHo%2F4BRmHB3X2q6qJDtpS17D2Zx7BcFPp0s4yPdWiZBPqmzkmWvo4yoBW9XJ7%2BwzgtfCVWfmy%2F0TzJwWUVbROzy0LDGHFPM9543cKTkWnf6%2FqoFcB1' \
    -H 'User-Agent:Mozilla/5.0 (iOS) ownCloud-iOS/3.7.0' \
    -H 'Accept-Language:en-US;q=1, es-US;q=0.9, zh-Hant-US;q=0.8, en-GB;q=0.7, en;q=0.6' \
    -H 'Authorization:Bearer fVbLupKEkYi4Yr6tzALsAZlMZIjMDEkpjZXr5kcwYR6HMKvjDy0RQPoXS4dJ7QSl' \
    -H 'Content-Length:383' \
    -X PROPFIND 'https://alfageme.solidgear.prv:4443/remote.php/webdav/' \
    --data-binary '<?xml version="1.0" encoding="UTF-8"?><D:propfind xmlns:D="DAV:"><D:prop><D:resourcetype/><D:getlastmodified/><size xmlns="http://owncloud.org/ns"/><D:creationdate/><id xmlns="http://owncloud.org/ns"/><D:getcontentlength/><D:displayname/><D:quota-available-bytes/><D:getetag/><permissions xmlns="http://owncloud.org/ns"/><D:quota-used-bytes/><D:getcontenttype/></D:prop></D:propfind>'

Diffs:

Will play with these differences and report back when I find the one that messes with the auth. middleware.

@DeepDiver1975
Copy link
Member Author

I honestly question if oauth works at all on the old endpoint .......

@PVince81
Copy link
Contributor

If we didn't break more stuff that wasn't broken before I'd suggest moving forward with the PR and get it released as it adresses the more critical issue. Then investigate this detail separately ?

@SamuAlfageme @DeepDiver1975

@SamuAlfageme
Copy link

As discussed with @DeepDiver1975 and @owncloud/ios-developers, in the end, owncloud/oauth2#103 was all about the iOS app circumventing the webview's sandbox (I haven't had the chance to check with Android's implementation, tho). This means the client was reusing cookies obtained during the authentication steps delegated to the browser (which goes against the end goal of the OAuth2 mechanism: isolation from this); those were bounded to the browser's activity; just like if they were obtained on safari or any other mobile browser, and valid as long as them (not dependent on the access_token at all).

After all the tests performed, all the basic access/refresh/revoke scenarios look sane enough. I'll go for the merge here. 👍

@lock
Copy link

lock bot commented Aug 1, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Aug 1, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
3 - To Review p1-urgent Critical issue, need to consider hotfix with just that issue
Projects
None yet
Development

Successfully merging this pull request may close these issues.

OAuth2 token revokation does not expire sessions
3 participants