UserToken / UserAPI
This commit is contained in:
@@ -7,6 +7,7 @@ use Core\Configuration\Settings;
|
||||
use Core\Driver\SQL\Condition\Compare;
|
||||
use Core\Driver\SQL\Condition\CondLike;
|
||||
use Core\Driver\SQL\Condition\CondOr;
|
||||
use Core\Driver\SQL\Join;
|
||||
use Core\Driver\SQL\SQL;
|
||||
use Firebase\JWT\JWT;
|
||||
use Core\Objects\DatabaseEntity\Language;
|
||||
@@ -92,6 +93,9 @@ class Context {
|
||||
private function loadSession(int $userId, int $sessionId) {
|
||||
$this->session = Session::init($this, $userId, $sessionId);
|
||||
$this->user = $this->session?->getUser();
|
||||
if ($this->user) {
|
||||
$this->user->session = $this->session;
|
||||
}
|
||||
}
|
||||
|
||||
public function parseCookies() {
|
||||
@@ -173,7 +177,7 @@ class Context {
|
||||
|
||||
public function loadApiKey(string $apiKey): bool {
|
||||
$this->user = User::findBuilder($this->sql)
|
||||
->addJoin(new \Driver\SQL\Join("INNER","ApiKey", "ApiKey.user_id", "User.id"))
|
||||
->addJoin(new Join("INNER","ApiKey", "ApiKey.user_id", "User.id"))
|
||||
->where(new Compare("ApiKey.api_key", $apiKey))
|
||||
->where(new Compare("valid_until", $this->sql->currentTimestamp(), ">"))
|
||||
->where(new Compare("ApiKey.active", true))
|
||||
@@ -184,19 +188,18 @@ class Context {
|
||||
return $this->user !== null;
|
||||
}
|
||||
|
||||
public function createSession(int $userId, bool $stayLoggedIn): ?Session {
|
||||
$this->user = User::find($this->sql, $userId);
|
||||
if ($this->user) {
|
||||
$this->session = new Session($this, $this->user);
|
||||
$this->session->stayLoggedIn = $stayLoggedIn;
|
||||
if ($this->session->update()) {
|
||||
return $this->session;
|
||||
}
|
||||
public function createSession(User $user, bool $stayLoggedIn): ?Session {
|
||||
$this->user = $user;
|
||||
$this->session = new Session($this, $this->user);
|
||||
$this->session->stayLoggedIn = $stayLoggedIn;
|
||||
if ($this->session->update()) {
|
||||
$user->session = $this->session;
|
||||
return $this->session;
|
||||
} else {
|
||||
$this->user = null;
|
||||
$this->session = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->user = null;
|
||||
$this->session = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getLanguage(): Language {
|
||||
|
||||
12
Core/Objects/DatabaseEntity/Attribute/EnumArr.class.php
Normal file
12
Core/Objects/DatabaseEntity/Attribute/EnumArr.class.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace Core\Objects\DatabaseEntity\Attribute;
|
||||
|
||||
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||
class EnumArr extends Enum {
|
||||
|
||||
public function __construct(array $values) {
|
||||
parent::__construct(...$values);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -322,7 +322,7 @@ class DatabaseEntityHandler {
|
||||
if ($property->isInitialized($entity)) {
|
||||
$value = $property->getValue($entity);
|
||||
if (isset($this->relations[$propertyName])) {
|
||||
$value = $value->getId();
|
||||
$value = $value?->getId();
|
||||
}
|
||||
} else if (!$this->columns[$propertyName]->notNull()) {
|
||||
$value = null;
|
||||
@@ -411,4 +411,8 @@ class DatabaseEntityHandler {
|
||||
$this->logger->error($message);
|
||||
throw new Exception($message);
|
||||
}
|
||||
|
||||
public function getSQL(): SQL {
|
||||
return $this->sql;
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Core\Objects\DatabaseEntity;
|
||||
|
||||
use Core\Driver\Logger\Logger;
|
||||
use Core\Driver\SQL\Condition\Condition;
|
||||
use Core\Driver\SQL\Join;
|
||||
use Core\Driver\SQL\Query\Select;
|
||||
@@ -13,20 +14,29 @@ use Core\Driver\SQL\SQL;
|
||||
*/
|
||||
class DatabaseEntityQuery {
|
||||
|
||||
private Logger $logger;
|
||||
private DatabaseEntityHandler $handler;
|
||||
private Select $selectQuery;
|
||||
private int $resultType;
|
||||
private bool $logVerbose;
|
||||
|
||||
private function __construct(DatabaseEntityHandler $handler, int $resultType) {
|
||||
$this->handler = $handler;
|
||||
$this->selectQuery = $handler->getSelectQuery();
|
||||
$this->logger = new Logger("DB-EntityQuery", $handler->getSQL());
|
||||
$this->resultType = $resultType;
|
||||
$this->logVerbose = false;
|
||||
|
||||
if ($this->resultType === SQL::FETCH_ONE) {
|
||||
$this->selectQuery->first();
|
||||
}
|
||||
}
|
||||
|
||||
public function debug(): DatabaseEntityQuery {
|
||||
$this->logVerbose = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public static function fetchAll(DatabaseEntityHandler $handler): DatabaseEntityQuery {
|
||||
return new DatabaseEntityQuery($handler, SQL::FETCH_ALL);
|
||||
}
|
||||
@@ -106,6 +116,13 @@ class DatabaseEntityQuery {
|
||||
}
|
||||
|
||||
public function execute(): DatabaseEntity|array|null {
|
||||
|
||||
if ($this->logVerbose) {
|
||||
$params = [];
|
||||
$query = $this->selectQuery->build($params);
|
||||
$this->logger->debug("QUERY: $query\nARGS: " . print_r($params, true));
|
||||
}
|
||||
|
||||
$res = $this->selectQuery->execute();
|
||||
if ($res === null || $res === false) {
|
||||
return null;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace Core\Objects\DatabaseEntity;
|
||||
|
||||
use Core\Driver\SQL\Expression\CurrentTimeStamp;
|
||||
use Core\Driver\SQL\SQL;
|
||||
use Core\Objects\DatabaseEntity\Attribute\MaxLength;
|
||||
use Core\Objects\DatabaseEntity\Attribute\DefaultValue;
|
||||
|
||||
@@ -16,12 +17,13 @@ class GpgKey extends DatabaseEntity {
|
||||
private \DateTime $expires;
|
||||
#[DefaultValue(CurrentTimeStamp::class)] private \DateTime $added;
|
||||
|
||||
public function __construct(int $id, bool $confirmed, string $fingerprint, string $algorithm, string $expires) {
|
||||
parent::__construct($id);
|
||||
$this->confirmed = $confirmed;
|
||||
public function __construct(string $fingerprint, string $algorithm, \DateTime $expires) {
|
||||
parent::__construct();
|
||||
$this->confirmed = false;
|
||||
$this->fingerprint = $fingerprint;
|
||||
$this->algorithm = $algorithm;
|
||||
$this->expires = new \DateTime($expires);
|
||||
$this->expires = $expires;
|
||||
$this->added = new \DateTime();
|
||||
}
|
||||
|
||||
public static function encrypt(string $body, string $gpgFingerprint): array {
|
||||
@@ -130,4 +132,9 @@ class GpgKey extends DatabaseEntity {
|
||||
"confirmed" => $this->confirmed
|
||||
];
|
||||
}
|
||||
|
||||
public function confirm(SQL $sql): bool {
|
||||
$this->confirmed = true;
|
||||
return $this->save($sql);
|
||||
}
|
||||
}
|
||||
@@ -96,7 +96,7 @@ class Session extends DatabaseEntity {
|
||||
return array(
|
||||
'id' => $this->getId(),
|
||||
'active' => $this->active,
|
||||
'expires' => $this->expires,
|
||||
'expires' => $this->expires->getTimestamp(),
|
||||
'ipAddress' => $this->ipAddress,
|
||||
'os' => $this->os,
|
||||
'browser' => $this->browser,
|
||||
|
||||
@@ -17,12 +17,12 @@ class User extends DatabaseEntity {
|
||||
#[MaxLength(128)] public string $password;
|
||||
#[MaxLength(64)] public string $fullName;
|
||||
#[MaxLength(64)] #[Unique] public ?string $email;
|
||||
#[MaxLength(64)] private ?string $profilePicture;
|
||||
#[MaxLength(64)] public ?string $profilePicture;
|
||||
private ?\DateTime $lastOnline;
|
||||
#[DefaultValue(CurrentTimeStamp::class)] public \DateTime $registeredAt;
|
||||
public bool $confirmed;
|
||||
#[DefaultValue(1)] public Language $language;
|
||||
private ?GpgKey $gpgKey;
|
||||
public ?GpgKey $gpgKey;
|
||||
private ?TwoFactorToken $twoFactorToken;
|
||||
|
||||
#[Transient] private array $groups;
|
||||
@@ -37,7 +37,6 @@ class User extends DatabaseEntity {
|
||||
$this->groups = [];
|
||||
|
||||
$groups = Group::findAllBuilder($sql)
|
||||
->fetchEntities()
|
||||
->addJoin(new Join("INNER", "UserGroup", "UserGroup.group_id", "Group.id"))
|
||||
->where(new Compare("UserGroup.user_id", $this->id))
|
||||
->execute();
|
||||
@@ -99,6 +98,9 @@ class User extends DatabaseEntity {
|
||||
'session' => (isset($this->session) ? $this->session->jsonSerialize() : null),
|
||||
"gpg" => (isset($this->gpgKey) ? $this->gpgKey->jsonSerialize() : null),
|
||||
"2fa" => (isset($this->twoFactorToken) ? $this->twoFactorToken->jsonSerialize() : null),
|
||||
"reqisteredAt" => $this->registeredAt->getTimestamp(),
|
||||
"lastOnline" => $this->lastOnline->getTimestamp(),
|
||||
"confirmed" => $this->confirmed
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
72
Core/Objects/DatabaseEntity/UserToken.class.php
Normal file
72
Core/Objects/DatabaseEntity/UserToken.class.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace Core\Objects\DatabaseEntity;
|
||||
|
||||
use Core\Driver\SQL\SQL;
|
||||
use Core\Objects\DatabaseEntity\Attribute\DefaultValue;
|
||||
use Core\Objects\DatabaseEntity\Attribute\EnumArr;
|
||||
use Core\Objects\DatabaseEntity\Attribute\MaxLength;
|
||||
|
||||
class UserToken extends DatabaseEntity {
|
||||
|
||||
const TYPE_PASSWORD_RESET = "password_reset";
|
||||
const TYPE_EMAIL_CONFIRM = "email_confirm";
|
||||
const TYPE_INVITE = "invite";
|
||||
const TYPE_GPG_CONFIRM = "gpg_confirm";
|
||||
|
||||
const TOKEN_TYPES = [
|
||||
self::TYPE_PASSWORD_RESET, self::TYPE_EMAIL_CONFIRM,
|
||||
self::TYPE_INVITE, self::TYPE_GPG_CONFIRM
|
||||
];
|
||||
|
||||
#[MaxLength(36)]
|
||||
private string $token;
|
||||
|
||||
#[EnumArr(self::TOKEN_TYPES)]
|
||||
private string $tokenType;
|
||||
|
||||
private User $user;
|
||||
private \DateTime $validUntil;
|
||||
|
||||
#[DefaultValue(false)]
|
||||
private bool $used;
|
||||
|
||||
public function __construct(User $user, string $token, string $type, int $validHours) {
|
||||
parent::__construct();
|
||||
$this->user = $user;
|
||||
$this->token = $token;
|
||||
$this->tokenType = $type;
|
||||
$this->validUntil = (new \DateTime())->modify("+$validHours HOUR");
|
||||
$this->used = false;
|
||||
}
|
||||
|
||||
public function jsonSerialize(): array {
|
||||
return [
|
||||
"id" => $this->getId(),
|
||||
"token" => $this->token,
|
||||
"tokenType" => $this->tokenType
|
||||
];
|
||||
}
|
||||
|
||||
public function getType(): string {
|
||||
return $this->tokenType;
|
||||
}
|
||||
|
||||
public function invalidate(SQL $sql): bool {
|
||||
$this->used = true;
|
||||
return $this->save($sql);
|
||||
}
|
||||
|
||||
public function getUser(): User {
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
public function updateDurability(SQL $sql, int $validHours): bool {
|
||||
$this->validUntil = (new \DateTime())->modify("+$validHours HOURS");
|
||||
return $this->save($sql);
|
||||
}
|
||||
|
||||
public function getToken(): string {
|
||||
return $this->token;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user