Compare commits

...

10 commits

Author SHA1 Message Date
947064a386
Add unit tests for SocialClient registration and validation
Some checks are pending
CI / release (push) Waiting to run
CI / debug (push) Waiting to run
CI / release_executable (push) Waiting to run
CI / debug_executable (push) Waiting to run
CI / check-phpunit (push) Waiting to run
CI / check-phpdoc (push) Waiting to run
CI / generate-phpdoc (push) Blocked by required conditions
CI / test (push) Blocked by required conditions
CI / release-documentation (push) Blocked by required conditions
CI / release-artifacts (push) Blocked by required conditions
2025-03-20 13:05:16 -04:00
49f400acdb
Add unit tests for AddressBook functionality 2025-03-20 13:05:11 -04:00
3935980146
Refactor getSelf method to instantiate Peer directly from sendRequest response 2025-03-20 13:05:07 -04:00
a7da38d5f9
Change flags property type from SessionFlags[] to string[] in SessionState 2025-03-20 13:05:01 -04:00
491345f310
Update default privacy settings to PUBLIC for first, middle, and last name 2025-03-20 13:04:48 -04:00
2d103cac13
Add random generation utilities to Helper class 2025-03-20 13:04:37 -04:00
0883f55328
Handle potential null values for signing keys and encryption channel secrets in ExportedSession 2025-03-20 13:04:28 -04:00
ef463a132d
Refactor ContactManager to accept PeerDatabaseRecord in place of string for peer UUID 2025-03-20 13:04:17 -04:00
a92391445a
Refactor PeerDatabaseRecord and SessionManager to handle ReservedUsernames and improve date handling 2025-03-19 15:06:59 -04:00
6a1aa6b353
Set default value for privacy parameter in settingsAddInformationField method 2025-03-19 14:00:05 -04:00
12 changed files with 780 additions and 47 deletions

View file

@ -15,6 +15,7 @@
use Socialbox\Exceptions\DatabaseOperationException;
use Socialbox\Objects\Database\ContactDatabaseRecord;
use Socialbox\Objects\Database\ContactKnownKeyRecord;
use Socialbox\Objects\Database\PeerDatabaseRecord;
use Socialbox\Objects\PeerAddress;
use Socialbox\Objects\Standard\Contact;
use Socialbox\Objects\Standard\Signature;
@ -24,13 +25,18 @@
/**
* Determines if a given contact address is associated with a specified peer UUID in the database.
*
* @param string $peerUuid The unique identifier of the peer.
* @param string|PeerDatabaseRecord $peerUuid The unique identifier of the peer.
* @param string|PeerAddress $contactAddress The contact's address, either as a string or a PeerAddress instance.
* @return bool Returns true if the contact exists in the database; otherwise, returns false.
* @throws DatabaseOperationException If the operation fails.
*/
public static function isContact(string $peerUuid, string|PeerAddress $contactAddress): bool
public static function isContact(string|PeerDatabaseRecord $peerUuid, string|PeerAddress $contactAddress): bool
{
if($peerUuid instanceof PeerDatabaseRecord)
{
$peerUuid = $peerUuid->getUuid();
}
if($contactAddress instanceof PeerAddress)
{
$contactAddress = $contactAddress->getAddress();
@ -65,14 +71,19 @@
* Creates a new contact associated with the given peer UUID and contact address
* in the database, with a specified relationship type.
*
* @param string $peerUuid The unique identifier of the peer.
* @param string|PeerDatabaseRecord $peerUuid The unique identifier of the peer.
* @param string|PeerAddress $contactAddress The contact's address, either as a string or a PeerAddress instance.
* @param ContactRelationshipType $relationship The type of relationship between the peer and the contact. Defaults to ContactRelationshipType::MUTUAL.
* @return string The UUID of the newly created contact.
* @throws DatabaseOperationException If the operation fails.
*/
public static function createContact(string $peerUuid, string|PeerAddress $contactAddress, ContactRelationshipType $relationship=ContactRelationshipType::MUTUAL): string
public static function createContact(string|PeerDatabaseRecord $peerUuid, string|PeerAddress $contactAddress, ContactRelationshipType $relationship=ContactRelationshipType::MUTUAL): string
{
if($peerUuid instanceof PeerDatabaseRecord)
{
$peerUuid = $peerUuid->getUuid();
}
if($contactAddress instanceof PeerAddress)
{
$contactAddress = $contactAddress->getAddress();
@ -111,12 +122,17 @@
/**
* Retrieves the total number of contacts associated with a specific peer.
*
* @param string $peerUuid The unique identifier for the peer whose contact count is to be retrieved.
* @param string|PeerDatabaseRecord $peerUuid The unique identifier for the peer whose contact count is to be retrieved.
* @return int The total number of contacts for the given peer.
* @throws DatabaseOperationException If the database query fails.
*/
public static function getContactCount(string $peerUuid): int
public static function getContactCount(string|PeerDatabaseRecord $peerUuid): int
{
if($peerUuid instanceof PeerDatabaseRecord)
{
$peerUuid = $peerUuid->getUuid();
}
try
{
// Get the contact count from the database
@ -134,13 +150,18 @@
/**
* Retrieves a specific contact associated with a peer based on the contact's address.
*
* @param string $peerUuid The unique identifier for the peer whose contact is to be retrieved.
* @param string|PeerDatabaseRecord $peerUuid The unique identifier for the peer whose contact is to be retrieved.
* @param string|PeerAddress $contactAddress The address of the contact, either as a string or a PeerAddress object.
* @return ContactDatabaseRecord|null The retrieved ContactRecord instance if found, or null if no matching contact exists.
* @throws DatabaseOperationException If the database query fails.
*/
public static function getContact(string $peerUuid, string|PeerAddress $contactAddress): ?ContactDatabaseRecord
public static function getContact(string|PeerDatabaseRecord $peerUuid, string|PeerAddress $contactAddress): ?ContactDatabaseRecord
{
if($peerUuid instanceof PeerDatabaseRecord)
{
$peerUuid = $peerUuid->getUuid();
}
if($contactAddress instanceof PeerAddress)
{
$contactAddress = $contactAddress->getAddress();
@ -180,13 +201,18 @@
/**
* Deletes a specific contact associated with a given peer.
*
* @param string $peerUuid The unique identifier for the peer whose contact is to be deleted.
* @param string|PeerDatabaseRecord $peerUuid The unique identifier for the peer whose contact is to be deleted.
* @param string|PeerAddress $contactAddress The address of the contact to be deleted. Can be provided as a string or a PeerAddress instance.
* @return void
* @throws DatabaseOperationException If the database query fails.
*/
public static function deleteContact(string $peerUuid, string|PeerAddress $contactAddress): void
public static function deleteContact(string|PeerDatabaseRecord $peerUuid, string|PeerAddress $contactAddress): void
{
if($peerUuid instanceof PeerDatabaseRecord)
{
$peerUuid = $peerUuid->getUuid();
}
if($contactAddress instanceof PeerAddress)
{
$contactAddress = $contactAddress->getAddress();
@ -217,14 +243,19 @@
/**
* Updates the relationship type of contact associated with a specific peer.
*
* @param string $peerUuid The unique identifier for the peer whose contact relationship is to be updated.
* @param string|PeerDatabaseRecord $peerUuid The unique identifier for the peer whose contact relationship is to be updated.
* @param string|PeerAddress $contactAddress The address of the contact to update. Can be provided as a string or an instance of PeerAddress.
* @param ContactRelationshipType $relationship The new relationship type to assign to the contact.
* @return void
* @throws DatabaseOperationException If the database query fails.
*/
public static function updateContactRelationship(string $peerUuid, string|PeerAddress $contactAddress, ContactRelationshipType $relationship): void
public static function updateContactRelationship(string|PeerDatabaseRecord $peerUuid, string|PeerAddress $contactAddress, ContactRelationshipType $relationship): void
{
if($peerUuid instanceof PeerDatabaseRecord)
{
$peerUuid = $peerUuid->getUuid();
}
if($contactAddress instanceof PeerAddress)
{
$contactAddress = $contactAddress->getAddress();
@ -257,17 +288,22 @@
/**
* Retrieves a contact by its unique identifier.
*
* @param string $uuid The unique identifier of the contact to retrieve.
* @param string|ContactDatabaseRecord $contactUuid The unique identifier of the contact to retrieve.
* @return ContactDatabaseRecord|null A ContactRecord instance if the contact is found, or null if no contact exists with the provided UUID.
* @throws DatabaseOperationException If the database query fails.
*/
public static function getContactByUuid(string $uuid): ?ContactDatabaseRecord
public static function getContactByUuid(string|ContactDatabaseRecord $contactUuid): ?ContactDatabaseRecord
{
if($contactUuid instanceof ContactDatabaseRecord)
{
$contactUuid = $contactUuid->getUuid();
}
try
{
// Get the contact from the database
$statement = Database::getConnection()->prepare('SELECT * FROM contacts WHERE uuid=:uuid LIMIT 1');
$statement->bindParam(':uuid', $uuid);
$statement->bindParam(':uuid', $contactUuid);
$statement->execute();
$result = $statement->fetch();
}
@ -287,14 +323,19 @@
/**
* Retrieves a list of contacts associated with a specific peer.
*
* @param string $peerUuid The unique identifier for the peer whose contacts are to be retrieved.
* @param string|PeerDatabaseRecord $peerUuid The unique identifier for the peer whose contacts are to be retrieved.
* @param int $limit The maximum number of contacts to retrieve per page. Defaults to 100.
* @param int $page The page number to retrieve. Defaults to 1.
* @return ContactDatabaseRecord[] An array of ContactRecord instances representing the contacts for the given peer.
* @throws DatabaseOperationException If the database query fails.
*/
public static function getContacts(string $peerUuid, int $limit=100, int $page=1): array
public static function getContacts(string|PeerDatabaseRecord $peerUuid, int $limit=100, int $page=1): array
{
if($peerUuid instanceof PeerDatabaseRecord)
{
$peerUuid = $peerUuid->getUuid();
}
if ($page < 1)
{
$page = 1;
@ -335,14 +376,19 @@
/**
* Retrieves a list of standard contacts associated with a specific peer.
*
* @param string $peerUuid The unique identifier for the peer whose contacts are to be retrieved.
* @param string|PeerDatabaseRecord $peerUuid The unique identifier for the peer whose contacts are to be retrieved.
* @param int $limit The maximum number of contacts to retrieve per page. Defaults to 100.
* @param int $page The page number to retrieve. Defaults to 1.
* @return Contact[] An array of ContactRecord instances representing the contacts for the given peer.
* @throws DatabaseOperationException If the database query fails.
*/
public static function getStandardContacts(string $peerUuid, int $limit=100, int $page=1): array
public static function getStandardContacts(string|PeerDatabaseRecord $peerUuid, int $limit=100, int $page=1): array
{
if($peerUuid instanceof PeerDatabaseRecord)
{
$peerUuid = $peerUuid->getUuid();
}
if ($page < 1)
{
throw new InvalidArgumentException('The page number cannot be less than 1');
@ -663,13 +709,18 @@
/**
* Returns a standard contact record for a given peer UUID and contact address.
*
* @param string $peerUuid The unique identifier of the peer.
* @param string|PeerDatabaseRecord $peerUuid The unique identifier of the peer.
* @param string|PeerAddress $contactAddress The contact's address, either as a string or a PeerAddress instance.
* @return Contact|null The standard contact record if found, or null if no matching contact exists.
* @throws DatabaseOperationException If the database query fails.
*/
public static function getStandardContact(string $peerUuid, string|PeerAddress $contactAddress): ?Contact
public static function getStandardContact(string|PeerDatabaseRecord $peerUuid, string|PeerAddress $contactAddress): ?Contact
{
if($peerUuid instanceof PeerDatabaseRecord)
{
$peerUuid = $peerUuid->getUuid();
}
$contact = self::getContact($peerUuid, $contactAddress);
if($contact === null)
{

View file

@ -54,13 +54,14 @@
// TODO: Update this to support `host` peers
if($peer->isExternal())
{
Logger::getLogger()->debug('Creating a session for an external peer');
$flags[] = SessionFlags::AUTHENTICATION_REQUIRED;
$flags[] = SessionFlags::VER_AUTHENTICATION;
}
else if($peer->isEnabled())
{
Logger::getLogger()->debug('Creating a session for an enabled peer');
$flags[] = SessionFlags::AUTHENTICATION_REQUIRED;
if(PasswordManager::usesPassword($peer->getUuid()))
{
$flags[] = SessionFlags::VER_PASSWORD;
@ -73,6 +74,7 @@
}
else
{
Logger::getLogger()->debug('Creating a session for a disabled peer');
$flags[] = SessionFlags::REGISTRATION_REQUIRED;
if(Configuration::getRegistrationConfiguration()->isDisplayNameRequired())

View file

@ -65,8 +65,8 @@
$this->clientTransportEncryptionKey = $data['client_transport_encryption_key'];
$this->serverTransportEncryptionKey = $data['server_transport_encryption_key'];
$this->defaultSigningKey = $data['default_signing_key'] ?? null;
$this->signingKeys = array_map(fn($key) => SignatureKeyPair::fromArray($key), $data['signing_keys']);
$this->encryptionChannelSecrets = array_map(fn($key) => EncryptionChannelSecret::fromArray($key), $data['encryption_channel_secrets']);
$this->signingKeys = array_map(fn($key) => SignatureKeyPair::fromArray($key), $data['signing_keys'] ?? []);
$this->encryptionChannelSecrets = array_map(fn($key) => EncryptionChannelSecret::fromArray($key), $data['encryption_channel_secrets'] ?? []);
}
/**

View file

@ -6,6 +6,7 @@
use InvalidArgumentException;
use Socialbox\Classes\Configuration;
use Socialbox\Enums\Flags\PeerFlags;
use Socialbox\Enums\ReservedUsernames;
use Socialbox\Interfaces\SerializableInterface;
use Socialbox\Objects\Standard\InformationFieldState;
use Socialbox\Objects\Standard\Peer;
@ -32,7 +33,15 @@
{
$this->uuid = $data['uuid'];
$this->username = $data['username'];
$this->server = $data['server'];
if($data['server'] === ReservedUsernames::HOST->value)
{
$this->server = Configuration::getInstanceConfiguration()->getDomain();
}
else
{
$this->server = $data['server'];
}
if($data['flags'])
{
@ -55,7 +64,14 @@
}
elseif(is_string($data['created']))
{
$this->created = new DateTime($data['created']);
try
{
$this->created = new DateTime($data['created']);
}
catch (\DateMalformedStringException $e)
{
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
}
else
{
@ -72,7 +88,14 @@
}
elseif(is_string($data['updated']))
{
$this->updated = new DateTime($data['updated']);
try
{
$this->updated = new DateTime($data['updated']);
}
catch (\DateMalformedStringException $e)
{
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
}
else
{
@ -192,7 +215,7 @@
*/
public function isExternal(): bool
{
return $this->username === 'host' || $this->server !== Configuration::getInstanceConfiguration()->getDomain();
return $this->username === ReservedUsernames::HOST->value || $this->server !== Configuration::getInstanceConfiguration()->getDomain();
}
/**

View file

@ -14,7 +14,7 @@
private string $identifiedAs;
private bool $authenticated;
/**
* @var SessionFlags[]|null
* @var string[]|null
*/
private ?array $flags;
private int $created;

View file

@ -398,9 +398,9 @@
*/
public function getSelf(): Peer
{
return $this->sendRequest(
return new Peer($this->sendRequest(
new RpcRequest(StandardMethods::GET_SELF)
)->getResponse()->getResult();
)->getResponse()->getResult());
}
/**
@ -938,7 +938,7 @@
* @return bool Returns True if the field was added
* @throws RpcException Thrown if there was an error with the RPC request
*/
public function settingsAddInformationField(InformationFieldName|string $field, string $value, null|PrivacyState|string $privacy): bool
public function settingsAddInformationField(InformationFieldName|string $field, string $value, null|PrivacyState|string $privacy=null): bool
{
if($field instanceof InformationFieldName)
{

View file

@ -251,15 +251,11 @@
// If-clause for handling the host peer, host peers are always enabled unless the fist clause is true
// in which case the host was blocked by this server.
if($clientRequest->getIdentifyAs()->getUsername() === ReservedUsernames::HOST->value)
if($clientRequest->getIdentifyAs()->getUsername() === ReservedUsernames::HOST->value && $registeredPeer === null)
{
// If the host is not registered, register it
if($registeredPeer === null)
{
$peerUuid = RegisteredPeerManager::createPeer(PeerAddress::fromAddress($clientRequest->getHeader(StandardHeaders::IDENTIFY_AS)));
RegisteredPeerManager::enablePeer($peerUuid);
$registeredPeer = RegisteredPeerManager::getPeer($peerUuid);
}
$peerUuid = RegisteredPeerManager::createPeer($clientRequest->getIdentifyAs());
RegisteredPeerManager::enablePeer($peerUuid);
$registeredPeer = RegisteredPeerManager::getPeer($peerUuid);
}
if($registeredPeer === null)
@ -272,7 +268,7 @@
}
// Register the peer if it is not already registered
$peerUuid = RegisteredPeerManager::createPeer(PeerAddress::fromAddress($clientRequest->getHeader(StandardHeaders::IDENTIFY_AS)));
$peerUuid = RegisteredPeerManager::createPeer($clientRequest->getIdentifyAs());
// Retrieve the peer object
$registeredPeer = RegisteredPeerManager::getPeer($peerUuid);
}

View file

@ -1,5 +1,12 @@
<?php
use Random\RandomException;
use Socialbox\Exceptions\CryptographyException;
use Socialbox\Exceptions\DatabaseOperationException;
use Socialbox\Exceptions\ResolutionException;
use Socialbox\Exceptions\RpcException;
use Socialbox\SocialClient;
class Helper
{
/**
@ -23,4 +30,80 @@
return sprintf('%s%s@%s', $prefix, $randomString, $domain);
}
/**
* Generates a random string.
*
* @param int $length The length of the random string.
* @return string Returns a randomly generated string.
*/
public static function generateRandomString(int $length=16): string
{
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++)
{
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
/**
* Generates a random number.
*
* @param int $length The length of the random number.
* @return int Returns a randomly generated number.
*/
public static function generateRandomNumber(int $length=16): int
{
$characters = '0123456789';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++)
{
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return (int)$randomString;
}
/**
* Generates a random string of bytes.
*
* @param int $size The size of the random bytes.
* @return string Returns a randomly generated string of bytes.
* @throws RuntimeException This exception is thrown if there's an issue with the random bytes generation.
*/
public static function gennerateRandomBytes(int $size=32): string
{
try
{
return bin2hex(random_bytes($size));
}
catch (RandomException $e)
{
throw new RuntimeException('Failed to generate random bytes.', 0, $e);
}
}
/**
* Generates a random SocialClient object based on the given domain.
*
* @param string $domain The domain to be appended to the generated username.
* @param int $length The length of the random string.
* @param string $prefix The prefix to be appended to the generated username.
* @return SocialClient Returns a randomly generated SocialClient object.
* @throws CryptographyException This exception is thrown if there's an issue with the cryptography.
* @throws DatabaseOperationException This exception is thrown if there's an issue with the database operation.
* @throws ResolutionException This exception is thrown if there's an issue with the resolution.
* @throws RpcException This exception is thrown if there's an issue with the RPC operation.
*/
public static function generateRandomClient(string $domain, int $length=16, string $prefix='clientTest'): SocialClient
{
return new SocialClient(self::generateRandomPeer($domain, $length, $prefix));
}
}

View file

@ -0,0 +1,39 @@
<?php
namespace Socialbox;
use Helper;
use PHPUnit\Framework\TestCase;
use Socialbox\Enums\Types\InformationFieldName;
use Socialbox\Exceptions\CryptographyException;
use Socialbox\Exceptions\DatabaseOperationException;
use Socialbox\Exceptions\ResolutionException;
use Socialbox\Exceptions\RpcException;
class AddressBookTest extends TestCase
{
/**
* @throws ResolutionException
* @throws RpcException
* @throws CryptographyException
* @throws DatabaseOperationException
*/
public function testAddressBookAdd(): void
{
$johnClient = Helper::generateRandomClient(TEAPOT_DOMAIN, prefix: 'johnAddressBookTest');
$johnClient->settingsAddInformationField(InformationFieldName::DISPLAY_NAME, 'John Doe');
$johnClient->settingsSetPassword('SecretTestingPassword123');
$this->assertTrue($johnClient->getSessionState()->isAuthenticated());
$aliceClient = Helper::generateRandomClient(COFFEE_DOMAIN, prefix: 'aliceAddressBookTest');
$aliceClient->settingsAddInformationField(InformationFieldName::DISPLAY_NAME, 'Alice Smith');
$aliceClient->settingsSetPassword('SecretTestingPassword123');
$this->assertTrue($aliceClient->getSessionState()->isAuthenticated());
$johnClient->addressBookAddContact($aliceClient->getIdentifiedAs());
$this->assertTrue($johnClient->addressBookContactExists($aliceClient->getIdentifiedAs()));
$aliceClient->addressBookAddContact($johnClient->getIdentifiedAs());
$this->assertTrue($aliceClient->addressBookContactExists($johnClient->getIdentifiedAs()));
}
}

View file

@ -0,0 +1,539 @@
<?php
namespace Socialbox;
use Helper;
use PHPUnit\Framework\TestCase;
use Socialbox\Enums\Flags\SessionFlags;
use Socialbox\Enums\Types\InformationFieldName;
use Socialbox\Exceptions\CryptographyException;
use Socialbox\Exceptions\DatabaseOperationException;
use Socialbox\Exceptions\ResolutionException;
use Socialbox\Exceptions\RpcException;
class SocialClientRegistrationTest extends TestCase
{
/**
* @throws CryptographyException
* @throws DatabaseOperationException
* @throws ResolutionException
* @throws RpcException
*/
public function testCreateAccount(): void
{
$rpcClient = Helper::generateRandomClient(COFFEE_DOMAIN, prefix: 'createTest');
$sessionState = $rpcClient->getSessionState();
$this->assertFalse($sessionState->isAuthenticated());
$this->assertTrue($sessionState->containsFlag(SessionFlags::REGISTRATION_REQUIRED));
foreach($rpcClient->getSessionState()->getFlags() as $sessionFlag)
{
if(SessionFlags::tryFrom($sessionFlag) === null)
{
$this->fail('Unknown session flag: ' . $sessionFlag);
}
}
$this->assertTrue($rpcClient->settingsAddInformationField(InformationFieldName::DISPLAY_NAME, 'Test User'));
$this->assertEquals('Test User', $rpcClient->settingsGetInformationField(InformationFieldName::DISPLAY_NAME)->getValue());
$this->assertFalse($rpcClient->getSessionState()->containsFlag(SessionFlags::SET_DISPLAY_NAME));
$this->assertTrue($rpcClient->settingsAddInformationField(InformationFieldName::FIRST_NAME, 'John'));
$this->assertEquals('John', $rpcClient->settingsGetInformationField(InformationFieldName::FIRST_NAME)->getValue());
$this->assertFalse($rpcClient->getSessionState()->containsFlag(SessionFlags::SET_FIRST_NAME));
$this->assertTrue($rpcClient->settingsAddInformationField(InformationFieldName::LAST_NAME, 'Doe'));
$this->assertEquals('Doe', $rpcClient->settingsGetInformationField(InformationFieldName::LAST_NAME)->getValue());
$this->assertFalse($rpcClient->getSessionState()->containsFlag(SessionFlags::SET_LAST_NAME));
$this->assertTrue($rpcClient->settingsAddInformationField(InformationFieldName::EMAIL_ADDRESS, 'johndoe@example.com'));
$this->assertEquals('johndoe@example.com', $rpcClient->settingsGetInformationField(InformationFieldName::EMAIL_ADDRESS)->getValue());
$this->assertFalse($rpcClient->getSessionState()->containsFlag(SessionFlags::SET_EMAIL));
$this->assertTrue($rpcClient->settingsSetPassword('SecuredTestingPassword123'));
$this->assertFalse($rpcClient->getSessionState()->containsFlag(SessionFlags::SET_PASSWORD));
$this->assertTrue($rpcClient->getSessionState()->isAuthenticated());
}
/**
* @throws ResolutionException
* @throws RpcException
* @throws CryptographyException
* @throws DatabaseOperationException
*/
public function testInvalidDisplayName(): void
{
$rpcClient = Helper::generateRandomClient(COFFEE_DOMAIN, prefix: 'malformedInputTest');
try
{
$rpcClient->settingsAddInformationField(InformationFieldName::DISPLAY_NAME, Helper::generateRandomString(2048));
$this->assertFalse($rpcClient->settingsInformationFieldExists(InformationFieldName::DISPLAY_NAME));
}
catch(RpcException $e)
{
$this->assertEquals(-1001, $e->getCode(), sprintf('Unexpected error code: %d', $e->getCode()));
}
try
{
$rpcClient->settingsAddInformationField(InformationFieldName::DISPLAY_NAME, '');
$this->assertFalse($rpcClient->settingsInformationFieldExists(InformationFieldName::DISPLAY_NAME));
}
catch(RpcException $e)
{
$this->assertEquals(-1001, $e->getCode(), sprintf('Unexpected error code: %d', $e->getCode()));
}
}
/**
* @throws RpcException
* @throws ResolutionException
* @throws CryptographyException
* @throws DatabaseOperationException
*/
public function testValidDisplayName(): void
{
$rpcClient = Helper::generateRandomClient(COFFEE_DOMAIN, prefix: 'validInputTest');
$displayName = Helper::generateRandomString(32);
$rpcClient->settingsAddInformationField(InformationFieldName::DISPLAY_NAME, $displayName);
$this->assertTrue($rpcClient->settingsInformationFieldExists(InformationFieldName::DISPLAY_NAME));
$this->assertEquals($displayName, $rpcClient->settingsGetInformationField(InformationFieldName::DISPLAY_NAME)->getValue());
}
/**
* @throws ResolutionException
* @throws RpcException
* @throws CryptographyException
* @throws DatabaseOperationException
*/
public function testInvalidFirstName(): void
{
$rpcClient = Helper::generateRandomClient(COFFEE_DOMAIN, prefix: 'malformedInputTest');
try
{
$rpcClient->settingsAddInformationField(InformationFieldName::FIRST_NAME, Helper::generateRandomString(2012));
$this->assertFalse($rpcClient->settingsInformationFieldExists(InformationFieldName::FIRST_NAME));
}
catch(RpcException $e)
{
$this->assertEquals(-1001, $e->getCode(), sprintf('Unexpected error code: %d', $e->getCode()));
}
try
{
$rpcClient->settingsAddInformationField(InformationFieldName::FIRST_NAME, '');
$this->assertFalse($rpcClient->settingsInformationFieldExists(InformationFieldName::FIRST_NAME));
}
catch(RpcException $e)
{
$this->assertEquals(-1001, $e->getCode(), sprintf('Unexpected error code: %d', $e->getCode()));
}
}
/**
* @throws RpcException
* @throws ResolutionException
* @throws CryptographyException
* @throws DatabaseOperationException
*/
public function testValidFirstName(): void
{
$rpcClient = Helper::generateRandomClient(COFFEE_DOMAIN, prefix: 'validInputTest');
$firstName = Helper::generateRandomString(32);
$rpcClient->settingsAddInformationField(InformationFieldName::FIRST_NAME, $firstName);
$this->assertTrue($rpcClient->settingsInformationFieldExists(InformationFieldName::FIRST_NAME));
$this->assertEquals($firstName, $rpcClient->settingsGetInformationField(InformationFieldName::FIRST_NAME)->getValue());
}
/**
* @throws ResolutionException
* @throws RpcException
* @throws CryptographyException
* @throws DatabaseOperationException
*/
public function testInvalidMiddleName(): void
{
$rpcClient = Helper::generateRandomClient(COFFEE_DOMAIN, prefix: 'malformedInputTest');
try
{
$rpcClient->settingsAddInformationField(InformationFieldName::MIDDLE_NAME, Helper::generateRandomString(2012));
$this->assertFalse($rpcClient->settingsInformationFieldExists(InformationFieldName::MIDDLE_NAME));
}
catch(RpcException $e)
{
$this->assertEquals(-1001, $e->getCode(), sprintf('Unexpected error code: %d', $e->getCode()));
}
try
{
$rpcClient->settingsAddInformationField(InformationFieldName::MIDDLE_NAME, '');
$this->assertFalse($rpcClient->settingsInformationFieldExists(InformationFieldName::MIDDLE_NAME));
}
catch(RpcException $e)
{
$this->assertEquals(-1001, $e->getCode(), sprintf('Unexpected error code: %d', $e->getCode()));
}
}
/**
* @throws RpcException
* @throws ResolutionException
* @throws CryptographyException
* @throws DatabaseOperationException
*/
public function testValidMiddleName(): void
{
$rpcClient = Helper::generateRandomClient(COFFEE_DOMAIN, prefix: 'validInputTest');
$middleName = Helper::generateRandomString(32);
$rpcClient->settingsAddInformationField(InformationFieldName::MIDDLE_NAME, $middleName);
$this->assertTrue($rpcClient->settingsInformationFieldExists(InformationFieldName::MIDDLE_NAME));
$this->assertEquals($middleName, $rpcClient->settingsGetInformationField(InformationFieldName::MIDDLE_NAME)->getValue());
}
/**
* @throws ResolutionException
* @throws RpcException
* @throws CryptographyException
* @throws DatabaseOperationException
*/
public function testInvalidLastName(): void
{
$rpcClient = Helper::generateRandomClient(COFFEE_DOMAIN, prefix: 'malformedInputTest');
try
{
$rpcClient->settingsAddInformationField(InformationFieldName::LAST_NAME, Helper::generateRandomString(2012));
$this->assertFalse($rpcClient->settingsInformationFieldExists(InformationFieldName::LAST_NAME));
}
catch(RpcException $e)
{
$this->assertEquals(-1001, $e->getCode(), sprintf('Unexpected error code: %d', $e->getCode()));
}
try
{
$rpcClient->settingsAddInformationField(InformationFieldName::LAST_NAME, '');
$this->assertFalse($rpcClient->settingsInformationFieldExists(InformationFieldName::LAST_NAME));
}
catch(RpcException $e)
{
$this->assertEquals(-1001, $e->getCode(), sprintf('Unexpected error code: %d', $e->getCode()));
}
}
/**
* @throws RpcException
* @throws ResolutionException
* @throws CryptographyException
* @throws DatabaseOperationException
*/
public function testValidLastName(): void
{
$rpcClient = Helper::generateRandomClient(COFFEE_DOMAIN, prefix: 'validInputTest');
$lastName = Helper::generateRandomString(32);
$rpcClient->settingsAddInformationField(InformationFieldName::LAST_NAME, $lastName);
$this->assertTrue($rpcClient->settingsInformationFieldExists(InformationFieldName::LAST_NAME));
$this->assertEquals($lastName, $rpcClient->settingsGetInformationField(InformationFieldName::LAST_NAME)->getValue());
}
public function testInvalidPhoneNumber(): void
{
$rpcClient = Helper::generateRandomClient(TEAPOT_DOMAIN, prefix: 'malformedTest');
try
{
$rpcClient->settingsAddInformationField(InformationFieldName::PHONE_NUMBER, Helper::generateRandomString(2048));
$this->assertFalse($rpcClient->settingsInformationFieldExists(InformationFieldName::PHONE_NUMBER));
}
catch(RpcException $e)
{
$this->assertEquals(-1001, $e->getCode(), sprintf('Unexpected error code: %d', $e->getCode()));
}
try
{
$rpcClient->settingsAddInformationField(InformationFieldName::PHONE_NUMBER, Helper::generateRandomNumber(152));
$this->assertFalse($rpcClient->settingsInformationFieldExists(InformationFieldName::PHONE_NUMBER));
}
catch(RpcException $e)
{
$this->assertEquals(-1001, $e->getCode(), sprintf('Unexpected error code: %d', $e->getCode()));
}
try
{
$rpcClient->settingsAddInformationField(InformationFieldName::PHONE_NUMBER, Helper::generateRandomNumber(2));
$this->assertFalse($rpcClient->settingsInformationFieldExists(InformationFieldName::PHONE_NUMBER));
}
catch(RpcException $e)
{
$this->assertEquals(-1001, $e->getCode(), sprintf('Unexpected error code: %d', $e->getCode()));
}
try
{
$rpcClient->settingsAddInformationField(InformationFieldName::PHONE_NUMBER, '');
$this->assertFalse($rpcClient->settingsInformationFieldExists(InformationFieldName::PHONE_NUMBER));
}
catch(RpcException $e)
{
$this->assertEquals(-1001, $e->getCode(), sprintf('Unexpected error code: %d', $e->getCode()));
}
}
public function testValidPhoneNumber(): void
{
$rpcClient = Helper::generateRandomClient(COFFEE_DOMAIN, prefix: 'validInputTest');
$phoneNumber = sprintf('+%d', Helper::generateRandomNumber(12));
$rpcClient->settingsAddInformationField(InformationFieldName::PHONE_NUMBER, $phoneNumber);
$this->assertTrue($rpcClient->settingsInformationFieldExists(InformationFieldName::PHONE_NUMBER));
$this->assertEquals($phoneNumber, $rpcClient->settingsGetInformationField(InformationFieldName::PHONE_NUMBER)->getValue());
}
/**
* @throws ResolutionException
* @throws RpcException
* @throws CryptographyException
* @throws DatabaseOperationException
*/
public function testInvalidEmail(): void
{
$rpcClient = Helper::generateRandomClient(TEAPOT_DOMAIN, prefix: 'malformedTest');
try
{
$rpcClient->settingsAddInformationField(InformationFieldName::EMAIL_ADDRESS, Helper::generateRandomString(2048));
$this->assertFalse($rpcClient->settingsInformationFieldExists(InformationFieldName::EMAIL_ADDRESS));
}
catch(RpcException $e)
{
$this->assertEquals(-1001, $e->getCode(), sprintf('Unexpected error code: %d', $e->getCode()));
}
try
{
$rpcClient->settingsAddInformationField(InformationFieldName::EMAIL_ADDRESS, '');
$this->assertFalse($rpcClient->settingsInformationFieldExists(InformationFieldName::EMAIL_ADDRESS));
}
catch(RpcException $e)
{
$this->assertEquals(-1001, $e->getCode(), sprintf('Unexpected error code: %d', $e->getCode()));
}
}
/**
* @throws RpcException
* @throws ResolutionException
* @throws CryptographyException
* @throws DatabaseOperationException
*/
public function testValidEmail(): void
{
$rpcClient = Helper::generateRandomClient(COFFEE_DOMAIN, prefix: 'validInputTest');
$rpcClient->settingsAddInformationField(InformationFieldName::EMAIL_ADDRESS, 'testing@example.com');
$this->assertTrue($rpcClient->settingsInformationFieldExists(InformationFieldName::EMAIL_ADDRESS));
$this->assertEquals('testing@example.com', $rpcClient->settingsGetInformationField(InformationFieldName::EMAIL_ADDRESS)->getValue());
}
public function testInvalidUrl(): void
{
$rpcClient = Helper::generateRandomClient(TEAPOT_DOMAIN, prefix: 'malformedTest');
try
{
$rpcClient->settingsAddInformationField(InformationFieldName::URL, Helper::generateRandomString(2048));
$this->assertFalse($rpcClient->settingsInformationFieldExists(InformationFieldName::URL));
}
catch(RpcException $e)
{
$this->assertEquals(-1001, $e->getCode(), sprintf('Unexpected error code: %d', $e->getCode()));
}
try
{
$rpcClient->settingsAddInformationField(InformationFieldName::URL, '');
$this->assertFalse($rpcClient->settingsInformationFieldExists(InformationFieldName::URL));
}
catch(RpcException $e)
{
$this->assertEquals(-1001, $e->getCode(), sprintf('Unexpected error code: %d', $e->getCode()));
}
}
public function testValidUrl(): void
{
$rpcClient = Helper::generateRandomClient(COFFEE_DOMAIN, prefix: 'validInputTest');
$rpcClient->settingsAddInformationField(InformationFieldName::URL, 'https://example.com');
$this->assertTrue($rpcClient->settingsInformationFieldExists(InformationFieldName::URL));
$this->assertEquals('https://example.com', $rpcClient->settingsGetInformationField(InformationFieldName::URL)->getValue());
}
public function testInvalidBirthday(): void
{
$rpcClient = Helper::generateRandomClient(TEAPOT_DOMAIN, prefix: 'malformedTest');
try
{
$rpcClient->settingsAddInformationField(InformationFieldName::BIRTHDAY, Helper::generateRandomString(2048));
$this->assertFalse($rpcClient->settingsInformationFieldExists(InformationFieldName::BIRTHDAY));
}
catch(RpcException $e)
{
$this->assertEquals(-1001, $e->getCode(), sprintf('Unexpected error code: %d', $e->getCode()));
}
try
{
$rpcClient->settingsAddInformationField(InformationFieldName::BIRTHDAY, '');
$this->assertFalse($rpcClient->settingsInformationFieldExists(InformationFieldName::BIRTHDAY));
}
catch(RpcException $e)
{
$this->assertEquals(-1001, $e->getCode(), sprintf('Unexpected error code: %d', $e->getCode()));
}
}
public function testValidBirthday(): void
{
$rpcClient = Helper::generateRandomClient(COFFEE_DOMAIN, prefix: 'validInputTest');
$rpcClient->settingsAddInformationField(InformationFieldName::BIRTHDAY, '2021-01-01');
$this->assertTrue($rpcClient->settingsInformationFieldExists(InformationFieldName::BIRTHDAY));
$this->assertEquals('2021-01-01', $rpcClient->settingsGetInformationField(InformationFieldName::BIRTHDAY)->getValue());
}
/**
* @throws RpcException
* @throws ResolutionException
* @throws CryptographyException
* @throws DatabaseOperationException
*/
public function testPeerResolution(): void
{
$johnClient = Helper::generateRandomClient(COFFEE_DOMAIN, prefix: 'johnDoe');
$johnClient->settingsAddInformationField(InformationFieldName::DISPLAY_NAME, 'Test User');
$this->assertEquals('Test User', $johnClient->settingsGetInformationField(InformationFieldName::DISPLAY_NAME)->getValue());
$johnClient->settingsAddInformationField(InformationFieldName::FIRST_NAME, 'John');
$this->assertEquals('John', $johnClient->settingsGetInformationField(InformationFieldName::FIRST_NAME)->getValue());
$johnClient->settingsAddInformationField(InformationFieldName::LAST_NAME, 'Doe');
$this->assertEquals('Doe', $johnClient->settingsGetInformationField(InformationFieldName::LAST_NAME)->getValue());
$johnClient->settingsSetPassword('SecuredTestingPassword123');
$this->assertTrue($johnClient->getSessionState()->isAuthenticated());
$this->assertFalse($johnClient->getSessionState()->containsFlag(SessionFlags::REGISTRATION_REQUIRED));
$this->assertFalse($johnClient->getSessionState()->containsFlag(SessionFlags::AUTHENTICATION_REQUIRED));
$aliceClient = Helper::generateRandomClient(COFFEE_DOMAIN, prefix: 'aliceSmith');
$aliceClient->settingsAddInformationField(InformationFieldName::DISPLAY_NAME, 'Test User');
$this->assertEquals('Test User', $aliceClient->settingsGetInformationField(InformationFieldName::DISPLAY_NAME)->getValue());
$aliceClient->settingsAddInformationField(InformationFieldName::FIRST_NAME, 'Alice');
$this->assertEquals('Alice', $aliceClient->settingsGetInformationField(InformationFieldName::FIRST_NAME)->getValue());
$aliceClient->settingsAddInformationField(InformationFieldName::LAST_NAME, 'Smith');
$this->assertEquals('Smith', $aliceClient->settingsGetInformationField(InformationFieldName::LAST_NAME)->getValue());
$aliceClient->settingsSetPassword('SecuredTestingPassword123');
$this->assertTrue($aliceClient->getSessionState()->isAuthenticated());
$this->assertFalse($aliceClient->getSessionState()->containsFlag(SessionFlags::REGISTRATION_REQUIRED));
$this->assertFalse($aliceClient->getSessionState()->containsFlag(SessionFlags::AUTHENTICATION_REQUIRED));
$aliceResolved = $aliceClient->resolvePeer($aliceClient->getSelf()->getPeerAddress());
foreach($aliceResolved->getInformationFields() as $informationField)
{
switch($informationField->getName())
{
case InformationFieldName::DISPLAY_NAME:
$this->assertEquals('Test User', $informationField->getValue());
break;
case InformationFieldName::FIRST_NAME:
$this->assertEquals('Alice', $informationField->getValue());
break;
case InformationFieldName::LAST_NAME:
$this->assertEquals('Smith', $informationField->getValue());
break;
default:
$this->fail('Unexpected information field: ' . $informationField->getName()->value);
}
}
$johnResolved = $aliceClient->resolvePeer($johnClient->getSelf()->getPeerAddress());
foreach($johnResolved->getInformationFields() as $informationField)
{
switch($informationField->getName())
{
case InformationFieldName::DISPLAY_NAME:
$this->assertEquals('Test User', $informationField->getValue());
break;
case InformationFieldName::FIRST_NAME:
$this->assertEquals('John', $informationField->getValue());
break;
case InformationFieldName::LAST_NAME:
$this->assertEquals('Doe', $informationField->getValue());
break;
default:
$this->fail('Unexpected information field: ' . $informationField->getName()->value);
}
}
$this->assertEquals($johnClient->getSelf()->getPeerAddress(), $johnResolved->getPeerAddress());
$this->assertEquals($aliceClient->getSelf()->getPeerAddress(), $aliceResolved->getPeerAddress());
}
/**
* @throws ResolutionException
* @throws RpcException
* @throws CryptographyException
* @throws DatabaseOperationException
*/
public function testIncorrectLogin(): void
{
$rpcClient = Helper::generateRandomClient(COFFEE_DOMAIN, prefix: 'incorrectLogin');
$generatedPeer = $rpcClient->getIdentifiedAs();
$rpcClient->settingsAddInformationField(InformationFieldName::DISPLAY_NAME, 'Test User');
$rpcClient->settingsSetPassword('SecuredTestingPassword123');
$this->assertTrue($rpcClient->getSessionState()->isAuthenticated());
$rpcClient = new SocialClient($generatedPeer);
$this->assertFalse($rpcClient->getSessionState()->isAuthenticated());
$this->assertTrue($rpcClient->getSessionState()->containsFlag(SessionFlags::AUTHENTICATION_REQUIRED));
$this->assertTrue($rpcClient->getSessionState()->containsFlag(SessionFlags::VER_PASSWORD));
$this->assertFalse($rpcClient->verificationPasswordAuthentication('IncorrectPassword'));
$this->assertTrue($rpcClient->getSessionState()->containsFlag(SessionFlags::AUTHENTICATION_REQUIRED));
$this->assertTrue($rpcClient->getSessionState()->containsFlag(SessionFlags::VER_PASSWORD));
}
/**
* @throws DatabaseOperationException
* @throws ResolutionException
* @throws CryptographyException
* @throws RpcException
*/
public function testCorrectLogin(): void
{
$rpcClient = Helper::generateRandomClient(COFFEE_DOMAIN, prefix: 'incorrectLogin');
$generatedPeer = $rpcClient->getIdentifiedAs();
$rpcClient->settingsAddInformationField(InformationFieldName::DISPLAY_NAME, 'Test User');
$rpcClient->settingsSetPassword('SecuredTestingPassword123');
$this->assertTrue($rpcClient->getSessionState()->isAuthenticated());
$rpcClient = new SocialClient($generatedPeer);
$this->assertFalse($rpcClient->getSessionState()->isAuthenticated());
$this->assertTrue($rpcClient->getSessionState()->containsFlag(SessionFlags::AUTHENTICATION_REQUIRED));
$this->assertTrue($rpcClient->getSessionState()->containsFlag(SessionFlags::VER_PASSWORD));
$this->assertTrue($rpcClient->verificationPasswordAuthentication('SecuredTestingPassword123'));
$this->assertFalse($rpcClient->getSessionState()->containsFlag(SessionFlags::AUTHENTICATION_REQUIRED));
$this->assertFalse($rpcClient->getSessionState()->containsFlag(SessionFlags::VER_PASSWORD));
}
}

View file

@ -101,9 +101,9 @@
"peer_sync_interval": 3600,
"get_contacts_limit": 100,
"default_display_picture_privacy": "PUBLIC",
"default_first_name_privacy": "CONTACTS",
"default_middle_name_privacy": "PRIVATE",
"default_last_name_privacy": "PRIVATE",
"default_first_name_privacy": "PUBLIC",
"default_middle_name_privacy": "PUBLIC",
"default_last_name_privacy": "PUBLIC",
"default_email_address_privacy": "CONTACTS",
"default_phone_number_privacy": "CONTACTS",
"default_birthday_privacy": "PRIVATE",

View file

@ -101,9 +101,9 @@
"peer_sync_interval": 3600,
"get_contacts_limit": 100,
"default_display_picture_privacy": "PUBLIC",
"default_first_name_privacy": "CONTACTS",
"default_middle_name_privacy": "PRIVATE",
"default_last_name_privacy": "PRIVATE",
"default_first_name_privacy": "PUBLIC",
"default_middle_name_privacy": "PUBLIC",
"default_last_name_privacy": "PUBLIC",
"default_email_address_privacy": "CONTACTS",
"default_phone_number_privacy": "CONTACTS",
"default_birthday_privacy": "PRIVATE",