Search code examples
scalaplayframeworkplayframework-2.4

Using play.api.libs.Crypto from the console


scala> play.api.libs.Crypto.encryptAES("test")
com.typesafe.config.ConfigException$Missing: No configuration setting found for key 'play.crypto.secret'

I've set the variable in application.conf, but I'm not sure how to generate the global state such that Crypto picks up the variable.

The documentation is incorrect:

scala> import play.api._
import play.api._

scala> val application = new DefaultApplication(new File("."), this.getClass.getClassloader, None, Play.Mode.Dev)
<console>:14: error: not enough arguments for constructor DefaultApplication: (environment: play.api.Environment, applicationLifecycle: play.api.inject.DefaultApplicationLifecycle, injector: play.api.inject.Injector, configuration: play.api.Configuration, requestHandler: play.api.http.HttpRequestHandler, errorHandler: play.api.http.HttpErrorHandler, actorSystem: akka.actor.ActorSystem, plugins: play.api.Plugins)play.api.DefaultApplication.
Unspecified value parameters requestHandler, errorHandler, actorSystem...
      val application = new DefaultApplication(new File("."), this.getClass.getClassloader, None, Play.Mode.Dev)

I've tried loading into the test:console and loading via

val application = new play.api.test.FakeApplication(additionalConfiguration = Map("play.application.secret" -> "foobar"))

But that didn't load it into the global config object.


Solution

  • a brute force way is to start the application from within the console, and doing that depends on whether you customize the ApplicationLoader or not. in my case, i do (so that i can use macwire for DI). here's how it works for me, i have this in my build.sbt:

    initialCommands in console := """
      import play.api.{ApplicationLoader, Environment, Mode}
      import com.projectname.apiserver.global.MacwireApplicationLoader
      import com.projectname.apiserver.model._
      val env = Environment(new java.io.File("."), this.getClass.getClassLoader, Mode.Dev)
      val context = ApplicationLoader.createContext(env)
      val loader = new MacwireApplicationLoader
      val registry = loader.loadRegistry(context)
      import registry._
    """
    

    and a custom application loader:

    /**
     * MacwireApplicationLoader replaces the default Play application loader with a
     * compile time DI system (using macwire).
     *
     * More info: https://www.playframework.com/documentation/2.5.x/ScalaCompileTimeDependencyInjection
     */
    class MacwireApplicationLoader extends ApplicationLoader {
      def load(context: Context) = loadRegistry(context).application
    
      def loadRegistry(context: Context): BuiltInComponentsFromContext with Registry =
        new BuiltInComponentsFromContext(context)
          with AppComponents
          with ApplyEvolutions
    }
    
    trait AppComponents
        extends BuiltInComponents
        with NingWSComponents
        with Registry {
    
      lazy val assets: Assets = wire[Assets]
      lazy val config = configuration
      lazy val app = application
      lazy val ws = wsClient
    
      lazy val router: Router = {
        lazy val prefix = "/"
        wire[Routes]
      }
    
    }
    
    trait ApplyEvolutions extends EvolutionsComponents {
      applicationEvolutions
      override def dynamicEvolutions = new DynamicEvolutions
    }
    

    then when i enter the console, i can just do:

    [api-server] $ console
    [info] Starting scala interpreter...
    [info]
    2016-07-23 11:11:01,106 [INFO] [p.a.d.DefaultDBApi] - Database [default] connected at jdbc:postgresql://localhost:5432/databasename
    import play.api.{ApplicationLoader, Environment, Mode}
    import com.projectname.apiserver.global.MacwireApplicationLoader
    import com.projectname.apiserver.model._
    env: play.api.Environment = Environment(.,scala.tools.nsc.interpreter.IMain$TranslatingClassLoader@5b0c7029,Dev)
    context: play.api.ApplicationLoader.Context = Context(Environment(.,scala.tools.nsc.interpreter.IMain$TranslatingClassLoader@5b0c7029,Dev),None,play.core.DefaultWebCommands@352ca33b,Configuration(Config(SimpleConfigObject({"akka":{"actor":{"creation-timeout":"20s","debug":{"autoreceive":"off","event-stream":"off","fsm":"off","lifecycle":"off","receive":"off","router-misconfiguration":"off","unhandled":"off"},"default-dispatcher":{"attempt-teamwork":"on","default-executor":{"fallback":"fork-join-executor"},"executor":"defa...Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_45).
    Type in expressions for evaluation. Or try :help.
    
    scala> crypto.encryptAES("test")
    res0: String = 2-ZLIW79WqQff4SDZ+aWLkf38cZyU=