OAuth2 support on the Desktop Client
Preconditions:
- ownCloud server version 10.072
Platform versions tested
- Desktop Client 2.4.1 for Mac OSX
- iOS Client 3.7.3.
- Android Client 2.6.0
Test Scope Variability
As pointed out in the preconditions, there has to be a browser installed in the underlying OS, as it's a critical piece for the auth. Additionally to the multiplatform tests, we will consider the mainstream browsers to check all the testcases: versions TBD
- Mozilla Firefox
- Google Chrome
- Safari
- Internet Explorer
- Edge
Each TC is considered to be independent, it's required both the session in the browser and the account created (if any) on the client are to be removed prior to next test cases.
Authentication
Since the entrypoint is the same as in the rest of authentication methods (the login form) there are also some protocol-agnostic test-cases that are inherited from the appropriate testplan(s). e.g. account log-out, redirections, http/s alternatives... that should be checked for the full picture. In this document we're just going to focus on pure OAuth2 implementation-related test-cases. For that, we have to differentiate between 2 scenarios:
- Account Setup: Wizard
- Login into existing accounts
First of all, it's important to understand the steps required to authenticate a user in the OAuth2 protocol implemented by ownCloud: https://github.com/owncloud/oauth2/#protocol-flow
Authentication Request -> Access Token Request ---Token Expiration---> Token Refresh
Account Setup
Login from scratch, creating a new account.
Successful Scenarios
| TestID |
Test Case |
Steps |
Expected Result |
Result |
Related Comment |
| 1 |
Login on a clean browser |
1. Input the server URL on the account wizard, click next 2. Input valid account credentials on the login form in the browser opened 3. Authorize the "Desktop client" application 4. Use the default folder sync config |
The account is created and syncing with the default config |
✅ |
|
| 1.1 |
Authentication Request |
When performing TC's s.1 |
Verify: - The header
WWW-Authenticate: Bearer realm="ownCloud" is included in the server's reply - The query parameters
response_type=<code>, redirect_uri=, client_id= are present and match the values described in Preconditions on the opened URL |
✅ |
|
| 1.2 |
Access Token Request |
After TC's s.3 (app authorization) |
Verify the Access Token request contains the right values and is successful |
✅ |
See Access Token Request below |
| 2 |
Login (authorize) on an already open session in the browser |
1. Open the server URL on the browser and login with valid credentials 2. Use the same server URL on the client's new account wizard, click next 3. Authorize the "Desktop client" application on the page opened |
Same as TC1 |
✅ |
|
Access Token Request:
Request:
curl [...] \
-H 'Content-Type:application/x-www-form-urlencoded' \
-X POST 'https://<server>/index.php/apps/oauth2/api/v1/token' \
--data-binary 'grant_type=authorization_code&code=<code>&redirect_uri=http://localhost:<random_port>'
Reply:
{
"access_token": "<access_token>",
"expires_in": 3600,
"message_url": "[...]/index.php/apps/oauth2/authorization-successful",
"refresh_token": "<refresh_token>",
"token_type": "Bearer",
"user_id": "demo"
}
Unauthorized/Alternative Paths
| TestID |
Test Case |
Steps |
Expected Result |
Result |
Related Comment |
| 3 |
Close the browser without authorizing the app |
1. Close the browser auth on TC1 s.2/3 |
The wizard allows restarting the auth. process by opening a new browser |
✅ |
|
| 4 |
Wait for more than 5 minutes without authorizing the application |
1. Wait for more than 5 minutes without completing TC1's s.2/3 |
The wizard displays an error to state it's no longer waiting for the authorization but allows restarting the operation by launching a new browser |
✅ |
|
| 5 |
Use the wrong password when trying to login |
1. Use the wrong username/password combination on TC1 s.2 |
The client keeps waiting until a successful authorization is made / times out (TC4) and offers the option to restart the auth. process |
✅ |
Being able to recover gracefully from this error depends on: owncloud/core#28129 |
| 6 |
Go back on wizard's page 2 ("Login in your browser") |
1. Input the server URL on the account wizard, click next 2. Click back |
A new server URL can be used in the wizard; if used, the client will no longer listen for the redirection on the original <random_port> but on a different one |
✅ |
|
| 7 |
Close wizard in any step |
1. Use the window controls to close the wizard in any of the steps |
No effect in the client: no account is included if any of the steps was not completed |
✅ |
|
References:
Request:
Existing Accounts
| TestID |
Test Case |
Steps |
Expected Result |
Result |
Related Comment |
| 8 |
Change a logged-in user password |
1. From the webUI, change the password of a user with a current, active, OAuth session on the Desktop Client |
The session is terminated in the Desktop Client and will be offline until the user logs in with the new password. |
❌ |
protocol-independent TC |
| 9 |
Delete a logged-in user |
1. As administrator user, remove the account of a user with a current, active, OAuth session on the Desktop Client |
Same as TC9 (Any attempt to login should be Unauthorized though) |
✅ |
protocol-independent TC |
Also, it's important to consider the cases either when upgrading a working client to support OAuth2 authentication or when an account was already setup but the AccountState is not "Connected" for any reason.
Upgrade path
Coming from an old version of the client (< 2.4.0) will require to re-login into the account since the client will consider the old credentials/sessions non-valid in virtue of the new auth. method.
| TestID |
Test Case |
Steps |
Expected Result |
Result |
Related Comment |
| 10 |
Basic-auth account with OAuth2 support from the server |
1. Create an account with basic auth on a client without OAuth2 support 2. Update the client to a version >= 2.4 3. Relaunch the client |
The user is prompted with OAuth login for that account. The client migrates seamlessly all the account details and preferences |
✅ |
See Account Migrations below for technical checks |
| 11 |
Any other credential type (dummy, SAML) |
1. Create a SAML/Dummy (testing) account on a client without OAuth2 support 2. Update the client to a version >= 2.4 3. Relaunch the client |
The accounts are still logged-in and no preference lost |
🚧 |
See the notes in SAML accounts |
Expired authorization token
When tokens' hit their expiration date come to an end the OAuth2 refresh token logic of the protocol is used.
| TestID |
Test Case |
Steps |
Expected Result |
Result |
Related Comment |
| 12 |
Token expiration & renovation |
1. Modify the expiration date of the access token in the server DB to match current 2. Monitor the client network requests with a proxy |
Verify the client gets reauthenticated transparently using the refresh token and the first unauthenticated operation gets retriggered |
✅ |
|
| 12.1 |
Token Refresh Request |
Open request from TC12 s.2 |
Verify the Access Token request contains the right values and is successful |
Same AC as TC1.2 with new access/secret tokens |
✅ |
Combination of Scenarios
These are not semantically different scenarios to the ones described already in previous sections but variations that have to meet many of the same acceptance criteria and some additional ones.
Branding
| TestID |
Test Case |
Steps |
Expected Result |
Result |
Related Comment |
| 16 |
|
1. Use a client with a branded, forced auth. method 2. Create a new account |
The branded method is used by default regardless of the headers sent by the server |
✅ |
|
#### Multi-account support
Some considerations have to be taken into account to solve the issue of the desktop client not being able to open independent and clean WebViews (as the mobile clients use) owncloud/client#5895: this means server supporting ways to wrap the workflow nicely.
Creating a new account in the client in a server with a current valid and different session in the browser: is currently not supported. This would require input of the username beforehand on the client's end to use it for the first authorize call.
| TestID |
Test Case |
Steps |
Expected Result |
Result |
Related Comment |
| 18 |
Have multiple accounts logged out and restart the client |
1. The client will open as many browser windows as accounts 2. Login into each one independently |
All the accounts are logged back in in the client |
✅ |
|
SAML accounts
Successful Scenarios
| TestID |
Test Case |
Steps |
Expected Result |
Result |
Related Comment |
| 1 |
Login on a clean browser |
1. Input the server URL on the account wizard, click next 2. Input valid account credentials on the login form in the browser opened 3. Authorize the "Desktop client" application 4. Use the default folder sync config |
The account is created and syncing with the default config |
✅ |
|
| 1.1 |
Authentication Request |
When performing TC's s.1 |
Verify: - The header
WWW-Authenticate: Bearer realm="ownCloud" is included in the server's reply - The query parameters
response_type=<code>, redirect_uri=, client_id= are present and match the values described in Preconditions on the opened URL |
✅ |
|
| 1.2 |
Access Token Request |
After TC's s.3 (app authorization) |
Verify the Access Token request contains the right values and is successful |
✅ |
See Access Token Request below |
| 2 |
Login (authorize) on an already open session in the browser |
1. Open the server URL on the browser and login with valid credentials 2. Use the same server URL on the client's new account wizard, click next 3. Authorize the "Desktop client" application on the page opened |
Same as TC1 |
✅ |
|
Same account on multiple, identical clients
| TestID |
Test Case |
Steps |
Expected Result |
Result |
Related Comment |
| 19 |
Login to the same account in multiple clients sharing id/secret simultaneously |
1. Repeat TC1 in more than one client |
Verify that all the clients can run in parallel and they're getting different (and valid) access/refresh tokens from the server |
✅ |
|
Preconditions Not Met
It is important to also consider what does happen when one or more of the preconditions is not met. In this order:
| TestID |
Test Case |
Steps |
Expected Result |
Result |
Related Comment |
| 20 |
Application uninstall/disabling |
1. Perform TC1 2. Disable OAuth2 app from the app settings pane in the WebUI |
Client detects the switch and migrates back the accounts to basic-auth and request re-login |
✅ |
|
| 21 |
Erroneous/missing Client ID/Secret |
1. Remove the client ID/secret from the OAuth2 settings pane 2. Perform TC1 |
The WebUI displays an error message indicating the issue: non-authorized clientID/secret + the client is notified |
✅ |
|
| 22 |
Apache removing the 'Authorization: Bearer' header in the requests |
1. Verify headers and rewrite modules are not enabled in Apache (apache2ctl -M) 2. Perform TC1 |
The WebUI displays an error message linking to docs about recommended Apache config. + the client is notified |
🚧 |
Discussion going on in #49 |
Testing functionality
| Test Case |
Expected Result |
Result |
Related Comment |
| CLI commands |
|
|
|
Enable OAuth2 app via CLI using occ app:enable oauth2 |
- The apps gets enabled - Replies from the WebDAV endpoint includes a new WWW-Authenticate: Bearer... header |
✅ |
|
Disable OAuth2 app via CLI using occ app:disable oauth2 |
- The apps gets disabled - Previously menctioned header goes away in further requests |
✅ |
|
| Registered Clients |
|
|
|
| Default clients |
The default Registered clients are included among the "Settings > Admin > User Authentication" OAuth 2.0: Registered Clients |
✅ |
See #38 for the default values |
| Register new Client |
64-character-lenght client_id and client_secret are generated together with a (optional) Client Name and a (required) Redirection URL |
✅ |
|
| Remove a Client |
- Confirmation dialog is prompted before removal - All client sessions opened from those clients get removed |
✅ |
|
| Unregistered Clients |
|
|
|
| Authentication flow from an unregistered client |
Unsuccessful [Authorization Request] |
✅ |
Browser displays the "Request not valid" screen. |
| Authorized Applications |
|
|
|
| Login with a Registered Client |
The Client Name is displayed amongst the "Personal > Security" OAuth 2.0 Authorized Applications |
✅ |
|
| Session Revocation (i.e. delete Authorized Application) |
All the sessions opened in the clients are revoked and must be re-authorized |
❌ |
#103 |
| User Account Handling |
|
|
|
| Password change |
Open sessions are revoked and new credentials must be used in further login attempts |
✅ |
|
| Authorization Flow |
|
|
|
| Successful [Authorization Request] without any session open in the browser |
Login form with an additional informative note about the application requesting access to ownCloud is displayed |
✅ |
|
| Successful [Authorization Request] with a valid session in the browser |
The "Authorize" screen is displayed |
✅ |
|
| Successful [Authorization Request] in a browser with a different user logged in |
The "Switch User" screen is displayed, allowing to modify the current session |
✅ |
See use of the additional user parameter in: #67 |
| Failed attempt in the authorization login form |
The query parameters for the [Authorization Request] are preserved in next attempts |
✅ |
See original issue in: owncloud/core#28129 |
| Relevant Smoke Tests |
|
|
|
| Unauthenticated Actions: Public File Drop |
Files get uploaded normally |
✅ |
See #100 |
OAuth2 support on the Desktop Client
Preconditions:
Platform versions tested
Test Scope Variability
As pointed out in the preconditions, there has to be a browser installed in the underlying OS, as it's a critical piece for the auth. Additionally to the multiplatform tests, we will consider the mainstream browsers to check all the testcases: versions TBD
Each TC is considered to be independent, it's required both the session in the browser and the account created (if any) on the client are to be removed prior to next test cases.
Authentication
Since the entrypoint is the same as in the rest of authentication methods (the login form) there are also some protocol-agnostic test-cases that are inherited from the appropriate testplan(s). e.g. account log-out, redirections, http/s alternatives... that should be checked for the full picture. In this document we're just going to focus on pure OAuth2 implementation-related test-cases. For that, we have to differentiate between 2 scenarios:
Account Setup
Login from scratch, creating a new account.
Successful Scenarios
2. Input valid account credentials on the login form in the browser opened
3. Authorize the "Desktop client" application
4. Use the default folder sync config
WWW-Authenticate: Bearer realm="ownCloud"is included in the server's replyresponse_type=<code>,redirect_uri=,client_id=are present and match the values described in Preconditions on the opened URL2. Use the same server URL on the client's new account wizard, click next
3. Authorize the "Desktop client" application on the page opened
Access Token Request:
Request:
Reply:
Unauthorized/Alternative Paths
2. Click back
<random_port>but on a different oneReferences:
Request:
Existing Accounts
Also, it's important to consider the cases either when upgrading a working client to support OAuth2 authentication or when an account was already setup but the
AccountStateis not "Connected" for any reason.Upgrade path
Coming from an old version of the client (< 2.4.0) will require to re-login into the account since the client will consider the old credentials/sessions non-valid in virtue of the new auth. method.
2. Update the client to a version >= 2.4
3. Relaunch the client
2. Update the client to a version >= 2.4
3. Relaunch the client
Expired authorization token
When tokens' hit their expiration date come to an end the OAuth2 refresh token logic of the protocol is used.
2. Monitor the client network requests with a proxy
Combination of Scenarios
These are not semantically different scenarios to the ones described already in previous sections but variations that have to meet many of the same acceptance criteria and some additional ones.
Branding
2. Create a new account
#### Multi-account support
Some considerations have to be taken into account to solve the issue of the desktop client not being able to open independent and clean WebViews (as the mobile clients use) owncloud/client#5895: this means server supporting ways to wrap the workflow nicely.
Creating a new account in the client in a server with a current valid and different session in the browser: is currently not supported. This would require input of the username beforehand on the client's end to use it for the first
authorizecall.authorizecall: Being able to specify the user name in theauthorizecall #48 - This allows requesting a specific user to login in to the browser. If a different session is open, it offers the switch.2. Login into each one independently
SAML accounts
Successful Scenarios
2. Input valid account credentials on the login form in the browser opened
3. Authorize the "Desktop client" application
4. Use the default folder sync config
WWW-Authenticate: Bearer realm="ownCloud"is included in the server's replyresponse_type=<code>,redirect_uri=,client_id=are present and match the values described in Preconditions on the opened URL2. Use the same server URL on the client's new account wizard, click next
3. Authorize the "Desktop client" application on the page opened
Same account on multiple, identical clients
Preconditions Not Met
It is important to also consider what does happen when one or more of the preconditions is not met. In this order:
2. Disable OAuth2 app from the app settings pane in the WebUI
2. Perform TC1
apache2ctl -M)2. Perform TC1
Testing functionality
occ app:enable oauth2- Replies from the WebDAV endpoint includes a new
WWW-Authenticate: Bearer...headerocc app:disable oauth2- Previously menctioned header goes away in further requests
client_idandclient_secretare generated together with a (optional) Client Name and a (required) Redirection URL- All client sessions opened from those clients get removed
userparameter in: #67