v2.0-alpha
This commit is contained in:
@@ -5,90 +5,27 @@ namespace Configuration;
|
||||
use Driver\SQL\SQL;
|
||||
use \Driver\SQL\Strategy\SetNullStrategy;
|
||||
use \Driver\SQL\Strategy\CascadeStrategy;
|
||||
use Objects\DatabaseEntity\DatabaseEntity;
|
||||
use PHPUnit\Util\Exception;
|
||||
|
||||
class CreateDatabase extends DatabaseScript {
|
||||
|
||||
public static function createQueries(SQL $sql): array {
|
||||
$queries = array();
|
||||
|
||||
// Language
|
||||
$queries[] = $sql->createTable("Language")
|
||||
->addSerial("uid")
|
||||
->addString("code", 5)
|
||||
->addString("name", 32)
|
||||
->primaryKey("uid")
|
||||
->unique("code")
|
||||
->unique("name");
|
||||
self::loadEntities($queries, $sql);
|
||||
|
||||
$queries[] = $sql->insert("Language", array("code", "name"))
|
||||
->addRow("en_US", 'American English')
|
||||
->addRow("de_DE", 'Deutsch Standard');
|
||||
|
||||
|
||||
$queries[] = $sql->createTable("GpgKey")
|
||||
->addSerial("uid")
|
||||
->addString("fingerprint", 64)
|
||||
->addDateTime("added", false, $sql->now())
|
||||
->addDateTime("expires")
|
||||
->addBool("confirmed")
|
||||
->addString("algorithm", 32)
|
||||
->primaryKey("uid");
|
||||
|
||||
$queries[] = $sql->createTable("2FA")
|
||||
->addSerial("uid")
|
||||
->addEnum("type", ["totp","fido"])
|
||||
->addString("data", 512) // either totp secret, fido challenge or fido public key information
|
||||
->addBool("confirmed", false)
|
||||
->addDateTime("added", false, $sql->now())
|
||||
->primaryKey("uid");
|
||||
|
||||
$queries[] = $sql->createTable("User")
|
||||
->addSerial("uid")
|
||||
->addString("email", 64, true)
|
||||
->addString("name", 32)
|
||||
->addString("password", 128)
|
||||
->addString("fullName", 64, false, "")
|
||||
->addString("profilePicture", 64, true)
|
||||
->addDateTime("last_online", true, NULL)
|
||||
->addBool("confirmed", false)
|
||||
->addInt("language_id", true, 1)
|
||||
->addInt("gpg_id", true)
|
||||
->addInt("2fa_id", true)
|
||||
->addDateTime("registered_at", false, $sql->currentTimestamp())
|
||||
->primaryKey("uid")
|
||||
->unique("email")
|
||||
->unique("name")
|
||||
->foreignKey("language_id", "Language", "uid", new SetNullStrategy())
|
||||
->foreignKey("gpg_id", "GpgKey", "uid", new SetNullStrategy())
|
||||
->foreignKey("2fa_id", "2FA", "uid", new SetNullStrategy());
|
||||
|
||||
$queries[] = $sql->createTable("Session")
|
||||
->addSerial("uid")
|
||||
->addBool("active", true)
|
||||
->addDateTime("expires")
|
||||
->addInt("user_id")
|
||||
->addString("ipAddress", 45)
|
||||
->addString("os", 64)
|
||||
->addString("browser", 64)
|
||||
->addJson("data", false, '{}')
|
||||
->addBool("stay_logged_in", true)
|
||||
->addString("csrf_token", 16)
|
||||
->primaryKey("uid", "user_id")
|
||||
->foreignKey("user_id", "User", "uid", new CascadeStrategy());
|
||||
|
||||
$queries[] = $sql->createTable("UserToken")
|
||||
->addInt("user_id")
|
||||
->addString("token", 36)
|
||||
->addEnum("token_type", array("password_reset", "email_confirm", "invite", "gpg_confirm"))
|
||||
->addDateTime("valid_until")
|
||||
->addBool("used", false)
|
||||
->foreignKey("user_id", "User", "uid", new CascadeStrategy());
|
||||
$queries[] = $sql->createTable("Group")
|
||||
->addSerial("uid")
|
||||
->addString("name", 32)
|
||||
->addString("color", 10)
|
||||
->primaryKey("uid")
|
||||
->unique("name");
|
||||
->foreignKey("user_id", "User", "id", new CascadeStrategy());
|
||||
|
||||
$queries[] = $sql->insert("Group", array("name", "color"))
|
||||
->addRow(USER_GROUP_MODERATOR_NAME, "#007bff")
|
||||
@@ -99,42 +36,25 @@ class CreateDatabase extends DatabaseScript {
|
||||
->addInt("user_id")
|
||||
->addInt("group_id")
|
||||
->unique("user_id", "group_id")
|
||||
->foreignKey("user_id", "User", "uid", new CascadeStrategy())
|
||||
->foreignKey("group_id", "Group", "uid", new CascadeStrategy());
|
||||
|
||||
$queries[] = $sql->createTable("Notification")
|
||||
->addSerial("uid")
|
||||
->addEnum("type", array("default", "message", "warning"), false, "default")
|
||||
->addDateTime("created_at", false, $sql->currentTimestamp())
|
||||
->addString("title", 32)
|
||||
->addString("message", 256)
|
||||
->primaryKey("uid");
|
||||
->foreignKey("user_id", "User", "id", new CascadeStrategy())
|
||||
->foreignKey("group_id", "Group", "id", new CascadeStrategy());
|
||||
|
||||
$queries[] = $sql->createTable("UserNotification")
|
||||
->addInt("user_id")
|
||||
->addInt("notification_id")
|
||||
->addBool("seen", false)
|
||||
->foreignKey("user_id", "User", "uid")
|
||||
->foreignKey("notification_id", "Notification", "uid")
|
||||
->foreignKey("user_id", "User", "id")
|
||||
->foreignKey("notification_id", "Notification", "id")
|
||||
->unique("user_id", "notification_id");
|
||||
|
||||
$queries[] = $sql->createTable("GroupNotification")
|
||||
->addInt("group_id")
|
||||
->addInt("notification_id")
|
||||
->addBool("seen", false)
|
||||
->foreignKey("group_id", "Group", "uid")
|
||||
->foreignKey("notification_id", "Notification", "uid")
|
||||
->foreignKey("group_id", "Group", "id")
|
||||
->foreignKey("notification_id", "Notification", "id")
|
||||
->unique("group_id", "notification_id");
|
||||
|
||||
$queries[] = $sql->createTable("ApiKey")
|
||||
->addSerial("uid")
|
||||
->addInt("user_id")
|
||||
->addBool("active", true)
|
||||
->addString("api_key", 64)
|
||||
->addDateTime("valid_until")
|
||||
->primaryKey("uid")
|
||||
->foreignKey("user_id", "User", "uid");
|
||||
|
||||
$queries[] = $sql->createTable("Visitor")
|
||||
->addInt("day")
|
||||
->addInt("count", false, 1)
|
||||
@@ -142,14 +62,14 @@ class CreateDatabase extends DatabaseScript {
|
||||
->unique("day", "cookie");
|
||||
|
||||
$queries[] = $sql->createTable("Route")
|
||||
->addSerial("uid")
|
||||
->addSerial("id")
|
||||
->addString("request", 128)
|
||||
->addEnum("action", array("redirect_temporary", "redirect_permanently", "static", "dynamic"))
|
||||
->addString("target", 128)
|
||||
->addString("extra", 64, true)
|
||||
->addBool("active", true)
|
||||
->addBool("exact", true)
|
||||
->primaryKey("uid")
|
||||
->primaryKey("id")
|
||||
->unique("request");
|
||||
|
||||
$queries[] = $sql->insert("Route", ["request", "action", "target", "extra", "exact"])
|
||||
@@ -184,17 +104,17 @@ class CreateDatabase extends DatabaseScript {
|
||||
$queries[] = $settingsQuery;
|
||||
|
||||
$queries[] = $sql->createTable("ContactRequest")
|
||||
->addSerial("uid")
|
||||
->addSerial("id")
|
||||
->addString("from_name", 32)
|
||||
->addString("from_email", 64)
|
||||
->addString("message", 512)
|
||||
->addString("messageId", 78, true) # null = don't sync with mails (usually if mail could not be sent)
|
||||
->addDateTime("created_at", false, $sql->currentTimestamp())
|
||||
->unique("messageId")
|
||||
->primaryKey("uid");
|
||||
->primaryKey("id");
|
||||
|
||||
$queries[] = $sql->createTable("ContactMessage")
|
||||
->addSerial("uid")
|
||||
->addSerial("id")
|
||||
->addInt("request_id")
|
||||
->addInt("user_id", true) # null = customer has sent this message
|
||||
->addString("message", 512)
|
||||
@@ -202,9 +122,9 @@ class CreateDatabase extends DatabaseScript {
|
||||
->addDateTime("created_at", false, $sql->currentTimestamp())
|
||||
->addBool("read", false)
|
||||
->unique("messageId")
|
||||
->primaryKey("uid")
|
||||
->foreignKey("request_id", "ContactRequest", "uid", new CascadeStrategy())
|
||||
->foreignKey("user_id", "User", "uid", new SetNullStrategy());
|
||||
->primaryKey("id")
|
||||
->foreignKey("request_id", "ContactRequest", "id", new CascadeStrategy())
|
||||
->foreignKey("user_id", "User", "id", new SetNullStrategy());
|
||||
|
||||
$queries[] = $sql->createTable("ApiPermission")
|
||||
->addString("method", 32)
|
||||
@@ -213,7 +133,7 @@ class CreateDatabase extends DatabaseScript {
|
||||
->primaryKey("method");
|
||||
|
||||
$queries[] = $sql->createTable("MailQueue")
|
||||
->addSerial("uid")
|
||||
->addSerial("id")
|
||||
->addString("from", 64)
|
||||
->addString("to", 64)
|
||||
->addString("subject")
|
||||
@@ -225,18 +145,9 @@ class CreateDatabase extends DatabaseScript {
|
||||
->addInt("retryCount", false, 5)
|
||||
->addDateTime("nextTry", false, $sql->now())
|
||||
->addString("errorMessage", NULL, true)
|
||||
->primaryKey("uid");
|
||||
->primaryKey("id");
|
||||
$queries = array_merge($queries, \Configuration\Patch\EntityLog_2021_04_08::createTableLog($sql, "MailQueue", 30));
|
||||
|
||||
$queries[] = $sql->createTable("News")
|
||||
->addSerial("uid")
|
||||
->addInt("publishedBy")
|
||||
->addDateTime("publishedAt", false, $sql->now())
|
||||
->addString("title", 128)
|
||||
->addString("text", 1024)
|
||||
->foreignKey("publishedBy", "User", "uid", new CascadeStrategy())
|
||||
->primaryKey("uid");
|
||||
|
||||
$queries[] = $sql->insert("ApiPermission", array("method", "groups", "description"))
|
||||
->addRow("ApiKey/create", array(), "Allows users to create API-Keys for themselves")
|
||||
->addRow("ApiKey/fetch", array(), "Allows users to list their API-Keys")
|
||||
@@ -265,7 +176,6 @@ class CreateDatabase extends DatabaseScript {
|
||||
->addRow("Contact/get", array(USER_GROUP_ADMIN, USER_GROUP_SUPPORT), "Allows users to see messages within a contact request");
|
||||
|
||||
self::loadPatches($queries, $sql);
|
||||
self::loadEntities($queries, $sql);
|
||||
|
||||
return $queries;
|
||||
}
|
||||
@@ -293,18 +203,47 @@ class CreateDatabase extends DatabaseScript {
|
||||
if (file_exists($entityDirectory) && is_dir($entityDirectory)) {
|
||||
$scan_arr = scandir($entityDirectory);
|
||||
$files_arr = array_diff($scan_arr, array('.', '..'));
|
||||
$handlers = [];
|
||||
foreach ($files_arr as $file) {
|
||||
$suffix = ".class.php";
|
||||
if (endsWith($file, $suffix)) {
|
||||
$className = substr($file, 0, strlen($file) - strlen($suffix));
|
||||
if (!in_array($className, ["DatabaseEntity", "DatabaseEntityHandler"])) {
|
||||
if (!in_array($className, ["DatabaseEntity", "DatabaseEntityQuery", "DatabaseEntityHandler"])) {
|
||||
$className = "\\Objects\\DatabaseEntity\\$className";
|
||||
$method = "$className::getHandler";
|
||||
$handler = call_user_func($method, $sql);
|
||||
$queries[] = $handler->getTableQuery();
|
||||
$reflectionClass = new \ReflectionClass($className);
|
||||
if ($reflectionClass->isSubclassOf(DatabaseEntity::class)) {
|
||||
$method = "$className::getHandler";
|
||||
$handler = call_user_func($method, $sql);
|
||||
$handlers[$handler->getTableName()] = $handler;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$tableCount = count($handlers);
|
||||
$createdTables = [];
|
||||
while (!empty($handlers)) {
|
||||
$prevCount = $tableCount;
|
||||
$unmetDependenciesTotal = [];
|
||||
|
||||
foreach ($handlers as $tableName => $handler) {
|
||||
$dependsOn = $handler->dependsOn();
|
||||
$unmetDependencies = array_diff($dependsOn, $createdTables);
|
||||
if (empty($unmetDependencies)) {
|
||||
$queries[] = $handler->getTableQuery();
|
||||
$createdTables[] = $tableName;
|
||||
unset($handlers[$tableName]);
|
||||
} else {
|
||||
$unmetDependenciesTotal = array_merge($unmetDependenciesTotal, $unmetDependencies);
|
||||
}
|
||||
}
|
||||
|
||||
$tableCount = count($handlers);
|
||||
if ($tableCount === $prevCount) {
|
||||
throw new Exception("Circular or unmet table dependency detected. Unmet dependencies: "
|
||||
. implode(", ", $unmetDependenciesTotal));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ class EntityLog_2021_04_08 extends DatabaseScript {
|
||||
->after()->insert($table)
|
||||
->exec(new CreateProcedure($sql, "InsertEntityLog"), [
|
||||
"tableName" => new CurrentTable(),
|
||||
"entityId" => new CurrentColumn("uid"),
|
||||
"entityId" => new CurrentColumn("id"),
|
||||
"lifetime" => $lifetime,
|
||||
]),
|
||||
|
||||
@@ -27,14 +27,14 @@ class EntityLog_2021_04_08 extends DatabaseScript {
|
||||
->after()->update($table)
|
||||
->exec(new CreateProcedure($sql, "UpdateEntityLog"), [
|
||||
"tableName" => new CurrentTable(),
|
||||
"entityId" => new CurrentColumn("uid"),
|
||||
"entityId" => new CurrentColumn("id"),
|
||||
]),
|
||||
|
||||
$sql->createTrigger("${table}_trg_delete")
|
||||
->after()->delete($table)
|
||||
->exec(new CreateProcedure($sql, "DeleteEntityLog"), [
|
||||
"tableName" => new CurrentTable(),
|
||||
"entityId" => new CurrentColumn("uid"),
|
||||
"entityId" => new CurrentColumn("id"),
|
||||
])
|
||||
];
|
||||
}
|
||||
@@ -51,32 +51,32 @@ class EntityLog_2021_04_08 extends DatabaseScript {
|
||||
|
||||
$insertProcedure = $sql->createProcedure("InsertEntityLog")
|
||||
->param(new CurrentTable())
|
||||
->param(new IntColumn("uid"))
|
||||
->param(new IntColumn("id"))
|
||||
->param(new IntColumn("lifetime", false, 90))
|
||||
->returns(new Trigger())
|
||||
->exec(array(
|
||||
$sql->insert("EntityLog", ["entityId", "tableName", "lifetime"])
|
||||
->addRow(new CurrentColumn("uid"), new CurrentTable(), new CurrentColumn("lifetime"))
|
||||
->addRow(new CurrentColumn("id"), new CurrentTable(), new CurrentColumn("lifetime"))
|
||||
));
|
||||
|
||||
$updateProcedure = $sql->createProcedure("UpdateEntityLog")
|
||||
->param(new CurrentTable())
|
||||
->param(new IntColumn("uid"))
|
||||
->param(new IntColumn("id"))
|
||||
->returns(new Trigger())
|
||||
->exec(array(
|
||||
$sql->update("EntityLog")
|
||||
->set("modified", $sql->now())
|
||||
->where(new Compare("entityId", new CurrentColumn("uid")))
|
||||
->where(new Compare("entityId", new CurrentColumn("id")))
|
||||
->where(new Compare("tableName", new CurrentTable()))
|
||||
));
|
||||
|
||||
$deleteProcedure = $sql->createProcedure("DeleteEntityLog")
|
||||
->param(new CurrentTable())
|
||||
->param(new IntColumn("uid"))
|
||||
->param(new IntColumn("id"))
|
||||
->returns(new Trigger())
|
||||
->exec(array(
|
||||
$sql->delete("EntityLog")
|
||||
->where(new Compare("entityId", new CurrentColumn("uid")))
|
||||
->where(new Compare("entityId", new CurrentColumn("id")))
|
||||
->where(new Compare("tableName", new CurrentTable()))
|
||||
));
|
||||
|
||||
|
||||
@@ -9,14 +9,6 @@ class SystemLog_2022_03_30 extends DatabaseScript {
|
||||
|
||||
public static function createQueries(SQL $sql): array {
|
||||
return [
|
||||
$sql->createTable("SystemLog")
|
||||
->onlyIfNotExists()
|
||||
->addSerial("id")
|
||||
->addDateTime("timestamp", false, $sql->now())
|
||||
->addString("message")
|
||||
->addString("module", 64, false, "global")
|
||||
->addEnum("severity", ["debug", "info", "warning", "error", "severe"])
|
||||
->primaryKey("id"),
|
||||
$sql->insert("ApiPermission", ["method", "groups", "description"])
|
||||
->addRow("Logs/get", [USER_GROUP_ADMIN], "Allows users to fetch system logs")
|
||||
];
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
namespace Configuration;
|
||||
|
||||
use Driver\SQL\Query\Insert;
|
||||
use Objects\User;
|
||||
use Objects\Context;
|
||||
|
||||
class Settings {
|
||||
|
||||
@@ -58,8 +58,8 @@ class Settings {
|
||||
return $settings;
|
||||
}
|
||||
|
||||
public function loadFromDatabase(User $user): bool {
|
||||
$req = new \Api\Settings\Get($user);
|
||||
public function loadFromDatabase(Context $context): bool {
|
||||
$req = new \Api\Settings\Get($context);
|
||||
$success = $req->execute();
|
||||
|
||||
if ($success) {
|
||||
@@ -78,7 +78,7 @@ class Settings {
|
||||
$this->allowedExtensions = explode(",", $result["allowed_extensions"] ?? strtolower(implode(",", $this->allowedExtensions)));
|
||||
|
||||
if (!isset($result["jwt_secret"])) {
|
||||
$req = new \Api\Settings\Set($user);
|
||||
$req = new \Api\Settings\Set($context);
|
||||
$req->execute(array("settings" => array(
|
||||
"jwt_secret" => $this->jwtSecret
|
||||
)));
|
||||
@@ -135,4 +135,8 @@ class Settings {
|
||||
public function isExtensionAllowed(string $ext): bool {
|
||||
return empty($this->allowedExtensions) || in_array(strtolower(trim($ext)), $this->allowedExtensions);
|
||||
}
|
||||
|
||||
public function getDomain(): string {
|
||||
return parse_url($this->getBaseUrl(), PHP_URL_HOST);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user