]> git.mxchange.org Git - friendica.git/commitdiff
Create events for authenticate, register_account and remove_user hooks
authorArt4 <art4@wlabs.de>
Thu, 20 Mar 2025 14:59:47 +0000 (14:59 +0000)
committerArt4 <art4@wlabs.de>
Thu, 20 Mar 2025 14:59:47 +0000 (14:59 +0000)
src/Core/Hooks/HookEventBridge.php
src/Event/ArrayFilterEvent.php
src/Model/User.php
src/Security/BasicAuth.php
tests/Unit/Core/Hooks/HookEventBridgeTest.php
tests/Unit/Event/ArrayFilterEventTest.php

index 82a11f1f55b02ad14b3766388041375a0a57f75d..bc2262df55bc3f03a34aca17f1eae20c5b29c5ad 100644 (file)
@@ -81,6 +81,9 @@ final class HookEventBridge
                ArrayFilterEvent::BLOCK_CONTACT                   => 'block',
                ArrayFilterEvent::UNBLOCK_CONTACT                 => 'unblock',
                ArrayFilterEvent::AVATAR_LOOKUP                   => 'avatar_lookup',
+               ArrayFilterEvent::ACCOUNT_AUTHENTICATE            => 'authenticate',
+               ArrayFilterEvent::ACCOUNT_REGISTER                => 'register_account',
+               ArrayFilterEvent::ACCOUNT_REMOVE                  => 'remove_user',
                ArrayFilterEvent::EVENT_CREATED                   => 'event_created',
                ArrayFilterEvent::EVENT_UPDATED                   => 'event_updated',
                ArrayFilterEvent::ADD_WORKER_TASK                 => 'proc_run',
@@ -149,6 +152,9 @@ final class HookEventBridge
                        ArrayFilterEvent::BLOCK_CONTACT                   => 'onArrayFilterEvent',
                        ArrayFilterEvent::UNBLOCK_CONTACT                 => 'onArrayFilterEvent',
                        ArrayFilterEvent::AVATAR_LOOKUP                   => 'onArrayFilterEvent',
+                       ArrayFilterEvent::ACCOUNT_AUTHENTICATE            => 'onArrayFilterEvent',
+                       ArrayFilterEvent::ACCOUNT_REGISTER                => 'onAccountRegisterEvent',
+                       ArrayFilterEvent::ACCOUNT_REMOVE                  => 'onAccountRemoveEvent',
                        ArrayFilterEvent::EVENT_CREATED                   => 'onEventCreatedEvent',
                        ArrayFilterEvent::EVENT_UPDATED                   => 'onEventUpdatedEvent',
                        ArrayFilterEvent::ADD_WORKER_TASK                 => 'onArrayFilterEvent',
@@ -295,6 +301,34 @@ final class HookEventBridge
                $event->setArray($data);
        }
 
+       /**
+        * Map the ACCOUNT_REGISTER event to `register_account` hook
+        */
+       public static function onAccountRegisterEvent(ArrayFilterEvent $event): void
+       {
+               $data = $event->getArray();
+
+               $uid = (int) $data['uid'] ?? 0;
+
+               $data['uid'] = static::callHook($event->getName(), $uid);
+
+               $event->setArray($data);
+       }
+
+       /**
+        * Map the ACCOUNT_REMOVE event to `remove_account` hook
+        */
+       public static function onAccountRemoveEvent(ArrayFilterEvent $event): void
+       {
+               $data = $event->getArray();
+
+               $user = (array) $data['user'] ?? [];
+
+               $data['user'] = static::callHook($event->getName(), $user);
+
+               $event->setArray($data);
+       }
+
        /**
         * Map the EVENT_CREATED event to `event_created` hook
         */
index 12105decc9408f1b4eda01834c868c6822b9193f..02a516bf61a36fe159121adac453b6958d729ffa 100644 (file)
@@ -112,6 +112,12 @@ final class ArrayFilterEvent extends Event
 
        public const AVATAR_LOOKUP = 'friendica.data.avatar_lookup';
 
+       public const ACCOUNT_AUTHENTICATE = 'friendica.data.account_authenticate';
+
+       public const ACCOUNT_REGISTER = 'friendica.data.account_register';
+
+       public const ACCOUNT_REMOVE = 'friendica.data.account_remove';
+
        public const EVENT_CREATED = 'friendica.data.event_created';
 
        public const EVENT_UPDATED = 'friendica.data.event_updated';
index 927a1a82bddaf0bc128c66fb33275dc8f640dfb7..5195fb77a3688292ef66b236720ccac3319ead0e 100644 (file)
@@ -13,7 +13,6 @@ use ErrorException;
 use Exception;
 use Friendica\App;
 use Friendica\Content\Pager;
-use Friendica\Core\Hook;
 use Friendica\Core\L10n;
 use Friendica\Core\Protocol;
 use Friendica\Core\Search;
@@ -21,6 +20,7 @@ use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBA;
 use Friendica\DI;
+use Friendica\Event\ArrayFilterEvent;
 use Friendica\Module;
 use Friendica\Network\HTTPClient\Client\HttpClientAccept;
 use Friendica\Network\HTTPClient\Client\HttpClientOptions;
@@ -758,12 +758,16 @@ class User
                        'user_record'   => null
                ];
 
-               /*
+               $eventDispatcher = DI::eventDispatcher();
+
+               /**
                 * An addon indicates successful login by setting 'authenticated' to non-zero value and returning a user record
                 * Addons should never set 'authenticated' except to indicate success - as hooks may be chained
                 * and later addons should not interfere with an earlier one that succeeded.
                 */
-               Hook::callAll('authenticate', $addon_auth);
+               $addon_auth = $eventDispatcher->dispatch(
+                       new ArrayFilterEvent(ArrayFilterEvent::ACCOUNT_AUTHENTICATE, $addon_auth),
+               )->getArray();
 
                if ($addon_auth['authenticated'] && $addon_auth['user_record']) {
                        return $addon_auth['user_record']['uid'];
@@ -1460,11 +1464,20 @@ class User
                        Contact::updateSelfFromUserID($uid, true);
                }
 
-               Hook::callAll('register_account', $uid);
+               $eventDispatcher = DI::eventDispatcher();
+
+               $hook_data = [
+                       'uid' => $uid,
+               ];
+
+               $eventDispatcher->dispatch(
+                       new ArrayFilterEvent(ArrayFilterEvent::ACCOUNT_REGISTER, $hook_data),
+               );
 
                self::setRegisterMethodByUserCount();
 
                $return['user'] = $user;
+
                return $return;
        }
 
@@ -1787,7 +1800,17 @@ class User
                        throw new \RuntimeException(DI::l10n()->t("User with delegates can't be removed, please remove delegate users first"));
                }
 
-               Hook::callAll('remove_user', $user);
+               $eventDispatcher = DI::eventDispatcher();
+
+               $hook_data = [
+                       'user' => $user,
+               ];
+
+               $hook_data = $eventDispatcher->dispatch(
+                       new ArrayFilterEvent(ArrayFilterEvent::ACCOUNT_REMOVE, $hook_data),
+               )->getArray();
+
+               $user = $hook_data['user'] ?? $user;
 
                // save username (actually the nickname as it is guaranteed
                // unique), so it cannot be re-registered in the future.
index fe89bf452e853c5bc8c5cf2c92f53a5cfd93973b..52a0f75026c8790252323b28de519193c87fa788 100644 (file)
@@ -11,6 +11,7 @@ use Exception;
 use Friendica\Core\Hook;
 use Friendica\Database\DBA;
 use Friendica\DI;
+use Friendica\Event\ArrayFilterEvent;
 use Friendica\Model\User;
 use Friendica\Network\HTTPException\UnauthorizedException;
 
@@ -136,12 +137,16 @@ class BasicAuth
                        'user_record'   => null,
                ];
 
-               /*
-               * An addon indicates successful login by setting 'authenticated' to non-zero value and returning a user record
-               * Addons should never set 'authenticated' except to indicate success - as hooks may be chained
-               * and later addons should not interfere with an earlier one that succeeded.
-               */
-               Hook::callAll('authenticate', $addon_auth);
+               $eventDispatcher = DI::eventDispatcher();
+
+               /**
+                * An addon indicates successful login by setting 'authenticated' to non-zero value and returning a user record
+                * Addons should never set 'authenticated' except to indicate success - as hooks may be chained
+                * and later addons should not interfere with an earlier one that succeeded.
+                */
+               $addon_auth = $eventDispatcher->dispatch(
+                       new ArrayFilterEvent(ArrayFilterEvent::ACCOUNT_AUTHENTICATE, $addon_auth),
+               )->getArray();
 
                if ($addon_auth['authenticated'] && !empty($addon_auth['user_record'])) {
                        $record = $addon_auth['user_record'];
index e6ec58a27cf10bf8a01de1a843ed98afcedfa4e8..d47ea1cbf737e96f5ede0c33fc2a09758ffe3eea 100644 (file)
@@ -70,6 +70,9 @@ class HookEventBridgeTest extends TestCase
                        ArrayFilterEvent::BLOCK_CONTACT                   => 'onArrayFilterEvent',
                        ArrayFilterEvent::UNBLOCK_CONTACT                 => 'onArrayFilterEvent',
                        ArrayFilterEvent::AVATAR_LOOKUP                   => 'onArrayFilterEvent',
+                       ArrayFilterEvent::ACCOUNT_AUTHENTICATE            => 'onArrayFilterEvent',
+                       ArrayFilterEvent::ACCOUNT_REGISTER                => 'onAccountRegisterEvent',
+                       ArrayFilterEvent::ACCOUNT_REMOVE                  => 'onAccountRemoveEvent',
                        ArrayFilterEvent::EVENT_CREATED                   => 'onEventCreatedEvent',
                        ArrayFilterEvent::EVENT_UPDATED                   => 'onEventUpdatedEvent',
                        ArrayFilterEvent::ADD_WORKER_TASK                 => 'onArrayFilterEvent',
@@ -385,6 +388,40 @@ class HookEventBridgeTest extends TestCase
                HookEventBridge::onEventCreatedEvent($event);
        }
 
+       public function testOnAccountRegisterEventCallsHookWithCorrectValue(): void
+       {
+               $event = new ArrayFilterEvent(ArrayFilterEvent::ACCOUNT_REGISTER, ['uid' => 123]);
+
+               $reflectionProperty = new \ReflectionProperty(HookEventBridge::class, 'mockedCallHook');
+               $reflectionProperty->setAccessible(true);
+
+               $reflectionProperty->setValue(null, function (string $name, int $data): int {
+                       $this->assertSame('register_account', $name);
+                       $this->assertSame(123, $data);
+
+                       return $data;
+               });
+
+               HookEventBridge::onAccountRegisterEvent($event);
+       }
+
+       public function testOnAccountRemoveEventCallsHookWithCorrectValue(): void
+       {
+               $event = new ArrayFilterEvent(ArrayFilterEvent::ACCOUNT_REMOVE, ['user' => ['uid' => 123]]);
+
+               $reflectionProperty = new \ReflectionProperty(HookEventBridge::class, 'mockedCallHook');
+               $reflectionProperty->setAccessible(true);
+
+               $reflectionProperty->setValue(null, function (string $name, array $data): array {
+                       $this->assertSame('remove_user', $name);
+                       $this->assertSame(['uid' => 123], $data);
+
+                       return $data;
+               });
+
+               HookEventBridge::onAccountRemoveEvent($event);
+       }
+
        public function testOnEventUpdatedEventCallsHookWithCorrectValue(): void
        {
                $event = new ArrayFilterEvent(ArrayFilterEvent::EVENT_UPDATED, ['event' => ['id' => 123]]);
@@ -427,7 +464,6 @@ class HookEventBridgeTest extends TestCase
                        [ArrayFilterEvent::RENDER_LOCATION, 'render_location'],
                        [ArrayFilterEvent::ITEM_PHOTO_MENU, 'item_photo_menu'],
                        [ArrayFilterEvent::CONTACT_PHOTO_MENU, 'contact_photo_menu'],
-                       [ArrayFilterEvent::PROFILE_SIDEBAR_ENTRY, 'profile_sidebar_enter'],
                        [ArrayFilterEvent::PROFILE_SIDEBAR, 'profile_sidebar'],
                        [ArrayFilterEvent::PAGE_INFO, 'page_info_data'],
                        [ArrayFilterEvent::SMILEY_LIST, 'smilie'],
@@ -441,6 +477,9 @@ class HookEventBridgeTest extends TestCase
                        [ArrayFilterEvent::BLOCK_CONTACT, 'block'],
                        [ArrayFilterEvent::UNBLOCK_CONTACT, 'unblock'],
                        [ArrayFilterEvent::AVATAR_LOOKUP, 'avatar_lookup'],
+                       [ArrayFilterEvent::ACCOUNT_AUTHENTICATE, 'authenticate'],
+                       [ArrayFilterEvent::ACCOUNT_REGISTER, 'register_account'],
+                       [ArrayFilterEvent::ACCOUNT_REMOVE, 'remove_user'],
                        [ArrayFilterEvent::EVENT_CREATED, 'event_created'],
                        [ArrayFilterEvent::EVENT_UPDATED, 'event_updated'],
                        [ArrayFilterEvent::ADD_WORKER_TASK, 'proc_run'],
index 85d90ba1323e913dd82d83f5d25dbf36ec61b9d7..5bc71084c381000367b54edd17cd03c261d27387 100644 (file)
@@ -67,6 +67,9 @@ class ArrayFilterEventTest extends TestCase
                        [ArrayFilterEvent::BLOCK_CONTACT, 'friendica.data.block_contact'],
                        [ArrayFilterEvent::UNBLOCK_CONTACT, 'friendica.data.unblock_contact'],
                        [ArrayFilterEvent::AVATAR_LOOKUP, 'friendica.data.avatar_lookup'],
+                       [ArrayFilterEvent::ACCOUNT_AUTHENTICATE, 'friendica.data.account_authenticate'],
+                       [ArrayFilterEvent::ACCOUNT_REGISTER, 'friendica.data.account_register'],
+                       [ArrayFilterEvent::ACCOUNT_REMOVE, 'friendica.data.account_remove'],
                        [ArrayFilterEvent::EVENT_CREATED, 'friendica.data.event_created'],
                        [ArrayFilterEvent::EVENT_UPDATED, 'friendica.data.event_updated'],
                        [ArrayFilterEvent::ADD_WORKER_TASK, 'friendica.data.add_worker_task'],