Moved render_info and render_error into Template class.

This commit is contained in:
flash 2023-08-31 15:59:53 +00:00
parent 45500ce698
commit c14195c4c3
45 changed files with 330 additions and 582 deletions

View file

@ -22,7 +22,6 @@ Environment::setDebug(MSZ_DEBUG);
mb_internal_encoding('utf-8'); mb_internal_encoding('utf-8');
date_default_timezone_set('utc'); date_default_timezone_set('utc');
require_once MSZ_ROOT . '/utility.php';
require_once MSZ_SOURCE . '/url.php'; require_once MSZ_SOURCE . '/url.php';
$dbConfig = parse_ini_file(MSZ_CONFIG . '/config.ini', true, INI_SCANNER_TYPED); $dbConfig = parse_ini_file(MSZ_CONFIG . '/config.ini', true, INI_SCANNER_TYPED);

View file

@ -5,25 +5,17 @@ use RuntimeException;
$redirect = filter_input(INPUT_GET, 'return') ?? $_SERVER['HTTP_REFERER'] ?? url('index'); $redirect = filter_input(INPUT_GET, 'return') ?? $_SERVER['HTTP_REFERER'] ?? url('index');
if(!is_local_url($redirect)) { if(!is_local_url($redirect))
echo render_info('Possible request forgery detected.', 403); Template::displayInfo('Possible request forgery detected.', 403);
return;
}
if(!CSRF::validateRequest()) { if(!CSRF::validateRequest())
echo render_info("Couldn't verify this request, please refresh the page and try again.", 403); Template::displayInfo("Couldn't verify this request, please refresh the page and try again.", 403);
return;
}
if(!$msz->isLoggedIn()) { if(!$msz->isLoggedIn())
echo render_info('You must be logged in to manage comments.', 403); Template::displayInfo('You must be logged in to manage comments.', 403);
return;
}
if($msz->hasActiveBan()) { if($msz->hasActiveBan())
echo render_info('You have been banned, check your profile for more information.', 403); Template::displayInfo('You have been banned, check your profile for more information.', 403);
return;
}
$currentUserInfo = $msz->getActiveUser(); $currentUserInfo = $msz->getActiveUser();
@ -38,50 +30,37 @@ if(!empty($commentId)) {
try { try {
$commentInfo = $comments->getPost($commentId); $commentInfo = $comments->getPost($commentId);
} catch(RuntimeException $ex) { } catch(RuntimeException $ex) {
echo render_info('Post not found.', 404); Template::displayInfo('Post not found.', 404);
return;
} }
$categoryInfo = $comments->getCategory(postInfo: $commentInfo); $categoryInfo = $comments->getCategory(postInfo: $commentInfo);
} }
if($commentMode !== 'create' && empty($commentInfo)) { if($commentMode !== 'create' && empty($commentInfo))
echo render_error(400); Template::throwError(400);
return;
}
switch($commentMode) { switch($commentMode) {
case 'pin': case 'pin':
case 'unpin': case 'unpin':
if(!$perms->check(Perm::G_COMMENTS_PIN) && !$categoryInfo->isOwner($currentUserInfo)) { if(!$perms->check(Perm::G_COMMENTS_PIN) && !$categoryInfo->isOwner($currentUserInfo))
echo render_info("You're not allowed to pin comments.", 403); Template::displayInfo("You're not allowed to pin comments.", 403);
break;
}
if($commentInfo->isDeleted()) { if($commentInfo->isDeleted())
echo render_info("This comment doesn't exist!", 400); Template::displayInfo("This comment doesn't exist!", 400);
break;
}
if($commentInfo->isReply()) { if($commentInfo->isReply())
echo render_info("You can't pin replies!", 400); Template::displayInfo("You can't pin replies!", 400);
break;
}
$isPinning = $commentMode === 'pin'; $isPinning = $commentMode === 'pin';
if($isPinning) { if($isPinning) {
if($commentInfo->isPinned()) { if($commentInfo->isPinned())
echo render_info('This comment is already pinned.', 400); Template::displayInfo('This comment is already pinned.', 400);
break;
}
$comments->pinPost($commentInfo); $comments->pinPost($commentInfo);
} else { } else {
if(!$commentInfo->isPinned()) { if(!$commentInfo->isPinned())
echo render_info("This comment isn't pinned yet.", 400); Template::displayInfo("This comment isn't pinned yet.", 400);
break;
}
$comments->unpinPost($commentInfo); $comments->unpinPost($commentInfo);
} }
@ -90,15 +69,11 @@ switch($commentMode) {
break; break;
case 'vote': case 'vote':
if(!$perms->check(Perm::G_COMMENTS_VOTE) && !$categoryInfo->isOwner($currentUserInfo)) { if(!$perms->check(Perm::G_COMMENTS_VOTE) && !$categoryInfo->isOwner($currentUserInfo))
echo render_info("You're not allowed to vote on comments.", 403); Template::displayInfo("You're not allowed to vote on comments.", 403);
break;
}
if($commentInfo->isDeleted()) { if($commentInfo->isDeleted())
echo render_info("This comment doesn't exist!", 400); Template::displayInfo("This comment doesn't exist!", 400);
break;
}
if($commentVote > 0) if($commentVote > 0)
$comments->addPostPositiveVote($commentInfo, $currentUserInfo); $comments->addPostPositiveVote($commentInfo, $currentUserInfo);
@ -112,27 +87,21 @@ switch($commentMode) {
case 'delete': case 'delete':
$canDelete = $perms->check(Perm::G_COMMENTS_DELETE_OWN | Perm::G_COMMENTS_DELETE_ANY); $canDelete = $perms->check(Perm::G_COMMENTS_DELETE_OWN | Perm::G_COMMENTS_DELETE_ANY);
if(!$canDelete && !$categoryInfo->isOwner($currentUserInfo)) { if(!$canDelete && !$categoryInfo->isOwner($currentUserInfo))
echo render_info("You're not allowed to delete comments.", 403); Template::displayInfo("You're not allowed to delete comments.", 403);
break;
}
$canDeleteAny = $perms->check(Perm::G_COMMENTS_DELETE_ANY); $canDeleteAny = $perms->check(Perm::G_COMMENTS_DELETE_ANY);
if($commentInfo->isDeleted()) { if($commentInfo->isDeleted())
echo render_info( Template::displayInfo(
$canDeleteAny ? 'This comment is already marked for deletion.' : "This comment doesn't exist.", $canDeleteAny ? 'This comment is already marked for deletion.' : "This comment doesn't exist.",
400 400
); );
break;
}
$isOwnComment = $commentInfo->getUserId() === $currentUserInfo->getId(); $isOwnComment = $commentInfo->getUserId() === $currentUserInfo->getId();
$isModAction = $canDeleteAny && !$isOwnComment; $isModAction = $canDeleteAny && !$isOwnComment;
if(!$isModAction && !$isOwnComment) { if(!$isModAction && !$isOwnComment)
echo render_info("You're not allowed to delete comments made by others.", 403); Template::displayInfo("You're not allowed to delete comments made by others.", 403);
break;
}
$comments->deletePost($commentInfo); $comments->deletePost($commentInfo);
@ -150,15 +119,11 @@ switch($commentMode) {
break; break;
case 'restore': case 'restore':
if(!$perms->check(Perm::G_COMMENTS_DELETE_ANY)) { if(!$perms->check(Perm::G_COMMENTS_DELETE_ANY))
echo render_info("You're not allowed to restore deleted comments.", 403); Template::displayInfo("You're not allowed to restore deleted comments.", 403);
break;
}
if(!$commentInfo->isDeleted()) { if(!$commentInfo->isDeleted())
echo render_info("This comment isn't in a deleted state.", 400); Template::displayInfo("This comment isn't in a deleted state.", 400);
break;
}
$comments->restorePost($commentInfo); $comments->restorePost($commentInfo);
@ -172,15 +137,11 @@ switch($commentMode) {
break; break;
case 'create': case 'create':
if(!$perms->check(Perm::G_COMMENTS_CREATE) && !$categoryInfo->isOwner($currentUserInfo)) { if(!$perms->check(Perm::G_COMMENTS_CREATE) && !$categoryInfo->isOwner($currentUserInfo))
echo render_info("You're not allowed to post comments.", 403); Template::displayInfo("You're not allowed to post comments.", 403);
break;
}
if(empty($_POST['comment']) || !is_array($_POST['comment'])) { if(empty($_POST['comment']) || !is_array($_POST['comment']))
echo render_info('Missing data.', 400); Template::displayInfo('Missing data.', 400);
break;
}
try { try {
$categoryId = isset($_POST['comment']['category']) && is_string($_POST['comment']['category']) $categoryId = isset($_POST['comment']['category']) && is_string($_POST['comment']['category'])
@ -188,15 +149,12 @@ switch($commentMode) {
: 0; : 0;
$categoryInfo = $comments->getCategory(categoryId: $categoryId); $categoryInfo = $comments->getCategory(categoryId: $categoryId);
} catch(RuntimeException $ex) { } catch(RuntimeException $ex) {
echo render_info('This comment category doesn\'t exist.', 404); Template::displayInfo('This comment category doesn\'t exist.', 404);
break;
} }
$canLock = $perms->check(Perm::G_COMMENTS_LOCK); $canLock = $perms->check(Perm::G_COMMENTS_LOCK);
if($categoryInfo->isLocked() && !$canLock) { if($categoryInfo->isLocked() && !$canLock)
echo render_info('This comment category has been locked.', 403); Template::displayInfo('This comment category has been locked.', 403);
break;
}
$commentText = !empty($_POST['comment']['text']) && is_string($_POST['comment']['text']) ? $_POST['comment']['text'] : ''; $commentText = !empty($_POST['comment']['text']) && is_string($_POST['comment']['text']) ? $_POST['comment']['text'] : '';
$commentReply = (string)(!empty($_POST['comment']['reply']) && is_string($_POST['comment']['reply']) ? (int)$_POST['comment']['reply'] : 0); $commentReply = (string)(!empty($_POST['comment']['reply']) && is_string($_POST['comment']['reply']) ? (int)$_POST['comment']['reply'] : 0);
@ -214,27 +172,23 @@ switch($commentMode) {
$commentText = preg_replace("/[\r\n]{2,}/", "\n", $commentText); $commentText = preg_replace("/[\r\n]{2,}/", "\n", $commentText);
} else { } else {
if($canLock) { if($canLock) {
echo render_info('The action has been processed.', 400); Template::displayInfo('The action has been processed.', 400);
} else { } else {
echo render_info('Your comment is too short.', 400); Template::displayInfo('Your comment is too short.', 400);
} }
break; break;
} }
if(mb_strlen($commentText) > 5000) { if(mb_strlen($commentText) > 5000)
echo render_info('Your comment is too long.', 400); Template::displayInfo('Your comment is too long.', 400);
break;
}
if($commentReply > 0) { if($commentReply > 0) {
try { try {
$parentInfo = $comments->getPost($commentReply); $parentInfo = $comments->getPost($commentReply);
} catch(RuntimeException $ex) {} } catch(RuntimeException $ex) {}
if(!isset($parentInfo) || $parentInfo->isDeleted()) { if(!isset($parentInfo) || $parentInfo->isDeleted())
echo render_info('The comment you tried to reply to does not exist.', 404); Template::displayInfo('The comment you tried to reply to does not exist.', 404);
break;
}
} }
$commentInfo = $comments->createPost( $commentInfo = $comments->createPost(
@ -249,5 +203,5 @@ switch($commentMode) {
break; break;
default: default:
echo render_info('Not found.', 404); Template::displayInfo('Not found.', 404);
} }

View file

@ -3,7 +3,6 @@ namespace Misuzu;
use stdClass; use stdClass;
use RuntimeException; use RuntimeException;
use Index\XArray;
$forum = $msz->getForum(); $forum = $msz->getForum();
$users = $msz->getUsers(); $users = $msz->getUsers();
@ -13,8 +12,7 @@ $categoryId = (int)filter_input(INPUT_GET, 'f', FILTER_SANITIZE_NUMBER_INT);
try { try {
$categoryInfo = $forum->getCategory(categoryId: $categoryId); $categoryInfo = $forum->getCategory(categoryId: $categoryId);
} catch(RuntimeException $ex) { } catch(RuntimeException $ex) {
echo render_error(404); Template::throwError(404);
return;
} }
$perms = $msz->getAuthInfo()->getPerms('forum', $categoryInfo); $perms = $msz->getAuthInfo()->getPerms('forum', $categoryInfo);
@ -22,10 +20,8 @@ $perms = $msz->getAuthInfo()->getPerms('forum', $categoryInfo);
$currentUser = $msz->getActiveUser(); $currentUser = $msz->getActiveUser();
$currentUserId = $currentUser === null ? '0' : $currentUser->getId(); $currentUserId = $currentUser === null ? '0' : $currentUser->getId();
if(!$perms->check(Perm::F_CATEGORY_VIEW)) { if(!$perms->check(Perm::F_CATEGORY_VIEW))
echo render_error(403); Template::throwError(403);
return;
}
if($msz->hasActiveBan()) if($msz->hasActiveBan())
$perms = $perms->apply(fn($calc) => $calc & (Perm::F_CATEGORY_LIST | Perm::F_CATEGORY_VIEW)); $perms = $perms->apply(fn($calc) => $calc & (Perm::F_CATEGORY_LIST | Perm::F_CATEGORY_VIEW));
@ -34,8 +30,10 @@ if($categoryInfo->isLink()) {
if($categoryInfo->hasLinkTarget()) { if($categoryInfo->hasLinkTarget()) {
$forum->incrementCategoryClicks($categoryInfo); $forum->incrementCategoryClicks($categoryInfo);
redirect($categoryInfo->getLinkTarget()); redirect($categoryInfo->getLinkTarget());
} else render_error(404); return;
return; }
Template::throwError(404);
} }
$forumPagination = new Pagination($forum->countTopics( $forumPagination = new Pagination($forum->countTopics(
@ -44,10 +42,8 @@ $forumPagination = new Pagination($forum->countTopics(
deleted: $perms->check(Perm::F_POST_DELETE_ANY) ? null : false deleted: $perms->check(Perm::F_POST_DELETE_ANY) ? null : false
), 20); ), 20);
if(!$forumPagination->hasValidOffset()) { if(!$forumPagination->hasValidOffset())
echo render_error(404); Template::throwError(404);
return;
}
$userInfos = []; $userInfos = [];
$userColours = []; $userColours = [];

View file

@ -12,10 +12,8 @@ $currentUser = $msz->getActiveUser();
$currentUserId = $currentUser === null ? '0' : $currentUser->getId(); $currentUserId = $currentUser === null ? '0' : $currentUser->getId();
if($mode === 'mark') { if($mode === 'mark') {
if(!$msz->isLoggedIn()) { if(!$msz->isLoggedIn())
echo render_error(403); Template::throwError(403);
return;
}
$categoryId = filter_input(INPUT_GET, 'f', FILTER_SANITIZE_NUMBER_INT); $categoryId = filter_input(INPUT_GET, 'f', FILTER_SANITIZE_NUMBER_INT);
@ -45,10 +43,8 @@ if($mode === 'mark') {
return; return;
} }
if($mode !== '') { if($mode !== '')
echo render_error(404); Template::throwError(404);
return;
}
$userInfos = []; $userInfos = [];
$userColours = []; $userColours = [];

View file

@ -3,10 +3,8 @@ namespace Misuzu;
use RuntimeException; use RuntimeException;
if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_FORUM_LEADERBOARD_VIEW)) { if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_FORUM_LEADERBOARD_VIEW))
echo render_error(403); Template::throwError(403);
return;
}
$forum = $msz->getForum(); $forum = $msz->getForum();
$users = $msz->getUsers(); $users = $msz->getUsers();
@ -26,23 +24,17 @@ $currentMonth = (int)date('m');
if(!empty($yearMonth)) { if(!empty($yearMonth)) {
$yearMonthLength = strlen($yearMonth); $yearMonthLength = strlen($yearMonth);
if(($yearMonthLength !== 4 && $yearMonthLength !== 6) || !ctype_digit($yearMonth)) { if(($yearMonthLength !== 4 && $yearMonthLength !== 6) || !ctype_digit($yearMonth))
echo render_error(404); Template::throwError(404);
return;
}
$year = (int)substr($yearMonth, 0, 4); $year = (int)substr($yearMonth, 0, 4);
if($year < $config['forum_leader.first_year'] || $year > $currentYear) { if($year < $config['forum_leader.first_year'] || $year > $currentYear)
echo render_error(404); Template::throwError(404);
return;
}
if($yearMonthLength === 6) { if($yearMonthLength === 6) {
$month = (int)substr($yearMonth, 4, 2); $month = (int)substr($yearMonth, 4, 2);
if($month < 1 || $month > 12 || ($year === $config['forum_leader.first_year'] && $month < $config['forum_leader.first_month'])) { if($month < 1 || $month > 12 || ($year === $config['forum_leader.first_year'] && $month < $config['forum_leader.first_month']))
echo render_error(404); Template::throwError(404);
return;
}
} }
} }

View file

@ -11,71 +11,52 @@ $submissionConfirmed = !empty($_GET['confirm']) && is_string($_GET['confirm']) &
$postRequestVerified = CSRF::validateRequest(); $postRequestVerified = CSRF::validateRequest();
if(!empty($postMode) && !$msz->isLoggedIn()) { if(!empty($postMode) && !$msz->isLoggedIn())
echo render_info('You must be logged in to manage posts.', 401); Template::displayInfo('You must be logged in to manage posts.', 401);
return;
}
$currentUser = $msz->getActiveUser(); $currentUser = $msz->getActiveUser();
$currentUserId = $currentUser === null ? '0' : $currentUser->getId(); $currentUserId = $currentUser === null ? '0' : $currentUser->getId();
if($postMode !== '' && $msz->hasActiveBan()) { if($postMode !== '' && $msz->hasActiveBan())
echo render_info('You have been banned, check your profile for more information.', 403); Template::displayInfo('You have been banned, check your profile for more information.', 403);
return;
}
try { try {
$postInfo = $forum->getPost(postId: $postId); $postInfo = $forum->getPost(postId: $postId);
} catch(RuntimeException $ex) { } catch(RuntimeException $ex) {
echo render_error(404); Template::throwError(404);
return;
} }
$perms = $msz->getAuthInfo()->getPerms('forum', $postInfo->getCategoryId()); $perms = $msz->getAuthInfo()->getPerms('forum', $postInfo->getCategoryId());
if(!$perms->check(Perm::F_CATEGORY_VIEW)) { if(!$perms->check(Perm::F_CATEGORY_VIEW))
echo render_error(403); Template::throwError(403);
return;
}
$canDeleteAny = $perms->check(Perm::F_POST_DELETE_ANY); $canDeleteAny = $perms->check(Perm::F_POST_DELETE_ANY);
switch($postMode) { switch($postMode) {
case 'delete': case 'delete':
if($canDeleteAny) { if($canDeleteAny) {
if($postInfo->isDeleted()) { if($postInfo->isDeleted())
echo render_info('This post has already been marked as deleted.', 404); Template::displayInfo('This post has already been marked as deleted.', 404);
return;
}
} else { } else {
if($postInfo->isDeleted()) { if($postInfo->isDeleted())
echo render_error(404); Template::throwError(404);
return;
}
if(!$perms->check(Perm::F_POST_DELETE_OWN)) { if(!$perms->check(Perm::F_POST_DELETE_OWN))
echo render_info('You are not allowed to delete posts.', 403); Template::displayInfo('You are not allowed to delete posts.', 403);
return;
}
if($postInfo->getUserId() !== $currentUser->getId()) { if($postInfo->getUserId() !== $currentUser->getId())
echo render_info('You can only delete your own posts.', 403); Template::displayInfo('You can only delete your own posts.', 403);
return;
}
// posts may only be deleted within a week of creation, this should be a config value // posts may only be deleted within a week of creation, this should be a config value
$deleteTimeFrame = 60 * 60 * 24 * 7; $deleteTimeFrame = 60 * 60 * 24 * 7;
if($postInfo->getCreatedTime() < time() - $deleteTimeFrame) { if($postInfo->getCreatedTime() < time() - $deleteTimeFrame)
echo render_info('This post has existed for too long. Ask a moderator to remove if it absolutely necessary.', 403); Template::displayInfo('This post has existed for too long. Ask a moderator to remove if it absolutely necessary.', 403);
return;
}
} }
$originalPostInfo = $forum->getPost(topicInfo: $postInfo->getTopicId()); $originalPostInfo = $forum->getPost(topicInfo: $postInfo->getTopicId());
if($originalPostInfo->getId() === $postInfo->getId()) { if($originalPostInfo->getId() === $postInfo->getId())
echo render_info('This is the opening post of the topic it belongs to, it may not be deleted without deleting the entire topic as well.', 403); Template::displayInfo('This is the opening post of the topic it belongs to, it may not be deleted without deleting the entire topic as well.', 403);
return;
}
if($postRequestVerified && !$submissionConfirmed) { if($postRequestVerified && !$submissionConfirmed) {
url_redirect('forum-post', [ url_redirect('forum-post', [
@ -103,10 +84,8 @@ switch($postMode) {
break; break;
case 'nuke': case 'nuke':
if(!$canDeleteAny) { if(!$canDeleteAny)
echo render_error(403); Template::throwError(403);
break;
}
if($postRequestVerified && !$submissionConfirmed) { if($postRequestVerified && !$submissionConfirmed) {
url_redirect('forum-post', [ url_redirect('forum-post', [
@ -134,10 +113,8 @@ switch($postMode) {
break; break;
case 'restore': case 'restore':
if(!$canDeleteAny) { if(!$canDeleteAny)
echo render_error(403); Template::throwError(403);
break;
}
if($postRequestVerified && !$submissionConfirmed) { if($postRequestVerified && !$submissionConfirmed) {
url_redirect('forum-post', [ url_redirect('forum-post', [

View file

@ -7,17 +7,13 @@ use Index\DateTime;
use Misuzu\Forum\ForumTopicInfo; use Misuzu\Forum\ForumTopicInfo;
use Misuzu\Parsers\Parser; use Misuzu\Parsers\Parser;
if(!$msz->isLoggedIn()) { if(!$msz->isLoggedIn())
echo render_error(401); Template::throwError(401);
return;
}
$currentUser = $msz->getActiveUser(); $currentUser = $msz->getActiveUser();
$currentUserId = $currentUser->getId(); $currentUserId = $currentUser->getId();
if($msz->hasActiveBan()) { if($msz->hasActiveBan())
echo render_error(403); Template::throwError(403);
return;
}
$forum = $msz->getForum(); $forum = $msz->getForum();
$users = $msz->getUsers(); $users = $msz->getUsers();
@ -42,10 +38,8 @@ if(!empty($_POST)) {
$forumId = !empty($_GET['f']) && is_string($_GET['f']) ? (int)$_GET['f'] : 0; $forumId = !empty($_GET['f']) && is_string($_GET['f']) ? (int)$_GET['f'] : 0;
} }
if(!in_array($mode, $forumPostingModes, true)) { if(!in_array($mode, $forumPostingModes, true))
echo render_error(400); Template::throwError(400);
return;
}
if($mode === 'preview') { if($mode === 'preview') {
header('Content-Type: text/plain; charset=utf-8'); header('Content-Type: text/plain; charset=utf-8');
@ -63,10 +57,8 @@ if($mode === 'preview') {
return; return;
} }
if(empty($postId) && empty($topicId) && empty($forumId)) { if(empty($postId) && empty($topicId) && empty($forumId))
echo render_error(404); Template::throwError(404);
return;
}
if(empty($postId)) { if(empty($postId)) {
$hasPostInfo = false; $hasPostInfo = false;
@ -74,14 +66,11 @@ if(empty($postId)) {
try { try {
$postInfo = $forum->getPost(postId: $postId); $postInfo = $forum->getPost(postId: $postId);
} catch(RuntimeException $ex) { } catch(RuntimeException $ex) {
echo render_error(404); Template::throwError(404);
return;
} }
if($postInfo->isDeleted()) { if($postInfo->isDeleted())
echo render_error(404); Template::throwError(404);
return;
}
// should automatic cross-quoting be a thing? if so, check if $topicId is < 1 first <-- what did i mean by this? // should automatic cross-quoting be a thing? if so, check if $topicId is < 1 first <-- what did i mean by this?
$topicId = $postInfo->getTopicId(); $topicId = $postInfo->getTopicId();
@ -94,14 +83,11 @@ if(empty($topicId)) {
try { try {
$topicInfo = $forum->getTopic(topicId: $topicId); $topicInfo = $forum->getTopic(topicId: $topicId);
} catch(RuntimeException $ex) { } catch(RuntimeException $ex) {
echo render_error(404); Template::throwError(404);
return;
} }
if($topicInfo->isDeleted()) { if($topicInfo->isDeleted())
echo render_error(404); Template::throwError(404);
return;
}
$forumId = $topicInfo->getCategoryId(); $forumId = $topicInfo->getCategoryId();
$originalPostInfo = $forum->getPost(topicInfo: $topicInfo); $originalPostInfo = $forum->getPost(topicInfo: $topicInfo);
@ -114,8 +100,7 @@ if(empty($forumId)) {
try { try {
$categoryInfo = $forum->getCategory(categoryId: $forumId); $categoryInfo = $forum->getCategory(categoryId: $forumId);
} catch(RuntimeException $ex) { } catch(RuntimeException $ex) {
echo render_error(404); Template::throwError(404);
return;
} }
$hasCategoryInfo = true; $hasCategoryInfo = true;
@ -127,15 +112,11 @@ if($categoryInfo->isArchived()
|| (isset($topicInfo) && $topicInfo->isLocked() && !$perms->check(Perm::F_TOPIC_LOCK)) || (isset($topicInfo) && $topicInfo->isLocked() && !$perms->check(Perm::F_TOPIC_LOCK))
|| !$perms->check(Perm::F_CATEGORY_VIEW) || !$perms->check(Perm::F_CATEGORY_VIEW)
|| !$perms->check(Perm::F_POST_CREATE) || !$perms->check(Perm::F_POST_CREATE)
|| (!isset($topicInfo) && !$perms->check(Perm::F_TOPIC_CREATE))) { || (!isset($topicInfo) && !$perms->check(Perm::F_TOPIC_CREATE)))
echo render_error(403); Template::throwError(403);
return;
}
if(!$categoryInfo->mayHaveTopics()) { if(!$categoryInfo->mayHaveTopics())
echo render_error(400); Template::throwError(400);
return;
}
$topicTypes = []; $topicTypes = [];
@ -151,10 +132,8 @@ if($mode === 'create' || $mode === 'edit') {
} }
// edit mode stuff // edit mode stuff
if($mode === 'edit' && !$perms->check($postInfo->getUserId() === $currentUserId ? Perm::F_POST_EDIT_OWN : Perm::F_POST_EDIT_ANY)) { if($mode === 'edit' && !$perms->check($postInfo->getUserId() === $currentUserId ? Perm::F_POST_EDIT_OWN : Perm::F_POST_EDIT_ANY))
echo render_error(403); Template::throwError(403);
return;
}
$notices = []; $notices = [];

View file

@ -20,18 +20,15 @@ if($topicId < 1 && $postId > 0) {
try { try {
$postInfo = $forum->getPost(postId: $postId); $postInfo = $forum->getPost(postId: $postId);
} catch(RuntimeException $ex) { } catch(RuntimeException $ex) {
echo render_error(404); Template::throwError(404);
return;
} }
$categoryId = $postInfo->getCategoryId(); $categoryId = $postInfo->getCategoryId();
$perms = $msz->getAuthInfo()->getPerms('forum', $postInfo->getCategoryId()); $perms = $msz->getAuthInfo()->getPerms('forum', $postInfo->getCategoryId());
$canDeleteAny = $perms->check(Perm::F_POST_DELETE_ANY); $canDeleteAny = $perms->check(Perm::F_POST_DELETE_ANY);
if($postInfo->isDeleted() && !$canDeleteAny) { if($postInfo->isDeleted() && !$canDeleteAny)
echo render_error(404); Template::throwError(404);
return;
}
$topicId = $postInfo->getTopicId(); $topicId = $postInfo->getTopicId();
$preceedingPostCount = $forum->countPosts( $preceedingPostCount = $forum->countPosts(
@ -68,17 +65,15 @@ if(($topicIsNuked || $topicIsDeleted) && $forum->hasTopicRedirect($topicId)) {
if($topicIsNuked || !$canDeleteAny) { if($topicIsNuked || !$canDeleteAny) {
if(empty($topicRedirectInfo)) if(empty($topicRedirectInfo))
echo render_error(404); Template::throwError(404);
else
header('Location: ' . $topicRedirectInfo->getLinkTarget()); header('Location: ' . $topicRedirectInfo->getLinkTarget());
return; return;
} }
} }
if(!$perms->check(Perm::F_CATEGORY_VIEW)) { if(!$perms->check(Perm::F_CATEGORY_VIEW))
echo render_error(403); Template::throwError(403);
return;
}
// Maximum amount of posts a topic may contain to still be deletable by the author // Maximum amount of posts a topic may contain to still be deletable by the author
// this should be in the config // this should be in the config
@ -108,57 +103,39 @@ $validModerationModes = [
]; ];
if(in_array($moderationMode, $validModerationModes, true)) { if(in_array($moderationMode, $validModerationModes, true)) {
if(!CSRF::validateRequest()) { if(!CSRF::validateRequest())
echo render_info("Couldn't verify this request, please refresh the page and try again.", 403); Template::displayInfo("Couldn't verify this request, please refresh the page and try again.", 403);
return;
}
if(!$msz->isLoggedIn()) { if(!$msz->isLoggedIn())
echo render_info('You must be logged in to manage posts.', 401); Template::displayInfo('You must be logged in to manage posts.', 401);
return;
}
if($msz->hasActiveBan()) { if($msz->hasActiveBan())
echo render_info('You have been banned, check your profile for more information.', 403); Template::displayInfo('You have been banned, check your profile for more information.', 403);
return;
}
switch($moderationMode) { switch($moderationMode) {
case 'delete': case 'delete':
if($canDeleteAny) { if($canDeleteAny) {
if($topicInfo->isDeleted()) { if($topicInfo->isDeleted())
echo render_info('This topic has already been marked as deleted.', 404); Template::displayInfo('This topic has already been marked as deleted.', 404);
return;
}
} else { } else {
if($topicInfo->isDeleted()) { if($topicInfo->isDeleted())
echo render_error(404); Template::throwError(404);
return;
}
if(!$canDeleteOwn) { if(!$canDeleteOwn)
echo render_info("You aren't allowed to delete topics.", 403); Template::displayInfo("You aren't allowed to delete topics.", 403);
return;
}
if($topicInfo->getUserId() !== $currentUser->getId()) { if($topicInfo->getUserId() !== $currentUser->getId())
echo render_info('You can only delete your own topics.', 403); Template::displayInfo('You can only delete your own topics.', 403);
return;
}
// topics may only be deleted within a day of creation, this should be a config value // topics may only be deleted within a day of creation, this should be a config value
$deleteTimeFrame = 60 * 60 * 24; $deleteTimeFrame = 60 * 60 * 24;
if($topicInfo->getCreatedTime() < time() - $deleteTimeFrame) { if($topicInfo->getCreatedTime() < time() - $deleteTimeFrame)
echo render_info('This topic has existed for too long. Ask a moderator to remove if it absolutely necessary.', 403); Template::displayInfo('This topic has existed for too long. Ask a moderator to remove if it absolutely necessary.', 403);
return;
}
// deleted posts are intentionally included // deleted posts are intentionally included
$topicPostCount = $forum->countPosts(topicInfo: $topicInfo); $topicPostCount = $forum->countPosts(topicInfo: $topicInfo);
if($topicPostCount > $deletePostThreshold) { if($topicPostCount > $deletePostThreshold)
echo render_info('This topic already has replies, you may no longer delete it. Ask a moderator to remove if it absolutely necessary.', 403); Template::displayInfo('This topic already has replies, you may no longer delete it. Ask a moderator to remove if it absolutely necessary.', 403);
return;
}
} }
if(!isset($_GET['confirm'])) { if(!isset($_GET['confirm'])) {
@ -189,10 +166,8 @@ if(in_array($moderationMode, $validModerationModes, true)) {
break; break;
case 'restore': case 'restore':
if(!$canNukeOrRestore) { if(!$canNukeOrRestore)
echo render_error(403); Template::throwError(403);
break;
}
if(!isset($_GET['confirm'])) { if(!isset($_GET['confirm'])) {
Template::render('forum.confirm', [ Template::render('forum.confirm', [
@ -221,10 +196,8 @@ if(in_array($moderationMode, $validModerationModes, true)) {
break; break;
case 'nuke': case 'nuke':
if(!$canNukeOrRestore) { if(!$canNukeOrRestore)
echo render_error(403); Template::throwError(403);
break;
}
if(!isset($_GET['confirm'])) { if(!isset($_GET['confirm'])) {
Template::render('forum.confirm', [ Template::render('forum.confirm', [
@ -297,10 +270,8 @@ $topicPagination = new Pagination($topicPosts, 10, 'page');
if(isset($preceedingPostCount)) if(isset($preceedingPostCount))
$topicPagination->setPage(floor($preceedingPostCount / $topicPagination->getRange()), true); $topicPagination->setPage(floor($preceedingPostCount / $topicPagination->getRange()), true);
if(!$topicPagination->hasValidOffset()) { if(!$topicPagination->hasValidOffset())
echo render_error(404); Template::throwError(404);
return;
}
$postInfos = $forum->getPosts( $postInfos = $forum->getPosts(
topicInfo: $topicInfo, topicInfo: $topicInfo,
@ -308,10 +279,8 @@ $postInfos = $forum->getPosts(
pagination: $topicPagination, pagination: $topicPagination,
); );
if(empty($postInfos)) { if(empty($postInfos))
echo render_error(404); Template::throwError(404);
return;
}
$originalPostInfo = $forum->getPost(topicInfo: $topicInfo); $originalPostInfo = $forum->getPost(topicInfo: $topicInfo);

View file

@ -7,10 +7,8 @@ use Index\DateTime;
use Index\XArray; use Index\XArray;
use Misuzu\Changelog\Changelog; use Misuzu\Changelog\Changelog;
if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_CL_CHANGES_MANAGE)) { if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_CL_CHANGES_MANAGE))
echo render_error(403); Template::throwError(403);
return;
}
$changeActions = []; $changeActions = [];
foreach(Changelog::ACTIONS as $action) foreach(Changelog::ACTIONS as $action)
@ -30,16 +28,16 @@ else
$changeInfo = $changelog->getChange($changeId); $changeInfo = $changelog->getChange($changeId);
$changeTagIds = XArray::select($changelog->getTags(changeInfo: $changeInfo), fn($tagInfo) => $tagInfo->getId()); $changeTagIds = XArray::select($changelog->getTags(changeInfo: $changeInfo), fn($tagInfo) => $tagInfo->getId());
} catch(RuntimeException $ex) { } catch(RuntimeException $ex) {
echo render_error(404); Template::throwError(404);
return;
} }
if($_SERVER['REQUEST_METHOD'] === 'GET' && !empty($_GET['delete'])) { if($_SERVER['REQUEST_METHOD'] === 'GET' && !empty($_GET['delete'])) {
if(CSRF::validateRequest()) { if(!CSRF::validateRequest())
$changelog->deleteChange($changeInfo); Template::throwError(403);
$msz->createAuditLog('CHANGELOG_ENTRY_DELETE', [$changeInfo->getId()]);
url_redirect('manage-changelog-changes'); $changelog->deleteChange($changeInfo);
} else render_error(403); $msz->createAuditLog('CHANGELOG_ENTRY_DELETE', [$changeInfo->getId()]);
url_redirect('manage-changelog-changes');
return; return;
} }

View file

@ -3,18 +3,14 @@ namespace Misuzu;
use RuntimeException; use RuntimeException;
if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_CL_CHANGES_MANAGE)) { if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_CL_CHANGES_MANAGE))
echo render_error(403); Template::throwError(403);
return;
}
$changelog = $msz->getChangelog(); $changelog = $msz->getChangelog();
$changelogPagination = new Pagination($changelog->countChanges(), 30); $changelogPagination = new Pagination($changelog->countChanges(), 30);
if(!$changelogPagination->hasValidOffset()) { if(!$changelogPagination->hasValidOffset())
echo render_error(404); Template::throwError(404);
return;
}
$changeInfos = $changelog->getChanges(pagination: $changelogPagination); $changeInfos = $changelog->getChanges(pagination: $changelogPagination);
$changes = []; $changes = [];

View file

@ -3,10 +3,8 @@ namespace Misuzu;
use RuntimeException; use RuntimeException;
if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_CL_TAGS_MANAGE)) { if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_CL_TAGS_MANAGE))
echo render_error(403); Template::throwError(403);
return;
}
$changelog = $msz->getChangelog(); $changelog = $msz->getChangelog();
$tagId = (string)filter_input(INPUT_GET, 't', FILTER_SANITIZE_NUMBER_INT); $tagId = (string)filter_input(INPUT_GET, 't', FILTER_SANITIZE_NUMBER_INT);
@ -19,16 +17,16 @@ else
$isNew = false; $isNew = false;
$tagInfo = $loadTagInfo(); $tagInfo = $loadTagInfo();
} catch(RuntimeException $ex) { } catch(RuntimeException $ex) {
echo render_error(404); Template::throwError(404);
return;
} }
if($_SERVER['REQUEST_METHOD'] === 'GET' && !empty($_GET['delete'])) { if($_SERVER['REQUEST_METHOD'] === 'GET' && !empty($_GET['delete'])) {
if(CSRF::validateRequest()) { if(!CSRF::validateRequest())
$changelog->deleteTag($tagInfo); Template::throwError(403);
$msz->createAuditLog('CHANGELOG_TAG_DELETE', [$tagInfo->getId()]);
url_redirect('manage-changelog-tags'); $changelog->deleteTag($tagInfo);
} else render_error(403); $msz->createAuditLog('CHANGELOG_TAG_DELETE', [$tagInfo->getId()]);
url_redirect('manage-changelog-tags');
return; return;
} }

View file

@ -1,10 +1,8 @@
<?php <?php
namespace Misuzu; namespace Misuzu;
if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_CL_TAGS_MANAGE)) { if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_CL_TAGS_MANAGE))
echo render_error(403); Template::throwError(403);
return;
}
Template::render('manage.changelog.tags', [ Template::render('manage.changelog.tags', [
'changelog_tags' => $msz->getChangelog()->getTags(), 'changelog_tags' => $msz->getChangelog()->getTags(),

View file

@ -3,10 +3,8 @@ namespace Misuzu;
use Misuzu\Perm; use Misuzu\Perm;
if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_FORUM_CATEGORIES_MANAGE)) { if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_FORUM_CATEGORIES_MANAGE))
echo render_error(403); Template::throwError(403);
return;
}
$perms = $msz->getPerms(); $perms = $msz->getPerms();
$permsInfos = $perms->getPermissionInfo(categoryNames: Perm::INFO_FOR_FORUM_CATEGORY); $permsInfos = $perms->getPermissionInfo(categoryNames: Perm::INFO_FOR_FORUM_CATEGORY);

View file

@ -1,10 +1,8 @@
<?php <?php
namespace Misuzu; namespace Misuzu;
if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_FORUM_TOPIC_REDIRS_MANAGE)) { if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_FORUM_TOPIC_REDIRS_MANAGE))
echo render_error(403); Template::throwError(403);
return;
}
$forum = $msz->getForum(); $forum = $msz->getForum();
@ -33,10 +31,8 @@ if(filter_input(INPUT_GET, 'm') === 'explode') {
} }
$pagination = new Pagination($forum->countTopicRedirects(), 20); $pagination = new Pagination($forum->countTopicRedirects(), 20);
if(!$pagination->hasValidOffset()) { if(!$pagination->hasValidOffset())
echo render_error(404); Template::throwError(404);
return;
}
$redirs = $forum->getTopicRedirects(pagination: $pagination); $redirs = $forum->getTopicRedirects(pagination: $pagination);

View file

@ -4,10 +4,8 @@ namespace Misuzu;
use RuntimeException; use RuntimeException;
use Index\XArray; use Index\XArray;
if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_EMOTES_MANAGE)) { if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_EMOTES_MANAGE))
echo render_error(403); Template::throwError(403);
return;
}
$emotes = $msz->getEmotes(); $emotes = $msz->getEmotes();
$emoteId = (string)filter_input(INPUT_GET, 'e', FILTER_SANITIZE_NUMBER_INT); $emoteId = (string)filter_input(INPUT_GET, 'e', FILTER_SANITIZE_NUMBER_INT);
@ -20,8 +18,7 @@ else
$emoteInfo = $emotes->getEmote($emoteId); $emoteInfo = $emotes->getEmote($emoteId);
$emoteStrings = $emotes->getEmoteStrings($emoteInfo); $emoteStrings = $emotes->getEmoteStrings($emoteInfo);
} catch(RuntimeException $ex) { } catch(RuntimeException $ex) {
echo render_error(404); Template::throwError(404);
return;
} }
// make errors not echos lol // make errors not echos lol

View file

@ -3,10 +3,8 @@ namespace Misuzu;
use RuntimeException; use RuntimeException;
if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_EMOTES_MANAGE)) { if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_EMOTES_MANAGE))
echo render_error(403); Template::throwError(403);
return;
}
$emotes = $msz->getEmotes(); $emotes = $msz->getEmotes();
@ -16,8 +14,7 @@ if(CSRF::validateRequest() && !empty($_GET['emote'])) {
try { try {
$emoteInfo = $emotes->getEmote($emoteId); $emoteInfo = $emotes->getEmote($emoteId);
} catch(RuntimeException $ex) { } catch(RuntimeException $ex) {
echo render_error(404); Template::throwError(404);
return;
} }
if(!empty($_GET['delete'])) { if(!empty($_GET['delete'])) {

View file

@ -3,19 +3,15 @@ namespace Misuzu;
use Misuzu\Pagination; use Misuzu\Pagination;
if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_LOGS_VIEW)) { if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_LOGS_VIEW))
echo render_error(403); Template::throwError(403);
return;
}
$users = $msz->getUsers(); $users = $msz->getUsers();
$auditLog = $msz->getAuditLog(); $auditLog = $msz->getAuditLog();
$pagination = new Pagination($auditLog->countLogs(), 50); $pagination = new Pagination($auditLog->countLogs(), 50);
if(!$pagination->hasValidOffset()) { if(!$pagination->hasValidOffset())
echo render_error(404); Template::throwError(404);
return;
}
$logs = $auditLog->getLogs(pagination: $pagination); $logs = $auditLog->getLogs(pagination: $pagination);
$userInfos = []; $userInfos = [];

View file

@ -3,17 +3,13 @@ namespace Misuzu;
use Misuzu\Config\CfgTools; use Misuzu\Config\CfgTools;
if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_CONFIG_MANAGE)) { if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_CONFIG_MANAGE))
echo render_error(403); Template::throwError(403);
return;
}
$valueName = (string)filter_input(INPUT_GET, 'name'); $valueName = (string)filter_input(INPUT_GET, 'name');
$valueInfo = $cfg->getValueInfo($valueName); $valueInfo = $cfg->getValueInfo($valueName);
if($valueInfo === null) { if($valueInfo === null)
echo render_error(404); Template::throwError(404);
return;
}
if($_SERVER['REQUEST_METHOD'] === 'POST' && CSRF::validateRequest()) { if($_SERVER['REQUEST_METHOD'] === 'POST' && CSRF::validateRequest()) {
$valueName = $valueInfo->getName(); $valueName = $valueInfo->getName();

View file

@ -3,10 +3,8 @@ namespace Misuzu;
use Misuzu\Config\DbConfig; use Misuzu\Config\DbConfig;
if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_CONFIG_MANAGE)) { if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_CONFIG_MANAGE))
echo render_error(403); Template::throwError(403);
return;
}
$isNew = true; $isNew = true;
$sName = (string)filter_input(INPUT_GET, 'name'); $sName = (string)filter_input(INPUT_GET, 'name');

View file

@ -1,10 +1,8 @@
<?php <?php
namespace Misuzu; namespace Misuzu;
if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_CONFIG_MANAGE)) { if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_CONFIG_MANAGE))
echo render_error(403); Template::throwError(403);
return;
}
$hidden = $cfg->getArray('settings.hidden'); $hidden = $cfg->getArray('settings.hidden');
$vars = $cfg->getAllValueInfos(); $vars = $cfg->getAllValueInfos();

View file

@ -1,18 +1,14 @@
<?php <?php
namespace Misuzu; namespace Misuzu;
if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_NEWS_CATEGORIES_MANAGE)) { if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_NEWS_CATEGORIES_MANAGE))
echo render_error(403); Template::throwError(403);
return;
}
$news = $msz->getNews(); $news = $msz->getNews();
$pagination = new Pagination($news->countCategories(), 15); $pagination = new Pagination($news->countCategories(), 15);
if(!$pagination->hasValidOffset()) { if(!$pagination->hasValidOffset())
echo render_error(404); Template::throwError(404);
return;
}
$categories = $news->getCategories(pagination: $pagination); $categories = $news->getCategories(pagination: $pagination);

View file

@ -3,10 +3,8 @@ namespace Misuzu;
use RuntimeException; use RuntimeException;
if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_NEWS_CATEGORIES_MANAGE)) { if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_NEWS_CATEGORIES_MANAGE))
echo render_error(403); Template::throwError(403);
return;
}
$news = $msz->getNews(); $news = $msz->getNews();
$categoryId = (string)filter_input(INPUT_GET, 'c', FILTER_SANITIZE_NUMBER_INT); $categoryId = (string)filter_input(INPUT_GET, 'c', FILTER_SANITIZE_NUMBER_INT);
@ -19,16 +17,16 @@ else
$isNew = false; $isNew = false;
$categoryInfo = $loadCategoryInfo(); $categoryInfo = $loadCategoryInfo();
} catch(RuntimeException $ex) { } catch(RuntimeException $ex) {
echo render_error(404); Template::throwError(404);
return;
} }
if($_SERVER['REQUEST_METHOD'] === 'GET' && !empty($_GET['delete'])) { if($_SERVER['REQUEST_METHOD'] === 'GET' && !empty($_GET['delete'])) {
if(CSRF::validateRequest()) { if(!CSRF::validateRequest())
$news->deleteCategory($categoryInfo); Template::throwError(403);
$msz->createAuditLog('NEWS_CATEGORY_DELETE', [$categoryInfo->getId()]);
url_redirect('manage-news-categories'); $news->deleteCategory($categoryInfo);
} else render_error(403); $msz->createAuditLog('NEWS_CATEGORY_DELETE', [$categoryInfo->getId()]);
url_redirect('manage-news-categories');
return; return;
} }

View file

@ -3,10 +3,8 @@ namespace Misuzu;
use RuntimeException; use RuntimeException;
if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_NEWS_POSTS_MANAGE)) { if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_NEWS_POSTS_MANAGE))
echo render_error(403); Template::throwError(403);
return;
}
$news = $msz->getNews(); $news = $msz->getNews();
$postId = (string)filter_input(INPUT_GET, 'p', FILTER_SANITIZE_NUMBER_INT); $postId = (string)filter_input(INPUT_GET, 'p', FILTER_SANITIZE_NUMBER_INT);
@ -19,16 +17,16 @@ else
$isNew = false; $isNew = false;
$postInfo = $loadPostInfo(); $postInfo = $loadPostInfo();
} catch(RuntimeException $ex) { } catch(RuntimeException $ex) {
echo render_error(404); Template::throwError(404);
return;
} }
if($_SERVER['REQUEST_METHOD'] === 'GET' && !empty($_GET['delete'])) { if($_SERVER['REQUEST_METHOD'] === 'GET' && !empty($_GET['delete'])) {
if(CSRF::validateRequest()) { if(!CSRF::validateRequest())
$news->deletePost($postInfo); Template::throwError(403);
$msz->createAuditLog('NEWS_POST_DELETE', [$postInfo->getId()]);
url_redirect('manage-news-posts'); $news->deletePost($postInfo);
} else render_error(403); $msz->createAuditLog('NEWS_POST_DELETE', [$postInfo->getId()]);
url_redirect('manage-news-posts');
return; return;
} }

View file

@ -1,10 +1,8 @@
<?php <?php
namespace Misuzu; namespace Misuzu;
if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_NEWS_POSTS_MANAGE)) { if(!$msz->getAuthInfo()->getPerms('global')->check(Perm::G_NEWS_POSTS_MANAGE))
echo render_error(403); Template::throwError(403);
return;
}
$news = $msz->getNews(); $news = $msz->getNews();
$pagination = new Pagination($news->countPosts( $pagination = new Pagination($news->countPosts(
@ -12,10 +10,8 @@ $pagination = new Pagination($news->countPosts(
includeDeleted: true includeDeleted: true
), 15); ), 15);
if(!$pagination->hasValidOffset()) { if(!$pagination->hasValidOffset())
echo render_error(404); Template::throwError(404);
return;
}
$posts = $news->getAllPosts( $posts = $news->getAllPosts(
includeScheduled: true, includeScheduled: true,

View file

@ -5,26 +5,24 @@ use DateTimeInterface;
use RuntimeException; use RuntimeException;
use Index\DateTime; use Index\DateTime;
if(!$msz->getAuthInfo()->getPerms('user')->check(Perm::U_BANS_MANAGE)) { if(!$msz->getAuthInfo()->getPerms('user')->check(Perm::U_BANS_MANAGE))
echo render_error(403); Template::throwError(403);
return;
}
$bans = $msz->getBans(); $bans = $msz->getBans();
if($_SERVER['REQUEST_METHOD'] === 'GET' && filter_has_var(INPUT_GET, 'delete')) { if($_SERVER['REQUEST_METHOD'] === 'GET' && filter_has_var(INPUT_GET, 'delete')) {
if(CSRF::validateRequest()) { if(!CSRF::validateRequest())
try { Template::throwError(403);
$banInfo = $bans->getBan((string)filter_input(INPUT_GET, 'b'));
} catch(RuntimeException $ex) {
echo render_error(404);
return;
}
$bans->deleteBans($banInfo); try {
$msz->createAuditLog('BAN_DELETE', [$banInfo->getId(), $banInfo->getUserId()]); $banInfo = $bans->getBan((string)filter_input(INPUT_GET, 'b'));
url_redirect('manage-users-bans', ['user' => $banInfo->getUserId()]); } catch(RuntimeException $ex) {
} else render_error(403); Template::throwError(404);
}
$bans->deleteBans($banInfo);
$msz->createAuditLog('BAN_DELETE', [$banInfo->getId(), $banInfo->getUserId()]);
url_redirect('manage-users-bans', ['user' => $banInfo->getUserId()]);
return; return;
} }
@ -33,8 +31,7 @@ $users = $msz->getUsers();
try { try {
$userInfo = $users->getUser(filter_input(INPUT_GET, 'u', FILTER_SANITIZE_NUMBER_INT), 'id'); $userInfo = $users->getUser(filter_input(INPUT_GET, 'u', FILTER_SANITIZE_NUMBER_INT), 'id');
} catch(RuntimeException $ex) { } catch(RuntimeException $ex) {
echo render_error(404); Template::throwError(404);
return;
} }
$modInfo = $msz->getActiveUser(); $modInfo = $msz->getActiveUser();

View file

@ -3,10 +3,8 @@ namespace Misuzu;
use RuntimeException; use RuntimeException;
if(!$msz->getAuthInfo()->getPerms('user')->check(Perm::U_BANS_MANAGE)) { if(!$msz->getAuthInfo()->getPerms('user')->check(Perm::U_BANS_MANAGE))
echo render_error(403); Template::throwError(403);
return;
}
$users = $msz->getUsers(); $users = $msz->getUsers();
@ -25,18 +23,15 @@ if(filter_has_var(INPUT_GET, 'u')) {
$userInfos[$filterUserId] = $filterUser; $userInfos[$filterUserId] = $filterUser;
$userColours[$filterUserId] = $users->getUserColour($filterUser); $userColours[$filterUserId] = $users->getUserColour($filterUser);
} catch(RuntimeException $ex) { } catch(RuntimeException $ex) {
echo render_error(404); Template::throwError(404);
return;
} }
} }
$bans = $msz->getBans(); $bans = $msz->getBans();
$pagination = new Pagination($bans->countBans(userInfo: $filterUser), 10); $pagination = new Pagination($bans->countBans(userInfo: $filterUser), 10);
if(!$pagination->hasValidOffset()) { if(!$pagination->hasValidOffset())
echo render_error(404); Template::throwError(404);
return;
}
$banList = []; $banList = [];
$banInfos = $bans->getBans(userInfo: $filterUser, activeFirst: true, pagination: $pagination); $banInfos = $bans->getBans(userInfo: $filterUser, activeFirst: true, pagination: $pagination);

View file

@ -1,19 +1,15 @@
<?php <?php
namespace Misuzu; namespace Misuzu;
if(!$msz->getAuthInfo()->getPerms('user')->check(Perm::U_USERS_MANAGE)) { if(!$msz->getAuthInfo()->getPerms('user')->check(Perm::U_USERS_MANAGE))
echo render_error(403); Template::throwError(403);
return;
}
$users = $msz->getUsers(); $users = $msz->getUsers();
$roles = $msz->getRoles(); $roles = $msz->getRoles();
$pagination = new Pagination($users->countUsers(), 30); $pagination = new Pagination($users->countUsers(), 30);
if(!$pagination->hasValidOffset()) { if(!$pagination->hasValidOffset())
echo render_error(404); Template::throwError(404);
return;
}
$userList = []; $userList = [];
$userInfos = $users->getUsers(pagination: $pagination, orderBy: 'id'); $userInfos = $users->getUsers(pagination: $pagination, orderBy: 'id');

View file

@ -3,18 +3,14 @@ namespace Misuzu;
use RuntimeException; use RuntimeException;
if(!$msz->getAuthInfo()->getPerms('user')->check(Perm::U_NOTES_MANAGE)) { if(!$msz->getAuthInfo()->getPerms('user')->check(Perm::U_NOTES_MANAGE))
echo render_error(403); Template::throwError(403);
return;
}
$hasNoteId = filter_has_var(INPUT_GET, 'n'); $hasNoteId = filter_has_var(INPUT_GET, 'n');
$hasUserId = filter_has_var(INPUT_GET, 'u'); $hasUserId = filter_has_var(INPUT_GET, 'u');
if((!$hasNoteId && !$hasUserId) || ($hasNoteId && $hasUserId)) { if((!$hasNoteId && !$hasUserId) || ($hasNoteId && $hasUserId))
echo render_error(400); Template::throwError(400);
return;
}
$users = $msz->getUsers(); $users = $msz->getUsers();
$modNotes = $msz->getModNotes(); $modNotes = $msz->getModNotes();
@ -25,8 +21,7 @@ if($hasUserId) {
try { try {
$userInfo = $users->getUser(filter_input(INPUT_GET, 'u', FILTER_SANITIZE_NUMBER_INT), 'id'); $userInfo = $users->getUser(filter_input(INPUT_GET, 'u', FILTER_SANITIZE_NUMBER_INT), 'id');
} catch(RuntimeException $ex) { } catch(RuntimeException $ex) {
echo render_error(404); Template::throwError(404);
return;
} }
$authorInfo = $msz->getActiveUser(); $authorInfo = $msz->getActiveUser();
@ -36,16 +31,16 @@ if($hasUserId) {
try { try {
$noteInfo = $modNotes->getNote((string)filter_input(INPUT_GET, 'n', FILTER_SANITIZE_NUMBER_INT)); $noteInfo = $modNotes->getNote((string)filter_input(INPUT_GET, 'n', FILTER_SANITIZE_NUMBER_INT));
} catch(RuntimeException $ex) { } catch(RuntimeException $ex) {
echo render_error(404); Template::throwError(404);
return;
} }
if($_SERVER['REQUEST_METHOD'] === 'GET' && filter_has_var(INPUT_GET, 'delete')) { if($_SERVER['REQUEST_METHOD'] === 'GET' && filter_has_var(INPUT_GET, 'delete')) {
if(CSRF::validateRequest()) { if(!CSRF::validateRequest())
$modNotes->deleteNotes($noteInfo); Template::throwError(403);
$msz->createAuditLog('MOD_NOTE_DELETE', [$noteInfo->getId(), $noteInfo->getUserId()]);
url_redirect('manage-users-notes', ['user' => $noteInfo->getUserId()]); $modNotes->deleteNotes($noteInfo);
} else render_error(403); $msz->createAuditLog('MOD_NOTE_DELETE', [$noteInfo->getId(), $noteInfo->getUserId()]);
url_redirect('manage-users-notes', ['user' => $noteInfo->getUserId()]);
return; return;
} }

View file

@ -3,10 +3,8 @@ namespace Misuzu;
use RuntimeException; use RuntimeException;
if(!$msz->getAuthInfo()->getPerms('user')->check(Perm::U_NOTES_MANAGE)) { if(!$msz->getAuthInfo()->getPerms('user')->check(Perm::U_NOTES_MANAGE))
echo render_error(403); Template::throwError(403);
return;
}
$users = $msz->getUsers(); $users = $msz->getUsers();
@ -25,18 +23,15 @@ if(filter_has_var(INPUT_GET, 'u')) {
$userInfos[$filterUserId] = $filterUser; $userInfos[$filterUserId] = $filterUser;
$userColours[$filterUserId] = $users->getUserColour($filterUser); $userColours[$filterUserId] = $users->getUserColour($filterUser);
} catch(RuntimeException $ex) { } catch(RuntimeException $ex) {
echo render_error(404); Template::throwError(404);
return;
} }
} }
$modNotes = $msz->getModNotes(); $modNotes = $msz->getModNotes();
$pagination = new Pagination($modNotes->countNotes(userInfo: $filterUser), 10); $pagination = new Pagination($modNotes->countNotes(userInfo: $filterUser), 10);
if(!$pagination->hasValidOffset()) { if(!$pagination->hasValidOffset())
echo render_error(404); Template::throwError(404);
return;
}
$notes = []; $notes = [];
$noteInfos = $modNotes->getNotes(userInfo: $filterUser, pagination: $pagination); $noteInfos = $modNotes->getNotes(userInfo: $filterUser, pagination: $pagination);

View file

@ -7,10 +7,8 @@ use Index\Colour\ColourRGB;
use Misuzu\Perm; use Misuzu\Perm;
$viewerPerms = $msz->getAuthInfo()->getPerms('user'); $viewerPerms = $msz->getAuthInfo()->getPerms('user');
if(!$viewerPerms->check(Perm::U_ROLES_MANAGE)) { if(!$viewerPerms->check(Perm::U_ROLES_MANAGE))
echo render_error(403); Template::throwError(403);
return;
}
$users = $msz->getUsers(); $users = $msz->getUsers();
$roles = $msz->getRoles(); $roles = $msz->getRoles();
@ -23,8 +21,7 @@ if(filter_has_var(INPUT_GET, 'r')) {
$isNew = false; $isNew = false;
$roleInfo = $roles->getRole($roleId); $roleInfo = $roles->getRole($roleId);
} catch(RuntimeException $ex) { } catch(RuntimeException $ex) {
echo render_error(404); Template::throwError(404);
return;
} }
} else $isNew = true; } else $isNew = true;

View file

@ -1,18 +1,14 @@
<?php <?php
namespace Misuzu; namespace Misuzu;
if(!$msz->getAuthInfo()->getPerms('user')->check(Perm::U_ROLES_MANAGE)) { if(!$msz->getAuthInfo()->getPerms('user')->check(Perm::U_ROLES_MANAGE))
echo render_error(403); Template::throwError(403);
return;
}
$roles = $msz->getRoles(); $roles = $msz->getRoles();
$pagination = new Pagination($roles->countRoles(), 10); $pagination = new Pagination($roles->countRoles(), 10);
if(!$pagination->hasValidOffset()) { if(!$pagination->hasValidOffset())
echo render_error(404); Template::throwError(404);
return;
}
$rolesAll = []; $rolesAll = [];
$roleInfos = $roles->getRoles(pagination: $pagination); $roleInfos = $roles->getRoles(pagination: $pagination);

View file

@ -8,10 +8,8 @@ use Misuzu\Auth\AuthTokenCookie;
use Misuzu\Users\User; use Misuzu\Users\User;
$viewerPerms = $msz->getAuthInfo()->getPerms('user'); $viewerPerms = $msz->getAuthInfo()->getPerms('user');
if(!$msz->isLoggedIn()) { if(!$msz->isLoggedIn())
echo render_error(403); Template::throwError(403);
return;
}
$users = $msz->getUsers(); $users = $msz->getUsers();
$roles = $msz->getRoles(); $roles = $msz->getRoles();
@ -28,10 +26,8 @@ $canImpersonate = $viewerPerms->check(Perm::U_CAN_IMPERSONATE);
$canSendTestMail = $currentUser->isSuperUser(); $canSendTestMail = $currentUser->isSuperUser();
$hasAccess = $canManageUsers || $canManageNotes || $canManageWarnings || $canManageBans; $hasAccess = $canManageUsers || $canManageNotes || $canManageWarnings || $canManageBans;
if(!$hasAccess) { if(!$hasAccess)
echo render_error(403); Template::throwError(403);
return;
}
$notices = []; $notices = [];
$userId = (int)filter_input(INPUT_GET, 'u', FILTER_SANITIZE_NUMBER_INT); $userId = (int)filter_input(INPUT_GET, 'u', FILTER_SANITIZE_NUMBER_INT);
@ -39,8 +35,7 @@ $userId = (int)filter_input(INPUT_GET, 'u', FILTER_SANITIZE_NUMBER_INT);
try { try {
$userInfo = $users->getUser($userId, 'id'); $userInfo = $users->getUser($userId, 'id');
} catch(RuntimeException $ex) { } catch(RuntimeException $ex) {
echo render_error(404); Template::throwError(404);
return;
} }
$currentUserRank = $users->getUserRank($currentUser); $currentUserRank = $users->getUserRank($currentUser);

View file

@ -3,26 +3,24 @@ namespace Misuzu;
use RuntimeException; use RuntimeException;
if(!$msz->getAuthInfo()->getPerms('user')->check(Perm::U_WARNINGS_MANAGE)) { if(!$msz->getAuthInfo()->getPerms('user')->check(Perm::U_WARNINGS_MANAGE))
echo render_error(403); Template::throwError(403);
return;
}
$warns = $msz->getWarnings(); $warns = $msz->getWarnings();
if($_SERVER['REQUEST_METHOD'] === 'GET' && filter_has_var(INPUT_GET, 'delete')) { if($_SERVER['REQUEST_METHOD'] === 'GET' && filter_has_var(INPUT_GET, 'delete')) {
if(CSRF::validateRequest()) { if(!CSRF::validateRequest())
try { Template::throwError(403);
$warnInfo = $warns->getWarning((string)filter_input(INPUT_GET, 'w'));
} catch(RuntimeException $ex) {
echo render_error(404);
return;
}
$warns->deleteWarnings($warnInfo); try {
$msz->createAuditLog('WARN_DELETE', [$warnInfo->getId(), $warnInfo->getUserId()]); $warnInfo = $warns->getWarning((string)filter_input(INPUT_GET, 'w'));
url_redirect('manage-users-warnings', ['user' => $warnInfo->getUserId()]); } catch(RuntimeException $ex) {
} else render_error(403); Template::throwError(404);
}
$warns->deleteWarnings($warnInfo);
$msz->createAuditLog('WARN_DELETE', [$warnInfo->getId(), $warnInfo->getUserId()]);
url_redirect('manage-users-warnings', ['user' => $warnInfo->getUserId()]);
return; return;
} }
@ -31,8 +29,7 @@ $users = $msz->getUsers();
try { try {
$userInfo = $users->getUser(filter_input(INPUT_GET, 'u', FILTER_SANITIZE_NUMBER_INT), 'id'); $userInfo = $users->getUser(filter_input(INPUT_GET, 'u', FILTER_SANITIZE_NUMBER_INT), 'id');
} catch(RuntimeException $ex) { } catch(RuntimeException $ex) {
echo render_error(404); Template::throwError(404);
return;
} }
$modInfo = $msz->getActiveUser(); $modInfo = $msz->getActiveUser();

View file

@ -3,10 +3,8 @@ namespace Misuzu;
use RuntimeException; use RuntimeException;
if(!$msz->getAuthInfo()->getPerms('user')->check(Perm::U_WARNINGS_MANAGE)) { if(!$msz->getAuthInfo()->getPerms('user')->check(Perm::U_WARNINGS_MANAGE))
echo render_error(403); Template::throwError(403);
return;
}
$users = $msz->getUsers(); $users = $msz->getUsers();
@ -25,18 +23,15 @@ if(filter_has_var(INPUT_GET, 'u')) {
$userInfos[$filterUserId] = $filterUser; $userInfos[$filterUserId] = $filterUser;
$userColours[$filterUserId] = $users->getUserColour($filterUser); $userColours[$filterUserId] = $users->getUserColour($filterUser);
} catch(RuntimeException $ex) { } catch(RuntimeException $ex) {
echo render_error(404); Template::throwError(404);
return;
} }
} }
$warns = $msz->getWarnings(); $warns = $msz->getWarnings();
$pagination = new Pagination($warns->countWarnings(userInfo: $filterUser), 10); $pagination = new Pagination($warns->countWarnings(userInfo: $filterUser), 10);
if(!$pagination->hasValidOffset()) { if(!$pagination->hasValidOffset())
echo render_error(404); Template::throwError(404);
return;
}
$warnList = []; $warnList = [];
$warnInfos = $warns->getWarnings(userInfo: $filterUser, pagination: $pagination); $warnInfos = $warns->getWarnings(userInfo: $filterUser, pagination: $pagination);

View file

@ -3,10 +3,8 @@ namespace Misuzu;
use RuntimeException; use RuntimeException;
if(!$msz->isLoggedIn()) { if(!$msz->isLoggedIn())
echo render_error(403); Template::throwError(403);
return;
}
// TODO: restore forum-topics and forum-posts orderings // TODO: restore forum-topics and forum-posts orderings
@ -53,8 +51,7 @@ $orderFields = [
if(empty($orderBy)) { if(empty($orderBy)) {
$orderBy = $defaultOrder; $orderBy = $defaultOrder;
} elseif(!array_key_exists($orderBy, $orderFields)) { } elseif(!array_key_exists($orderBy, $orderFields)) {
echo render_error(400); Template::throwError(400);
return;
} }
if(array_key_exists('alt', $orderFields[$orderBy])) if(array_key_exists('alt', $orderFields[$orderBy]))
@ -63,8 +60,7 @@ if(array_key_exists('alt', $orderFields[$orderBy]))
if(empty($orderDir)) { if(empty($orderDir)) {
$orderDir = 'asc'; $orderDir = 'asc';
} elseif(!array_key_exists($orderDir, $orderDirs)) { } elseif(!array_key_exists($orderDir, $orderDirs)) {
echo render_error(400); Template::throwError(400);
return;
} }
if($roleId === null) { if($roleId === null) {
@ -73,8 +69,7 @@ if($roleId === null) {
try { try {
$roleInfo = $roles->getRole($roleId); $roleInfo = $roles->getRole($roleId);
} catch(RuntimeException $ex) { } catch(RuntimeException $ex) {
echo render_error(404); Template::throwError(404);
return;
} }
} }

View file

@ -46,8 +46,7 @@ if($userInfo->isDeleted()) {
switch($profileMode) { switch($profileMode) {
default: default:
echo render_error(404); Template::throwError(404);
return;
case 'forum-topics': case 'forum-topics':
url_redirect('search-query', ['query' => sprintf('type:forum:topic author:%s', $userInfo->getName()), 'section' => 'topics']); url_redirect('search-query', ['query' => sprintf('type:forum:topic author:%s', $userInfo->getName()), 'section' => 'topics']);
@ -80,10 +79,8 @@ $avatarInfo = new UserAvatarAsset($userInfo);
$backgroundInfo = new UserBackgroundAsset($userInfo); $backgroundInfo = new UserBackgroundAsset($userInfo);
if($isEditing) { if($isEditing) {
if(!$canEdit) { if(!$canEdit)
echo render_error(403); Template::throwError(403);
return;
}
$perms = $viewerPerms->checkMany([ $perms = $viewerPerms->checkMany([
'edit_profile' => Perm::U_PROFILE_EDIT, 'edit_profile' => Perm::U_PROFILE_EDIT,

View file

@ -6,10 +6,8 @@ use RuntimeException;
use Index\XArray; use Index\XArray;
use Misuzu\Comments\CommentsCategory; use Misuzu\Comments\CommentsCategory;
if(!$msz->isLoggedIn()) { if(!$msz->isLoggedIn())
echo render_error(403); Template::throwError(403);
return;
}
$searchQuery = !empty($_GET['q']) && is_string($_GET['q']) ? $_GET['q'] : ''; $searchQuery = !empty($_GET['q']) && is_string($_GET['q']) ? $_GET['q'] : '';

View file

@ -6,10 +6,8 @@ use Misuzu\Users\User;
use chillerlan\QRCode\QRCode; use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions; use chillerlan\QRCode\QROptions;
if(!$msz->isLoggedIn()) { if(!$msz->isLoggedIn())
echo render_error(401); Template::throwError(401);
return;
}
$errors = []; $errors = [];
$users = $msz->getUsers(); $users = $msz->getUsers();

View file

@ -6,10 +6,8 @@ use Index\XString;
use Index\IO\FileStream; use Index\IO\FileStream;
use Misuzu\Users\UserInfo; use Misuzu\Users\UserInfo;
if(!$msz->isLoggedIn()) { if(!$msz->isLoggedIn())
echo render_error(401); Template::throwError(401);
return;
}
$dbConn = $msz->getDbConn(); $dbConn = $msz->getDbConn();

View file

@ -1,9 +1,7 @@
<?php <?php
namespace Misuzu; namespace Misuzu;
if(!$msz->isLoggedIn()) { if(!$msz->isLoggedIn())
echo render_error(401); Template::throwError(401);
return;
}
url_redirect('settings-account'); url_redirect('settings-account');

View file

@ -4,10 +4,8 @@ namespace Misuzu;
use Misuzu\Pagination; use Misuzu\Pagination;
$currentUser = $msz->getActiveUser(); $currentUser = $msz->getActiveUser();
if($currentUser === null) { if($currentUser === null)
echo render_error(401); Template::throwError(401);
return;
}
$loginAttempts = $msz->getLoginAttempts(); $loginAttempts = $msz->getLoginAttempts();
$auditLog = $msz->getAuditLog(); $auditLog = $msz->getAuditLog();

View file

@ -3,10 +3,8 @@ namespace Misuzu;
use RuntimeException; use RuntimeException;
if(!$msz->isLoggedIn()) { if(!$msz->isLoggedIn())
echo render_error(401); Template::throwError(401);
return;
}
$errors = []; $errors = [];
$sessions = $msz->getSessions(); $sessions = $msz->getSessions();

View file

@ -236,10 +236,8 @@ if($inManageMode) {
} }
} }
if(!$hasManageAccess) { if(!$hasManageAccess)
echo render_error(403); Template::throwError(403);
exit;
}
} }
$mszRequestPath = $request->getPath(); $mszRequestPath = $request->getPath();

View file

@ -59,4 +59,19 @@ final class Template {
throw new InvalidArgumentException('First parameter must be of type array or string.'); throw new InvalidArgumentException('First parameter must be of type array or string.');
} }
} }
public static function displayInfo(?string $message, int $statusCode, ?string $template = null): never {
http_response_code($statusCode);
self::$vars['http_code'] = $statusCode;
if(!empty($message))
self::$vars['message'] = $message;
self::render(sprintf($template ?? 'errors.%d', $statusCode));
exit;
}
public static function throwError(int $statusCode, ?string $template = null): never {
self::displayInfo(null, $statusCode, $template);
}
} }

View file

@ -1,19 +0,0 @@
<?php
// render_error and render_info need to be nuked from orbit
function render_error(int $code, string $template = 'errors.%d'): string {
return render_info(null, $code, $template);
}
function render_info(?string $message, int $httpCode, string $template = 'errors.%d'): string {
http_response_code($httpCode);
\Misuzu\Template::set('http_code', $httpCode);
if(!empty($message))
\Misuzu\Template::set('message', $message);
$template = sprintf($template, $httpCode);
return \Misuzu\Template::renderRaw(sprintf($template, $httpCode));
}