From 8c2cbf48d513d158bbb55afd3e76b5a71e8d2d07 Mon Sep 17 00:00:00 2001 From: netkas Date: Fri, 31 Jan 2025 15:31:07 -0500 Subject: [PATCH] Improved Peer Resolution and fixed minor bugs and issues, completed todo --- .../Classes/StandardMethods/Core/GetSelf.php | 28 ++ .../Standard/StandardRpcException.php | 6 + .../Objects/Database/PeerDatabaseRecord.php | 6 +- src/Socialbox/Objects/Standard/SelfUser.php | 272 +++++++++--------- src/Socialbox/Socialbox.php | 52 +++- 5 files changed, 209 insertions(+), 155 deletions(-) create mode 100644 src/Socialbox/Classes/StandardMethods/Core/GetSelf.php diff --git a/src/Socialbox/Classes/StandardMethods/Core/GetSelf.php b/src/Socialbox/Classes/StandardMethods/Core/GetSelf.php new file mode 100644 index 0000000..d5c4a0b --- /dev/null +++ b/src/Socialbox/Classes/StandardMethods/Core/GetSelf.php @@ -0,0 +1,28 @@ +produceError(StandardError::from($this->code), $this->message); } + + public static function fromRpcException(RpcException $e): StandardRpcException + { + return new self($e->getMessage(), StandardError::tryFrom($e->getCode()) ?? StandardError::UNKNOWN, $e); + } } \ No newline at end of file diff --git a/src/Socialbox/Objects/Database/PeerDatabaseRecord.php b/src/Socialbox/Objects/Database/PeerDatabaseRecord.php index 7bb77d4..4611b59 100644 --- a/src/Socialbox/Objects/Database/PeerDatabaseRecord.php +++ b/src/Socialbox/Objects/Database/PeerDatabaseRecord.php @@ -7,6 +7,7 @@ use Socialbox\Classes\Configuration; use Socialbox\Enums\Flags\PeerFlags; use Socialbox\Interfaces\SerializableInterface; + use Socialbox\Objects\Standard\InformationFieldState; use Socialbox\Objects\Standard\Peer; class PeerDatabaseRecord implements SerializableInterface @@ -197,13 +198,14 @@ /** * Converts the current instance to a Peer object. * + * @param PeerInformationFieldRecord[]|InformationFieldState[]|array $informationFields * @return Peer The Peer representation of the current instance. */ - public function toStandardPeer(): Peer + public function toStandardPeer(array $informationFields): Peer { - // TODO: TO be updated return Peer::fromArray([ 'address' => $this->getAddress(), + 'information_fields' => $informationFields, 'flags' => array_map(fn(PeerFlags $flag) => $flag->value, $this->flags), 'registered' => $this->created->getTimestamp() ]); diff --git a/src/Socialbox/Objects/Standard/SelfUser.php b/src/Socialbox/Objects/Standard/SelfUser.php index 1d862bd..bf9a3c0 100644 --- a/src/Socialbox/Objects/Standard/SelfUser.php +++ b/src/Socialbox/Objects/Standard/SelfUser.php @@ -1,159 +1,151 @@ uuid = $data->getUuid(); - $this->enabled = $data->isEnabled(); - $this->username = $data->getUsername(); - $this->address = $data->getAddress(); - $this->displayName = $data->getDisplayName(); - $this->flags = $data->getFlags(); - $this->created = $data->getCreated()->getTimestamp(); + $this->uuid = $data['uuid']; + $this->enabled = $data['enabled']; + $this->username = $data['username']; + $this->address = $data['address']; + $this->displayName = $data['display_name'] ?? null; + + if(is_string($data['flags'])) + { + $this->flags = PeerFlags::fromString($data['flags']); + } + elseif(is_array($data['flags'])) + { + $this->flags = $data['flags']; + } + else + { + $this->flags = []; + } + + if($data['created'] instanceof DateTime) + { + $this->registered = $data['created']->getTimestamp(); + } + else + { + $this->registered = $data['created']; + } return; } - $this->uuid = $data['uuid']; - $this->enabled = $data['enabled']; - $this->username = $data['username']; - $this->address = $data['address']; - $this->displayName = $data['display_name'] ?? null; - - if(is_string($data['flags'])) + /** + * Retrieves the UUID of the object. + * + * @return string The UUID of the object. + */ + public function getUuid(): string { - $this->flags = PeerFlags::fromString($data['flags']); - } - elseif(is_array($data['flags'])) - { - $this->flags = $data['flags']; - } - else - { - $this->flags = []; + return $this->uuid; } - if($data['created'] instanceof DateTime) + public function isEnabled(): bool { - $this->created = $data['created']->getTimestamp(); - } - else - { - $this->created = $data['created']; + return $this->enabled; } - return; - } - - /** - * Retrieves the UUID of the object. - * - * @return string The UUID of the object. - */ - public function getUuid(): string - { - return $this->uuid; - } - - public function isEnabled(): bool - { - return $this->enabled; - } - - /** - * - * @return string The username of the user. - */ - public function getUsername(): string - { - return $this->username; - } - - public function getAddress(): string - { - return $this->address; - } - - /** - * - * @return string|null The display name. - */ - public function getDisplayName(): ?string - { - return $this->displayName; - } - - /** - * - * @return array - */ - public function getFlags(): array - { - return $this->flags; - } - - /** - * - * @return int The timestamp when the object was created. - */ - public function getCreated(): int - { - return $this->created; - } - - /** - * @inheritDoc - */ - public static function fromArray(array $data): SelfUser - { - return new self($data); - } - - /** - * @inheritDoc - */ - public function toArray(): array - { - $flags = []; - foreach($this->flags as $flag) + /** + * + * @return string The username of the user. + */ + public function getUsername(): string { - $flags[] = $flag->value; + return $this->username; } - return [ - 'uuid' => $this->uuid, - 'enabled' => $this->enabled, - 'username' => $this->username, - 'address' => $this->address, - 'display_name' => $this->displayName, - 'flags' => $flags, - 'created' => $this->created - ]; - } -} \ No newline at end of file + public function getAddress(): string + { + return $this->address; + } + + /** + * + * @return string|null The display name. + */ + public function getDisplayName(): ?string + { + return $this->displayName; + } + + /** + * + * @return array + */ + public function getFlags(): array + { + return $this->flags; + } + + /** + * + * @return int The timestamp when the object was created. + */ + public function getRegistered(): int + { + return $this->registered; + } + + /** + * @inheritDoc + */ + public static function fromArray(array $data): SelfUser + { + return new self($data); + } + + /** + * @inheritDoc + */ + public function toArray(): array + { + $flags = []; + foreach($this->flags as $flag) + { + $flags[] = $flag->value; + } + + return [ + 'uuid' => $this->uuid, + 'enabled' => $this->enabled, + 'username' => $this->username, + 'address' => $this->address, + 'display_name' => $this->displayName, + 'flags' => $flags, + 'created' => $this->registered + ]; + } + } \ No newline at end of file diff --git a/src/Socialbox/Socialbox.php b/src/Socialbox/Socialbox.php index e5dc7ea..77754ad 100644 --- a/src/Socialbox/Socialbox.php +++ b/src/Socialbox/Socialbox.php @@ -891,41 +891,53 @@ } catch(DatabaseOperationException $e) { - throw new StandardRpcException('Failed to resolve the peer: ' . $e->getMessage(), StandardError::INTERNAL_SERVER_ERROR, $e); + throw new StandardRpcException('Failed to resolve the peer due to an internal server error', StandardError::INTERNAL_SERVER_ERROR, $e); } if($existingPeer === null) { // if the peer doesn't exist, resolve it externally and synchronize it - try { $peer = self::getExternalSession($peerAddress->getDomain())->resolvePeer($peerAddress, $identifiedAs); } + catch(RpcException $e) + { + throw StandardRpcException::fromRpcException($e); + } catch(Exception $e) { throw new StandardRpcException('Failed to resolve the peer: ' . $e->getMessage(), StandardError::RESOLUTION_FAILED, $e); } - try + // Do not synchronize if this is a personal request, there may be information fields that + // the peer does not want to share with the server + if($identifiedAs !== null) { - RegisteredPeerManager::synchronizeExternalPeer($peer); - } - catch(DatabaseOperationException $e) - { - throw new StandardRpcException('Failed to synchronize the external peer: ' . $e->getMessage(), StandardError::INTERNAL_SERVER_ERROR, $e); + try + { + RegisteredPeerManager::synchronizeExternalPeer($peer); + } + catch(DatabaseOperationException $e) + { + throw new StandardRpcException('Failed to synchronize the external peer due to an internal server error', StandardError::INTERNAL_SERVER_ERROR, $e); + } } return $peer; } - // If the peer exists, but it's outdated, synchronize it - if($existingPeer->getUpdated()->getTimestamp() < time() - Configuration::getPoliciesConfiguration()->getPeerSyncInterval()) + // if we're not identifying as a personal peer and If the peer exists, but it's outdated, synchronize it + if($identifiedAs === null && $existingPeer->getUpdated()->getTimestamp() < time() - Configuration::getPoliciesConfiguration()->getPeerSyncInterval()) { try { $peer = self::getExternalSession($peerAddress->getDomain())->resolvePeer($peerAddress, $identifiedAs); } + catch(RpcException $e) + { + throw StandardRpcException::fromRpcException($e); + } catch(Exception $e) { throw new StandardRpcException('Failed to resolve the peer: ' . $e->getMessage(), StandardError::RESOLUTION_FAILED, $e); @@ -937,14 +949,28 @@ } catch(DatabaseOperationException $e) { - throw new StandardRpcException('Failed to synchronize the external peer: ' . $e->getMessage(), StandardError::INTERNAL_SERVER_ERROR, $e); + throw new StandardRpcException('Failed to synchronize the external peer due to an internal server error', StandardError::INTERNAL_SERVER_ERROR, $e); } return $peer; } - // If the peer exists and is up to date, return it - return $existingPeer->toStandardPeer(); + // If the peer exists and is up to date, return it from our local database instead. (Quicker) + try + { + $informationFields = PeerInformationManager::getFields($existingPeer); + } + catch(DatabaseOperationException $e) + { + throw new StandardRpcException('Failed to obtain local information fields about an external peer locally due to an internal server error', StandardError::INTERNAL_SERVER_ERROR, $e); + } + + return new Peer([ + 'address' => $existingPeer->getAddress(), + 'information_fields' => $informationFields, + 'flags' => $existingPeer->getFlags(), + 'registered' => $existingPeer->getCreated()->getTimestamp() + ]); } /**