UserToken / UserAPI

This commit is contained in:
2022-11-19 01:15:34 +01:00
parent f6bae08c05
commit b5b8f9b856
21 changed files with 496 additions and 613 deletions

View File

@@ -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 {

View 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);
}
}

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -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,

View File

@@ -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
];
}

View 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;
}
}