Problem/Motivation

  • Reassign UID to anonymous for entities that have revisions enabled. If saving any of these entities with a deleted user, it will throw the 500 error.
  • Reassign uid for the following entities when if the user that owns them is deleted.
    • Cloud Config
    • Cloud Project
    • Cloud Store
    #0 /var/www/cloud_orchestrator/docroot/modules/contrib/cloud/src/Entity/CloudConfig.php(126): Drupal\cloud\Entity\CloudConfig->getOwner()
    #1 /var/www/cloud_orchestrator/docroot/core/lib/Drupal/Core/Entity/EntityStorageBase.php(562): Drupal\cloud\Entity\CloudConfig->preSave(Object(Drupal\cloud\Entity\CloudConfigStorage))
    #2 /var/www/cloud_orchestrator/docroot/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php(756): Drupal\Core\Entity\EntityStorageBase->doPreSave(Object(Drupal\cloud\Entity\CloudConfig))
    #3 /var/www/cloud_orchestrator/docroot/core/lib/Drupal/Core/Entity/EntityStorageBase.php(517): Drupal\Core\Entity\ContentEntityStorageBase->doPreSave(Object(Drupal\cloud\Entity\CloudConfig))
    #4 /var/www/cloud_orchestrator/docroot/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php(802): Drupal\Core\Entity\EntityStorageBase->save(Object(Drupal\cloud\Entity\CloudConfig))
    #5 /var/www/cloud_orchestrator/docroot/core/lib/Drupal/Core/Entity/EntityBase.php(339): Drupal\Core\Entity\Sql\SqlContentEntityStorage->save(Object(Drupal\cloud\Entity\CloudConfig))
    #6 /var/www/cloud_orchestrator/docroot/modules/contrib/cloud/src/Entity/CloudConfig.php(286): Drupal\Core\Entity\EntityBase->save()
    #7 /var/www/cloud_orchestrator/docroot/modules/contrib/cloud/src/Form/CloudContentForm.php(140): Drupal\cloud\Entity\CloudConfig->save()
    #8 /var/www/cloud_orchestrator/docroot/modules/contrib/cloud/src/Form/CloudConfigForm.php(68): Drupal\cloud\Form\CloudContentForm->save(Array, Object(Drupal\Core\Form\FormState))
    #9 [internal function]: Drupal\cloud\Form\CloudConfigForm->save(Array, Object(Drupal\Core\Form\FormState))
    #10 /var/www/cloud_orchestrator/docroot/core/lib/Drupal/Core/Form/FormSubmitter.php(114): call_user_func_array(Array, Array)
    #11 /var/www/cloud_orchestrator/docroot/core/lib/Drupal/Core/Form/FormSubmitter.php(52): Drupal\Core\Form\FormSubmitter->executeSubmitHandlers(Array, Object(Drupal\Core\Form\FormState))
    #12 /var/www/cloud_orchestrator/docroot/core/lib/Drupal/Core/Form/FormBuilder.php(592): Drupal\Core\Form\FormSubmitter->doSubmitForm(Array, Object(Drupal\Core\Form\FormState))
    #13 /var/www/cloud_orchestrator/docroot/core/lib/Drupal/Core/Form/FormBuilder.php(320): Drupal\Core\Form\FormBuilder->processForm('cloud_config_aw...', Array, Object(Drupal\Core\Form\FormState))
    #14 /var/www/cloud_orchestrator/docroot/core/lib/Drupal/Core/Controller/FormController.php(73): Drupal\Core\Form\FormBuilder->buildForm(Object(Drupal\cloud\Form\CloudConfigForm), Object(Drupal\Core\Form\FormState))
    #15 [internal function]: Drupal\Core\Controller\FormController->getContentResult(Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\RouteMatch))
    #16 /var/www/cloud_orchestrator/docroot/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array)
    #17 /var/www/cloud_orchestrator/docroot/core/lib/Drupal/Core/Render/Renderer.php(564): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
    #18 /var/www/cloud_orchestrator/docroot/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
    #19 /var/www/cloud_orchestrator/docroot/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array)
    #20 /var/www/cloud_orchestrator/vendor/symfony/http-kernel/HttpKernel.php(158): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
    #21 /var/www/cloud_orchestrator/vendor/symfony/http-kernel/HttpKernel.php(80): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
    #22 /var/www/cloud_orchestrator/docroot/core/lib/Drupal/Core/StackMiddleware/Session.php(58): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #23 /var/www/cloud_orchestrator/docroot/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #24 /var/www/cloud_orchestrator/docroot/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #25 /var/www/cloud_orchestrator/docroot/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #26 /var/www/cloud_orchestrator/docroot/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #27 /var/www/cloud_orchestrator/docroot/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #28 /var/www/cloud_orchestrator/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #29 /var/www/cloud_orchestrator/docroot/core/lib/Drupal/Core/DrupalKernel.php(709): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #30 /var/www/cloud_orchestrator/docroot/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
    #31 {main}
    

Issue fork cloud-3313552

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

baldwinlouie created an issue. See original summary.

baldwinlouie’s picture

Title: Reassign UID for Cloud Config, Cloud Launch Template and Cloud Store » Reassign UID for Cloud Config, Cloud Project
Issue summary: View changes
baldwinlouie’s picture

Title: Reassign UID for Cloud Config, Cloud Project » Reassign UID for Cloud Config, Cloud Project and Cloud Store
Issue summary: View changes

baldwinlouie’s picture

@yas @kumikoono,

This patch adds a generic method \Drupal::service('cloud')->reassignUids() that handles reassigning the UID when a user is deleted. Other modules can use it as well.

You can use the method like this:

  // Reassign entities from the user being deleted.
  $cloud_config_ids = \Drupal::entityTypeManager()
    ->getStorage('cloud_config')
    ->userRevisionIds($account);

  // Reassign cloud config entities.
  \Drupal::service('cloud')->reassignUids($cloud_config_ids, [
    'uid' => 0,
    'revision_uid' => 0,
  ], 'cloud_config', TRUE);

The method sets up a batch process and loops through passed in entities and reassigns the uid to 0. In the future, some modules such as AWS and K8s will need to make some API calls during the reassignment process. To accommodate for that, I've set up reassignUids such that you can pass in additional callback functions. Those callback functions will be called and you can do additional processing such as make API calls to do additional updates.

For example, in the future

  // Reassign entities from the user being deleted.
  $launch_template_ids = \Drupal::entityTypeManager()
    ->getStorage('server_templates')
    ->userRevisionIds($account);

  // Reassign cloud config entities.
  \Drupal::service('cloud')->reassignUids($launch_template_ids, [
    'uid' => 0,
    'revision_uid' => 0,
  ], 'cloud_config', TRUE, [
    '\Drupal\aws_cloud\Service\AdditionalCallbackFunction::updateUidsInAWS',
  ]);

then in the future, we can write:

  public static function updateUidsInAWS(array $entities, array $updates, bool $revision, string $entity_type, &$context): void {
    //Loop through the $entities and make some API calls.
  }

Additionally, I've added additional wording to the User Cancellation choices. This further explains what happens to Cloud related entities if a user deletes an account.

See screenshot:

yas made their first commit to this issue’s fork.

yas’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community

@baldwinlouie

Thank you for fixing the issue. The patch looks so great.

@kumikoono

What do you think?

yas’s picture

Status: Reviewed & tested by the community » Needs review

@baldwinlouie

I just posted my minor comment. Thanks

baldwinlouie’s picture

@yas. I've adjusted the wording. Thoughts?

yas’s picture

Title: Reassign UID for Cloud Config, Cloud Project and Cloud Store » Refactor to reassign UID for Cloud Config, Cloud Project and Cloud Store

@baldwinlouie

Thank you for the update. It looks good to me. Thanks!

kumikoono’s picture

@baldwin Thanks for your providing the patch.
As you know, other resources (e.g,. a key pair) has been already set to "Anonymous" when the owner user is deleted.
You might want to modify the text on the screenshot for cloud-related entities.

baldwinlouie’s picture

@kumikoono,

Thank you for reviewing. We actually have wording talking about setting entities to "Anonymous". See screenshot and let me know if this wording is ok.

Also, I did a test to see if other entities are automatically set to "Anonymous". This is actually not the case. See the following two screenshots.

After deleting a user, the Authored By field is blank. In the database, the uid is still pointing to the deleted user.

If I try to save the entity, I get the following screenshot. In the database, the UID is now blank.

Therefore, in each of our modules, we need to reassign the UID after the user is deleted. We can take care of those in other tickets.

This first patch sets up the method which other modules can call.

It also fixes the 500 error you are seeing with Cloud Config entities when you delete a user.

kumikoono’s picture

Thanks @baldwin.
It looks a key pair was not a good example. I understand the difference between disabling and deleting users.
This patch looks good to me.

yas’s picture

Status: Needs review » Reviewed & tested by the community

@kumikoono

Thank you for your review.

@baldwinlouie

I'll merge the patch to 4.x and 5.x, and close this issue as Fixed.

  • yas committed 313e402 on 5.x authored by baldwinlouie
    Issue #3313552 by baldwinlouie, yas, kumikoono: Refactor to reassign UID...

  • yas committed 156a0c5 on 4.x
    Issue #3313552 by baldwinlouie, yas, kumikoono: Refactor to reassign UID...
yas’s picture

Status: Reviewed & tested by the community » Fixed

Status: Fixed » Closed (fixed)

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