110 lines
3.4 KiB
PHP
110 lines
3.4 KiB
PHP
<?php
|
|
namespace Mince;
|
|
|
|
use InvalidArgumentException;
|
|
use RuntimeException;
|
|
use Index\Data\{DbStatementCache,IDbConnection};
|
|
use Index\Net\IPAddress;
|
|
use Index\Serialisation\Base32;
|
|
use Ramsey\Uuid\UuidInterface;
|
|
|
|
class Verifications {
|
|
private IDbConnection $dbConn;
|
|
private DbStatementCache $cache;
|
|
|
|
public function __construct(IDbConnection $dbConn) {
|
|
$this->dbConn = $dbConn;
|
|
$this->cache = new DbStatementCache($dbConn);
|
|
}
|
|
|
|
public static function generateCode(): string {
|
|
return Base32::encode(random_bytes(6));
|
|
}
|
|
|
|
public function prune(): void {
|
|
$this->dbConn->execute('DELETE FROM verifications WHERE verify_created < NOW() - INTERVAL 15 MINUTE');
|
|
}
|
|
|
|
public function getVerification(
|
|
?string $code = null,
|
|
UuidInterface|string|null $uuid = null,
|
|
IPAddress|string|null $remoteAddr = null
|
|
): VerificationInfo {
|
|
$hasCode = $code !== null;
|
|
$hasUuid = $uuid !== null;
|
|
$hasRemoteAddr = $remoteAddr !== null;
|
|
|
|
$values = [];
|
|
$query = 'SELECT verify_code, verify_uuid, verify_name, INET6_NTOA(verify_addr), UNIX_TIMESTAMP(verify_created) FROM verifications';
|
|
if($hasCode) {
|
|
$query .= ' WHERE verify_code = ?';
|
|
$values[] = $code;
|
|
} else {
|
|
$args = 0;
|
|
|
|
if($hasUuid) {
|
|
if($uuid instanceof UuidInterface)
|
|
$uuid = $uuid->getBytes();
|
|
|
|
++$args;
|
|
$query .= ' WHERE verify_uuid = ?';
|
|
$values[] = $uuid;
|
|
}
|
|
|
|
if($hasRemoteAddr) {
|
|
if($remoteAddr instanceof IPAddress)
|
|
$remoteAddr = (string)$remoteAddr;
|
|
|
|
$query .= sprintf(' %s verify_addr = INET6_ATON(?)', ++$args > 1 ? 'AND' : 'WHERE');
|
|
$values[] = $remoteAddr;
|
|
}
|
|
}
|
|
|
|
if(empty($values))
|
|
throw new InvalidArgumentException('Not enough arguments specified.');
|
|
|
|
$args = 0;
|
|
$stmt = $this->cache->get($query);
|
|
foreach($values as $value)
|
|
$stmt->addParameter(++$args, $value);
|
|
$stmt->execute();
|
|
|
|
$result = $stmt->getResult();
|
|
if(!$result->next())
|
|
throw new RuntimeException('Verification info not found.');
|
|
|
|
return VerificationInfo::fromResult($result);
|
|
}
|
|
|
|
public function createVerification(
|
|
UuidInterface|string $uuid,
|
|
string $name,
|
|
IPAddress|string $remoteAddr
|
|
): string {
|
|
if($uuid instanceof UuidInterface)
|
|
$uuid = $uuid->getBytes();
|
|
if($remoteAddr instanceof IPAddress)
|
|
$remoteAddr = (string)$remoteAddr;
|
|
|
|
$code = self::generateCode();
|
|
|
|
$stmt = $this->cache->get('REPLACE INTO verifications (verify_code, verify_uuid, verify_name, verify_addr) VALUES (?, ?, ?, INET6_ATON(?))');
|
|
$stmt->addParameter(1, $code);
|
|
$stmt->addParameter(2, $uuid);
|
|
$stmt->addParameter(3, $name);
|
|
$stmt->addParameter(4, $remoteAddr);
|
|
$stmt->execute();
|
|
|
|
return $code;
|
|
}
|
|
|
|
public function deleteVerification(VerificationInfo|string $code): void {
|
|
if($code instanceof VerificationInfo)
|
|
$code = $code->getCode();
|
|
|
|
$stmt = $this->cache->get('DELETE FROM verifications WHERE verify_code = ?');
|
|
$stmt->addParameter(1, $code);
|
|
$stmt->execute();
|
|
}
|
|
}
|