From ceb53e5abb134c18ba06d85cb93920bc72dd2944 Mon Sep 17 00:00:00 2001 From: Override-6 Date: Sat, 4 Feb 2023 15:55:21 +0100 Subject: [PATCH] fixing webservice and redirection bugs --- Core/src/org/tbasket/Main.scala | 4 +-- ...ourceDispatcher.scala => WebService.scala} | 29 ++++++++++++------- Core/src/org/tbasket/endpoint/Endpoint.scala | 6 ++-- .../org/tbasket/handler/HandlerUtils.scala | 4 +-- .../tbasket/handler/LoginPageHandler.scala | 2 +- tests/src/org/tbasket/test/TestLayers.scala | 4 +-- .../test/pages/LoginPageHandlerTests.scala | 2 +- .../tbasket/test/pages/TBasketPageSpec.scala | 4 +-- 8 files changed, 31 insertions(+), 24 deletions(-) rename Core/src/org/tbasket/dispatch/{ResourceDispatcher.scala => WebService.scala} (53%) diff --git a/Core/src/org/tbasket/Main.scala b/Core/src/org/tbasket/Main.scala index 7313895..ea63f65 100644 --- a/Core/src/org/tbasket/Main.scala +++ b/Core/src/org/tbasket/Main.scala @@ -4,7 +4,7 @@ import org.apache.logging.log4j.LogManager import org.tbasket.auth.Authenticator import org.tbasket.config.{FileServerConfig, ServerConfig} import org.tbasket.data.Database -import org.tbasket.dispatch.ResourceDispatcher +import org.tbasket.dispatch.WebService import org.tbasket.endpoint.Endpoint import pdi.jwt.algorithms.JwtAsymmetricAlgorithm import zio.* @@ -33,7 +33,7 @@ object Main extends ZIOAppDefault: } private def setupPageDispatcher(config: ServerConfig) = ZIO.attempt { - val dispatcher = new ResourceDispatcher(config.pagesLocation) + val dispatcher = new WebService(config.pagesLocation) ZLayer.succeed(dispatcher) } diff --git a/Core/src/org/tbasket/dispatch/ResourceDispatcher.scala b/Core/src/org/tbasket/dispatch/WebService.scala similarity index 53% rename from Core/src/org/tbasket/dispatch/ResourceDispatcher.scala rename to Core/src/org/tbasket/dispatch/WebService.scala index bc7324f..c5aed5c 100644 --- a/Core/src/org/tbasket/dispatch/ResourceDispatcher.scala +++ b/Core/src/org/tbasket/dispatch/WebService.scala @@ -9,7 +9,7 @@ import zio.stream.ZStream import java.nio.file.{Files, Path} import scala.collection.mutable -class ResourceDispatcher(pagesLocation: Path) { +class WebService(pagesLocation: Path) { private val resources = resolveResources @@ -25,6 +25,7 @@ class ResourceDispatcher(pagesLocation: Path) { ZIO.attempt(Response.status(status)) } + private def resolveResources: Map[String, Body] = { val map = mutable.HashMap.empty[String, Body] @@ -32,17 +33,23 @@ class ResourceDispatcher(pagesLocation: Path) { def resolveAll(loc: Path): Unit = { Files.list(loc) .forEach { - case d if Files.isDirectory(d) => resolveAll(d) - case f => - val body = Body.fromFile(f.toFile) - val fileName = f.toString - map.put(fileName, body) - val extension = fileName.drop(fileName.indexOf('.')) + case d if Files.isDirectory(d) => resolveAll(d) + case f => + val body = Body.fromFile(f.toFile) + val fullPath = f.toString + val fileName = f.getFileName.toString + val purename = fileName.take(fileName.indexOf('.')) - val dirPath = f.getParent.toString - if (extension == ".html") - map.put(dirPath, body) //also bind the dir path with the index body - else map.put(dirPath + extension, body) + map.put(fullPath, body) + + //also bind the dir path with the index body + if (purename == "index" || purename == f.getParent.getFileName.toString) { + val extension = fullPath.drop(fullPath.indexOf('.')) + val dirPath = f.getParent.toString + if (extension == ".html") + map.put(dirPath, body) + else map.put(dirPath + extension, body) + } } } diff --git a/Core/src/org/tbasket/endpoint/Endpoint.scala b/Core/src/org/tbasket/endpoint/Endpoint.scala index b44c0f0..8a80e27 100644 --- a/Core/src/org/tbasket/endpoint/Endpoint.scala +++ b/Core/src/org/tbasket/endpoint/Endpoint.scala @@ -8,7 +8,7 @@ import io.netty.handler.codec.http.HttpMethod import org.apache.logging.log4j.{LogManager, Logger} import org.tbasket.auth.Authenticator import org.tbasket.data.DatabaseContext -import org.tbasket.dispatch.ResourceDispatcher +import org.tbasket.dispatch.WebService import org.tbasket.endpoint.Endpoint.{Log, app} import org.tbasket.error.* import org.tbasket.handler.HandlerUtils.errorBody @@ -37,7 +37,7 @@ class Endpoint(port: Int): Server.install(app).flatMap { port => Log.info(s"Listening API entries on $port") ZIO.never - }.provideSome[DatabaseContext & Authenticator & DataSource & ResourceDispatcher]( + }.provideSome[DatabaseContext & Authenticator & DataSource & WebService]( Scope.default, serverConfigLayer, ConnectionPool.fixed(4), @@ -57,7 +57,7 @@ object Endpoint: RegisterPageHandler.post(r) case r@GET -> _ => - ZIO.serviceWithZIO[ResourceDispatcher](_.send(r)) + ZIO.serviceWithZIO[WebService](_.send(r)) case r@method -> path => val ipInsights = r.remoteAddress diff --git a/Core/src/org/tbasket/handler/HandlerUtils.scala b/Core/src/org/tbasket/handler/HandlerUtils.scala index 42ea329..b6016af 100644 --- a/Core/src/org/tbasket/handler/HandlerUtils.scala +++ b/Core/src/org/tbasket/handler/HandlerUtils.scala @@ -26,7 +26,7 @@ object HandlerUtils { def parseRequestForm(body: Body) = (for - decoded <- body.asString.map(URLDecoder.decode(_, StandardCharsets.UTF_8.name())) + decoded <- body.asString.map(str => URLDecoder.decode(str.stripPrefix("&"), StandardCharsets.UTF_8.name())) params = decoded.split('&').collect { case s"$k=$v" => (k, v)}.toMap yield params) .mapError(s => InvalidRequest("Invalid request body", s.getMessage)) @@ -34,4 +34,4 @@ object HandlerUtils { def search(map: Map[String, String])(name: String) = ZIO.attempt(map.get(name)).someOrFail(InvalidRequest(s"Missing or invalid field $name.")) -} +} \ No newline at end of file diff --git a/Core/src/org/tbasket/handler/LoginPageHandler.scala b/Core/src/org/tbasket/handler/LoginPageHandler.scala index d08a7ba..29fb235 100644 --- a/Core/src/org/tbasket/handler/LoginPageHandler.scala +++ b/Core/src/org/tbasket/handler/LoginPageHandler.scala @@ -49,7 +49,7 @@ object LoginPageHandler extends PageHandler: def post(request: Request) = tryPost(request).catchSome { case UserNotFound(msg) => ZIO.attempt(Response( - status = Status.Unauthorized, + status = Status.Found, body = errorBody("unauthorized", msg), headers = Headers( diff --git a/tests/src/org/tbasket/test/TestLayers.scala b/tests/src/org/tbasket/test/TestLayers.scala index d943c8c..cbf77e2 100644 --- a/tests/src/org/tbasket/test/TestLayers.scala +++ b/tests/src/org/tbasket/test/TestLayers.scala @@ -3,7 +3,7 @@ package org.tbasket.test import org.tbasket.auth.Authenticator import org.tbasket.config.ServerConfig import org.tbasket.data.Database -import org.tbasket.dispatch.ResourceDispatcher +import org.tbasket.dispatch.WebService import zio.{Task, ZLayer} import java.nio.file.{Files, Path} @@ -22,7 +22,7 @@ object TestLayers { ZLayer.succeed(auth) } - val resp = ZLayer.succeed(new ResourceDispatcher(TestServerConfig.pagesLocation)) + val resp = ZLayer.succeed(new WebService(TestServerConfig.pagesLocation)) val db = { //ensure that the test table is always new in order to make tests on the same dataset all the time. diff --git a/tests/src/org/tbasket/test/pages/LoginPageHandlerTests.scala b/tests/src/org/tbasket/test/pages/LoginPageHandlerTests.scala index 69d4bed..3374e74 100644 --- a/tests/src/org/tbasket/test/pages/LoginPageHandlerTests.scala +++ b/tests/src/org/tbasket/test/pages/LoginPageHandlerTests.scala @@ -52,7 +52,7 @@ object LoginPageHandlerTests extends TBasketPageSpec("/login") { errorType <- parseAttribute(json, "error", JsonCursor.field("error").isString) yield //assert that the response error is of type unauthorized and headers are Location: /register - assert(response)(hasField("status", _.status, equalTo(Status.Unauthorized))) + assert(response)(hasField("status", _.status, equalTo(Status.Found))) && assert(errorType)(equalTo("unauthorized")) && assert(response)(hasField("headers", _.headers, contains(Headers.location("/register")))) }, diff --git a/tests/src/org/tbasket/test/pages/TBasketPageSpec.scala b/tests/src/org/tbasket/test/pages/TBasketPageSpec.scala index 5438d0e..8a3695e 100644 --- a/tests/src/org/tbasket/test/pages/TBasketPageSpec.scala +++ b/tests/src/org/tbasket/test/pages/TBasketPageSpec.scala @@ -5,7 +5,7 @@ import io.getquill.context.qzio.ZioJdbcContext import io.getquill.context.sql.idiom.SqlIdiom import org.tbasket.auth.Authenticator import org.tbasket.data.DatabaseContext -import org.tbasket.dispatch.ResourceDispatcher +import org.tbasket.dispatch.WebService import zio.test.{Spec, TestEnvironment, ZIOSpecDefault} import org.tbasket.handler.LoginPageHandler.post import zio.* @@ -21,7 +21,7 @@ abstract class TBasketPageSpec(location: String) extends ZIOSpecDefault { case Left(value) => throw value case Right(url) => url - protected def tspec: Spec[DataSource & ClientConfig & Authenticator & ConnectionPool & Scope & DatabaseContext & Client & ResourceDispatcher, Any] + protected def tspec: Spec[DataSource & ClientConfig & Authenticator & ConnectionPool & Scope & DatabaseContext & Client & WebService, Any] final override def spec = tspec.provide( db.datasourceLayer,