This is supported by the League server library yet we need to make clients configurable to utilize this option. I have done most of the work on my end with a client project and will update here with a patch shortly.

Comments

bradjones1 created an issue. See original summary.

bradjones1’s picture

Status: Active » Needs review
StatusFileSize
new14.92 KB

See attached.

I ended up changing the signature of Oauth2GrantManager::getAuthorizationServer() to take the Consumer entity, as well, however it can take a NULL in an effort to not break BC on any customized integrations. I'm open to thoughts on how this could be avoided, especially since this means the PKCE-related changes bleed from the extras submodule into the main module, however it does not create a dependency on extras.

In 2 of the 3 calls to ::getAuthorizationServer() the client is already loaded, and I don't believe adding it to the token controller adds any notable overhead or complexity.

This also requires 7.x of the league library, a patch for which is at #2977127: Update league/oauth2-server to 7.1.x to incorporate the PKCE-related items released in 7.0.0.

e0ipso’s picture

Thanks for the patch! I left some considerations, please let me know what you think.

  1. +++ b/simple_oauth_extras/src/Controller/Oauth2AuthorizeController.php
    @@ -120,22 +139,13 @@ class Oauth2AuthorizeController extends ControllerBase {
    -      watchdog_exception('simple_oauth_extras', $exception);
    -      return RedirectResponse::create(Url::fromRoute('<front>')->toString());
    

    Why are we losing this?

  2. +++ b/simple_oauth_extras/src/Controller/Oauth2AuthorizeController.php
    @@ -120,22 +139,13 @@ class Oauth2AuthorizeController extends ControllerBase {
    -    $client_drupal_entities = $consumer_storage
    -      ->loadByProperties([
    -        'uuid' => $client_uuid,
    -      ]);
    

    Is there any other benefit to introduce the entity storage service? We can already do this with the currently injected dependencies. If there is no additional benefit, I'd rather keep the original code.

  3. +++ b/simple_oauth_extras/src/Controller/Oauth2AuthorizeController.php
    @@ -168,7 +178,7 @@ class Oauth2AuthorizeController extends ControllerBase {
    -        $server = $this->grantManager->getAuthorizationServer($grant_type);
    +        $server = $this->grantManager->getAuthorizationServer($grant_type, $client_drupal_entity);
    

    As I understand, this is the main goal of the change in this file. Would your patch work if we only had this change in this file?

  4. +++ b/simple_oauth_extras/src/Controller/Oauth2AuthorizeForm.php
    @@ -133,9 +151,18 @@ class Oauth2AuthorizeForm extends FormBase {
    +      $client_drupal_entity = $this->entityRepository
    +        ->loadEntityByUuid('consumer', $client_uuid);
    

    Let's use the entity manager to get the storage to load entities by UUID. This way we can avoid the additional dependency on the entity.repository service.

e0ipso’s picture

Status: Needs review » Needs work
bradjones1’s picture

Status: Needs work » Needs review
StatusFileSize
new9.92 KB

Updated per above.

I backed out the addition of the entity repository; agreed it's not really a substantive change.

I removed the try/catch on loading the entity storage handler for the consumer since we can be confident it exists due to our dependency on consumers module in the main module, and it seems like that's an unlikely failure point on which we need to specifically react. The actual failure condition is that of not having a valid client ID specified/client loaded, which is what we're now targeting with error handling.

Also see updated patch on the upstream library bump issue, linked above.

bradjones1’s picture

Not triggering a test since it depends on the other patch so we know it will fail.

bradjones1’s picture

bradjones1’s picture

StatusFileSize
new9.25 KB

Cleaning up some unused references.

bradjones1’s picture

Issue tags: +Needs tests
e0ipso’s picture

Status: Needs review » Needs work
+++ b/simple_oauth_extras/src/Controller/Oauth2AuthorizeController.php
@@ -119,13 +118,7 @@ class Oauth2AuthorizeController extends ControllerBase {
-    try {
-      $consumer_storage = $this->entityTypeManager()->getStorage('consumer');
-    }
-    catch (InvalidPluginDefinitionException $exception) {
-      watchdog_exception('simple_oauth_extras', $exception);
-      return RedirectResponse::create(Url::fromRoute('<front>')->toString());
-    }
+    $consumer_storage = $this->entityTypeManager()->getStorage('consumer');

Why did you drop the error handling here? This was useful for static code analysis and in case some nasty overwrite was in place.

e0ipso’s picture

+++ b/src/Plugin/Oauth2GrantManager.php
@@ -142,9 +144,14 @@ class Oauth2GrantManager extends DefaultPluginManager implements Oauth2GrantMana
+    if ($client && ($grant instanceof AuthCodeGrant) && ($client->hasField('pkce') && $client->get('pkce')->first()->value)) {
+      $grant->enableCodeExchangeProof();
+    }

Let's extract some booleans before hand so we can make the if statement more readable.

if ($grant_is_auth_code && $client_has_pkce_enabled) {
  // …
}
e0ipso’s picture

+++ b/simple_oauth_extras/src/Controller/Oauth2AuthorizeForm.php
@@ -133,9 +133,19 @@ class Oauth2AuthorizeForm extends FormBase {
+    $consumer_storage = $this->entityTypeManager->getStorage('consumer');

We probably want that awkward error handling here as well.


This patch is pretty impressive! Thanks for the work. As far as I can tell we are only missing 2 things before merging:

  1. Testing for the "new grant".
  2. An update hook to install the new base field to existing sites. The simple_oauth.install file should have examples of this.

Again, I'm so grateful to get patches with such great quality work.

bradjones1’s picture

Thanks for the review. I'll make some changes this week.

Regarding the question regarding the error handling on getting the entity storage, I'll just point to my note on the original patch... I haven't found it common practice to put this kind of thing in a try-catch if your dependency is sufficient to require the existence of the entity type. E.g., Commerce loads entities from other modules all the time and doesn't wrap these in a try-catch. If someone has overridden their codebase in such a way that the consumer entity storage doesn't load, this exception will still bubble up and is probably more meaningful in that context than being wrapped. Let me know if it needs to stay, regardless.

If you are concerned about the uncaught exception notice in static code analysis, we can wrap those lines in an exception maybe.

Agreed on adding tests, will be easier given the commit we just made on the library version bump... thanks for including the updates to the tests, there.

bradjones1’s picture

StatusFileSize
new9.35 KB

Getting current tests to pass; then I'll tackle new tests.

e0ipso’s picture

Great job! Current tests are green now.

e0ipso’s picture

@bradjones1 is there any chance I can motivate you to contribute the tests for last leg of this issue?

bradjones1’s picture

This issue is still on my radar, I am just lacking bandwidth with the day job at the moment. This is an important part of our infrastructure though so I'd like to get it committed. No ETA but I do intend to see this through.

bradjones1’s picture

Issue tags: +dcco2019

Tagging for DrupalCamp Colorado 2019 sprint day.

bradjones1’s picture

This needs an entity update performed as entity schema updates are no longer automatically done per https://www.drupal.org/project/drupal/issues/2976035

e0ipso’s picture

Version: 8.x-3.x-dev » 8.x-4.x-dev
Issue tags: +Needs reroll

I recently merged Simple OAuth Extras into Simple OAuth. This means that the patch no longer applies. However, this will make things easier in the future.

rpayanm’s picture

Status: Needs work » Needs review
StatusFileSize
new9.7 KB
ajits’s picture

Issue tags: -Needs reroll

Taking the tag off as the patch was rerolled.

ajits’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll

Or maybe not, as the patch uploaded failed to apply ;)

olafkarsten’s picture

StatusFileSize
new11.43 KB

Rerolled #14. Interdiff isn't much of a help, cause of the simple_oauth_extras merge. It's a straight reroll plus the hook_update for updating the consumer entity (adding the pkce basefield). Lets see what the testbot has to say.

olafkarsten’s picture

StatusFileSize
new11.22 KB
new799 bytes

The changed catch clause in Oauth2GrantManager::getAuthorizationServer caused the failures. Lets try this one.

olafkarsten’s picture

Issue tags: -dcco2019, -Needs reroll

Okay, seems somebody can code the tests now :)

olafkarsten’s picture

Issue tags: -Needs tests
StatusFileSize
new14.42 KB
new3.67 KB

- Adding tests
- Addressing #11

olafkarsten’s picture

Assigned: bradjones1 » Unassigned
Status: Needs work » Needs review

ready for review

e0ipso’s picture

Status: Needs review » Fixed

This is a great patch! Thanks for all the effort you put into this.

OAuth2 logo Thanks for contributing @bradjones1, @olafkarsten, @rpayanm, and @AjitS! This module is better and more useful thanks to you. Open source maintainers need contributions to keep up. ❤️

  • e0ipso committed 2a4b0e4 on 8.x-4.x authored by olafkarsten
    Issue #3027432 by bradjones1, olafkarsten, rpayanm, e0ipso, AjitS: Make...
  • e0ipso committed 92dc779 on 8.x-4.x authored by bradjones1
    Issue #3027432 by bradjones1, olafkarsten, rpayanm, e0ipso, AjitS: Make...
  • e0ipso committed fa2227d on 8.x-4.x authored by bradjones1
    Issue #3027432 by bradjones1, olafkarsten, rpayanm, e0ipso, AjitS: Make...
e0ipso’s picture

I granted some additional commit credit because this was tricky!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.