summaryrefslogtreecommitdiff
path: root/src/Router
diff options
context:
space:
mode:
Diffstat (limited to 'src/Router')
-rw-r--r--src/Router/Router.php85
-rw-r--r--src/Router/routes_client_server.php41
-rw-r--r--src/Router/routes_server_server.php24
3 files changed, 150 insertions, 0 deletions
diff --git a/src/Router/Router.php b/src/Router/Router.php
new file mode 100644
index 0000000..b167142
--- /dev/null
+++ b/src/Router/Router.php
@@ -0,0 +1,85 @@
+<?php
+
+namespace App\Router;
+
+use App\Errors\ErrorCode;
+use App\Errors\ErrorResponse;
+use App\Errors\Exception;
+use App\Singleton;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\Loader\Configurator\RouteConfigurator;
+use Symfony\Component\Routing\Matcher\UrlMatcher;
+use Symfony\Component\Routing\RequestContext;
+use Symfony\Component\Routing\RouteCollection;
+
+class Router
+{
+ use Singleton;
+
+ private RouteCollection $routes;
+ private RouteConfigurator $configurator;
+
+ public function __construct()
+ {
+ $this->routes = new RouteCollection();
+ $this->configurator = new RouteConfigurator($this->routes, $this->routes);
+
+ $this->addRoutes();
+ }
+
+ /**
+ * match the current url against the routes.
+ * also add preflight CORS headers on OPTIONS requests.
+ */
+ public function run(): Response
+ {
+ $request = Request::createFromGlobals();
+
+ if ($request->isMethod("OPTIONS")) {
+ $response = new Response();
+ $response->headers->add([
+ "Access-Control-Allow-Origin" => "*",
+ "Access-Control-Allow-Methods" => "GET, POST, PUT, DELETE, OPTIONS, PATCH, HEAD",
+ "Access-Control-Allow-Headers" => "X-Requested-With, Content-Type, Authorization",
+ ]);
+
+ return $response;
+ }
+
+ $context = new RequestContext();
+ $context->fromRequest($request);
+
+ try {
+ $matcher = new UrlMatcher($this->routes, $context);
+ $match = $matcher->matchRequest($request);
+
+ $class = $match["_controller"][0];
+ $method = $match["_controller"][1];
+
+ return (new $class)->$method();
+ } catch (Exception $exception) {
+ return ErrorResponse::fromException($exception);
+ } catch (ResourceNotFoundException $exception) {
+ return new ErrorResponse(ErrorCode::NOT_FOUND, "404", Response::HTTP_NOT_FOUND);
+ } catch (MethodNotAllowedException $exception) {
+ return new ErrorResponse(ErrorCode::FORBIDDEN, "403", Response::HTTP_FORBIDDEN);
+ } catch (\Exception $exception) {
+ return new ErrorResponse(ErrorCode::UNKNOWN, "Unknown error occured", Response::HTTP_INTERNAL_SERVER_ERROR);
+ }
+ }
+
+ /**
+ * add routes from the routes file
+ */
+ private function addRoutes(): void
+ {
+ $routesClientServer = include_once(__DIR__ . "/routes_client_server.php");
+ $routesClientServer($this->configurator);
+
+ $routesServerServer = include_once(__DIR__ . "/routes_server_server.php");
+ $routesServerServer($this->configurator);
+ }
+}
diff --git a/src/Router/routes_client_server.php b/src/Router/routes_client_server.php
new file mode 100644
index 0000000..eff0be5
--- /dev/null
+++ b/src/Router/routes_client_server.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace App\Router;
+
+use App\Controllers\LoginController;
+use App\Controllers\ServerDiscoveryController;
+use App\Controllers\ServerImplementationController;
+use Symfony\Component\Routing\Loader\Configurator\RouteConfigurator;
+
+return function (RouteConfigurator $routes): void
+{
+ $routes
+ ->add("well_known_matrix_client", "/.well-known/matrix/client")
+ ->controller([ServerDiscoveryController::class, "client"])
+ ->methods(["GET"]);
+
+ $routes
+ ->add("well_known_matrix_support", "/.well-known/matrix/support")
+ ->controller([ServerDiscoveryController::class, "support"])
+ ->methods(["GET"]);
+
+ $routes
+ ->add("matrix_client_versions", "/_matrix/client/versions")
+ ->controller([ServerImplementationController::class, "versions"])
+ ->methods(["GET"]);
+
+ $supportedLoginTypes = [LoginController::class, "supportedLoginTypes"];
+ $routes
+ ->add("matrix_client_r0_login_types", "/_matrix/client/r0/login")
+ ->controller($supportedLoginTypes)
+ ->methods(["GET"]);
+ $routes
+ ->add("matrix_client_v3_login_types", "/_matrix/client/v3/login")
+ ->controller($supportedLoginTypes)
+ ->methods(["GET"]);
+
+ $routes
+ ->add("matrix_client_v3_login", "/_matrix/client/v3/login")
+ ->controller([LoginController::class, "login"])
+ ->methods(["POST"]);
+};
diff --git a/src/Router/routes_server_server.php b/src/Router/routes_server_server.php
new file mode 100644
index 0000000..2e85a17
--- /dev/null
+++ b/src/Router/routes_server_server.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace App\Router;
+
+use App\Controllers\ServerDiscoveryController;
+use App\Controllers\ServerImplementationController;
+use Symfony\Component\Routing\Loader\Configurator\RouteConfigurator;
+
+return function (RouteConfigurator $routes): void
+{
+ $routes
+ ->add("well_known_matrix_server", "/.well-known/matrix/server")
+ ->controller([ServerDiscoveryController::class, "server"])
+ ->methods(["GET"]);
+
+ $routes
+ ->add("matrix_federation_version", "/_matrix/federation/v1/version")
+ ->controller([ServerImplementationController::class, "version"])
+ ->methods(["GET"]);
+
+ # /_matrix/key/v2/server
+ # /_matrix/key/v2/query
+ # /_matrix/key/v2/query/{serverName}
+};