scalaplayframework-2.0securesocial

Error on porting a play 2.2 application to 2.3.2 version (Scala)


I'm porting a Play 2.2 application to a Play 2.3 application (Scala). To do that i change te secure social version to the master-SNAPSHOT, that support Play 2.3. But encounter errors in my play console while compile.

What's wrong?

[error] /Users/alberto/git/recommendation-system/app/security/CustomTemplatesPlugin.scala:33: ambiguous implicit values:
[error]  both method request2lang in trait Controller of type (implicit request: play.api.mvc.RequestHeader)play.api.i18n.Lang
[error]  and value lang of type play.api.i18n.Lang
[error]  match expected type play.api.i18n.Lang
[error]     securesocial.views.html.Registration.signUp(form, token)
[error]                                                ^
[error] /Users/alberto/git/recommendation-system/app/security/CustomTemplatesPlugin.scala:44: could not find implicit value for parameter env: securesocial.core.RuntimeEnvironment[_]
[error]     securesocial.views.html.Registration.startSignUp(form)
[error]                                                     ^
[error] /Users/alberto/git/recommendation-system/app/security/CustomTemplatesPlugin.scala:55: could not find implicit value for parameter env: securesocial.core.RuntimeEnvironment[_]
[error]     securesocial.views.html.Registration.startResetPassword(form)
[error]                                                            ^
[error] /Users/alberto/git/recommendation-system/app/security/CustomTemplatesPlugin.scala:66: could not find implicit value for parameter env: securesocial.core.RuntimeEnvironment[_]
[error]     securesocial.views.html.Registration.resetPasswordPage(form, token)
[error]                                                           ^
[error] /Users/alberto/git/recommendation-system/app/security/CustomTemplatesPlugin.scala:77: not found: type SecuredRequest
[error]   def getPasswordChangePage[A](implicit request: SecuredRequest[A], form: Form[ChangeInfo]): Html = {
[error]                                                  ^
[error] /Users/alberto/git/recommendation-system/app/security/CustomTemplatesPlugin.scala:78: Cannot find any HTTP Request Header here
[error]     securesocial.views.html.passwordChange(form)
[error]                                           ^
[error] /Users/alberto/git/recommendation-system/app/security/CustomTemplatesPlugin.scala:99: not found: type Identity
[error]   def getAlreadyRegisteredEmail(user: Identity)(implicit request: RequestHeader): (Option[Txt], Option[Html]) = {
[error]                                       ^
[error] /Users/alberto/git/recommendation-system/app/security/CustomTemplatesPlugin.scala:100: could not find implicit value for parameter env: securesocial.core.RuntimeEnvironment[_]
[error]     (None, Some(securesocial.views.html.mails.alreadyRegisteredEmail(user)))
[error]                                                                     ^
[error] /Users/alberto/git/recommendation-system/app/security/CustomTemplatesPlugin.scala:110: not found: type Identity
[error]   def getWelcomeEmail(user: Identity)(implicit request: RequestHeader): (Option[Txt], Option[Html]) = {
[error]                             ^
[error] /Users/alberto/git/recommendation-system/app/security/CustomTemplatesPlugin.scala:111: could not find implicit value for parameter env: securesocial.core.RuntimeEnvironment[_]
[error]     (None, Some(securesocial.views.html.mails.welcomeEmail(user)))
[error]                                                           ^
[error] /Users/alberto/git/recommendation-system/app/security/CustomTemplatesPlugin.scala:122: too many arguments for method apply: ()(implicit request: play.api.mvc.RequestHeader, implicit lang: play.api.i18n.Lang)play.twirl.api.HtmlFormat.Appendable in object unknownEmailNotice
[error]     (None, Some(securesocial.views.html.mails.unknownEmailNotice(request)))
[error]                                                                 ^
[error] /Users/alberto/git/recommendation-system/app/security/CustomTemplatesPlugin.scala:133: not found: type Identity
[error]   def getSendPasswordResetEmail(user: Identity, token: String)(implicit request: RequestHeader): (Option[Txt], Option[Html]) = {
[error]                                       ^
[error] /Users/alberto/git/recommendation-system/app/security/CustomTemplatesPlugin.scala:134: could not find implicit value for parameter env: securesocial.core.RuntimeEnvironment[_]
[error]     (None, Some(securesocial.views.html.mails.passwordResetEmail(user, token)))
[error]                                                                 ^
[error] /Users/alberto/git/recommendation-system/app/security/CustomTemplatesPlugin.scala:144: not found: type Identity
[error]   def getPasswordChangedNoticeEmail(user: Identity)(implicit request: RequestHeader): (Option[Txt], Option[Html]) = {
[error]                                           ^
[error] /Users/alberto/git/recommendation-system/app/security/CustomTemplatesPlugin.scala:145: could not find implicit value for parameter env: securesocial.core.RuntimeEnvironment[_]
[error]     (None, Some(securesocial.views.html.mails.passwordChangedNotice(user)))
[error]                                                                    ^
[error] /Users/alberto/git/recommendation-system/app/security/CustomTemplatesPlugin.scala:155: could not find implicit value for parameter env: securesocial.core.RuntimeEnvironment[_]
[error]     securesocial.views.html.notAuthorized()
[error]                                          ^
[error] /Users/alberto/git/recommendation-system/app/security/UserService.scala:4: object Token is not a member of package securesocial.core.providers
[error] import securesocial.core.providers.Token
[error]        ^
[error] /Users/alberto/git/recommendation-system/app/security/UserService.scala:5: object IdentityId is not a member of package securesocial.core
[error] import securesocial.core.IdentityId
[error]        ^
[error] /Users/alberto/git/recommendation-system/app/security/UserService.scala:25: not found: type Identity
[error]   passwordInfo: Option[PasswordInfo] = None) extends Identity {
[error]                                                      ^
[error] /Users/alberto/git/recommendation-system/app/security/UserService.scala:16: not found: type IdentityId
[error]   identityId: IdentityId,
[error]               ^
[error] /Users/alberto/git/recommendation-system/app/security/UserService.scala:30: not found: type IdentityId
[error]   implicit val identityIdFormat = Json.format[IdentityId]
[error]                                               ^
[error] /Users/alberto/git/recommendation-system/app/security/UserService.scala:35: Unapply of object LoginUser has no parameters. Are you using an empty case class?
[error]   implicit val storageFormat = Json.format[LoginUser]
[error]                                           ^
[error] /Users/alberto/git/recommendation-system/app/security/UserService.scala:39: not found: type IdentityId
[error]   implicit val identityIdFormat = Json.format[IdentityId]
[error]                                               ^
[error] /Users/alberto/git/recommendation-system/app/security/UserService.scala:49: not found: type Identity
[error]   def apply(user: Identity): Option[LoginUser] = {
[error]                   ^
[error] /Users/alberto/git/recommendation-system/app/security/UserService.scala:58: not found: type UserServicePlugin
[error] class UserService(application: Application) extends UserServicePlugin(application) {
[error]                                                     ^
[error] /Users/alberto/git/recommendation-system/app/security/UserService.scala:59: not found: type Token
[error]   private var tokens = Map[String, Token]()
[error]                                    ^
[error] /Users/alberto/git/recommendation-system/app/security/UserService.scala:69: not found: type Identity
[error]   def find(id: IdentityId): Option[Identity] = {
[error]                                    ^
[error] /Users/alberto/git/recommendation-system/app/security/UserService.scala:69: not found: type IdentityId
[error]   def find(id: IdentityId): Option[Identity] = {
[error]                ^
[error] /Users/alberto/git/recommendation-system/app/security/UserService.scala:72: No Json formatter found for type security.LoginUser. Try to implement an implicit Format for this type.
[error]     val futureUser = UserServiceLogin.find(Json.obj("identityId" -> Json.toJson(id))).one
[error]                                           ^
[error] /Users/alberto/git/recommendation-system/app/security/UserService.scala:86: not found: type Identity
[error]   def findByEmailAndProvider(email: String, providerId: String): Option[Identity] = {
[error]                                                                         ^
[error] /Users/alberto/git/recommendation-system/app/security/UserService.scala:88: No Json formatter found for type security.LoginUser. Try to implement an implicit Format for this type.
[error]     val futureUser = UserServiceLogin.find(Json.obj("email" -> email)).one
[error]                                           ^
[error] /Users/alberto/git/recommendation-system/app/security/UserService.scala:97: not found: type Identity
[error]   def save(user: Identity): Identity = {
[error]                             ^
[error] /Users/alberto/git/recommendation-system/app/security/UserService.scala:97: not found: type Identity
[error]   def save(user: Identity): Identity = {
[error]                  ^
[error] /Users/alberto/git/recommendation-system/app/security/UserService.scala:117: not found: type Token
[error]   def save(token: Token) = {
[error]                   ^
[error] /Users/alberto/git/recommendation-system/app/security/UserService.scala:130: not found: type Token
[error]   def findToken(token: String): Option[Token] = {
[error]                                        ^
[error] /Users/alberto/git/recommendation-system/conf/routes:41: value resetPassword is not a member of securesocial.controllers.Registration
[error] GET       /reset/:token                 @securesocial.controllers.Registration.resetPassword(token)
[error] /Users/alberto/git/recommendation-system/conf/routes:36: value startResetPassword is not a member of securesocial.controllers.Registration
[error] POST      /signup                       @securesocial.controllers.Registration.startResetPassword
[error] /Users/alberto/git/recommendation-system/conf/routes:42: value handleResetPassword is not a member of securesocial.controllers.Registration
[error] POST      /reset/:token                 @securesocial.controllers.Registration.handleResetPassword(token)
[error] /Users/alberto/git/recommendation-system/conf/routes:49: value notAuthorized is not a member of securesocial.controllers.ProviderController
[error] GET       /not-authorized               @securesocial.controllers.ProviderController.notAuthorized            
[error] /Users/alberto/git/recommendation-system/conf/routes:36: value startResetPassword is not a member of securesocial.controllers.Registration
[error] POST      /signup                       @securesocial.controllers.Registration.startResetPassword
[error] /Users/alberto/git/recommendation-system/conf/routes:39: value startResetPassword is not a member of securesocial.controllers.Registration
[error] GET       /reset                        @securesocial.controllers.Registration.startResetPassword
[error] /Users/alberto/git/recommendation-system/conf/routes:40: value startResetPassword is not a member of securesocial.controllers.Registration
[error] POST      /reset                        @securesocial.controllers.Registration.startResetPassword
[error] /Users/alberto/git/recommendation-system/conf/routes:41: value resetPassword is not a member of securesocial.controllers.Registration
[error] GET       /reset/:token                 @securesocial.controllers.Registration.resetPassword(token)
[error] /Users/alberto/git/recommendation-system/conf/routes:42: value handleResetPassword is not a member of securesocial.controllers.Registration
[error] POST      /reset/:token                 @securesocial.controllers.Registration.handleResetPassword(token)
[error] /Users/alberto/git/recommendation-system/conf/routes:49: value notAuthorized is not a member of securesocial.controllers.ProviderController
[error] GET       /not-authorized               @securesocial.controllers.ProviderController.notAuthorized            
[error] /Users/alberto/git/recommendation-system/app/views/secure/login.scala.html:5: object Registry is not a member of package securesocial.core
[error] @import securesocial.core.AuthenticationMethod._
[error]                             ^
[error] /Users/alberto/git/recommendation-system/app/views/secure/login.scala.html:35: not found: value Registry
[error]         @defining( Registry.providers.all.values.filter( _.id != UsernamePassword) ) { externalProviders =>
[error]                    ^
[error] /Users/alberto/git/recommendation-system/app/views/secure/provider.scala.html:4: object Registry is not a member of package securesocial.core
[error] @import securesocial.core.IdentityProvider
[error]                              ^
[error] /Users/alberto/git/recommendation-system/app/views/secure/provider.scala.html:8: object RoutesHelper is not a member of package securesocial.core.providers.utils
[error] @import play.api.Logger
[error]      ^
[error] /Users/alberto/git/recommendation-system/app/views/secure/provider.scala.html:12: not found: value Registry
[error] @Registry.providers.get(providerId).map { provider =>
[error]  ^

Thanks Alberto


Solution

  • There has been a huge refactoring in securesocial between 2.1.4 and master.

    The whole plugin system has bee scraped in favor of injected components. The Identity and IdentityId traits have been removed and the Actions are now parameterized by you own type.

    The UserService API has changed a lot too, moving from synchronous to asynchronous.

    The documentation is still being worked on for now. You will have to check out the samples to see how this all fits together.

    @edit

    Regarding the view templates : securesocial.controllers.ViewTemplates is now a trait which you can extend to override the corresponding views. then you have to change the default wiring to introduce your own view provider.

    if you look at the samples in Global it creates an object MyRuntimeEnvironment

    object MyRuntimeEnvironment extends RuntimeEnvironment.Default[DemoUser] {
        override lazy val routes = new CustomRoutesService()
        override lazy val userService: InMemoryUserService = new InMemoryUserService()
        override lazy val eventListeners = List(new MyEventListener())
      }
    

    you can create your own ViewTemplate and override that here :

      object MyRuntimeEnvironment extends RuntimeEnvironment.Default[DemoUser] {
        override lazy val routes = new CustomRoutesService()
        override lazy val userService: InMemoryUserService = new InMemoryUserService()
        override lazy val eventListeners = List(new MyEventListener())
        override lazy val viewTemplates = new ViewTemplates{
    
          override def getLoginPage(form: Form[(String, String)], msg: Option[String])(implicit request: RequestHeader, lang: Lang): Html = ???
    
          override def getPasswordChangePage(form: Form[ChangeInfo])(implicit request: RequestHeader, lang: Lang): Html = ???
    
          override def getNotAuthorizedPage(implicit request: RequestHeader, lang: Lang): Html = ???
    
          override def getStartSignUpPage(form: Form[String])(implicit request: RequestHeader, lang: Lang): Html = ???
    
          override def getSignUpPage(form: Form[RegistrationInfo], token: String)(implicit request: RequestHeader, lang: Lang): Html = ???
    
          override def getResetPasswordPage(form: Form[(String, String)], token: String)(implicit request: RequestHeader, lang: Lang): Html = ???
    
          override def getStartResetPasswordPage(form: Form[String])(implicit request: RequestHeader, lang: Lang): Html = ???
        }
      }
    

    Of course I don't suggest actually implementing it right there, the correct way would be to create

    class CustomViewTemplates extends ViewTemplates{
    //...
    }
    

    then

    override lazy val viewTemplates = new CustomViewTemplates()
    

    The default implementation for ViewTemplates is in securesocial.core.ViewTemplates.Default

    The same mechanism can be used for every "old" plugin (userService, authenticator store, IdGenerator, PasswordValidator, mail templates and so on) an actual list can actually be derived from securesocial.core.RuntimeEnvironment.Default

    The design was changed to allow both compile and runtime based dependency injection. it will probably (unfortunately) have to change again with play 2.4 and play 3.0 which will make runtime DI a first class citizen of the framework (while still supporting compile time injection)