Scenario:

  1. Create a user.
  2. Edit the user. Add a pair of OAuth consumer keys
  3. Look at the URL once the keys are created: see that they were added to the Admin user, not the user that you were editing.

Comments

juampynr created an issue. See original summary.

juampynr’s picture

Title: Keys are creating for the wrong user » Admin users can't create keys to other users

Adjusted title.

willwh’s picture

Assigned: Unassigned » willwh
willwh’s picture

StatusFileSize
new2.87 KB

Here's a patch with a start on this. I'm passing a {user} param in the add route, and then trying to use an AccountInterface in my AddForm to fetch the user, that should be passed in a parameter with this route, although, my $user object is always NULL.

juampynr’s picture

Status: Active » Needs work
  1. +++ b/oauth.info.yml
    @@ -2,5 +2,11 @@ name: OAuth
    +# core: 8.x
    ...
    +# Information added by Drupal.org packaging script on 2015-11-20
    +version: '8.x-1.2'
    

    Looks like you had already the Downloaded version of the module, this change shouldn't be here.

  2. +++ b/src/Controller/OAuthController.php
    @@ -73,7 +73,7 @@ class OAuthController extends ControllerBase implements ContainerInjectionInterf
    +    $list['heading']['#markup'] = $this->linkGenerator->generate($this->t('Add consumer'), Url::fromRoute('oauth.user_consumer_add', ['user' => $user->id()]));
    

    This looks fine to me. I don't know what could be wrong.

  3. +++ b/src/Form/OAuthAddConsumerForm.php
    @@ -81,7 +82,7 @@ class OAuthAddConsumerForm extends FormBase {
    +  public function submitForm(array &$form, FormStateInterface $form_state, AccountInterface $user = NULL) {
    

    Once we find the user, we should check that if we get a user object, the current user should have enough permissions to perform this action. Otherwise, authenticated users could create keys for other users.

willwh’s picture

Here's another patch. I'd love if you could take a look.

Seems that keys are being created properly per user now, but they are not visible, which is bizarre, as they exist in the database.

oauth_hmm

I'm going to keep digging on this, but if you have any thoughts, I'm all ears :)

willwh’s picture

Looks like it was a cache issue, hah :/

The #6 seems to work well, I'm going to work on some custom auth checks now to make sure people can't mess with other users keys.

willwh’s picture

StatusFileSize
new6.86 KB

So I have some custom auth checking going on.

There is one problem to iron out here... Logged in as an admin user, this works great.

Logging in as a regular user, the oauth.user_consumer route seems to get cached.

I can add and delete keys, although the list itself is never updated. However, you can check in mysql and see the keys being added and deleted successfully.

I'm probably missing something, thought I'd throw this patch up anyway :)

willwh’s picture

StatusFileSize
new8.48 KB

Oops, that patch was missing some stuff, here we go!

juampynr’s picture

  1. +++ b/src/Access/CustomAccessCheck.php
    @@ -0,0 +1,36 @@
    +  public function applies(Route $route) {
    

    Looks like this method is not needed for what I have seen in Drupal core. The AccessInterface is empty.

  2. +++ b/src/Form/OAuthAddConsumerForm.php
    @@ -85,17 +91,17 @@ class OAuthAddConsumerForm extends FormBase {
    +    drupal_set_message($this->t('Added a new consumer for uid: ' . $uid));
    

    I don't think that the uid adds useful information to the site admin. Can we keep the message as it is?

  3. +++ b/src/Form/OAuthDeleteConsumerForm.php
    @@ -98,12 +111,17 @@ class OAuthDeleteConsumerForm extends ConfirmFormBase implements ContainerInject
    +      '#value' => $user->id()
    

    Missing comma :neckbeard:

Looking good! We should adjust the module tests so they cover the logic that you are adding in this patch.

willwh’s picture

StatusFileSize
new40.94 KB
new10.87 KB

Test resultsUpdated tests.

willwh’s picture

StatusFileSize
new17.57 KB

Ok, I went off down the rabbit hole... and this patch is a large refactor of the way we are storing consumers, it's all chx's fault. (Thanks for the guidance @chx)

I am happy to split this out in to a couple of patches, let me know if you'd like to do that...

I'm opting for storing consumers as UserData (and using the 'user.data' service, instead of using a custom SQL table)

Let me know if you want me to split this patch up in to this issue, and then perhaps one for a refactor of consumer storage?

I thought I'd wait on updating tests until I know what you'd like to do here.

Thanks, this has been fun and I've learned a lot! :)

willwh’s picture

StatusFileSize
new23.45 KB

This patch allows admin users to administer other users keys.

This patch introduces a new custom access check for routes, and a new way of storing consumer data (in UserData).

I've got tests passing locally. Happy Hogmanay!

willwh’s picture

willwh’s picture

Actually, I re-ran tests today, and realized my patch removed the schema from the .install, and I ran tests prior.

Running tests and the last test pukes, so tests still require work, back at it next week some time ;)

willwh’s picture

StatusFileSize
new23.87 KB

Ok, tests passing now, I forgot to remove the hook_user_delete() which was calling db_delete on a non-existent table, now that we're using UserData :)

juampynr’s picture

Awesome work @willwh!

Here is my feedback:

  1. +++ b/oauth.install
    @@ -26,57 +26,3 @@ function oauth_requirements($phase) {
    -    ),
    ...
    -  return $schema;
    

    We need a database update that ports existing data to the new architecture. This allows existing sites to upgrade to the new version.

  2. +++ b/src/Authentication/Provider/OAuthDrupalProvider.php
    @@ -116,12 +118,13 @@ class OAuthDrupalProvider implements AuthenticationProviderInterface {
    +      foreach ($user_data as $uid => $consumer) {
    

    Why is this a loop?

  3. +++ b/src/Authentication/Provider/OAuthDrupalProvider.php
    @@ -116,12 +118,13 @@ class OAuthDrupalProvider implements AuthenticationProviderInterface {
    +          return OAUTH_OK;
    

    Indentation.

  4. +++ b/src/Tests/OAuthTest.php
    @@ -38,12 +39,34 @@ class OAuthTest extends WebTestBase {
    +    foreach ($user_data as $key => $consumer) {
    

    Why this is a loop?

  5. +++ b/src/Tests/OAuthTest.php
    @@ -38,12 +39,34 @@ class OAuthTest extends WebTestBase {
    +    foreach ($user_data as $key => $consumer) {
    

    Loop?

  6. +++ b/src/Tests/OAuthTest.php
    @@ -90,25 +113,27 @@ class OAuthTest extends WebTestBase {
    +    $this->drupalPostForm('oauth/consumer/add/' . $account->id(), array(), 'Add');
    ...
    +    foreach ($user_data as $key => $consumer) {
    

    Loop?

willwh’s picture

I have these loops fixed in my local, just trying to understand how I write this update hook to port consumer data and then delete the old schema ;)

juampynr’s picture

I did something similar for Metatag module. You can get an idea of the process here: http://cgit.drupalcode.org/metatag/tree/metatag.install?h=8.x-1.x#n217.

Here is how I would do it:

1. Re-install Drupal to make sure that there are no remainings of oauth.
2. Install the current version of oauth.
3. Add a few keys to some users.
4. Dump the database into a file (in case we want to run the database update again).
5. Write a database update that:
5.1 Loads all keys.
5.2 Adds the keys to each user via UserData.
5.3 Deletes the custom oauth table.

willwh’s picture

StatusFileSize
new23.35 KB

Here we go :D

juampynr’s picture

  1. +++ b/oauth.install
    @@ -28,55 +30,21 @@ function oauth_requirements($phase) {
    + * Implements hook_update_N().
    

    This is not needed in this kind of hook. It results in confusing reporting when you run database updates via the web interface or drush. Keep the description but please remove the Implements...

  2. +++ b/oauth.install
    @@ -28,55 +30,21 @@ function oauth_requirements($phase) {
    +function oauth_update_8001() {
    

    As per https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Extension..., this should be 8100.

  3. +++ b/oauth.install
    @@ -28,55 +30,21 @@ function oauth_requirements($phase) {
    +    // Insert each row in to Userdata
    

    Missing period :neckbeard:

  4. +++ b/oauth.install
    @@ -28,55 +30,21 @@ function oauth_requirements($phase) {
    +    \Drupal::service('user.data')
    

    Can we load the service into a variable first instead of invoking it on every loop?

  5. +++ b/src/Authentication/Provider/OAuthDrupalProvider.php
    @@ -8,25 +8,25 @@
    +use Symfony\Component\DependencyInjection\ContainerInterface;
    

    Is this needed in the class?

  6. +++ b/src/Authentication/Provider/OAuthDrupalProvider.php
    @@ -116,12 +118,11 @@ class OAuthDrupalProvider implements AuthenticationProviderInterface {
    +        return OAUTH_OK;
    

    Indentation.

  7. +++ b/src/Controller/OAuthController.php
    @@ -11,10 +11,11 @@ use Drupal\Core\Controller\ControllerBase;
    +use Drupal\user\UserDataInterface;
    

    Is this needed?

  8. +++ b/src/Controller/OAuthController.php
    @@ -11,10 +11,11 @@ use Drupal\Core\Controller\ControllerBase;
    +use Drupal\Core\Routing\RouteBuilderInterface;
    

    Is this needed?

willwh’s picture

StatusFileSize
new23.2 KB

How's this? :)

juampynr’s picture

  1. +++ b/oauth.install
    @@ -28,55 +30,20 @@ function oauth_requirements($phase) {
    +  $result = Database::getConnection()->query('select * from oauth_consumer');
    

    Missing brackets.

  2. +++ b/oauth.install
    @@ -28,55 +30,20 @@ function oauth_requirements($phase) {
    +      $user_data->set('oauth', $row->uid, $row->consumer_key, [
    

    Indentation.

willwh’s picture

StatusFileSize
new47.23 KB

Doh, here we go!

juampynr’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 24: oauth-admin-2627994-24.patch, failed testing.

The last submitted patch, 24: oauth-admin-2627994-24.patch, failed testing.

The last submitted patch, 24: oauth-admin-2627994-24.patch, failed testing.

The last submitted patch, 24: oauth-admin-2627994-24.patch, failed testing.

The last submitted patch, 24: oauth-admin-2627994-24.patch, failed testing.

The last submitted patch, 24: oauth-admin-2627994-24.patch, failed testing.

The last submitted patch, 24: oauth-admin-2627994-24.patch, failed testing.

deviantintegral’s picture

Looks like the patch file got added to the patch?

+++ b/oauth-admin-2627994-22.patch

deviantintegral’s picture

phpcs is showing errors added in this patch. I'm about to submit a phpcbf run against 8.x-1.x, but even after merging that here I'm getting the following. This is also failing all the tests on my local, so I haven't done an in-depth review yet.


FILE: ...nt/d8/www/docroot/modules/oauth/src/Access/CustomAccessCheck.php
----------------------------------------------------------------------
FOUND 4 ERRORS AFFECTING 3 LINES
----------------------------------------------------------------------
 21 | ERROR | Doc comment short description must be on a single line,
    |       | further text should be a separate paragraph
 23 | ERROR | Missing parameter comment
 23 | ERROR | Missing parameter name
 27 | ERROR | Return comment must be on the next line
----------------------------------------------------------------------


FILE: ...odules/oauth/src/Authentication/Provider/OAuthDrupalProvider.php
----------------------------------------------------------------------
FOUND 2 ERRORS AFFECTING 2 LINES
----------------------------------------------------------------------
 26 | ERROR | Class property $user_data should use lowerCamel naming
    |       | without underscores
 45 | ERROR | Missing parameter name
----------------------------------------------------------------------


FILE: .../d8/www/docroot/modules/oauth/src/Controller/OAuthController.php
----------------------------------------------------------------------
FOUND 2 ERRORS AFFECTING 2 LINES
----------------------------------------------------------------------
 34 | ERROR | Class property $user_data should use lowerCamel naming
    |       | without underscores
 42 | ERROR | Parameter tags must be grouped together in a doc
    |       | comment
----------------------------------------------------------------------


FILE: ...t/d8/www/docroot/modules/oauth/src/Form/OAuthAddConsumerForm.php
----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
 37 | ERROR | Class property $user_data should use lowerCamel naming
    |       | without underscores
----------------------------------------------------------------------


FILE: ...8/www/docroot/modules/oauth/src/Form/OAuthDeleteConsumerForm.php
----------------------------------------------------------------------
FOUND 7 ERRORS AFFECTING 4 LINES
----------------------------------------------------------------------
 39 | ERROR | Class property $user_data should use lowerCamel naming
    |       | without underscores
 64 | ERROR | Missing parameter comment
 64 | ERROR | Missing parameter name
 66 | ERROR | Parameter tags must be grouped together in a doc
    |       | comment
 66 | ERROR | Missing parameter comment
 66 | ERROR | Missing parameter name
 76 | ERROR | Public method name "OAuthDeleteConsumerForm::getFormID"
    |       | is not in lowerCamel format
----------------------------------------------------------------------


FILE: ...rew/vagrant/d8/www/docroot/modules/oauth/src/Tests/OAuthTest.php
----------------------------------------------------------------------
FOUND 3 ERRORS AFFECTING 3 LINES
----------------------------------------------------------------------
  28 | ERROR | Visibility must be declared on method "testConsumers"
  74 | ERROR | Visibility must be declared on method
     |       | "testRequestAuthentication"
 138 | ERROR | Visibility must be declared on method
     |       | "testConsumerDeletion"
----------------------------------------------------------------------

Time: 315ms; Memory: 7.5Mb

willwh’s picture

Status: Needs work » Needs review
StatusFileSize
new23.25 KB

Woops! Let's try that again!

Status: Needs review » Needs work

The last submitted patch, 35: oauth-admin-2627994-35.patch, failed testing.

The last submitted patch, 35: oauth-admin-2627994-35.patch, failed testing.

The last submitted patch, 35: oauth-admin-2627994-35.patch, failed testing.

The last submitted patch, 35: oauth-admin-2627994-35.patch, failed testing.

The last submitted patch, 35: oauth-admin-2627994-35.patch, failed testing.

The last submitted patch, 35: oauth-admin-2627994-35.patch, failed testing.

The last submitted patch, 35: oauth-admin-2627994-35.patch, failed testing.

willwh’s picture

According to chx, it's not possible to support this in DCI currently:

chx: willwh: you cnat test that on DCI ATM
chx: willwh: it should not be hard to add a plugin to DCI to allow a PECL isntallation step
chx: willwh: but it'd require a C building environment which is slow and slow is expensive
willwh: my tests are passing locally, and I’m okay with that
chx: willwh: and this is a really rare request

are you guys ok with tests passing locally? :)

mikebell_’s picture

I've applied this patch to my local codebase and can confirm it does what it's supposed to.

* Applied patch
* drush updb -y
* drush cr
* Confirmed existing keys moved to user.data
* No oauth_consumer table
* Created a key as another user and confirmed uid in user.data
* Delete a key from uid 1 which was removed
* Delete a key from new user which was removed
* Succesfully tested REST endpoint which required oauth key from new user.

  • juampynr committed 50363f4 on 8.x-1.x authored by willwh
    Issue #2627994 by willwh, juampynr, deviantintegral, mikebell_: Admin...
juampynr’s picture

Status: Needs work » Fixed

Made the following changes to the patch:

diff --git a/oauth.install b/oauth.install
index c95bf4f..373e1b5 100644
--- a/oauth.install
+++ b/oauth.install
@@ -1,11 +1,12 @@
 <?php
 
-use Drupal\Core\Database\Database;
 /**
  * @file
  * Installation and schema related functions for the OAuth module.
  */
 
+use Drupal\Core\Database\Database;
+
 /**
  * Implements hook_requirements().
  */
@@ -31,9 +32,8 @@ function oauth_requirements($phase) {
 
 /**
  * Move any existing oauth data to UserData and remove 'oauth_consumers' table.
- *
  */
-function oauth_update_8100() {
+function oauth_update_8100(&$sandbox) {
   // Fetch any current consumer data.
   $result = Database::getConnection()->query('select * from {oauth_consumer}');
   $user_data =  \Drupal::service('user.data');

Committed. Thanks!

  • juampynr committed 50363f4 on 8.x-2.x authored by willwh
    Issue #2627994 by willwh, juampynr, deviantintegral, mikebell_: Admin...

  • juampynr committed be384be on 8.x-1.x
    Revert "Issue #2627994 by willwh, juampynr, deviantintegral, mikebell_:...

Status: Fixed » Closed (fixed)

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