From befd626599ef7f654f959ed1f6c1b40f64929dd6 Mon Sep 17 00:00:00 2001 From: Evan Sims Date: Sun, 23 Oct 2022 22:35:39 -0500 Subject: [PATCH] Enhancements to sync and Management API calls --- src/Actions/Authentication.php | 53 +++++++++++++++------------ src/Actions/Configuration.php | 17 +++++---- src/Actions/Sync.php | 65 +++++++++++++++++++++------------- src/Database.php | 24 ++++++++++--- src/Plugin.php | 4 +-- src/Utilities/Sanitize.php | 9 ++++- 6 files changed, 110 insertions(+), 62 deletions(-) diff --git a/src/Actions/Authentication.php b/src/Actions/Authentication.php index 88095861..6a92c890 100644 --- a/src/Actions/Authentication.php +++ b/src/Actions/Authentication.php @@ -39,7 +39,11 @@ final class Authentication extends Base public function onInit(): void { - if (! $this->getPlugin()->isReady() || ! $this->getPlugin()->isEnabled()) { + if (! $this->getPlugin()->isReady()) { + return; + } + + if (! $this->getPlugin()->isEnabled()) { return; } @@ -292,11 +296,11 @@ public function onCreatedUser($userId, $notify = null): void $payload = json_encode([ 'event' => 'wp_user_created', 'user' => $userId - ]); + ], JSON_THROW_ON_ERROR); $checksum = hash('sha256', $payload); // TODO: Optimize this by creating an InsertIgnoreRow() method with a custom query. - $dupe = $database->selectRow('id', $table, 'WHERE `hashsum` = "%s";', $checksum); + $dupe = $database->selectRow('id', $table, 'WHERE `hashsum` = "%s";', [$checksum]); if (! $dupe) { $database->insertRow($table, [ @@ -334,11 +338,11 @@ public function onDeletedUser($userId): void 'event' => 'wp_user_deleted', 'user' => $userId, 'connection' => $connection->auth0 - ]); + ], JSON_THROW_ON_ERROR); $checksum = hash('sha256', $payload); // TODO: Optimize this by creating an InsertIgnoreRow() method with a custom query. - $dupe = $database->selectRow('id', $table, 'WHERE `hashsum` = "%s";', $checksum); + $dupe = $database->selectRow('id', $table, 'WHERE `hashsum` = "%s";', [$checksum]); if (! $dupe) { $database->insertRow($table, [ @@ -377,11 +381,11 @@ public function onUpdatedUser($userId, $previousUserData = null): void $payload = json_encode([ 'event' => 'wp_user_updated', 'user' => $userId - ]); + ], JSON_THROW_ON_ERROR); $checksum = hash('sha256', $payload); // TODO: Optimize this by creating an InsertIgnoreRow() method with a custom query. - $dupe = $database->selectRow('id', $table, 'WHERE `hashsum` = "%s";', $checksum); + $dupe = $database->selectRow('id', $table, 'WHERE `hashsum` = "%s";', [$checksum]); if (! $dupe) { $database->insertRow($table, [ @@ -470,17 +474,17 @@ private function resolveIdentity( private function prepDatabase(string $databaseName) { - // $cacheKey = 'auth0_db_check_' . hash('sha256', $databaseName); + $cacheKey = 'auth0_db_check_' . hash('sha256', $databaseName); - // $found = false; - // wp_cache_get($cacheKey, '', false, $found); + $found = false; + wp_cache_get($cacheKey, '', false, $found); - // if (! $found && false === get_transient($cacheKey)) { - // set_transient($cacheKey, true, 1800); - // wp_cache_set($cacheKey, true, 1800); + if (! $found && false === get_transient($cacheKey)) { + set_transient($cacheKey, true, 1800); + wp_cache_set($cacheKey, true, 1800); - return $this->getPlugin()->database()->createTable($databaseName); - // } + return $this->getPlugin()->database()->createTable($databaseName); + } } public function setAccountEmail(WP_User $wpUser, string $email): ?WP_User @@ -506,17 +510,17 @@ public function createAccountConnection(WP_User $wpUser, string $connection): vo $found = false; wp_cache_get($cacheKey, '', false, $found); - if (! $found) { // && false === get_transient($cacheKey) + if (! $found && false === get_transient($cacheKey)) { $database = $this->getPlugin()->database(); $table = $database->getTableName(Database::CONST_TABLE_ACCOUNTS); $found = null; $this->prepDatabase(Database::CONST_TABLE_ACCOUNTS); - $found = $database->selectRow('*', $table, 'WHERE `user` = %d AND `site` = %d AND `blog` = %d AND `auth0` = "%s" LIMIT 1', $wpUser->ID, $network, $blog, $connection); + $found = $database->selectRow('*', $table, 'WHERE `user` = %d AND `site` = %d AND `blog` = %d AND `auth0` = "%s" LIMIT 1', [$wpUser->ID, $network, $blog, $connection]); if (null === $found) { - // set_transient($cacheKey, $wpUser->ID, 120); + set_transient($cacheKey, $wpUser->ID, 120); wp_cache_set($cacheKey, $found, 120); $database->insertRow($table, [ @@ -548,14 +552,14 @@ public function getAccountByConnection(string $connection): ?WP_User } if (! $found) { - // $found = get_transient($cacheKey); + $found = get_transient($cacheKey); if (false === $found) { $database = $this->getPlugin()->database(); $table = $database->getTableName(Database::CONST_TABLE_ACCOUNTS); $this->prepDatabase(Database::CONST_TABLE_ACCOUNTS); - $found = $database->selectRow('user', $table, 'WHERE `site` = %d AND `blog` = %d AND `auth0` = "%s" LIMIT 1', $network, $blog, $connection); + $found = $database->selectRow('user', $table, 'WHERE `site` = %d AND `blog` = %d AND `auth0` = "%s" LIMIT 1', [$network, $blog, $connection]); if (null === $found) { return null; @@ -565,8 +569,11 @@ public function getAccountByConnection(string $connection): ?WP_User } } + + $found = $found->user; + if ($found) { - // set_transient($cacheKey, $found, 120); + set_transient($cacheKey, $found, 120); wp_cache_set($cacheKey, $found, 120); $user = get_user_by('ID', $found); @@ -588,7 +595,7 @@ public function getAccountConnections(int $userId): ?array $this->prepDatabase(Database::CONST_TABLE_ACCOUNTS); - $connections = $database->selectResults('auth0', $table, 'WHERE `site` = %d AND `blog` = %d AND `user` = "%s" LIMIT 1', $network, $blog, $userId); + $connections = $database->selectResults('auth0', $table, 'WHERE `site` = %d AND `blog` = %d AND `user` = "%s" LIMIT 1', [$network, $blog, $userId]); if ($connections) { return $connections; @@ -606,7 +613,7 @@ public function deleteAccountConnections(int $userId): ?array $this->prepDatabase(Database::CONST_TABLE_ACCOUNTS); - $connections = $database->selectResults('auth0', $table, 'WHERE `site` = %d AND `blog` = %d AND `user` = "%s" LIMIT 1', $network, $blog, $userId); + $connections = $database->selectResults('auth0', $table, 'WHERE `site` = %d AND `blog` = %d AND `user` = "%s" LIMIT 1', [$network, $blog, $userId]); if ($connections) { $database->deleteRow($table, ['user' => $userId, 'site' => $network, 'blog' => $blog], ['%d', '%s', '%s']); diff --git a/src/Actions/Configuration.php b/src/Actions/Configuration.php index fc55e5dd..227d24b7 100644 --- a/src/Actions/Configuration.php +++ b/src/Actions/Configuration.php @@ -647,16 +647,16 @@ public function onUpdateSync(?array $input): ?array if ($sanitized['database'] !== '') { $database = Sanitize::alphanumeric($sanitized['database'], "A-Za-z0-9\-_"); - if (strlen($database) >= 3 && strlen($database) <= 64 && substr($database, 0, 4) === 'con_') { + if (strlen($database) >= 3 && strlen($database) <= 64 && str_starts_with($database, 'con_')) { $filteredDatabase = $database; } } // Check if connection is valid - $api = $this->getSdk()->management()->connections()->get($filteredDatabase); + $response = $this->getSdk()->management()->connections()->get($filteredDatabase); - if (! HttpResponse::wasSuccessful($api)) { + if (! HttpResponse::wasSuccessful($response)) { $filteredDatabase = ''; } @@ -748,19 +748,22 @@ public function onUpdateClientAdvanced(?array $input): ?array $filteredApis = []; $filteredOrgs = []; + $apisCount = is_countable($apis) ? count($apis) : 0; - for ($i=0; $i < count($apis); $i++) { + for ($i=0; $i < $apisCount; ++$i) { $apis[$i] = trim($apis[$i]); - if (strlen($apis[$i]) >= 3 && strlen($apis[$i]) <= 64 && preg_match('/^[a-z0-9]/', $apis[$i]) === 1) { + if (strlen($apis[$i]) >= 3 && strlen($apis[$i]) <= 64 && preg_match('#^[a-z0-9]#', $apis[$i]) === 1) { $filteredApis[] = $apis[$i]; } } - for ($i=0; $i < count($orgs); $i++) { + $orgsCount = is_countable($orgs) ? count($orgs) : 0; + + for ($i=0; $i < $orgsCount; ++$i) { $orgs[$i] = trim($orgs[$i]); - if (strlen($orgs[$i]) >= 4 && strlen($orgs[$i]) <= 64 && substr($orgs[$i], 0, 4) === 'org_') { + if (strlen($orgs[$i]) >= 4 && strlen($orgs[$i]) <= 64 && str_starts_with($orgs[$i], 'org_')) { $filteredOrgs[] = $orgs[$i]; } } diff --git a/src/Actions/Sync.php b/src/Actions/Sync.php index 2abad735..5cc48281 100644 --- a/src/Actions/Sync.php +++ b/src/Actions/Sync.php @@ -4,16 +4,31 @@ namespace Auth0\WordPress\Actions; +use WP_User; use Auth0\SDK\Utility\HttpResponse; use Auth0\WordPress\Database; use Psr\Http\Message\ResponseInterface; final class Sync extends Base { + /** + * @var string + */ public const CONST_JOB_BACKGROUND_SYNC = 'AUTH0_CRON_SYNC'; + + /** + * @var string + */ public const CONST_JOB_BACKGROUND_MAINTENANCE = 'AUTH0_CRON_MAINTENANCE'; + /** + * @var string + */ public const CONST_SCHEDULE_BACKGROUND_SYNC = 'AUTH0_SYNC'; + + /** + * @var string + */ public const CONST_SCHEDULE_BACKGROUND_MAINTENANCE = 'AUTH0_MAINTENANCE'; /** @@ -25,17 +40,14 @@ final class Sync extends Base 'cron_schedules' => 'updateCronSchedule', ]; + /** + * @return mixed[] + */ public function updateCronSchedule($schedules): array { - $schedules[self::CONST_SCHEDULE_BACKGROUND_SYNC] = array( - 'interval' => $this->getPlugin()->getOptionInteger('sync', 'schedule') ?? 3600, - 'display' => 'Plugin Configuration' - ); + $schedules[self::CONST_SCHEDULE_BACKGROUND_SYNC] = ['interval' => $this->getPlugin()->getOptionInteger('sync', 'schedule') ?? 3600, 'display' => 'Plugin Configuration']; - $schedules[self::CONST_SCHEDULE_BACKGROUND_MAINTENANCE] = array( - 'interval' => 300, - 'display' => 'Every 5 Minutes' - ); + $schedules[self::CONST_SCHEDULE_BACKGROUND_MAINTENANCE] = ['interval' => 300, 'display' => 'Every 5 Minutes']; return $schedules; } @@ -69,7 +81,7 @@ public function onBackgroundSync(): void $this->getPlugin()->database()->createTable(Database::CONST_TABLE_SYNC); - $queue = $database->selectResults('*', $table, 'WHERE `site` = %d AND `blog` = %d ORDER BY created LIMIT 10', $network, $blog); + $queue = $database->selectResults('*', $table, 'WHERE `site` = %d AND `blog` = %d ORDER BY created LIMIT 10', [$network, $blog]); $enabledEvents = [ 'wp_user_created' => $this->getPlugin()->getOptionBoolean('sync_events', 'user_creation') ?? true, @@ -79,26 +91,26 @@ public function onBackgroundSync(): void $dbConnection = $this->getPlugin()->getOptionString('sync', 'database'); - foreach ($queue as $event) { + foreach ($queue as $singleQueue) { if (null !== $dbConnection) { - $payload = json_decode($event->payload, true); + $payload = json_decode($singleQueue->payload, true, 512, JSON_THROW_ON_ERROR); if (isset($payload['event'])) { - if ($payload['event'] === 'wp_user_created' && $enabledEvents['wp_user_created'] === true) { + if ($payload['event'] === 'wp_user_created' && $enabledEvents['wp_user_created']) { $this->eventUserCreated($dbConnection, $payload); } - if ($payload['event'] === 'wp_user_deleted' && $enabledEvents['wp_user_deleted'] === true) { + if ($payload['event'] === 'wp_user_deleted' && $enabledEvents['wp_user_deleted']) { $this->eventUserDeleted($dbConnection, $payload); } - if ($payload['event'] === 'wp_user_updated' && $enabledEvents['wp_user_updated'] === true) { + if ($payload['event'] === 'wp_user_updated' && $enabledEvents['wp_user_updated']) { $this->eventUserUpdated($dbConnection, $payload); } } } - $database->deleteRow($table, ['id' => $event->id], ['%d']); + $database->deleteRow($table, ['id' => $singleQueue->id], ['%d']); } } @@ -157,9 +169,9 @@ public function eventUserDeleted(string $dbConnection, array $event): void if (null !== $user && null !== $connection) { // Verify that the connection has not been claimed by another account already - $claimed = $this->authentication()->getAccountByConnection($connection); + $wpUser = $this->authentication()->getAccountByConnection($connection); - if (null === $claimed) { + if (!$wpUser instanceof WP_User) { // Determine if the Auth0 counterpart account still exists $api = $this->getResults($this->getSdk()->management()->users()->get($connection)); @@ -233,15 +245,20 @@ public function cleanupOrphanedConnections(): void $this->getPlugin()->database()->createTable(Database::CONST_TABLE_ACCOUNTS); - $users = $database->selectDistinctResults('user', $table, 'WHERE `site` = %d AND `blog` = %d', $network, $blog); + $users = $database->selectDistinctResults('user', $table, 'WHERE `site` = %d AND `blog` = %d', [$network, $blog]); + if (!is_array($users)) { + return; + } + + if ([] === $users) { + return; + } - if (is_array($users) && [] !== $users) { - foreach ($users as $user) { - $found = get_user_by('ID', $user->user); + foreach ($users as $user) { + $found = get_user_by('ID', $user->user); - if (! $found) { - $this->authentication()->deleteAccountConnections((int) $user->user); - } + if (! $found) { + $this->authentication()->deleteAccountConnections((int) $user->user); } } } diff --git a/src/Database.php b/src/Database.php index 96049761..aaf7a867 100644 --- a/src/Database.php +++ b/src/Database.php @@ -4,11 +4,27 @@ namespace Auth0\WordPress; +use Throwable; final class Database { + /** + * @var string + */ public const CONST_TABLE_OPTIONS = 'options'; + + /** + * @var string + */ public const CONST_TABLE_ACCOUNTS = 'accounts'; + + /** + * @var string + */ public const CONST_TABLE_SYNC = 'sync'; + + /** + * @var string + */ public const CONST_TABLE_LOG = 'log'; public function createTable(string $table) @@ -29,7 +45,7 @@ public function insertRow( ): int|bool { try { return $this->getWpdb()->insert($table, $data, $formats); - } catch (\Throwable $th) { + } catch (Throwable) { return false; } } @@ -38,7 +54,7 @@ public function selectRow( string $select, string $from, string $query, - ...$args + array $args = [] ): array|object|null { $query = $this->getWpdb()->prepare($query, ...$args); return $this->getWpdb()->get_row(sprintf('SELECT %s FROM %s ', $select, $from) . $query); @@ -56,7 +72,7 @@ public function selectResults( string $select, string $from, string $query, - ...$args + array $args = [] ): array|object|null { $query = $this->getWpdb()->prepare($query, ...$args); return $this->getWpdb()->get_results(sprintf('SELECT %s FROM %s ', $select, $from) . $query); @@ -66,7 +82,7 @@ public function selectDistinctResults( string $select, string $from, string $query, - ...$args + array $args = [] ): array|object|null { $query = $this->getWpdb()->prepare($query, ...$args); return $this->getWpdb()->get_results(sprintf('SELECT DISTINCT %s FROM %s ', $select, $from) . $query); diff --git a/src/Plugin.php b/src/Plugin.php index de299c5e..445bba79 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -191,8 +191,6 @@ public function isEnabled(): bool } /** - * @param int|null $default - * * @psalm-param 0|null $default */ public function getOption(string $group, string $key, ?int $default = null, string $prefix = 'auth0_'): mixed @@ -301,7 +299,7 @@ private function importConfiguration(): SdkConfiguration cookieDomain: $this->getOptionString('cookies', 'domain'), cookiePath: $this->getOptionString('cookies', 'path') ?? '/', cookieExpires: $expires, - cookieSecure: $secure ? true : false, + cookieSecure: (bool) $secure, cookieSameSite: $this->getOptionString('cookies', 'samesite'), redirectUri: get_site_url(null, 'wp-login.php') ); diff --git a/src/Utilities/Sanitize.php b/src/Utilities/Sanitize.php index 6376ef1a..ca6e7782 100644 --- a/src/Utilities/Sanitize.php +++ b/src/Utilities/Sanitize.php @@ -8,13 +8,20 @@ final class Sanitize { public static function alphanumeric(string|null $item, string $allowed = 'A-Za-z0-9 '): string|null { - if ($item === '' || $item === null) { + if ($item === '') { + return $item; + } + + if ($item === null) { return $item; } return preg_replace('/[^' . $allowed . ']/', '', $item); } + /** + * @return mixed[] + */ public static function arrayUnique(array $array): array { if ($array === []) {