From 33344541d66ceb1a887fbe23a38a92be6b96f346 Mon Sep 17 00:00:00 2001 From: flashwave Date: Wed, 29 Jan 2025 00:25:53 +0000 Subject: [PATCH] Added ability to scope RoutingContext. --- misuzu.php | 18 +- public/index.php | 30 +-- src/MisuzuContext.php | 235 ++++++++++++---------- src/Routing/BackedRoutingContext.php | 39 ++++ src/Routing/RoutingContext.php | 12 ++ src/{ => Routing}/RoutingErrorHandler.php | 3 +- src/Routing/ScopedRoutingContext.php | 32 +++ src/RoutingContext.php | 29 --- src/Satori/SatoriRoutes.php | 1 - src/SharpChat/SharpChatRoutes.php | 1 - 10 files changed, 235 insertions(+), 165 deletions(-) create mode 100644 src/Routing/BackedRoutingContext.php create mode 100644 src/Routing/RoutingContext.php rename src/{ => Routing}/RoutingErrorHandler.php (95%) create mode 100644 src/Routing/ScopedRoutingContext.php delete mode 100644 src/RoutingContext.php diff --git a/misuzu.php b/misuzu.php index e3f8ab63..0588eab3 100644 --- a/misuzu.php +++ b/misuzu.php @@ -22,26 +22,26 @@ error_reporting(MSZ_DEBUG ? -1 : 0); mb_internal_encoding('UTF-8'); date_default_timezone_set('GMT'); -$cfg = FsConfig::fromFile(MSZ_CONFIG . '/config.cfg'); +$env = FsConfig::fromFile(MSZ_CONFIG . '/config.cfg'); -if($cfg->hasValues('sentry:dsn')) - (function($cfg) { +if($env->hasValues('sentry:dsn')) + (function($env) { \Sentry\init([ - 'dsn' => $cfg->getString('dsn'), - 'traces_sample_rate' => $cfg->getFloat('tracesRate', 0.2), - 'profiles_sample_rate' => $cfg->getFloat('profilesRate', 0.2), + 'dsn' => $env->getString('dsn'), + 'traces_sample_rate' => $env->getFloat('tracesRate', 0.2), + 'profiles_sample_rate' => $env->getFloat('profilesRate', 0.2), ]); set_exception_handler(function(\Throwable $ex) { \Sentry\captureException($ex); }); - })($cfg->scopeTo('sentry')); + })($env->scopeTo('sentry')); -$db = DbBackends::create($cfg->getString('database:dsn', 'null:')); +$db = DbBackends::create($env->getString('database:dsn', 'null:')); $db->execute('SET SESSION time_zone = \'+00:00\', sql_mode = \'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION\';'); $cfg = new DbConfig($db, 'msz_config'); Mailer::init($cfg->scopeTo('mail')); -$msz = new MisuzuContext($db, $cfg); +$msz = new MisuzuContext($db, $cfg, $env); diff --git a/public/index.php b/public/index.php index d0722f19..a892175b 100644 --- a/public/index.php +++ b/public/index.php @@ -126,25 +126,27 @@ CSRF::init( ); // order for these two currently matters i think: it shouldn't. -$router = $msz->createRouting(); +$router = $msz->createRouting($request); $msz->startTemplating(); -$mszRequestPath = substr($request->getPath(), 1); -$mszLegacyPathPrefix = MSZ_PUBLIC . '-legacy/'; -$mszLegacyPath = $mszLegacyPathPrefix . $mszRequestPath; +if(in_array('main', $env->getArray(sprintf('domain:%s', $request->getHeaderLine('Host'))))) { + $mszRequestPath = substr($request->getPath(), 1); + $mszLegacyPathPrefix = MSZ_PUBLIC . '-legacy/'; + $mszLegacyPath = $mszLegacyPathPrefix . $mszRequestPath; -if(str_starts_with($mszLegacyPath, $mszLegacyPathPrefix)) { - $mszLegacyPathReal = realpath($mszLegacyPath); - if($mszLegacyPath === $mszLegacyPathReal || $mszLegacyPath === $mszLegacyPathReal . '/') { - if(str_starts_with($mszRequestPath, '/manage') && !$msz->hasManageAccess()) - Template::throwError(403); + if(str_starts_with($mszLegacyPath, $mszLegacyPathPrefix)) { + $mszLegacyPathReal = realpath($mszLegacyPath); + if($mszLegacyPath === $mszLegacyPathReal || $mszLegacyPath === $mszLegacyPathReal . '/') { + if(str_starts_with($mszRequestPath, '/manage') && !$msz->hasManageAccess()) + Template::throwError(403); - if(is_dir($mszLegacyPath)) - $mszLegacyPath .= '/index.php'; + if(is_dir($mszLegacyPath)) + $mszLegacyPath .= '/index.php'; - if(is_file($mszLegacyPath)) { - require_once $mszLegacyPath; - return; + if(is_file($mszLegacyPath)) { + require_once $mszLegacyPath; + return; + } } } } diff --git a/src/MisuzuContext.php b/src/MisuzuContext.php index 908dca75..1846a6de 100644 --- a/src/MisuzuContext.php +++ b/src/MisuzuContext.php @@ -13,12 +13,14 @@ use Misuzu\Messages\MessagesContext; use Misuzu\News\News; use Misuzu\Perms\Permissions; use Misuzu\Profile\ProfileFields; +use Misuzu\Routing\{BackedRoutingContext,RoutingContext}; use Misuzu\Users\{UsersContext,UserInfo}; use RPCii\HmacVerificationProvider; use RPCii\Server\HttpRpcServer; use Index\Config\Config; use Index\Db\DbConnection; use Index\Db\Migration\{DbMigrationManager,DbMigrationRepo,FsDbMigrationRepo}; +use Index\Http\HttpRequest; use Index\Templating\TplEnvironment; use Index\Urls\UrlRegistry; @@ -55,7 +57,8 @@ class MisuzuContext { public function __construct( public private(set) DbConnection $dbConn, - public private(set) Config $config + public private(set) Config $config, + public private(set) Config $env ) { $this->perms = new Permissions($dbConn); $this->authInfo = new AuthInfo($this->perms); @@ -144,132 +147,144 @@ class MisuzuContext { Template::init($this->templating); } - public function createRouting(): RoutingContext { - $routingCtx = new RoutingContext; + public function createRouting(HttpRequest $request): RoutingContext { + $prefix = sprintf('domain:%s', $request->getHeaderLine('Host')); + $hostInfo = $this->env->scopeTo($prefix); + $purposes = $this->env->getArray($prefix); + + $routingCtx = new BackedRoutingContext; $this->urls = $routingCtx->urls; - $routingCtx->register(new \Misuzu\Home\HomeRoutes( - $this->config, - $this->dbConn, - $this->siteInfo, - $this->authInfo, - $this->changelog, - $this->comments, - $this->counters, - $this->news, - $this->usersCtx - )); + if(in_array('main', $purposes)) { + $scopedInfo = $hostInfo->scopeTo('main'); + $scopedCtx = $routingCtx->scopeTo( + $scopedInfo->getString('name'), + $scopedInfo->getString('path') + ); - $routingCtx->register(new \Misuzu\Users\Assets\AssetsRoutes( - $this->authInfo, - $this->urls, - $this->usersCtx - )); + $scopedCtx->register(new \Misuzu\Home\HomeRoutes( + $this->config, + $this->dbConn, + $this->siteInfo, + $this->authInfo, + $this->changelog, + $this->comments, + $this->counters, + $this->news, + $this->usersCtx + )); - $routingCtx->register(new \Misuzu\Info\InfoRoutes); + $scopedCtx->register(new \Misuzu\Users\Assets\AssetsRoutes( + $this->authInfo, + $this->urls, + $this->usersCtx + )); - $routingCtx->register(new \Misuzu\News\NewsRoutes( - $this->siteInfo, - $this->authInfo, - $this->urls, - $this->news, - $this->usersCtx, - $this->comments - )); + $scopedCtx->register(new \Misuzu\Info\InfoRoutes); - $routingCtx->register(new \Misuzu\Messages\MessagesRoutes( - $this->config->scopeTo('messages'), - $this->urls, - $this->authInfo, - $this->messagesCtx, - $this->usersCtx, - $this->perms - )); + $scopedCtx->register(new \Misuzu\News\NewsRoutes( + $this->siteInfo, + $this->authInfo, + $this->urls, + $this->news, + $this->usersCtx, + $this->comments + )); - $routingCtx->register(new \Misuzu\Forum\ForumCategoriesRoutes( - $this->forumCtx, - $this->usersCtx, - $this->authInfo, - )); - $routingCtx->register(new \Misuzu\Forum\ForumTopicsRoutes( - $this->urls, - $this->forumCtx, - $this->usersCtx, - $this->auditLog, - $this->authInfo, - )); - $routingCtx->register(new \Misuzu\Forum\ForumPostsRoutes( - $this->urls, - $this->forumCtx, - $this->usersCtx, - $this->auditLog, - $this->authInfo, - )); + $scopedCtx->register(new \Misuzu\Messages\MessagesRoutes( + $this->config->scopeTo('messages'), + $this->urls, + $this->authInfo, + $this->messagesCtx, + $this->usersCtx, + $this->perms + )); - $routingCtx->register(new \Misuzu\Changelog\ChangelogRoutes( - $this->siteInfo, - $this->urls, - $this->changelog, - $this->usersCtx, - $this->authInfo, - $this->comments - )); + $scopedCtx->register(new \Misuzu\Forum\ForumCategoriesRoutes( + $this->forumCtx, + $this->usersCtx, + $this->authInfo, + )); + $scopedCtx->register(new \Misuzu\Forum\ForumTopicsRoutes( + $this->urls, + $this->forumCtx, + $this->usersCtx, + $this->auditLog, + $this->authInfo, + )); + $scopedCtx->register(new \Misuzu\Forum\ForumPostsRoutes( + $this->urls, + $this->forumCtx, + $this->usersCtx, + $this->auditLog, + $this->authInfo, + )); - $routingCtx->register(new \Misuzu\SharpChat\SharpChatRoutes( - $this->config->scopeTo('sockChat'), - $this->config->scopeTo('impersonate'), - $this->urls, - $this->usersCtx, - $this->authCtx, - $this->emotes, - $this->perms, - $this->authInfo, - $this->counters - )); + $scopedCtx->register(new \Misuzu\Changelog\ChangelogRoutes( + $this->siteInfo, + $this->urls, + $this->changelog, + $this->usersCtx, + $this->authInfo, + $this->comments + )); - $routingCtx->register(new \Misuzu\Satori\SatoriRoutes( - $this->config->scopeTo('satori'), - $this->usersCtx, - $this->forumCtx, - $this->profileFields - )); + $scopedCtx->register(new \Misuzu\SharpChat\SharpChatRoutes( + $this->config->scopeTo('sockChat'), + $this->config->scopeTo('impersonate'), + $this->urls, + $this->usersCtx, + $this->authCtx, + $this->emotes, + $this->perms, + $this->authInfo, + $this->counters + )); - $routingCtx->register(new LegacyRoutes($this->urls)); + $scopedCtx->register(new \Misuzu\Satori\SatoriRoutes( + $this->config->scopeTo('satori'), + $this->usersCtx, + $this->forumCtx, + $this->profileFields + )); - $rpcServer = new HttpRpcServer; - $routingCtx->router->register($rpcServer->createRouteHandler( - new HmacVerificationProvider(fn() => $this->config->getString('aleister.secret')) - )); + $routingCtx->register(new LegacyRoutes($this->urls)); - $rpcServer->register(new Auth\AuthRpcHandler( - $this->config->scopeTo('impersonate'), - $this->usersCtx, - $this->authCtx - )); + $rpcServer = new HttpRpcServer; + $scopedCtx->register($rpcServer->createRouteHandler( + new HmacVerificationProvider(fn() => $this->config->getString('aleister.secret')) + )); - $rpcServer->register(new Emoticons\EmotesRpcHandler( - $this->emotes - )); + $rpcServer->register(new Auth\AuthRpcHandler( + $this->config->scopeTo('impersonate'), + $this->usersCtx, + $this->authCtx + )); - $rpcServer->register(new Users\UsersRpcHandler( - $this->siteInfo, - $this->urls, - $this->usersCtx - )); + $rpcServer->register(new Emoticons\EmotesRpcHandler( + $this->emotes + )); - // This RPC server will eventually despawn when Hanyuu fully owns auth - $hanyuuRpcServer = new HttpRpcServer; - $routingCtx->router->scopeTo('/_hanyuu')->register($hanyuuRpcServer->createRouteHandler( - new HmacVerificationProvider(fn() => $this->config->getString('hanyuu.secret')) - )); + $rpcServer->register(new Users\UsersRpcHandler( + $this->siteInfo, + $this->urls, + $this->usersCtx + )); - $hanyuuRpcServer->register(new Hanyuu\HanyuuRpcHandler( - fn() => $this->config->getString('hanyuu.endpoint'), - $this->config->scopeTo('impersonate'), - $this->urls, - $this->usersCtx, - $this->authCtx - )); + // This RPC server will eventually despawn when Hanyuu fully owns auth + $hanyuuRpcServer = new HttpRpcServer; + $scopedCtx->scopeTo('', '/_hanyuu')->register($hanyuuRpcServer->createRouteHandler( + new HmacVerificationProvider(fn() => $this->config->getString('hanyuu.secret')) + )); + + $hanyuuRpcServer->register(new Hanyuu\HanyuuRpcHandler( + fn() => $this->config->getString('hanyuu.endpoint'), + $this->config->scopeTo('impersonate'), + $this->urls, + $this->usersCtx, + $this->authCtx + )); + } return $routingCtx; } diff --git a/src/Routing/BackedRoutingContext.php b/src/Routing/BackedRoutingContext.php new file mode 100644 index 00000000..05b027bc --- /dev/null +++ b/src/Routing/BackedRoutingContext.php @@ -0,0 +1,39 @@ +urls = $urls ?? new ArrayUrlRegistry; + $this->router = $router ?? new HttpRouter(errorHandler: new RoutingErrorHandler); + $this->router->use('/', fn($resp) => $resp->setPoweredBy('Misuzu')); + } + + public function register(RouteHandler|UrlSource $handler): void { + if($handler instanceof RouteHandler) + $this->router->register($handler); + if($handler instanceof UrlSource) + $this->urls->register($handler); + } + + public function scopeTo(string $namePrefix, string $pathPrefix): RoutingContext { + return new ScopedRoutingContext( + $this->router->scopeTo($pathPrefix), + $this->urls->scopeTo($namePrefix, $pathPrefix) + ); + } + + /** @param mixed[] $args */ + public function dispatch(?HttpRequest $request = null, array $args = []): void { + $this->router->dispatch($request, $args); + } +} diff --git a/src/Routing/RoutingContext.php b/src/Routing/RoutingContext.php new file mode 100644 index 00000000..faac7623 --- /dev/null +++ b/src/Routing/RoutingContext.php @@ -0,0 +1,12 @@ +router->register($handler); + if($handler instanceof UrlSource) + $this->urls->register($handler); + } + + public function scopeTo(string $namePrefix, string $pathPrefix): RoutingContext { + return new ScopedRoutingContext( + $this->router->scopeTo($pathPrefix), + $this->urls->scopeTo($namePrefix, $pathPrefix) + ); + } + + /** @param mixed[] $args */ + public function dispatch(?HttpRequest $request = null, array $args = []): void { + $this->router->dispatch($request, $args); + } +} diff --git a/src/RoutingContext.php b/src/RoutingContext.php deleted file mode 100644 index dab90526..00000000 --- a/src/RoutingContext.php +++ /dev/null @@ -1,29 +0,0 @@ -urls = new ArrayUrlRegistry; - $this->router = new HttpRouter(errorHandler: new RoutingErrorHandler); - $this->router->use('/', fn($resp) => $resp->setPoweredBy('Misuzu')); - } - - public function register(RouteHandler|UrlSource $handler): void { - if($handler instanceof RouteHandler) - $this->router->register($handler); - if($handler instanceof UrlSource) - $this->urls->register($handler); - } - - /** @param mixed[] $args */ - public function dispatch(?HttpRequest $request = null, array $args = []): void { - $this->router->dispatch($request, $args); - } -} diff --git a/src/Satori/SatoriRoutes.php b/src/Satori/SatoriRoutes.php index 5f9e8f5e..572cbf52 100644 --- a/src/Satori/SatoriRoutes.php +++ b/src/Satori/SatoriRoutes.php @@ -7,7 +7,6 @@ use Index\Config\Config; use Index\Http\{HttpRequest,HttpResponseBuilder}; use Index\Http\Routing\{HttpGet,HttpMiddleware,RouteHandler,RouteHandlerTrait}; use Misuzu\Pagination; -use Misuzu\RoutingContext; use Misuzu\Forum\ForumContext; use Misuzu\Profile\ProfileFields; use Misuzu\Users\UsersContext; diff --git a/src/SharpChat/SharpChatRoutes.php b/src/SharpChat/SharpChatRoutes.php index 25bd44c1..48cad9e1 100644 --- a/src/SharpChat/SharpChatRoutes.php +++ b/src/SharpChat/SharpChatRoutes.php @@ -2,7 +2,6 @@ namespace Misuzu\SharpChat; use RuntimeException; -use Misuzu\RoutingContext; use Misuzu\Auth\{AuthContext,AuthInfo,Sessions}; use Misuzu\Counters\Counters; use Misuzu\Emoticons\Emotes;