2017-07-01 1 views
0

J'utilise Scala bCrypt wrapper pour crypter le mot de passe utilisateur, ce wrapper fournit une classe implicite.Scala membre de la classe implicite n'est pas accessible dans l'objet

package object bcrypt { 

    implicit class Password(val pswrd: String) extends AnyVal { 
    def bcrypt: String = B.hashpw(pswrd, BCrypt.gensalt()) 

    def bcrypt(rounds: Int): String = B.hashpw(pswrd, BCrypt.gensalt(rounds)) 

    def bcrypt(salt: String): String = B.hashpw(pswrd, salt) 

    def isBcrypted(hash: String): Boolean = B.checkpw(pswrd, hash) 
    } 

    def generateSalt: String = B.gensalt() 
} 

Mais je suis confronté à un problème étrange, chaque fois que je me sers de ce converision Implicite dans classe il workes travail ne marche pas bien, mais converiosn avec objet ou cas des classes.

scala> import com.github.t3hnar.bcrypt._ 
import com.github.t3hnar.bcrypt._ 

scala> class Password(secret: String) { 
    | def validate(userSecret: String): Boolean = userSecret.isBcrypted(secret) 
    | 
    | override def toString = secret 
    | } 
defined class Password 

scala> object Password { 
    | def apply(secret: String): Password = new Password(secret) 
    | 
    | def getEncrypted(secret: String) = new Password(secret.bcrypt) 
    | } 
<console>:18: error: value bcrypt is not a member of String 
     def getEncrypted(secret: String) = new Password(secret.bcrypt) 
                   ^

scala> 

Je ne suis pas sûr de ce que je fais mal ici.

Répondre

2

Tout identificateur d'ombres stable importé identificateurs implicit. Les choses qui peuvent impliquer des implicits incluent val, def, object et l'objet compagnon généré de case class. class es et type s ne créent pas d'identifiants et n'obstruent donc pas les identifiants implicit importés.

implicit class Password est juste du sucre syntaxique pour un class Password et un implicit def Password, et ainsi un identifiant dans votre nom de code Password serait que l'ombre implicit def.

Ainsi, alors que le code compile OK:

object Foo { 
    import bcrypt._ 
    class Password() 
    "123".bcrypt 
} 

Tous les extraits suivants ne parviendra pas à compiler:

object Foo2 { 
    import bcrypt._ 
    val Password = 1 
    "123".bcrypt 
} 

object Foo3 { 
    import bcrypt._ 
    def Password() = 1 
    "123".bcrypt 
} 

object Foo4 { 
    import bcrypt._ 
    case class Password() 
    "123".bcrypt 
} 

object Foo5 { 
    import bcrypt._ 
    object Password 
    "123".bcrypt 
} 

La solution dans votre cas est simple: renommer la classe implicite à autre chose , il serait peu probable de se heurter à d'autres identifiants. Par exemple, implicit class PasswordExtensions.

Si vous ne pouvez pas renommer le implicit class dans le code d'origine, vous pouvez importer sous un autre nom: import com.github.t3hnar.bcrypt.{Password => PasswordExtensions, _}

+0

Ok, donc il a été se révèle collision de « Mot de passe » comme identifiant causais cette échec de la compilation, cela fonctionne en changeant seulement cette instruction import com.github.t3hnar.bcrypt. {Password => BcryptUtil} –