misuzu/misuzu.php

262 lines
9.2 KiB
PHP
Raw Normal View History

<?php
namespace Misuzu;
2018-05-27 23:24:16 +00:00
date_default_timezone_set('UTC');
2018-04-30 21:39:43 +00:00
require_once __DIR__ . '/vendor/autoload.php';
2018-07-17 17:17:57 +00:00
require_once __DIR__ . '/src/audit_log.php';
2018-07-06 01:28:06 +00:00
require_once __DIR__ . '/src/changelog.php';
2018-04-30 21:39:43 +00:00
require_once __DIR__ . '/src/colour.php';
2018-07-10 21:24:00 +00:00
require_once __DIR__ . '/src/comments.php';
require_once __DIR__ . '/src/general.php';
require_once __DIR__ . '/src/git.php';
2018-07-07 23:24:34 +00:00
require_once __DIR__ . '/src/manage.php';
2018-07-08 19:24:59 +00:00
require_once __DIR__ . '/src/news.php';
2018-07-07 23:24:34 +00:00
require_once __DIR__ . '/src/perms.php';
2018-04-30 21:39:43 +00:00
require_once __DIR__ . '/src/zalgo.php';
2018-05-23 01:41:57 +00:00
require_once __DIR__ . '/src/Forum/forum.php';
require_once __DIR__ . '/src/Forum/post.php';
require_once __DIR__ . '/src/Forum/topic.php';
require_once __DIR__ . '/src/Forum/validate.php';
2018-05-16 02:58:21 +00:00
require_once __DIR__ . '/src/Users/login_attempt.php';
2018-05-27 00:20:35 +00:00
require_once __DIR__ . '/src/Users/profile.php';
require_once __DIR__ . '/src/Users/role.php';
require_once __DIR__ . '/src/Users/session.php';
require_once __DIR__ . '/src/Users/user.php';
2018-05-16 02:58:21 +00:00
require_once __DIR__ . '/src/Users/validation.php';
$app = new Application(
__DIR__ . '/config/config.ini',
IO\Directory::exists(__DIR__ . '/vendor/phpunit/phpunit')
);
$app->startDatabase();
if (PHP_SAPI === 'cli') {
if ($argv[0] === basename(__FILE__)) {
switch ($argv[1] ?? null) {
case 'cron':
// Ensure main role exists.
Database::exec("
INSERT IGNORE INTO `msz_roles`
(`role_id`, `role_name`, `role_hierarchy`, `role_colour`, `role_description`, `created_at`)
VALUES
(1, 'Member', 1, 1073741824, NULL, NOW())
");
// Ensures all users are in the main role.
Database::exec('
INSERT INTO `msz_user_roles`
(`user_id`, `role_id`)
SELECT `user_id`, 1 FROM `msz_users` as u
WHERE NOT EXISTS (
SELECT 1
FROM `msz_user_roles` as ur
WHERE `role_id` = 1
AND u.`user_id` = ur.`user_id`
)
');
// Ensures all display_role values are correct with `msz_user_roles`
Database::exec('
UPDATE `msz_users` as u
SET `display_role` = (
SELECT ur.`role_id`
FROM `msz_user_roles` as ur
LEFT JOIN `msz_roles` as r
ON r.`role_id` = ur.`role_id`
WHERE ur.`user_id` = u.`user_id`
ORDER BY `role_hierarchy` DESC
LIMIT 1
)
WHERE NOT EXISTS (
SELECT 1
FROM `msz_user_roles` as ur
WHERE ur.`role_id` = u.`display_role`
AND `ur`.`user_id` = u.`user_id`
)
');
2018-07-17 17:55:28 +00:00
// Deletes expired sessions
Database::exec('
DELETE FROM `msz_sessions`
WHERE `expires_on` < NOW()
');
2018-07-21 23:54:12 +00:00
// Remove old password reset records, left for a week for possible review
Database::exec('
DELETE FROM `msz_users_password_resets`
WHERE `reset_requested` < NOW() - INTERVAL 1 WEEK
');
2018-07-17 17:55:28 +00:00
// Cleans up the login history table
Database::exec('
DELETE FROM `msz_login_attempts`
WHERE `created_at` < NOW() - INTERVAL 1 YEAR
');
// Cleans up the audit log table
Database::exec('
DELETE FROM `msz_audit_log`
WHERE `log_created` < NOW() - INTERVAL 1 YEAR
');
break;
case 'migrate':
$migrationTargets = [
2018-08-06 22:19:35 +00:00
'mysql-main' => __DIR__ . '/database',
];
$doRollback = !empty($argv[2]) && $argv[2] === 'rollback';
$targetDb = isset($argv[$doRollback ? 3 : 2]) ? $argv[$doRollback ? 3 : 2] : null;
if ($targetDb !== null && !array_key_exists($targetDb, $migrationTargets)) {
echo 'Invalid target database connection.' . PHP_EOL;
break;
}
foreach ($migrationTargets as $db => $path) {
echo "Creating migration manager for '{$db}'..." . PHP_EOL;
$migrationManager = new DatabaseMigrationManager(Database::connection($db), $path);
$migrationManager->setLogger(function ($log) {
echo $log . PHP_EOL;
});
if ($doRollback) {
echo "Rolling back last migrations for '{$db}'..." . PHP_EOL;
$migrationManager->rollback();
} else {
echo "Running migrations for '{$db}'..." . PHP_EOL;
$migrationManager->migrate();
}
$errors = $migrationManager->getErrors();
$errorCount = count($errors);
if ($errorCount < 1) {
echo 'Completed with no errors!' . PHP_EOL;
} else {
echo PHP_EOL . "There were {$errorCount} errors during the migrations..." . PHP_EOL;
foreach ($errors as $error) {
echo $error . PHP_EOL;
}
}
}
break;
case 'new-mig':
if (empty($argv[2])) {
echo 'Specify a migration name.' . PHP_EOL;
return;
}
if (!preg_match('#^([a-z_]+)$#', $argv[2])) {
echo 'Migration name may only contain alpha and _ characters.' . PHP_EOL;
return;
}
$filename = date('Y_m_d_His_') . trim($argv[2], '_') . '.php';
$filepath = __DIR__ . '/database/' . $filename;
$namespace = snake_to_camel($argv[2]);
$template = <<<MIG
<?php
namespace Misuzu\DatabaseMigrations\\$namespace;
use PDO;
function migrate_up(PDO \$conn): void
{
\$conn->exec('
CREATE TABLE ...
');
}
function migrate_down(PDO \$conn): void
{
\$conn->exec('DROP TABLE ...');
}
MIG;
file_put_contents($filepath, $template);
echo "Template for '{$namespace}' has been created." . PHP_EOL;
break;
default:
echo 'Unknown command.' . PHP_EOL;
break;
}
}
} else {
if (!$app->inDebugMode()) {
ob_start('ob_gzhandler');
}
// we're running this again because ob_clean breaks gzip otherwise
ob_start();
2018-07-14 17:57:21 +00:00
2018-03-24 04:31:42 +00:00
$storage_dir = $app->getStoragePath();
if (!$storage_dir->isReadable()
|| !$storage_dir->isWritable()) {
echo 'Cannot access storage directory.';
exit;
}
2018-07-15 22:39:39 +00:00
$app->startCache();
2018-07-07 23:24:34 +00:00
$app->startTemplating();
$tpl = $app->getTemplating();
if ($app->getConfig()->get('Auth', 'lockdown', 'bool', false)) {
2018-03-31 22:28:32 +00:00
http_response_code(503);
2018-07-07 23:24:34 +00:00
$tpl->addPath('auth', __DIR__ . '/views/auth');
echo $tpl->render('lockdown');
2018-03-31 22:28:32 +00:00
exit;
}
2018-07-07 23:24:34 +00:00
$tpl->addPath('mio', __DIR__ . '/views/mio');
2018-05-16 02:58:21 +00:00
2018-03-31 22:28:32 +00:00
if (isset($_COOKIE['msz_uid'], $_COOKIE['msz_sid'])) {
$app->startSession((int)$_COOKIE['msz_uid'], $_COOKIE['msz_sid']);
2018-05-16 02:58:21 +00:00
if ($app->hasActiveSession()) {
$bumpUserLast = Database::prepare('
2018-05-16 02:58:21 +00:00
UPDATE `msz_users` SET
`last_seen` = NOW(),
`last_ip` = INET6_ATON(:last_ip)
WHERE `user_id` = :user_id
');
$bumpUserLast->bindValue('last_ip', Net\IPAddress::remote()->getString());
$bumpUserLast->bindValue('user_id', $app->getUserId());
$bumpUserLast->execute();
$getUserDisplayInfo = Database::prepare('
2018-05-16 02:58:21 +00:00
SELECT
u.`user_id`, u.`username`,
2018-08-06 22:19:35 +00:00
COALESCE(u.`user_colour`, r.`role_colour`) as `user_colour`
2018-05-16 02:58:21 +00:00
FROM `msz_users` as u
LEFT JOIN `msz_roles` as r
ON u.`display_role` = r.`role_id`
WHERE `user_id` = :user_id
');
$getUserDisplayInfo->bindValue('user_id', $app->getUserId());
$userDisplayInfo = $getUserDisplayInfo->execute() ? $getUserDisplayInfo->fetch() : [];
2018-07-07 23:24:34 +00:00
$tpl->var('current_user', $userDisplayInfo);
}
2018-03-31 22:28:32 +00:00
}
2018-07-07 23:24:34 +00:00
$inManageMode = starts_with($_SERVER['REQUEST_URI'], '/manage');
2018-07-10 21:24:00 +00:00
$hasManageAccess = perms_check(perms_get_user(MSZ_PERMS_GENERAL, $app->getUserId()), MSZ_GENERAL_PERM_CAN_MANAGE);
2018-07-07 23:24:34 +00:00
$tpl->var('has_manage_access', $hasManageAccess);
2018-03-28 00:35:37 +00:00
2018-07-07 23:24:34 +00:00
if ($inManageMode) {
if (!$hasManageAccess) {
echo render_error(403);
2018-03-28 00:35:37 +00:00
exit;
}
2018-07-07 23:24:34 +00:00
$tpl = $app->getTemplating();
$tpl->var('manage_menu', manage_get_menu($app->getUserId()));
$tpl->addPath('manage', __DIR__ . '/views/manage');
2018-03-28 00:35:37 +00:00
}
}