From 8b47c866ed13baae09bd60e43c809495b123bd81 Mon Sep 17 00:00:00 2001 From: flashwave Date: Wed, 16 Aug 2023 23:17:14 +0000 Subject: [PATCH] Moved Templating stuff into a class and use Index CSRFP for verification. --- composer.lock | 4 +-- public/index.php | 71 ++++++++++++++------------------------------ src/Templating.php | 49 ++++++++++++++++++++++++++++++ templates/index.twig | 4 +-- 4 files changed, 76 insertions(+), 52 deletions(-) create mode 100644 src/Templating.php diff --git a/composer.lock b/composer.lock index d5f4802..20695c5 100644 --- a/composer.lock +++ b/composer.lock @@ -12,7 +12,7 @@ "source": { "type": "git", "url": "https://git.flash.moe/flash/index.git", - "reference": "553b7c4a14aa7f2403c87ce474933986ac17d040" + "reference": "a4c1d5627e590e669998f68cae64691b1ce0e0ac" }, "require": { "ext-mbstring": "*", @@ -50,7 +50,7 @@ ], "description": "Composer package for the common library for my projects.", "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", diff --git a/public/index.php b/public/index.php index da7f3cf..308c6b4 100644 --- a/public/index.php +++ b/public/index.php @@ -2,54 +2,36 @@ namespace Mince; use Index\XString; -use Index\Data\DbType; use Index\Http\HttpFx; -use Twig\Environment as TwigEnvironment; -use Twig\Loader\FilesystemLoader as TwigLoaderFilesystem; +use Index\Security\CSRFP; 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 -$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 -$twigLoader = new TwigLoaderFilesystem([MCR_DIR_TPL]); -$twigEnv = new TwigEnvironment($twigLoader, [ - //'cache' => $cache ?? false, - 'debug' => MCR_DEBUG, - 'strict_variables' => true, -]); -$twigArgs = [ +$csrfp = new CSRFP( + $config['csrf_secret'], + $userInfo->success ? $authToken : $_SERVER['REMOTE_ADDR'] +); + +$templating = new Templating; +$templating->addPath(MCR_DIR_TPL); + +$templating->addVars([ 'global' => [ 'title' => 'Flashii Minecraft Servers', 'loginUrl' => $config['login_url'], ], 'auth' => $userInfo, - 'verification' => $sVerification, -]; - -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)); -} + 'csrfp' => $csrfp->createToken(), +]); $router = new HttpFx; -$router->setDefaultErrorHandler(function($response, $request, $code, $text) use ($userInfo) { - $response->setContent(tpl_render('http-error', [ +$router->setDefaultErrorHandler(function($response, $request, $code, $text) use ($userInfo, $templating) { + $response->setContent($templating->render('http-error', [ 'error' => [ 'code' => sprintf('%03d', $code), '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'); }); @@ -65,7 +47,7 @@ $router->get('/index.php', function($response) { $response->redirect('/', true); }); -$router->get('/', function($response, $request) use ($userInfo) { +$router->get('/', function($response, $request) use ($userInfo, $templating) { $name = (string)$request->getParam('name'); $error = (string)$request->getParam('error'); @@ -90,7 +72,7 @@ $router->get('/', function($response, $request) use ($userInfo) { $mErrorComment = $error; } - tpl_vars([ + $templating->addVars([ 'error' => [ 'title' => $mErrorTitle, 'body' => $mErrorComment, @@ -99,14 +81,14 @@ $router->get('/', function($response, $request) use ($userInfo) { } 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, ]); }); -$router->use('/whitelist', function($response, $request) use ($sVerification) { +$router->use('/whitelist', function($response, $request) use ($csrfp) { if(!$request->isFormContent()) { $response->redirect('/?error=request'); return true; @@ -114,7 +96,7 @@ $router->use('/whitelist', function($response, $request) use ($sVerification) { $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'); return true; } @@ -148,11 +130,4 @@ $router->post('/whitelist/remove', function($response) use ($db, $userInfo) { $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(); diff --git a/src/Templating.php b/src/Templating.php new file mode 100644 index 0000000..616a190 --- /dev/null +++ b/src/Templating.php @@ -0,0 +1,49 @@ +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)); + } +} diff --git a/templates/index.twig b/templates/index.twig index cfaa908..8ed61c1 100644 --- a/templates/index.twig +++ b/templates/index.twig @@ -20,7 +20,7 @@

Add to Whitelist

This will give you access to the server.

- +