I created a few custom REST resources that are working as intended with Simple OAuth working as required.
Now I'm trying to create a REST resource where I update a few of the user's fields and I'm getting the following error:
"message": "A fatal error occurred: 'user_id' not found"
when I POST to my custom resource endpoint. This does not happen for other resources and/or HTTP verbs. In my code I'm simply doing the following:
$user = \Drupal\user\Entity\User::load($user_id);
$user->field_myfield[] = $node->id();
$user->save();
to store a Entity reference i the User entity custom field I created. $user_id is coming from $this->currentUser->id() above in my code.
The $user is loaded correctly and when I hit save(), the API returns the above error message with the watchdog reporting the following two statements:
Drupal\Core\Entity\Query\QueryException: 'user_id' not found in Drupal\Core\Entity\Query\Sql\Tables->ensureEntityTable() (line 316 of /vagrant/www/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php).
and
Drupal\Core\Entity\EntityStorageException: 'user_id' not found in Drupal\Core\Entity\Sql\SqlContentEntityStorage->save() (line 777 of /vagrant/www/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php).
Curiously, if the Simple OAuth module is installed and activated, the same error message pops up in the watchdog when submitting Drupal's own User Profile form, which does not happen if I uninstall the Simple OAuth module.
I tried drush entup but nothing changed.
Can someone please help?
Comment | File | Size | Author |
---|---|---|---|
#25 | 2883862--user_id-not-found-and-security-update--25.patch | 16.43 KB | e0ipso |
#25 | 2883862--interdiff--23-25.txt | 371 bytes | e0ipso |
Comments
Comment #2
joumJust a note to help you reproduce the error (I did so in simplytest.me):
- install simple_oauth and configure it as usual
- add a custom field to the User profile entity
- try to change the value of that custom field with Drupal's User Profile form
- get the "Unexpected error" message
- check the watchdog logs to verify the error message regarding user_id:
Drupal\Core\Entity\EntityStorageException: 'user_id' not found in Drupal\Core\Entity\Sql\SqlContentEntityStorage->save() (line 777 of /home/dc61s/www/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php).
Comment #3
joumComment #4
joumComment #5
joumI've been trying to track down what is going on and I found out that when I try to change a User entity's fields and save my changes, the oauth tokens generated for that user must be expired - I think that means deleted from the DB.
My issue above did not happen when I changed the field name in ExpiredCollector.php, line 78 from 'user_id' to 'owner_id' which is the field name in the table.
But I have one question: what happens when you "expire" a token being used? Should a token being used expire mid-session?
Is there anyway we could only expire the token if "critical" fields are changed (ie, username, password, etc)?
Comment #6
joumAnyway, if someone is just worried about refreshing tokens to make the backend usable when changing the User entity, here's a simple patch.
Comment #7
joumComment #9
e0ipsoThe best way to deal with this would be to only clear the tokens for a user if any of the following fields are changed:
However, detecting changes is still in core's roadmap (see ContentEntityBase) to see the todos there. If we can find a good workaround for this, we can move this forward.
Comment #10
joumYes, I agree. Due to time constraints, I ended up clearing the fields I had attached to the User entity and created a different content type with entity reference to users so that I could change them without bumping into this issue.
Even so, my patch probably shouldn't be used lightly because it isn't actually doing what should be done, it just prevents the error, leaving God-knows-what poorly handled behind.
Is there any regression/change that could be made to the ExpiredCollector.php file that could prevent the error while core hasn't caught up?
If our issue is with token cleanup, maybe we should try to handle it ourselves before reaching this point, by checking if the critical fields mentioned are being changed or not. Maybe hook_user_update() could be used to validate this?
Comment #11
Wim LeersThis bug was introduced in http://cgit.drupalcode.org/simple_oauth/commit/?id=7358d41. Specifically, this code:
The full error:
This assumes that the
user_id
base field always exists onoauth2_client
entities. But that's not true: it is added bysimple_oauth_extras_entity_base_field_info()
.Therefore this problem occurs for every site that uses
simple_oauth
without also usingsimple_oauth_extras
.Comment #13
hubobbb CreditAttribution: hubobbb as a volunteer commentedI have the same problem and enable the simple_oauth_extras as #11 Wim Leers said.
thanks.
Comment #14
Wim LeersNote that the failures in #11 are all due to tests needing to be updated. They need extra mocking a.o.
Comment #15
e0ipso@Wim Leers thanks for the patch! And sorry it took so long to respond (I could swear I already did!).
I like the direction of the patch. I don't have any significant comments. Once the tests are fixed, we can get this in.
Comment #16
wiifmCan confirm that our Drupal 8 site is also experiencing this issue, which is preventing users from being saved. So about as critical functionality as you can imagine.
Keen to see some movement on this issue, for now we will likely just patch the module.
Comment #17
e0ipsoThis will add a try catch for the error. This also comes with a library update.
Merging if green.
Comment #18
e0ipsoI'll merge. Something broke the tests in 8.4. We'll need some more investigation and a separate issue for that.
Comment #20
e0ipsoFixes some CS issues, but it does not address the permission issue.
Comment #21
e0ipsoComment #22
e0ipsoComment #23
e0ipsoComment #25
e0ipsoComment #26
e0ipsoComment #29
e0ipso