~jan0sch/smederee
Showing details for patch 2a5d22d7c33cc0b93ff218c1da65e05d8b58e9b1.
diff -rN -u old-smederee/build.sbt new-smederee/build.sbt --- old-smederee/build.sbt 2025-02-02 23:14:59.424942624 +0000 +++ new-smederee/build.sbt 2025-02-02 23:14:59.424942624 +0000 @@ -164,6 +164,7 @@ //library.http4sTwirl, library.jclOverSlf4j, // Bridge Java Commons Logging to SLF4J. library.logback, + library.osLib, library.postgresql, library.pureConfig, library.springSecurityCrypto, @@ -269,6 +270,7 @@ val munit = "0.7.29" val munitCatsEffect = "1.0.7" val munitDiscipline = "1.0.9" + val osLib = "0.8.1" val postgresql = "42.4.1" val pureConfig = "0.17.1" val scalaCheck = "1.16.0" @@ -299,6 +301,7 @@ val munitCatsEffect = "org.typelevel" %% "munit-cats-effect-3" % Version.munitCatsEffect val munitDiscipline = "org.typelevel" %% "discipline-munit" % Version.munitDiscipline val munitScalaCheck = "org.scalameta" %% "munit-scalacheck" % Version.munit + val osLib = "com.lihaoyi" %% "os-lib" % Version.osLib val postgresql = "org.postgresql" % "postgresql" % Version.postgresql val pureConfig = "com.github.pureconfig" %% "pureconfig-core" % Version.pureConfig val scalaCheck = "org.scalacheck" %% "scalacheck" % Version.scalaCheck diff -rN -u old-smederee/modules/hub/src/main/scala/de/smederee/hub/Account.scala new-smederee/modules/hub/src/main/scala/de/smederee/hub/Account.scala --- old-smederee/modules/hub/src/main/scala/de/smederee/hub/Account.scala 2025-02-02 23:14:59.424942624 +0000 +++ new-smederee/modules/hub/src/main/scala/de/smederee/hub/Account.scala 2025-02-02 23:14:59.424942624 +0000 @@ -330,6 +330,18 @@ } } +/** Extractor to retrieve an Username from a path parameter. + */ +object UsernamePathParameter { + def unapply(str: String): Option[Username] = + Option(str).flatMap { string => + if (string.startsWith("~")) + Username.from(string.drop(1)) + else + None + } +} + /** A user account. * * @param uid diff -rN -u old-smederee/modules/hub/src/main/scala/de/smederee/hub/VcsRepositoryRoutes.scala new-smederee/modules/hub/src/main/scala/de/smederee/hub/VcsRepositoryRoutes.scala --- old-smederee/modules/hub/src/main/scala/de/smederee/hub/VcsRepositoryRoutes.scala 2025-02-02 23:14:59.424942624 +0000 +++ new-smederee/modules/hub/src/main/scala/de/smederee/hub/VcsRepositoryRoutes.scala 2025-02-02 23:14:59.424942624 +0000 @@ -11,6 +11,7 @@ import java.nio.file._ +import cats._ import cats.data._ import cats.effect._ import cats.syntax.all._ @@ -24,6 +25,7 @@ import org.http4s.implicits._ import org.http4s.twirl.TwirlInstances._ import org.slf4j.LoggerFactory +import os.{ /, GlobSyntax } /** Routes for handling VCS repositories, including creation, management and public serving. * @@ -108,6 +110,30 @@ } yield resp } - val protectedRoutes = parseCreateRepositoryForm <+> showCreateRepositoryForm + private val showRepository: AuthedRoutes[Account, F] = AuthedRoutes.of { + case ar @ GET -> Root / UsernamePathParameter(repositoryOwner) / VcsRepositoryNamePathParameter( + repositoryName + ) as user => + for { + csrf <- Sync[F].delay(ar.req.getCsrfToken) + directory <- Sync[F].delay( + os.Path( + Paths.get( + config.repositoriesDirectory.toPath.toString, + repositoryOwner.toString, + repositoryName.toString + ) + ) + ) + listing <- Sync[F].delay( + os.walk + .attrs(directory, skip = (path, _) => path.baseName === "_darcs", maxDepth = 2) + .map((path, attrs) => (path.relativeTo(directory), attrs)) + ) + resp <- Ok(listing.mkString("\n")) + } yield resp + } + + val protectedRoutes = parseCreateRepositoryForm <+> showCreateRepositoryForm <+> showRepository } diff -rN -u old-smederee/modules/hub/src/main/scala/de/smederee/hub/VcsRepository.scala new-smederee/modules/hub/src/main/scala/de/smederee/hub/VcsRepository.scala --- old-smederee/modules/hub/src/main/scala/de/smederee/hub/VcsRepository.scala 2025-02-02 23:14:59.424942624 +0000 +++ new-smederee/modules/hub/src/main/scala/de/smederee/hub/VcsRepository.scala 2025-02-02 23:14:59.424942624 +0000 @@ -70,6 +70,12 @@ } } +/** Extractor to retrieve a VcsRepositoryName from a path parameter. + */ +object VcsRepositoryNamePathParameter { + def unapply(str: String): Option[VcsRepositoryName] = Option(str).flatMap(VcsRepositoryName.from) +} + /** Data about a VCS respository. * * @param name