Skip to content

Commit

Permalink
Extract user deletion into a new service
Browse files Browse the repository at this point in the history
Introduce a programming API for downstream developers that allows
customizing what should happen when a user is deleted in Drupal.

Co-authored-by: Dezső BICZÓ <[email protected]>
  • Loading branch information
FCsongradi and mxr576 committed Aug 28, 2023
1 parent 230b0c5 commit b43b807
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 24 deletions.
26 changes: 2 additions & 24 deletions apigee_edge.module
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ function apigee_edge_entity_view(array &$build, EntityInterface $entity, EntityV
],
],
]))->toRenderable();

$build['#attached']['library'][] = 'core/drupal.dialog.ajax';
}
}
Expand Down Expand Up @@ -1490,29 +1490,7 @@ function apigee_edge_user_cancel_methods_alter(&$methods) {
* Implements hook_user_delete().
*/
function apigee_edge_user_delete(UserInterface $account) {
// Do not try to delete developer of the anonymous user because it does
// not exist.
if ($account->isAnonymous()) {
return;
}

try {
/** @var \Drupal\apigee_edge\Entity\Developer $developer */
$developer = Developer::load($account->getEmail());
// Sanity check, the developer may not exist in Apigee Edge.
if ($developer) {
$developer->delete();
}
}
catch (\Exception $exception) {
$context = [
'@developer' => $account->getEmail(),
'@message' => (string) $exception,
];
// @todo watchdog_exception() function has been deprecated for Drupal 10.1 https://www.drupal.org/node/2932520
// @phpstan-ignore-next-line
watchdog_exception('apigee_edge', $exception, 'Could not delete @developer developer entity. @message %function (line %line of %file). <pre>@backtrace_string</pre>', $context);
}
(\Drupal::service('apigee_edge.user_removal_handler'))($account);
}

/**
Expand Down
4 changes: 4 additions & 0 deletions apigee_edge.services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -213,3 +213,7 @@ services:
apigee_edge.authentication.oauth_token_storage:
class: Drupal\apigee_edge\OauthTokenFileStorage
arguments: ['@config.factory', '@file_system', '@logger.channel.apigee_edge']

apigee_edge.user_removal_handler:
class: Drupal\apigee_edge\User\RemoveDeveloperWithUserSynchronousUserRemovalHandler
arguments: ['@entity_type.manager', '@logger.channel.apigee_edge']
96 changes: 96 additions & 0 deletions src/User/RemoveDeveloperWithUserSynchronousUserRemovalHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<?php

/**
* Copyright 2023 Google Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/

namespace Drupal\apigee_edge\User;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Utility\Error;
use Drupal\user\UserInterface;
use Psr\Log\LoggerInterface;

/**
* Handler that removes the related developer when a user is deleted.
*
* ATTENTION!!! Removing a developer from Apigee is a dangerous operation
* because it also destroys all API keys the developer pwns. If that is not
* an intended behavior, use the service decorator pattern to customize
* this process.
*
* @see \apigee_edge_user_delete()
*/
final class RemoveDeveloperWithUserSynchronousUserRemovalHandler implements UserRemovalHandlerInterface {

/**
* Entity type manager service.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
private EntityTypeManagerInterface $entityTypeManager;

/**
* Logger interface.
*
* @var \Psr\Log\LoggerInterface
*/
private LoggerInterface $logger;

/**
* RemoveDeveloperWithUserSynchronousUserRemovalHandler constructor.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* Entity type manager service.
* @param \Psr\Log\LoggerInterface $logger
* The logger.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, LoggerInterface $logger) {
$this->entityTypeManager = $entity_type_manager;
$this->logger = $logger;
}

/**
* {@inheritdoc}
*/
public function __invoke(UserInterface $account): void {
// Do not try to delete developer of the anonymous user because it does
// not exist.
if ($account->isAnonymous()) {
return;
}

try {
/** @var \Drupal\apigee_edge\Entity\DeveloperInterface|null $developer */
$developer = $this->entityTypeManager->getStorage('developer')->load($account->getEmail());
// Sanity check, the developer may not exist in Apigee Edge.
if ($developer) {
$developer->delete();
$this->logger->info('The @developer developer has been deleted as a reaction to removing its user account.', [
'@developer' => $account->getEmail(),
]);
}
}
catch (\Exception $exception) {
$context = [
'@developer' => $account->getEmail(),
];
Error::logException($this->logger, $exception, 'The @developer developer could not be deleted as a reaction to removing its user account. @message %function (line %line of %file). <pre>@backtrace_string</pre>', $context);
}
}

}
40 changes: 40 additions & 0 deletions src/User/UserRemovalHandlerInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

/**
* Copyright 2023 Google Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/

namespace Drupal\apigee_edge\User;

use Drupal\user\UserInterface;

/**
* Contract for triggering an Apigee specific reaction on user removal.
*/
interface UserRemovalHandlerInterface {

/**
* React on user removal.
*
* @param \Drupal\user\UserInterface $account
* The deleted user account.
*
* @see \hook_ENTITY_TYPE_delete()
*/
public function __invoke(UserInterface $account): void;

}

0 comments on commit b43b807

Please sign in to comment.