I am implementing authentication based on this Scala Play Authentication example.
Therefore I use the following ActionBuilder
to build an UserAction
.
UserAction.scala
class UserRequest[A](val user: Option[Admin], request: Request[A]) extends WrappedRequest[A](request)
class UserAction @Inject()(adminService: AdminService, parser: BodyParsers.Default)(implicit val executionContext: ExecutionContext)
extends ActionBuilder[UserRequest, AnyContent]
with ActionTransformer[Request, UserRequest] {
def transform[A](request: Request[A]) = Future.successful {
val sessionTokenOpt = request.session.get("sessionToken")
val user = sessionTokenOpt
.flatMap(token => Sessions.getSession(token))
.filter(_.expiration.isAfter(LocalDateTime.now(ZoneOffset.UTC)))
.map(_.email)
// Signature: getAdminByEmail(email: String): Future[Option[Admin]]
.flatMap(adminService.getAdminByEmail) // <- Extract Future here
// The user has to be Option[Admin] but is Future[Option[Admin]]
// because of adminService.getAdminByEmail
new UserRequest(user, request)
}
}
Since the example implementation in line 25 does not return a Future because there is no database setup included, I get the following error:
type mismatch;
found : scala.concurrent.Future[Option[models.Tables.Admin]]
required: Option[?]
Because I am new to scala I have no clue how to extract the Future at this point. How to handle the Future result to make sure we return a Option[Admin]
?
Fixed it on my own. I just divided the email and fetching into two different parts and moved the
Future
inside theemail match
.