~jan0sch/smederee
Showing details for patch e35dfb061f148b395da6bd9bf59797e2984736b8.
diff -rN -u old-smederee/modules/hub/src/test/scala/de/smederee/hub/AuthenticationMiddlewareTest.scala new-smederee/modules/hub/src/test/scala/de/smederee/hub/AuthenticationMiddlewareTest.scala --- old-smederee/modules/hub/src/test/scala/de/smederee/hub/AuthenticationMiddlewareTest.scala 2025-01-11 00:06:04.353875010 +0000 +++ new-smederee/modules/hub/src/test/scala/de/smederee/hub/AuthenticationMiddlewareTest.scala 2025-01-11 00:06:04.353875010 +0000 @@ -11,27 +11,31 @@ import cats.effect.* import cats.syntax.all.* import de.smederee.TestTags.* -import de.smederee.hub.Generators.* +import de.smederee.hub.Generators.given import de.smederee.hub.config.* import de.smederee.security.* import doobie.* import org.http4s.* +import org.scalacheck.effect.PropF + +import scala.concurrent.duration.FiniteDuration + final class AuthenticationMiddlewareTest extends BaseSpec with AuthenticationMiddleware { + override def scalaCheckTestParameters = super.scalaCheckTestParameters.withMinSuccessfulTests(1) + test("extractSessionId must return the session id".tag(NeedsDatabase)) { - (genSignAndValidate.sample, genSessionId.sample) match { - case (Some(signAndValidate), Some(sessionId)) => - val clock = java.time.Clock.systemUTC - val token = signAndValidate.signToken(sessionId.toString)(clock.millis.toString) - val request = Request[IO](method = Method.GET) - .addCookie(RequestCookie(Constants.authenticationCookieName.toString, token.toString)) - val test = for { - id <- extractSessionId[IO](request, signAndValidate) - } yield id - test.map { result => - assert(result === sessionId) - } - case _ => fail("Could not generate data samples!") + PropF.forAllF { (signAndValidate: SignAndValidate, sessionId: SessionId) => + val clock = java.time.Clock.systemUTC + val token = signAndValidate.signToken(sessionId.toString)(clock.millis.toString) + val request = Request[IO](method = Method.GET) + .addCookie(RequestCookie(Constants.authenticationCookieName.toString, token.toString)) + val test = for { + id <- IO(extractSessionId[IO](request, signAndValidate)) + } yield id + test.start.flatMap(_.joinWithNever).map { result => + assert(result.exists(_ === sessionId)) + } } } @@ -39,29 +43,27 @@ "resolveUser must return the account if session id and account exist and the session has not reached absolute timeout" .tag(NeedsDatabase) ) { - (genFiniteDuration.sample, genValidSession.sample, genValidAccount.sample) match { - case (Some(duration), Some(s), Some(account)) => - val createdAt = OffsetDateTime.now(ZoneOffset.UTC) - val session = s.copy(uid = account.uid, createdAt = createdAt) - val timeouts = AuthenticationTimeouts(duration, duration, duration) - val dbConfig = configuration.database - val tx = Transactor.fromDriverManager[IO]( - driver = dbConfig.driver, - url = dbConfig.url, - user = dbConfig.user, - password = dbConfig.pass, - logHandler = None - ) - val repo = new DoobieAuthenticationRepository[IO](tx) - val test = for { - _ <- createAccount(account, PasswordHash("I am not a password hash!"), None, None) - _ <- createUserSession(session) - user <- resolveUser[IO](repo)(timeouts).run(session.id) - } yield user - test.map { maybeUser => - assert(clue(maybeUser) === clue(Option(account))) - } - case _ => fail("Could not generate data samples!") + PropF.forAllF { (duration: FiniteDuration, s: Session, account: Account) => + val createdAt = OffsetDateTime.now(ZoneOffset.UTC) + val session = s.copy(uid = account.uid, createdAt = createdAt) + val timeouts = AuthenticationTimeouts(duration, duration, duration) + val dbConfig = configuration.database + val tx = Transactor.fromDriverManager[IO]( + driver = dbConfig.driver, + url = dbConfig.url, + user = dbConfig.user, + password = dbConfig.pass, + logHandler = None + ) + val repo = new DoobieAuthenticationRepository[IO](tx) + val test = for { + _ <- createAccount(account, PasswordHash("I am not a password hash!"), None, None) + _ <- createUserSession(session) + user <- resolveUser[IO](repo)(timeouts).run(session.id) + } yield user + test.start.flatMap(_.joinWithNever).map { maybeUser => + assert(clue(maybeUser) === clue(Option(account))) + } } } @@ -70,55 +72,50 @@ NeedsDatabase ) ) { - (genFiniteDuration.sample, genValidSession.sample, genValidAccount.sample) match { - case (Some(duration), Some(s), Some(account)) => - val createdAt = OffsetDateTime.now(ZoneOffset.UTC).minusSeconds(duration.toSeconds + 5L) - val session = s.copy(uid = account.uid, createdAt = createdAt) - val timeouts = AuthenticationTimeouts(duration, duration, duration) - val dbConfig = configuration.database - val tx = Transactor.fromDriverManager[IO]( - driver = dbConfig.driver, - url = dbConfig.url, - user = dbConfig.user, - password = dbConfig.pass, - logHandler = None - ) - val repo = new DoobieAuthenticationRepository[IO](tx) - val test = for { - _ <- createAccount(account, PasswordHash("I am not a password hash!"), None, None) - _ <- createUserSession(session) - user <- resolveUser[IO](repo)(timeouts).run(session.id) - } yield user - test.map { maybeUser => - assert(clue(maybeUser) === clue(Option(account))) - } - case _ => fail("Could not generate data samples!") + PropF.forAllF { (duration: FiniteDuration, s: Session, account: Account) => + val createdAt = OffsetDateTime.now(ZoneOffset.UTC).minusSeconds(duration.toSeconds + 5L) + val session = s.copy(uid = account.uid, createdAt = createdAt) + val timeouts = AuthenticationTimeouts(duration, duration, duration) + val dbConfig = configuration.database + val tx = Transactor.fromDriverManager[IO]( + driver = dbConfig.driver, + url = dbConfig.url, + user = dbConfig.user, + password = dbConfig.pass, + logHandler = None + ) + val repo = new DoobieAuthenticationRepository[IO](tx) + val test = for { + _ <- createAccount(account, PasswordHash("I am not a password hash!"), None, None) + _ <- createUserSession(session) + user <- resolveUser[IO](repo)(timeouts).run(session.id) + } yield user + test.start.flatMap(_.joinWithNever).map { maybeUser => + assert(clue(maybeUser) === clue(Option(account))) + } } } test("resolveUser must return None if no session exists".tag(NeedsDatabase)) { - (genFiniteDuration.sample, genValidSession.sample, genValidAccount.sample) match { - case (Some(duration), Some(s), Some(account)) => - val session = s.copy(uid = account.uid) - val timeouts = AuthenticationTimeouts(duration, duration, duration) - val dbConfig = configuration.database - val tx = Transactor.fromDriverManager[IO]( - driver = dbConfig.driver, - url = dbConfig.url, - user = dbConfig.user, - password = dbConfig.pass, - logHandler = None - ) - val repo = new DoobieAuthenticationRepository[IO](tx) - val test = for { - _ <- createAccount(account, PasswordHash("I am not a password hash!"), None, None) - user <- resolveUser[IO](repo)(timeouts).run(session.id) - } yield user - test.map { maybeUser => - assert(clue(maybeUser) === None) - } - case _ => fail("Could not generate data samples!") + PropF.forAllF { (duration: FiniteDuration, s: Session, account: Account) => + val session = s.copy(uid = account.uid) + val timeouts = AuthenticationTimeouts(duration, duration, duration) + val dbConfig = configuration.database + val tx = Transactor.fromDriverManager[IO]( + driver = dbConfig.driver, + url = dbConfig.url, + user = dbConfig.user, + password = dbConfig.pass, + logHandler = None + ) + val repo = new DoobieAuthenticationRepository[IO](tx) + val test = for { + _ <- createAccount(account, PasswordHash("I am not a password hash!"), None, None) + user <- resolveUser[IO](repo)(timeouts).run(session.id) + } yield user + test.start.flatMap(_.joinWithNever).map { maybeUser => + assert(clue(maybeUser) === None) + } } } - } diff -rN -u old-smederee/modules/hub/src/test/scala/de/smederee/hub/Generators.scala new-smederee/modules/hub/src/test/scala/de/smederee/hub/Generators.scala --- old-smederee/modules/hub/src/test/scala/de/smederee/hub/Generators.scala 2025-01-11 00:06:04.353875010 +0000 +++ new-smederee/modules/hub/src/test/scala/de/smederee/hub/Generators.scala 2025-01-11 00:06:04.353875010 +0000 @@ -68,6 +68,8 @@ val genSessionId: Gen[SessionId] = Gen.delay(SessionId.generate) + given Arbitrary[SessionId] = Arbitrary(genSessionId) + val genSignAndValidate: Gen[SignAndValidate] = Gen .nonEmptyListOf(Gen.alphaNumChar) .map(cs => PrivateKey(cs.mkString.getBytes(StandardCharsets.UTF_8)))