Remove unused StandardMethods and improve session logic

This commit is contained in:
netkas 2024-12-12 04:33:10 -05:00
parent 86435a3d0b
commit 701acfde35
30 changed files with 1032 additions and 704 deletions

View file

@ -12,6 +12,7 @@ use Socialbox\Enums\StandardError;
use Socialbox\Exceptions\DatabaseOperationException;
use Socialbox\Exceptions\StandardException;
use Socialbox\Objects\Database\RegisteredPeerRecord;
use Socialbox\Objects\Database\SecurePasswordRecord;
use Symfony\Component\Uid\Uuid;
class RegisteredPeerManager
@ -55,71 +56,12 @@ class RegisteredPeerManager
Logger::getLogger()->verbose(sprintf("Creating a new peer with username %s", $username));
$uuid = Uuid::v4()->toRfc4122();
// If `enabled` is True, we insert the peer into the database as an activated account.
if($enabled)
{
try
{
$statement = Database::getConnection()->prepare('INSERT INTO `registered_peers` (uuid, username, enabled) VALUES (?, ?, ?)');
$statement->bindParam(1, $uuid);
$statement->bindParam(2, $username);
$statement->bindParam(3, $enabled, PDO::PARAM_BOOL);
$statement->execute();
}
catch(PDOException $e)
{
throw new DatabaseOperationException('Failed to create the peer in the database', $e);
}
return $uuid;
}
// Otherwise, we insert the peer into the database as a disabled account & the required verification flags.
$flags = [];
if(Configuration::getRegistrationConfiguration()->isPasswordRequired())
{
$flags[] = PeerFlags::VER_SET_PASSWORD;
}
if(Configuration::getRegistrationConfiguration()->isOtpRequired())
{
$flags[] = PeerFlags::VER_SET_OTP;
}
if(Configuration::getRegistrationConfiguration()->isDisplayNameRequired())
{
$flags[] = PeerFlags::VER_SET_DISPLAY_NAME;
}
if(Configuration::getRegistrationConfiguration()->isEmailVerificationRequired())
{
$flags[] = PeerFlags::VER_EMAIL;
}
if(Configuration::getRegistrationConfiguration()->isSmsVerificationRequired())
{
$flags[] = PeerFlags::VER_SMS;
}
if(Configuration::getRegistrationConfiguration()->isPhoneCallVerificationRequired())
{
$flags[] = PeerFlags::VER_PHONE_CALL;
}
if(Configuration::getRegistrationConfiguration()->isImageCaptchaVerificationRequired())
{
$flags[] = PeerFlags::VER_SOLVE_IMAGE_CAPTCHA;
}
try
{
$implodedFlags = implode(',', array_map(fn($flag) => $flag->name, $flags));
$statement = Database::getConnection()->prepare('INSERT INTO `registered_peers` (uuid, username, enabled, flags) VALUES (?, ?, ?, ?)');
$statement = Database::getConnection()->prepare('INSERT INTO `registered_peers` (uuid, username, enabled) VALUES (?, ?, ?)');
$statement->bindParam(1, $uuid);
$statement->bindParam(2, $username);
$statement->bindParam(3, $enabled, PDO::PARAM_BOOL);
$statement->bindParam(4, $implodedFlags);
$statement->execute();
}
catch(PDOException $e)
@ -200,11 +142,10 @@ class RegisteredPeerManager
* Retrieves a peer record by the given username.
*
* @param string $username The username of the peer to be retrieved.
* @return RegisteredPeerRecord The record of the peer associated with the given username.
* @return RegisteredPeerRecord|null The record of the peer associated with the given username.
* @throws DatabaseOperationException If there is an error while querying the database.
* @throws StandardException If the peer does not exist.
*/
public static function getPeerByUsername(string $username): RegisteredPeerRecord
public static function getPeerByUsername(string $username): ?RegisteredPeerRecord
{
Logger::getLogger()->verbose(sprintf("Retrieving peer %s from the database", $username));
@ -218,7 +159,7 @@ class RegisteredPeerManager
if($result === false)
{
throw new StandardException(sprintf("The requested peer '%s' does not exist", $username), StandardError::PEER_NOT_FOUND);
return null;
}
return new RegisteredPeerRecord($result);
@ -365,4 +306,35 @@ class RegisteredPeerManager
throw new DatabaseOperationException('Failed to remove the flag from the peer in the database', $e);
}
}
/**
*
*/
public static function getPasswordAuthentication(string|RegisteredPeerRecord $peerUuid): ?SecurePasswordRecord
{
if($peerUuid instanceof RegisteredPeerRecord)
{
$peerUuid = $peerUuid->getUuid();
}
try
{
$statement = Database::getConnection()->prepare('SELECT * FROM `authentication_passwords` WHERE peer_uuid=?');
$statement->bindParam(1, $peerUuid);
$statement->execute();
$result = $statement->fetch(PDO::FETCH_ASSOC);
if($result === false)
{
return null;
}
return new SecurePasswordRecord($result);
}
catch(PDOException | \DateMalformedStringException $e)
{
throw new DatabaseOperationException('Failed to get the secure password record from the database', $e);
}
}
}

View file

@ -7,10 +7,12 @@
use InvalidArgumentException;
use PDO;
use PDOException;
use Socialbox\Classes\Configuration;
use Socialbox\Classes\Cryptography;
use Socialbox\Classes\Database;
use Socialbox\Classes\Logger;
use Socialbox\Classes\Utilities;
use Socialbox\Enums\Flags\SessionFlags;
use Socialbox\Enums\SessionState;
use Socialbox\Enums\StandardError;
use Socialbox\Exceptions\DatabaseOperationException;
@ -31,25 +33,89 @@
* @throws InvalidArgumentException If the public key is empty or invalid.
* @throws DatabaseOperationException If there is an error while creating the session in the database.
*/
public static function createSession(string $publicKey): string
public static function createSession(string $publicKey, RegisteredPeerRecord $peer): string
{
if($publicKey === '')
{
throw new InvalidArgumentException('The public key cannot be empty', 400);
throw new InvalidArgumentException('The public key cannot be empty');
}
if(!Cryptography::validatePublicKey($publicKey))
{
throw new InvalidArgumentException('The given public key is invalid', 400);
throw new InvalidArgumentException('The given public key is invalid');
}
$uuid = Uuid::v4()->toRfc4122();
$flags = [];
if($peer->isEnabled())
{
if(RegisteredPeerManager::getPasswordAuthentication($peer))
{
$flags[] = SessionFlags::VER_PASSWORD;
}
if(Configuration::getRegistrationConfiguration()->isImageCaptchaVerificationRequired())
{
$flags[] = SessionFlags::VER_IMAGE_CAPTCHA;
}
}
else
{
if(Configuration::getRegistrationConfiguration()->isDisplayNameRequired())
{
$flags[] = SessionFlags::SET_DISPLAY_NAME;
}
if(Configuration::getRegistrationConfiguration()->isEmailVerificationRequired())
{
$flags[] = SessionFlags::VER_EMAIL;
}
if(Configuration::getRegistrationConfiguration()->isSmsVerificationRequired())
{
$flags[] = SessionFlags::VER_SMS;
}
if(Configuration::getRegistrationConfiguration()->isPhoneCallVerificationRequired())
{
$flags[] = SessionFlags::VER_PHONE_CALL;
}
if(Configuration::getRegistrationConfiguration()->isImageCaptchaVerificationRequired())
{
$flags[] = SessionFlags::VER_IMAGE_CAPTCHA;
}
if(Configuration::getRegistrationConfiguration()->isPasswordRequired())
{
$flags[] = SessionFlags::SET_PASSWORD;
}
if(Configuration::getRegistrationConfiguration()->isOtpRequired())
{
$flags[] = SessionFlags::SET_OTP;
}
}
if(count($flags) > 0)
{
$implodedFlags = SessionFlags::toString($flags);
}
else
{
$implodedFlags = null;
}
$peerUuid = $peer->getUuid();
try
{
$statement = Database::getConnection()->prepare("INSERT INTO sessions (uuid, public_key) VALUES (?, ?)");
$statement = Database::getConnection()->prepare("INSERT INTO sessions (uuid, peer_uuid, public_key, flags) VALUES (?, ?, ?, ?)");
$statement->bindParam(1, $uuid);
$statement->bindParam(2, $publicKey);
$statement->bindParam(2, $peerUuid);
$statement->bindParam(3, $publicKey);
$statement->bindParam(4, $implodedFlags);
$statement->execute();
}
catch(PDOException $e)
@ -219,6 +285,8 @@
$statement = Database::getConnection()->prepare('UPDATE sessions SET state=? WHERE uuid=?');
$statement->bindParam(1, $state_value);
$statement->bindParam(2, $uuid);
$statement->execute();
}
catch(PDOException $e)
{
@ -226,6 +294,34 @@
}
}
/**
* Updates the encryption key for the specified session.
*
* @param string $uuid The unique identifier of the session for which the encryption key is to be set.
* @param string $encryptionKey The new encryption key to be assigned.
* @return void
* @throws DatabaseOperationException If the database operation fails.
*/
public static function setEncryptionKey(string $uuid, string $encryptionKey): void
{
Logger::getLogger()->verbose(sprintf('Setting the encryption key for %s', $uuid));
try
{
$state_value = SessionState::ACTIVE->value;
$statement = Database::getConnection()->prepare('UPDATE sessions SET state=?, encryption_key=? WHERE uuid=?');
$statement->bindParam(1, $state_value);
$statement->bindParam(2, $encryptionKey);
$statement->bindParam(3, $uuid);
$statement->execute();
}
catch(PDOException $e)
{
throw new DatabaseOperationException('Failed to set the encryption key', $e);
}
}
/**
* Retrieves the flags associated with a specific session.
*