From 15f125ac7e96b5458721ad141da4d845553ffed7 Mon Sep 17 00:00:00 2001
From: Felipe D'Abrantes <felidabrantes@gmail>
Date: Tue, 11 Apr 2023 01:16:55 +0100
Subject: [PATCH] Inject a CSRF token into all responses

---
 .../models/actions/AuthenticatedUserAction.scala | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/backend-services/feed-service/app/models/actions/AuthenticatedUserAction.scala b/backend-services/feed-service/app/models/actions/AuthenticatedUserAction.scala
index 7382920c..b4351c78 100644
--- a/backend-services/feed-service/app/models/actions/AuthenticatedUserAction.scala
+++ b/backend-services/feed-service/app/models/actions/AuthenticatedUserAction.scala
@@ -1,12 +1,12 @@
 package models.actions
 
 import models.actions.AuthenticationRequest
-import play.api.mvc.{ActionBuilder, BodyParsers, Request, Result, AnyContent}
 
-import scala.concurrent.Future
+import play.api.mvc.{ActionBuilder, BodyParsers, Request, Result, AnyContent, Cookie}
+import play.filters.csrf.CSRF
 
 import javax.inject.Inject
-import scala.concurrent.ExecutionContext
+import scala.concurrent.{Future, ExecutionContext}
 
 
 /**
@@ -17,13 +17,19 @@ class AuthenticatedUserAction @Inject()(authenticationTransformer: Authenticatio
     extends ActionBuilder[AuthenticationRequest, AnyContent] {
 
     /**
-     * Invoke the main controller block, with the transformations and filtering middleware.
+     * Invoke the main controller block, with the transformations and filtering middleware, and the CSRF token injection.
      *
      * @param request The incoming request.
      * @param block The block of code to invoke.
      * @return A future of the result.
      */
     override def invokeBlock[A](request: Request[A], block: AuthenticationRequest[A] => Future[Result]): Future[Result] = {
-        (authenticationTransformer andThen authenticationFilter).invokeBlock(request, block)
+        val result: Future[Result] = (authenticationTransformer andThen authenticationFilter).invokeBlock(request, block)
+
+        (result).map(_result => {
+            // Add CSRF token to response
+            val token = CSRF.getToken(request).map(_.value).getOrElse("")
+            _result.withHeaders("Csrf-Token" -> token).withCookies(Cookie(name = "PLAY_CSRF_TOKEN", value = token))
+        })
     }
 }
-- 
GitLab