~jan0sch/smederee

Showing details for patch 335543917f12cfba6137b04422387f070dbc0bd9.
2023-04-22 (Sat), 2:08 PM - Jens Grassel - 335543917f12cfba6137b04422387f070dbc0bd9

VCS: Fix a regression that prevented repository access via SSH.

Due to the change of the VcsRepositoryOwner the SSH layer did no longer
allow accessing your repositories (crash while accessing database).

- fix the regression by adjusting the relevant code
- add a template for displaying error messages upon internal server errors
- add recover and error logging logic to SSH repository access check and to
  repository creation route

Fixes: f2925545a468ee68878007aebeb472bb107eff4b
Summary of changes
1 files added
  • modules/hub/src/main/twirl/de/smederee/hub/views/errors/internalServerError.scala.html
4 files modified with 25 lines added and 9 lines removed
  • modules/hub/src/main/resources/messages.properties with 2 added and 0 removed lines
  • modules/hub/src/main/scala/de/smederee/hub/VcsRepositoryRoutes.scala with 9 added and 1 removed lines
  • modules/hub/src/main/scala/de/smederee/ssh/DarcsSshCommand.scala with 11 added and 6 removed lines
  • modules/hub/src/main/scala/de/smederee/ssh/DoobieSshAuthenticationRepository.scala with 3 added and 2 removed lines
diff -rN -u old-smederee/modules/hub/src/main/resources/messages.properties new-smederee/modules/hub/src/main/resources/messages.properties
--- old-smederee/modules/hub/src/main/resources/messages.properties	2025-01-31 02:43:31.973553927 +0000
+++ new-smederee/modules/hub/src/main/resources/messages.properties	2025-01-31 02:43:31.973553927 +0000
@@ -12,6 +12,8 @@
 #
 errors.account.not-validated=Sorry, but your account has not been validated and is therefore not allowed to perform the desired action. Please validate your account. You can do so on the settings page.
 errors.forbidden.title=403 - Forbidden
+errors.internal-server-error.title=500 - Internal Server Error
+errors.internal-server-error.message=An error occured while processing the request.
 
 # Forms
 form.account.delete.button.submit=Delete my account!
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-01-31 02:43:31.973553927 +0000
+++ new-smederee/modules/hub/src/main/scala/de/smederee/hub/VcsRepositoryRoutes.scala	2025-01-31 02:43:31.973553927 +0000
@@ -933,7 +933,7 @@
   private val parseCreateRepositoryForm: AuthedRoutes[Account, F] = AuthedRoutes.of {
     case ar @ POST -> Root / "repo" / "create" as user =>
       ar.req.decodeStrict[F, UrlForm] { urlForm =>
-        for {
+        val response = for {
           csrf     <- Sync[F].delay(ar.req.getCsrfToken)
           language <- Sync[F].delay(user.language.getOrElse(LanguageCode("en")))
           _ <- Sync[F].raiseUnless(user.validatedEmail)(
@@ -1027,6 +1027,14 @@
               } yield resp
           }
         } yield resp
+        response.recoverWith { error =>
+          log.error("Internal Server Error", error)
+          for {
+            csrf     <- Sync[F].delay(ar.req.getCsrfToken)
+            language <- Sync[F].delay(user.language.getOrElse(LanguageCode("en")))
+            resp     <- InternalServerError(views.html.errors.internalServerError(lang = language)(csrf, user.some))
+          } yield resp
+        }
       }
   }
 
diff -rN -u old-smederee/modules/hub/src/main/scala/de/smederee/ssh/DarcsSshCommand.scala new-smederee/modules/hub/src/main/scala/de/smederee/ssh/DarcsSshCommand.scala
--- old-smederee/modules/hub/src/main/scala/de/smederee/ssh/DarcsSshCommand.scala	2025-01-31 02:43:31.973553927 +0000
+++ new-smederee/modules/hub/src/main/scala/de/smederee/ssh/DarcsSshCommand.scala	2025-01-31 02:43:31.973553927 +0000
@@ -236,12 +236,17 @@
     Dispatcher
       .sequential[IO]
       .use { dispatcher =>
-        for {
-          _        <- IO.delay(log.debug(s"Checking if vcs repository $ownerName/$repoName is readable by $userId."))
-          vcsOwner <- repository.findVcsRepositoryOwner(ownerName)
-          _        <- IO.delay(log.debug(s"VCS repository owner name maps to $vcsOwner."))
-          userIsOwner = vcsOwner.exists(_.uid === userId)
-        } yield userIsOwner
+        val checkPermissions =
+          for {
+            _        <- IO.delay(log.debug(s"Checking if vcs repository $ownerName/$repoName is readable by $userId."))
+            vcsOwner <- repository.findVcsRepositoryOwner(ownerName)
+            _        <- IO.delay(log.debug(s"VCS repository owner name maps to $vcsOwner."))
+            userIsOwner = vcsOwner.exists(_.uid === userId)
+          } yield userIsOwner
+        checkPermissions.recoverWith { error =>
+          log.error("Internal Server Error", error)
+          false.pure[IO]
+        }
       }
       .unsafeRunSync()
 
diff -rN -u old-smederee/modules/hub/src/main/scala/de/smederee/ssh/DoobieSshAuthenticationRepository.scala new-smederee/modules/hub/src/main/scala/de/smederee/ssh/DoobieSshAuthenticationRepository.scala
--- old-smederee/modules/hub/src/main/scala/de/smederee/ssh/DoobieSshAuthenticationRepository.scala	2025-01-31 02:43:31.973553927 +0000
+++ new-smederee/modules/hub/src/main/scala/de/smederee/ssh/DoobieSshAuthenticationRepository.scala	2025-01-31 02:43:31.973553927 +0000
@@ -20,6 +20,7 @@
 import java.util.UUID
 
 import cats.effect._
+import de.smederee.email.EmailAddress
 import de.smederee.hub._
 import de.smederee.security.{ UserId, Username }
 import doobie._
@@ -27,7 +28,7 @@
 import doobie.postgres.implicits._
 
 final class DoobieSshAuthenticationRepository[F[_]: Sync](tx: Transactor[F]) extends SshAuthenticationRepository[F] {
-
+  given Meta[EmailAddress]      = Meta[String].timap(EmailAddress.apply)(_.toString)
   given Meta[EncodedKeyBytes]   = Meta[String].timap(EncodedKeyBytes.unsafeFrom)(_.toString)
   given Meta[KeyComment]        = Meta[String].timap(KeyComment.apply)(_.toString)
   given Meta[KeyFingerprint]    = Meta[String].timap(KeyFingerprint.apply)(_.toString)
@@ -43,7 +44,7 @@
       .transact(tx)
 
   override def findVcsRepositoryOwner(name: Username): F[Option[VcsRepositoryOwner]] =
-    sql"""SELECT uid, name FROM "hub"."accounts" WHERE name = $name LIMIT 1"""
+    sql"""SELECT uid, name, email FROM "hub"."accounts" WHERE name = $name LIMIT 1"""
       .query[VcsRepositoryOwner]
       .option
       .transact(tx)
diff -rN -u old-smederee/modules/hub/src/main/twirl/de/smederee/hub/views/errors/internalServerError.scala.html new-smederee/modules/hub/src/main/twirl/de/smederee/hub/views/errors/internalServerError.scala.html
--- old-smederee/modules/hub/src/main/twirl/de/smederee/hub/views/errors/internalServerError.scala.html	1970-01-01 00:00:00.000000000 +0000
+++ new-smederee/modules/hub/src/main/twirl/de/smederee/hub/views/errors/internalServerError.scala.html	2025-01-31 02:43:31.973553927 +0000
@@ -0,0 +1,21 @@
+@import de.smederee.hub._
+@import de.smederee.hub.views.html._
+
+@(baseUri: Uri = Uri(path = Uri.Path.Root), lang: LanguageCode = LanguageCode("en"))(csrf: Option[CsrfToken] = None, user: Option[Account])
+@defining(lang.toLocale) { implicit locale =>
+@main(baseUri, lang)()(csrf, Messages("errors.internal-server-error.title").some, user) {
+  <div class="content">
+    <div class="pure-g">
+      <div class="pure-u-1-1 pure-u-md-1-1">
+        <div class="l-box">
+          <p class="alert alert-error">
+            <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
+            <span class="sr-only">@Messages("errors.internal-server-error.title"):</span>
+            @Messages("errors.internal-server-error.message")
+          </p>
+        </div>
+      </div>
+    </div>
+  </div>
+}
+}