score:2

Accepted answer

trouble here that action(request) is returning future[result] not just result. so type of whole expression before getorelse is option[future[result]] and it awaits future[result] as parameter to getorelse.

so at first you can wrap your unauthorized.withheaders thing into future.successfull( ... )

next thing is that result of whole expression then is future[result] and it's not correct argument type for the action.apply(bodyparser)( ... ), but there is action.async method that could handle it.

so whole corrected block with minimum type corrections \ refactoring is

import org.apache.commons.codec.binary.base64

def secured[a](username: string, password: string)(action: action[a]) =
  action.async(action.parser) {
    request => request.headers.get("authorization").flatmap { authorization =>
      authorization.split(" ").drop(1).headoption.filter { encoded =>
        val bytes = base64.decodebase64(encoded.getbytes)
        new string(bytes).split(":").tolist match {
          case u :: p :: nil if u == username && password == p => true
          case _ => false
        }
      }.map(_ => action(request))
    }.getorelse {
      future.successful(
        unauthorized.withheaders(
          "www-authenticate" -> """basic realm="secured""""))
    }
  }

further sugar injections could lead to even more readable version:

import org.apache.commons.codec.binary.base64

def secured[a](username: string, password: string)(action: action[a]) =
  action.async(action.parser) { request =>
    val result = for {
      authorization <- request.headers.get("authorization")
      array(_, encoded, _*) <- some(authorization.split(" "))
      bytes = base64.decodebase64(encoded.getbytes)
      credentials = new string(bytes).split(":").tolist
      list(`username`, `password`) <- some(credentials)
    } yield action(request)

    result.getorelse {
      future.successful(
        unauthorized.withheaders(
          "www-authenticate" -> """basic realm="secured""""))
    }
  }

note that unpacking in the left hand side of <- is transformed to filter with match


Related Query