リアクティブ mongo での認証のために、scala で play-2 auth を実装したいと考えています。私はたくさん試しましたが、それをノンブロッキングにすることができませんでした..
これが私のユーザーコントローラーです
import scala.concurrent.Future
import org.mindrot.jbcrypt.BCrypt
import play.api.Logger
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import play.api.libs.json.Json
import play.api.libs.json.Json.toJsFieldJsValueWrapper
import play.api.mvc.Action
import play.api.mvc.Controller
import play.modules.reactivemongo.MongoController
import play.modules.reactivemongo.json.collection.JSONCollection
import jp.t2v.lab.play2.auth.LoginLogout
import jp.t2v.lab.play2.auth.AuthConfig
object UserController extends Controller with MongoController {
def collection: JSONCollection = db.collection[JSONCollection]("users")
def create = Action.async(parse.json) { implicit request =>
request.body.validate[User].map { user =>
val pass = BCrypt.hashpw(user.password, BCrypt.gensalt())
user.password = pass;
collection.insert(user).map { lastError =>
Logger.debug(s"Successfully inserted with LastError: $lastError")
Created
}
}.getOrElse(Future.successful(BadRequest("invalid json")))
}
def list = Action.async {
val cursor = collection.find(Json.obj()).cursor[User]
val futureList = cursor.collect[List]()
futureList.map { users => Ok(Json.toJson(users)) }
}
def findByEmail(email: String): Future[Option[User]] = {
val futureItem: Future[Option[User]] = collection.find(Json.obj("email" -> email)).one[User]
futureItem
}
def findByUsername(username: String): Future[Option[User]] = {
val futureItem: Future[Option[User]] = collection.find(Json.obj("username" -> username)).one[User]
futureItem
}
}
これは BasicAuthConfig です
import scala.annotation.implicitNotFound
import scala.concurrent.ExecutionContext
import scala.concurrent.Future
import scala.reflect.ClassTag
import scala.reflect.classTag
import com.loven.web.user.UserController
import jp.t2v.lab.play2.auth.AuthConfig
import play.Logger
import play.api.mvc.RequestHeader
import play.api.mvc.Results.Forbidden
trait BaseAuthConfig extends AuthConfig {
type Id = String
type User = com.loven.web.user.User
type Authority = String
val idTag: ClassTag[Id] = classTag[Id]
val sessionTimeoutInSeconds = 3600
def resolveUser(username: String)(implicit ctx: ExecutionContext) = Future.successful(UserController.findByUsername(username))
def authorizationFailed(request: RequestHeader)(implicit ctx: ExecutionContext) = throw new AssertionError("don't use")
override def authorizationFailed(request: RequestHeader, user: User, authority: Option[Authority])(implicit ctx: ExecutionContext) = {
Logger.info(s"authorizationFailed. username: ${user.username}, authority: $authority")
Future.successful(Forbidden("no permission"))
}
def authorize(user: User, authority: Authority)(implicit ctx: ExecutionContext) = Future.successful((user.role, authority) match {
case ("admin", _) => true
case ("normal", "normal") => true
case _ => false
})
}
この行でエラーが発生しています
def resolveUser(username: String)(implicit ctx: ExecutionContext) = Future.successful(UserController.findByUsername(username))