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

Add oauth code flow support #4704

Merged
merged 35 commits into from
May 18, 2017
Merged

Add oauth code flow support #4704

merged 35 commits into from
May 18, 2017

Conversation

LukasReschke
Copy link
Member

@LukasReschke LukasReschke commented May 4, 2017

This adds the OAuth Code Flow support to our existing code base.

One example is the Moodle plugin from https://pssl16.github.io/.

TODOs:

  • Add unit tests
  • Adjust existing unit tests
  • I added an app "oauth2", however, our regular login flow in core depends on that app now. This should really be more structured. => Ignore for now…
  • Don't show "login with app token" when an OAuth login is requested
  • Delete all app tokens assigned to an application when the application is deleted by the administrator
  • Don't show the OAuth secrets in the admin panel by default. Add a button that unhides them.
  • Apparently, Apache strips the Authorization header by default. Our .htaccess fixes that but this means that currently this only works when Apache is instructed to not strip the header. Might be good enough though. But if someone can investigate on this: awesome 🚀
  • Fix merge conflicts
  • Add hardening as per https://github.com/nextcloud/server/pull/4704/files#r114908717
  • Add appropriate indexes to DB
  • Cleanup SabreDAV auth changes as per Add oauth code flow support #4704 (comment)
  • Move oauthState to the session so that somebody isn't accidentally copying the URL to other users and thus disclosing it.
  • Use name of the OAuth application instead of the current browser as token name as per https://github.com/nextcloud/server/pull/4704/files#r114910589
  • Document the auth flow and endpoints

Known Issues

  • Create two oauth clients in the admin settings: First the right one, then a fake client. Login will no longer work: wrong redirect exception.

screen shot 2017-05-05 at 00 57 09

screen shot 2017-05-05 at 00 57 15

screen shot 2017-05-05 at 00 56 42

@LukasReschke LukasReschke added the 1. to develop Accepted and waiting to be taken care of label May 4, 2017
@LukasReschke LukasReschke added this to the Nextcloud 12.0 milestone May 4, 2017
@LukasReschke LukasReschke requested review from rullzer and schiessle May 4, 2017 23:07
@mention-bot
Copy link

@LukasReschke, thanks for your PR! By analyzing the history of the files in this pull request, we identified @ChristophWurst, @icewind1991 and @blizzz to be potential reviewers.

* @return TemplateResponse
*/
public function showAuthPickerPage() {
if($this->userSession->isLoggedIn()) {
Copy link
Member Author

Choose a reason for hiding this comment

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

What we should do instead here is that at least one of the following conditions is met:

  1. Verify that a valid client identifier is given
  2. Verify that the request contains a OCS-APIRequest: true HTTP header

If none of those are fulfilled show an error page.

Copy link
Member

@schiessle schiessle May 12, 2017

Choose a reason for hiding this comment

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

handled here: 52734b3

@@ -720,15 +720,15 @@ private function validateToken($token, $user = null) {
*/
public function tryTokenLogin(IRequest $request) {
$authHeader = $request->getHeader('Authorization');
if (strpos($authHeader, 'token ') === false) {
Copy link
Member Author

Choose a reason for hiding this comment

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

Wasn't used before by any client and didn't even work via WebDAV so that change should be fine :)

cc @ChristophWurst fyi :)

\OC_Util::setupFS($user);
$this->currentUser = $user;
$this->session->close();
return [true, $this->principalPrefix . $user];
Copy link
Member Author

Choose a reason for hiding this comment

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

This return is a huge mess and copied code from below. Basically if we just call tryTokenLogin then it would lead into the code path to parent::check and there it checks if a Basic Auth header is set. None is set and thus SabreDAV throws an exception. We should clean this up.

$token,
$this->userSession->getUser()->getUID(),
$uid,
$loginName,
$password,
$this->getClientName(),
Copy link
Member Author

Choose a reason for hiding this comment

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

This should use the name of the OAuth application just like https://github.com/nextcloud/server/pull/4704/files#diff-652646310472be421d6b80289b907cb8R160 has.

@schiessle schiessle force-pushed the add-oauth-code-flow-support branch 3 times, most recently from 5f80b53 to fb72698 Compare May 12, 2017 11:07
@codecov
Copy link

codecov bot commented May 12, 2017

Codecov Report

Merging #4704 into master will increase coverage by 0.03%.
The diff coverage is 68.9%.

@@             Coverage Diff              @@
##             master    #4704      +/-   ##
============================================
+ Coverage      54.2%   54.23%   +0.03%     
- Complexity    22195    22228      +33     
============================================
  Files          1367     1378      +11     
  Lines         84876    85142     +266     
  Branches       1322     1322              
============================================
+ Hits          46003    46179     +176     
- Misses        38873    38963      +90
Impacted Files Coverage Δ Complexity Δ
core/templates/loginflow/redirect.php 0% <ø> (ø) 0 <0> (ø) ⬇️
core/templates/loginflow/authpicker.php 0% <ø> (ø) 0 <0> (ø) ⬇️
apps/dav/lib/Connector/Sabre/Auth.php 80.8% <ø> (ø) 33 <0> (ø) ⬇️
settings/personal.php 0% <0%> (ø) 0 <0> (ø) ⬇️
apps/oauth2/templates/admin.php 0% <0%> (ø) 0 <0> (?)
apps/oauth2/appinfo/routes.php 0% <0%> (ø) 0 <0> (?)
...rivate/Authentication/Token/DefaultTokenMapper.php 100% <100%> (ø) 11 <1> (+1) ⬆️
apps/dav/lib/Server.php 47.05% <100%> (+2.02%) 12 <0> (ø) ⬇️
apps/oauth2/lib/Db/Client.php 100% <100%> (ø) 1 <1> (?)
apps/oauth2/lib/Db/AccessToken.php 100% <100%> (ø) 1 <1> (?)
... and 23 more

@schiessle schiessle force-pushed the add-oauth-code-flow-support branch 3 times, most recently from a8fdf43 to cd02164 Compare May 12, 2017 14:50
@MorrisJobke
Copy link
Member

@LukasReschke How to move this forward?

@LukasReschke
Copy link
Member Author

Rebased upon master. Will continue tonight.

THX a lot already, @schiessle 🚀

@LukasReschke LukasReschke force-pushed the add-oauth-code-flow-support branch from cd02164 to 49a6eb1 Compare May 17, 2017 16:28
@schiessle schiessle force-pushed the add-oauth-code-flow-support branch 2 times, most recently from 40886b0 to 44f4b2c Compare May 18, 2017 09:42
@@ -58,8 +58,8 @@ protected function setUp() {

private function resetDatabase() {
$qb = $this->dbConnection->getQueryBuilder();
$qb->delete('authtoken')->execute();
$qb->insert('authtoken')->values([
$qb->delete('AuthToken')->execute();
Copy link
Member Author

Choose a reason for hiding this comment

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

Renaming this breaks as databases tend to be case sensitive 😉

cc @schiessle – will revert the renaming.


if(!$this->userSession->isLoggedIn()) {
$this->userSession->tryTokenLogin($this->request);
}
Copy link
Member

Choose a reason for hiding this comment

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

else?

Copy link
Member

Choose a reason for hiding this comment

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

Ah no... tryTokenLogin might log the user in...

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep. 🙈 – We don't have a method where I can just pass the token and login and so as a short-term solution I thought of just abusing this behaviour 😉

],
[
'name' => 'Settings#deleteClient',
'url' => '/clients/{id}/delete',
Copy link
Member

Choose a reason for hiding this comment

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

uhm... why not a DELETE to /clients/{id} ?

$client->setSecret($this->secureRandom->generate(64, self::validChars));
$client->setClientIdentifier($this->secureRandom->generate(64, self::validChars));
$this->clientMapper->insert($client);
return new RedirectResponse($this->urlGenerator->getAbsoluteURL('/index.php/settings/admin/security'));
Copy link
Member

Choose a reason for hiding this comment

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

Why this redirect magic and not just AJAX calls?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah. JS isn't mine and @schiessle most preferred activity. Let's adjust that in the future :)

@@ -25,6 +25,9 @@
use OC\Authentication\Exceptions\PasswordlessTokenException;
use OC\Authentication\Token\IProvider;
use OC\Authentication\Token\IToken;
use OCA\OAuth2\Db\AccessToken;
use OCA\OAuth2\Db\AccessTokenMapper;
use OCA\OAuth2\Db\ClientMapper;
Copy link
Member

Choose a reason for hiding this comment

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

I get why. But I'm really not a fan of this hard app dependency.
We should think how we can make this somewhat modular in the future. Just so we have a clear defined interface between the two.

Copy link
Member Author

Choose a reason for hiding this comment

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

👍 – Yes. We need to think how to solve that better in the future.

Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
@LukasReschke LukasReschke force-pushed the add-oauth-code-flow-support branch from f4ddd43 to e34942f Compare May 18, 2017 18:49
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
@LukasReschke LukasReschke force-pushed the add-oauth-code-flow-support branch from 0e5dbf8 to ba7b6bd Compare May 18, 2017 18:58
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
@LukasReschke LukasReschke added 3. to review Waiting for reviews and removed 1. to develop Accepted and waiting to be taken care of labels May 18, 2017
Copy link
Member

@rullzer rullzer left a comment

Choose a reason for hiding this comment

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

rullzer approved! ✅ 👍

@LukasReschke LukasReschke changed the title [WIP] Add oauth code flow support Add oauth code flow support May 18, 2017
@LukasReschke LukasReschke merged commit 0eb4970 into master May 18, 2017
@LukasReschke LukasReschke deleted the add-oauth-code-flow-support branch May 18, 2017 21:30
@hanzei
Copy link

hanzei commented May 31, 2017

Will there be documentation for the endpoints?

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

Successfully merging this pull request may close these issues.

6 participants