Moved Templating stuff into a class and use Index CSRFP for verification.

This commit is contained in:
flash 2023-08-16 23:17:14 +00:00
parent 0d692454eb
commit 8b47c866ed
4 changed files with 76 additions and 52 deletions

4
composer.lock generated
View file

@ -12,7 +12,7 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://git.flash.moe/flash/index.git", "url": "https://git.flash.moe/flash/index.git",
"reference": "553b7c4a14aa7f2403c87ce474933986ac17d040" "reference": "a4c1d5627e590e669998f68cae64691b1ce0e0ac"
}, },
"require": { "require": {
"ext-mbstring": "*", "ext-mbstring": "*",
@ -50,7 +50,7 @@
], ],
"description": "Composer package for the common library for my projects.", "description": "Composer package for the common library for my projects.",
"homepage": "https://railgun.sh/index", "homepage": "https://railgun.sh/index",
"time": "2023-08-03T01:29:57+00:00" "time": "2023-08-16T23:03:01+00:00"
}, },
{ {
"name": "symfony/polyfill-ctype", "name": "symfony/polyfill-ctype",

View file

@ -2,54 +2,36 @@
namespace Mince; namespace Mince;
use Index\XString; use Index\XString;
use Index\Data\DbType;
use Index\Http\HttpFx; use Index\Http\HttpFx;
use Twig\Environment as TwigEnvironment; use Index\Security\CSRFP;
use Twig\Loader\FilesystemLoader as TwigLoaderFilesystem;
require_once __DIR__ . '/../mince.php'; require_once __DIR__ . '/../mince.php';
if(empty($_COOKIE['mc_random'])) {
$sVerification = XString::random(32);
setcookie('mc_random', $sVerification, strtotime('1 day'), '/', $_SERVER['HTTP_HOST']);
} else
$sVerification = (string)filter_input(INPUT_COOKIE, 'mc_random');
$sVerification = hash('sha256', $sVerification);
// replace this with id.flashii.net shit // replace this with id.flashii.net shit
$userInfo = ChatAuth::attempt($db, $config['chat_endpoint'], $config['chat_secret'], (string)filter_input(INPUT_COOKIE, 'msz_auth')); $authToken = (string)filter_input(INPUT_COOKIE, 'msz_auth');
$userInfo = ChatAuth::attempt($db, $config['chat_endpoint'], $config['chat_secret'], $authToken);
// need a more permanent solution for this $csrfp = new CSRFP(
$twigLoader = new TwigLoaderFilesystem([MCR_DIR_TPL]); $config['csrf_secret'],
$twigEnv = new TwigEnvironment($twigLoader, [ $userInfo->success ? $authToken : $_SERVER['REMOTE_ADDR']
//'cache' => $cache ?? false, );
'debug' => MCR_DEBUG,
'strict_variables' => true, $templating = new Templating;
]); $templating->addPath(MCR_DIR_TPL);
$twigArgs = [
$templating->addVars([
'global' => [ 'global' => [
'title' => 'Flashii Minecraft Servers', 'title' => 'Flashii Minecraft Servers',
'loginUrl' => $config['login_url'], 'loginUrl' => $config['login_url'],
], ],
'auth' => $userInfo, 'auth' => $userInfo,
'verification' => $sVerification, 'csrfp' => $csrfp->createToken(),
]; ]);
function tpl_vars(array $args): void {
global $twigArgs;
$twigArgs = array_merge($twigArgs, $args);
}
function tpl_render(string $name, array $args, string $suffix = '.twig'): string {
global $twigEnv, $twigArgs;
return $twigEnv->render($name . $suffix, array_merge($twigArgs, $args));
}
$router = new HttpFx; $router = new HttpFx;
$router->setDefaultErrorHandler(function($response, $request, $code, $text) use ($userInfo) { $router->setDefaultErrorHandler(function($response, $request, $code, $text) use ($userInfo, $templating) {
$response->setContent(tpl_render('http-error', [ $response->setContent($templating->render('http-error', [
'error' => [ 'error' => [
'code' => sprintf('%03d', $code), 'code' => sprintf('%03d', $code),
'text' => $text, 'text' => $text,
@ -57,7 +39,7 @@ $router->setDefaultErrorHandler(function($response, $request, $code, $text) use
])); ]));
}); });
$router->use('/', function($response) { $router->use('/', function($response, $request) {
$response->setPoweredBy('Mince'); $response->setPoweredBy('Mince');
}); });
@ -65,7 +47,7 @@ $router->get('/index.php', function($response) {
$response->redirect('/', true); $response->redirect('/', true);
}); });
$router->get('/', function($response, $request) use ($userInfo) { $router->get('/', function($response, $request) use ($userInfo, $templating) {
$name = (string)$request->getParam('name'); $name = (string)$request->getParam('name');
$error = (string)$request->getParam('error'); $error = (string)$request->getParam('error');
@ -90,7 +72,7 @@ $router->get('/', function($response, $request) use ($userInfo) {
$mErrorComment = $error; $mErrorComment = $error;
} }
tpl_vars([ $templating->addVars([
'error' => [ 'error' => [
'title' => $mErrorTitle, 'title' => $mErrorTitle,
'body' => $mErrorComment, 'body' => $mErrorComment,
@ -99,14 +81,14 @@ $router->get('/', function($response, $request) use ($userInfo) {
} }
if($userInfo->mc_whitelisted > 0) if($userInfo->mc_whitelisted > 0)
tpl_vars(['whitelist_pending' => floor($userInfo->mc_whitelisted / 300) === floor(time() / 300)]); $templating->setVar('whitelist_pending', floor($userInfo->mc_whitelisted / 300) === floor(time() / 300));
return tpl_render('index', [ return $templating->render('index', [
'wladdform_username' => $name, 'wladdform_username' => $name,
]); ]);
}); });
$router->use('/whitelist', function($response, $request) use ($sVerification) { $router->use('/whitelist', function($response, $request) use ($csrfp) {
if(!$request->isFormContent()) { if(!$request->isFormContent()) {
$response->redirect('/?error=request'); $response->redirect('/?error=request');
return true; return true;
@ -114,7 +96,7 @@ $router->use('/whitelist', function($response, $request) use ($sVerification) {
$body = $request->getContent(); $body = $request->getContent();
if(!$body->hasParam('boob') || !hash_equals($sVerification, (string)$body->getParam('boob'))) { if(!$body->hasParam('csrfp') || !$csrfp->verifyToken((string)$body->getParam('csrfp'))) {
$response->redirect('/?error=verify'); $response->redirect('/?error=verify');
return true; return true;
} }
@ -148,11 +130,4 @@ $router->post('/whitelist/remove', function($response) use ($db, $userInfo) {
$response->redirect("/?error={$resp}"); $response->redirect("/?error={$resp}");
}); });
$router->get('/errors/:code', function($res, $req, $code) {
$code = (int)$code;
if($code < 100 || $code >= 600)
$code = 400;
return $code;
});
$router->dispatch(); $router->dispatch();

49
src/Templating.php Normal file
View file

@ -0,0 +1,49 @@
<?php
namespace Mince;
use Twig\Environment as TwigEnvironment;
use Twig\Loader\FilesystemLoader as TwigLoaderFilesystem;
class Templating {
private const FILE_EXT = '.twig';
private TwigEnvironment $env;
private TwigLoaderFilesystem $loader;
private array $vars = [];
public function __construct() {
$this->loader = new TwigLoaderFilesystem;
$this->env = new TwigEnvironment($this->loader, [
//'cache' => $cache ?? false,
'debug' => MCR_DEBUG,
'strict_variables' => true,
]);
}
public function addPath(string $path): void {
$this->loader->addPath($path);
}
public function setVar(string $path, $value): void {
$path = array_reverse(explode('.', $path));
$target = &$this->vars;
$targetName = array_pop($path);
if(!empty($path))
while(($name = array_pop($path)) !== null) {
if(!array_key_exists($name, $target))
$target[$name] = [];
$target = &$target[$name];
}
$target[$targetName] = $value;
}
public function addVars(array $vars): void {
$this->vars = array_merge($this->vars, $vars);
}
public function render(string $path, array $vars = []): string {
return $this->env->render($path . self::FILE_EXT, array_merge($this->vars, $vars));
}
}

View file

@ -20,7 +20,7 @@
<h2>Add to Whitelist</h2> <h2>Add to Whitelist</h2>
<p>This will give you access to the server.</p> <p>This will give you access to the server.</p>
<form method="post" action="/whitelist/add"> <form method="post" action="/whitelist/add">
<input type="hidden" name="boob" value="{{ verification }}"> <input type="hidden" name="csrfp" value="{{ csrfp }}">
<label> <label>
<div class="label-header">Username</div> <div class="label-header">Username</div>
<div class="label-input"><input type="text" name="name" value="{{ wladdform_username }}"></div> <div class="label-input"><input type="text" name="name" value="{{ wladdform_username }}"></div>
@ -56,7 +56,7 @@
<p>If you're playing a modpack, take that time to start the game up; it'll take a while.</p> <p>If you're playing a modpack, take that time to start the game up; it'll take a while.</p>
{% endif %} {% endif %}
<form method="post" action="/whitelist/remove"> <form method="post" action="/whitelist/remove">
<input type="hidden" name="boob" value="{{ verification }}"> <input type="hidden" name="csrfp" value="{{ csrfp }}">
<input type="submit" value="Remove me from the whitelist"> <input type="submit" value="Remove me from the whitelist">
</form> </form>
</div> </div>