Add new classes and methods for session management
This commit is contained in:
parent
b9c84aeb27
commit
764ec51fa4
12 changed files with 1026 additions and 28 deletions
96
src/Socialbox/Objects/PeerAddress.php
Normal file
96
src/Socialbox/Objects/PeerAddress.php
Normal file
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
namespace Socialbox\Objects;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Socialbox\Classes\Validator;
|
||||
use Socialbox\Enums\ReservedUsernames;
|
||||
|
||||
class PeerAddress
|
||||
{
|
||||
private string $username;
|
||||
private string $domain;
|
||||
|
||||
/**
|
||||
* Constructs a PeerAddress object from a given username and domain
|
||||
*
|
||||
* @param string $username The username of the peer
|
||||
* @param string $domain The domain of the peer
|
||||
*/
|
||||
public function __construct(string $username, string $domain)
|
||||
{
|
||||
$this->username = $username;
|
||||
$this->domain = $domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a PeerAddress from a full peer address (eg; john@example.com)
|
||||
*
|
||||
* @param string $address The full address of the peer
|
||||
* @return PeerAddress The constructed PeerAddress object
|
||||
*/
|
||||
public static function fromAddress(string $address): PeerAddress
|
||||
{
|
||||
if(!Validator::validatePeerAddress($address))
|
||||
{
|
||||
throw new InvalidArgumentException("Invalid peer address: $address");
|
||||
}
|
||||
|
||||
$parts = explode('@', $address);
|
||||
return new PeerAddress($parts[0], $parts[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the username of the peer
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUsername(): string
|
||||
{
|
||||
return $this->username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the domain of the peer
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDomain(): string
|
||||
{
|
||||
return $this->domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the peer is the host
|
||||
*
|
||||
* @return bool True if the peer is the host, false otherwise
|
||||
*/
|
||||
public function isHost(): bool
|
||||
{
|
||||
return $this->username === ReservedUsernames::HOST->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the peer requires authentication, for example, the anonymous user does not require authentication
|
||||
*
|
||||
* @return bool True if authentication is required, false otherwise
|
||||
*/
|
||||
public function authenticationRequired(): bool
|
||||
{
|
||||
return match($this->username)
|
||||
{
|
||||
ReservedUsernames::ANONYMOUS->value => false,
|
||||
default => true
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full address of the peer
|
||||
*
|
||||
* @return string The full address of the peer
|
||||
*/
|
||||
public function getAddress(): string
|
||||
{
|
||||
return sprintf("%s@%s", $this->username, $this->domain);
|
||||
}
|
||||
}
|
|
@ -2,26 +2,27 @@
|
|||
|
||||
namespace Socialbox\Objects;
|
||||
|
||||
use Socialbox\Enums\StandardError;
|
||||
use Socialbox\Interfaces\SerializableInterface;
|
||||
|
||||
class RpcError implements SerializableInterface
|
||||
{
|
||||
private string $id;
|
||||
private string $error;
|
||||
private int $code;
|
||||
private string $message;
|
||||
private StandardError $code;
|
||||
|
||||
/**
|
||||
* Constructs the RPC error object.
|
||||
*
|
||||
* @param string $id The ID of the RPC request
|
||||
* @param string $error The error message
|
||||
* @param int $code The error code
|
||||
* @param StandardError $error The error code
|
||||
* @param string $message The error message
|
||||
*/
|
||||
public function __construct(string $id, string $error, int $code)
|
||||
public function __construct(string $id, StandardError $error, string $message)
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->error = $error;
|
||||
$this->code = $code;
|
||||
$this->code = $error;
|
||||
$this->message = $message;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -39,17 +40,17 @@ class RpcError implements SerializableInterface
|
|||
*
|
||||
* @return string The error message.
|
||||
*/
|
||||
public function getError(): string
|
||||
public function getMessage(): string
|
||||
{
|
||||
return $this->error;
|
||||
return $this->message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the error code.
|
||||
*
|
||||
* @return int The error code.
|
||||
* @return StandardError The error code.
|
||||
*/
|
||||
public function getCode(): int
|
||||
public function getCode(): StandardError
|
||||
{
|
||||
return $this->code;
|
||||
}
|
||||
|
@ -63,8 +64,8 @@ class RpcError implements SerializableInterface
|
|||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'error' => $this->error,
|
||||
'code' => $this->code
|
||||
'error' => $this->message,
|
||||
'code' => $this->code->value
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -76,6 +77,13 @@ class RpcError implements SerializableInterface
|
|||
*/
|
||||
public static function fromArray(array $data): RpcError
|
||||
{
|
||||
return new RpcError($data['id'], $data['error'], $data['code']);
|
||||
$errorCode = StandardError::tryFrom($data['code']);
|
||||
|
||||
if($errorCode == null)
|
||||
{
|
||||
$errorCode = StandardError::UNKNOWN;
|
||||
}
|
||||
|
||||
return new RpcError($data['id'], $data['error'], $errorCode);
|
||||
}
|
||||
}
|
|
@ -2,6 +2,11 @@
|
|||
|
||||
namespace Socialbox\Objects;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use ncc\ThirdParty\nikic\PhpParser\Node\Expr\BinaryOp\BooleanOr;
|
||||
use Socialbox\Enums\StandardError;
|
||||
use Socialbox\Exceptions\RpcException;
|
||||
use Socialbox\Exceptions\StandardException;
|
||||
use Socialbox\Interfaces\SerializableInterface;
|
||||
|
||||
class RpcRequest implements SerializableInterface
|
||||
|
@ -13,13 +18,15 @@ class RpcRequest implements SerializableInterface
|
|||
/**
|
||||
* Constructs the object from an array of data.
|
||||
*
|
||||
* @param array $data The data to construct the object from.
|
||||
* @param string $method The method of the request.
|
||||
* @param string|null $id The ID of the request.
|
||||
* @param array|null $parameters The parameters of the request.
|
||||
*/
|
||||
public function __construct(array $data)
|
||||
public function __construct(string $method, ?string $id, ?array $parameters)
|
||||
{
|
||||
$this->id = $data['id'] ?? null;
|
||||
$this->method = $data['method'];
|
||||
$this->parameters = $data['parameters'] ?? null;
|
||||
$this->method = $method;
|
||||
$this->parameters = $parameters;
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -45,13 +52,106 @@ class RpcRequest implements SerializableInterface
|
|||
/**
|
||||
* Returns the parameters of the request.
|
||||
*
|
||||
* @return array|null The parameters of the request.
|
||||
* @return array|null The parameters of the request, null if the request is a notification.
|
||||
*/
|
||||
public function getParameters(): ?array
|
||||
{
|
||||
return $this->parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the parameter exists within the RPC request
|
||||
*
|
||||
* @param string $parameter The parameter to check
|
||||
* @return bool True if the parameter exists, False otherwise.
|
||||
*/
|
||||
public function containsParameter(string $parameter): bool
|
||||
{
|
||||
return isset($this->parameters[$parameter]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parameter value from the RPC request
|
||||
*
|
||||
* @param string $parameter The parameter name to get
|
||||
* @return mixed The parameter value, null if the parameter value is null or not found.
|
||||
*/
|
||||
public function getParameter(string $parameter): mixed
|
||||
{
|
||||
if(!$this->containsParameter($parameter))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->parameters[$parameter];
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces a response based off the request, null if the request is a notification
|
||||
*
|
||||
* @param mixed|null $result
|
||||
* @return RpcResponse|null
|
||||
*/
|
||||
public function produceResponse(mixed $result=null): ?RpcResponse
|
||||
{
|
||||
if($this->id == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
$valid = false;
|
||||
if(is_array($result))
|
||||
{
|
||||
$valid = true;
|
||||
}
|
||||
elseif($result instanceof SerializableInterface)
|
||||
{
|
||||
$valid = true;
|
||||
}
|
||||
elseif(is_null($result))
|
||||
{
|
||||
$valid = true;
|
||||
}
|
||||
|
||||
if(!$valid)
|
||||
{
|
||||
throw new InvalidArgumentException('The \'$result\' property must either be array, null or SerializableInterface');
|
||||
}
|
||||
|
||||
return new RpcResponse($this->id, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces an error response based off the request, null if the request is a notification
|
||||
*
|
||||
* @param StandardError $error
|
||||
* @param string|null $message
|
||||
* @return RpcError|null
|
||||
*/
|
||||
public function produceError(StandardError $error, ?string $message=null): ?RpcError
|
||||
{
|
||||
if($this->id == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if($message == null)
|
||||
{
|
||||
$message = $error->getMessage();
|
||||
}
|
||||
|
||||
return new RpcError($this->id, $error, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param StandardException $e
|
||||
* @return RpcError|null
|
||||
*/
|
||||
public function handleStandardException(StandardException $e): ?RpcError
|
||||
{
|
||||
return $this->produceError($e->getStandardError(), $e->getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array representation of the object.
|
||||
*
|
||||
|
@ -74,6 +174,6 @@ class RpcRequest implements SerializableInterface
|
|||
*/
|
||||
public static function fromArray(array $data): RpcRequest
|
||||
{
|
||||
return static($data);
|
||||
return new RpcRequest($data['method'], $data['id'] ?? null, $data['parameters'] ?? null);
|
||||
}
|
||||
}
|
|
@ -7,15 +7,15 @@ use Socialbox\Interfaces\SerializableInterface;
|
|||
class RpcResponse implements SerializableInterface
|
||||
{
|
||||
private string $id;
|
||||
private ?object $result;
|
||||
private mixed $result;
|
||||
|
||||
/**
|
||||
* Constructs the response object.
|
||||
*
|
||||
* @param string $id The ID of the response.
|
||||
* @param object|null $result The result of the response.
|
||||
* @param mixed|null $result The result of the response.
|
||||
*/
|
||||
public function __construct(string $id, ?object $result)
|
||||
public function __construct(string $id, mixed $result)
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->result = $result;
|
||||
|
@ -34,13 +34,37 @@ class RpcResponse implements SerializableInterface
|
|||
/**
|
||||
* Returns the result of the response.
|
||||
*
|
||||
* @return object|null The result of the response.
|
||||
* @return mixed|null The result of the response.
|
||||
*/
|
||||
public function getResult(): ?object
|
||||
public function getResult(): mixed
|
||||
{
|
||||
return $this->result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given data to an array.
|
||||
*
|
||||
* @param mixed $data The data to be converted. This can be an instance of SerializableInterface, an array, or a scalar value.
|
||||
* @return mixed The converted data as an array if applicable, or the original data.
|
||||
*/
|
||||
private function convertToArray(mixed $data): mixed
|
||||
{
|
||||
// If the data is an instance of SerializableInterface, call toArray on it
|
||||
if ($data instanceof SerializableInterface)
|
||||
{
|
||||
return $data->toArray();
|
||||
}
|
||||
|
||||
// If the data is an array, recursively apply this method to each element
|
||||
if (is_array($data))
|
||||
{
|
||||
return array_map([$this, 'convertToArray'], $data);
|
||||
}
|
||||
|
||||
// Otherwise, return the data as-is (e.g., for scalar values)
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array representation of the object.
|
||||
*
|
||||
|
@ -50,7 +74,7 @@ class RpcResponse implements SerializableInterface
|
|||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'result' => $this->result->toArray()
|
||||
'result' => $this->convertToArray($this->result)
|
||||
];
|
||||
}
|
||||
|
||||
|
|
82
src/Socialbox/Objects/SessionRecord.php
Normal file
82
src/Socialbox/Objects/SessionRecord.php
Normal file
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
namespace Socialbox\Objects;
|
||||
|
||||
use DateTime;
|
||||
use Socialbox\Enums\SessionState;
|
||||
use Socialbox\Interfaces\SerializableInterface;
|
||||
|
||||
class SessionRecord implements SerializableInterface
|
||||
{
|
||||
private string $uuid;
|
||||
private ?string $authenticatedPeerUuid;
|
||||
private string $publicKey;
|
||||
private SessionState $state;
|
||||
private DateTime $created;
|
||||
private DateTime $lastRequest;
|
||||
|
||||
public function __construct(array $data)
|
||||
{
|
||||
$this->uuid = $data['uuid'];
|
||||
$this->authenticatedPeerUuid = $data['authenticated_peer_uuid'] ?? null;
|
||||
$this->publicKey = $data['public_key'];
|
||||
$this->created = $data['created'];
|
||||
$this->lastRequest = $data['last_request'];
|
||||
|
||||
if(SessionState::tryFrom($data['state']) == null)
|
||||
{
|
||||
$this->state = SessionState::CLOSED;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = SessionState::from($data['state']);
|
||||
}
|
||||
}
|
||||
|
||||
public function getUuid(): string
|
||||
{
|
||||
return $this->uuid;
|
||||
}
|
||||
|
||||
public function getAuthenticatedPeerUuid(): ?string
|
||||
{
|
||||
return $this->authenticatedPeerUuid;
|
||||
}
|
||||
|
||||
public function getPublicKey(): string
|
||||
{
|
||||
return $this->publicKey;
|
||||
}
|
||||
|
||||
public function getState(): SessionState
|
||||
{
|
||||
return $this->state;
|
||||
}
|
||||
|
||||
public function getCreated(): int
|
||||
{
|
||||
return $this->created;
|
||||
}
|
||||
|
||||
public function getLastRequest(): int
|
||||
{
|
||||
return $this->lastRequest;
|
||||
}
|
||||
|
||||
public static function fromArray(array $data): object
|
||||
{
|
||||
return new self($data);
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'uuid' => $this->uuid,
|
||||
'authenticated_peer_uuid' => $this->authenticatedPeerUuid,
|
||||
'public_key' => $this->publicKey,
|
||||
'state' => $this->state->value,
|
||||
'created' => $this->created,
|
||||
'last_request' => $this->lastRequest,
|
||||
];
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue