2015-01-04 82 views
0

這是我實現的UserService類。這是一個稍微修改後的版本(http://www.shrikar.com/blog/2013/10/26/playframework-securesocial-and-mongodb/用於SecureSocial(Play Framework)的MongoUserService多次保留同一用戶

我將它與默認的securesocial FacebookProvider一起使用。一切工作正常,除了它每次登錄時重複用戶輸入的事實。我只想堅持一次用戶。我認爲這是由插件本身處理的,但我不確定是這樣。是否由我來檢查用戶是否存在,並且只有當同一用戶沒有其他條目時才插入記錄的用戶?或者還有其他什麼是錯的?

class MongoUserService(application: Application) extends UserServicePlugin(application) with Controller with MongoController { 
    def collection: JSONCollection = db.collection[JSONCollection]("users") 
    def tokens: JSONCollection = db.collection[JSONCollection]("tokens") 
    val outPutUser = (__ \ "id").json.prune 

    def retIdentity(json: JsObject): Identity = { 
    val userid = (json \ "userid").as[String] 

    val provider = (json \ "provider").as[String] 
    val firstname = (json \ "firstname").as[String] 
    val lastname = (json \ "lastname").as[String] 
    val email = (json \ "email").as[String] 
    val avatar = (json \ "avatar").as[String] 
    val hash = (json \ "password" \ "hasher").as[String] 
    val password = (json \ "password" \ "password").as[String] 
    println("password : " + password) 
    val salt = (json \ "password" \ "salt").asOpt[String] 
    val authmethod = (json \ "authmethod").as[String] 

    val identity: IdentityId = new IdentityId(userid, authmethod) 
    val authMethod: AuthenticationMethod = new AuthenticationMethod(authmethod) 
    val pwdInfo: PasswordInfo = new PasswordInfo(hash, password) 
    val serial:Integer=((json\"serial").as[Long]).toInt 
    val user: NWOUser = new NWOUser(identity, firstname, lastname, firstname, Some(email), Some(avatar), authMethod, None, None, Some(pwdInfo),serial) 
    user 
    } 

    def generateSerial():Integer={ 
    val collection = db[JSONCollection]("serial") 
    val cursor = collection.find(Json.obj()).cursor[JsObject] 
    val futureserial = cursor.headOption.map { 
     case Some(i) => i 
     case None => 0 
    } 
    val jobj = Await.result(futureserial, 5 seconds) 
    val newSerial=jobj match { 
     case x: Boolean => 0 
     case _ =>retSerial(jobj.asInstanceOf[JsObject])+1 

    } 
    collection.update(Json.obj(), Json.obj("$set"->Json.obj("serial"->newSerial))).onComplete { 
    case _=>println("updated") 
} 
    newSerial 
    } 
    def retSerial(json: JsObject): Integer = { 
    println(json) 
    val serial=(json \ "serial").as[Long] 
    serial.toInt 
    } 

    def findByEmailAndProvider(email: String, providerId: String): Option[Identity] = { 
    val cursor = collection.find(Json.obj("userid" -> email, "provider" -> providerId)).cursor[JsObject] 
    val futureuser = cursor.headOption.map { 
     case Some(user) => user 
     case None => false 
    } 
    val jobj = Await.result(futureuser, 5 seconds) 

    jobj match { 
     case x: Boolean => None 
     case _ => Some(retIdentity(jobj.asInstanceOf[JsObject])) 

    } 
    } 

    def save(user: Identity): Identity = { 

    val email = user.email match { 
     case Some(email) => email 
     case _ => "N/A" 
    } 

    val avatar = user.avatarUrl match { 
     case Some(url) => url 
     case _ => "N/A" 
    } 
    val savejson = Json.obj(
     "userid" -> user.identityId.userId, 
     "provider" -> user.identityId.providerId, 
     "firstname" -> user.firstName, 
     "lastname" -> user.lastName, 
     "email" -> email, 
     "avatar" -> avatar, 
     "authmethod" -> user.authMethod.method, 
     "serial"->this.generateSerial.toLong, 
     user.passwordInfo match { 
     case None =>"password" -> Json.obj( "hasher" -> "", 
      "password" -> "", 
      "salt" -> "") 

     case x =>"password" -> Json.obj(
      "hasher" -> x.get.hasher, 
      "password" -> x.get.password, 
      "salt" -> x.get.salt) 

     }, 
     "created_at" -> Json.obj("$date" -> new Date()), 
     "updated_at" -> Json.obj("$date" -> new Date())) 
    println(Json.toJson(savejson)) 
    collection.insert(savejson) 
    user 
    } 

    def find(id: IdentityId): Option[Identity] = { 
    findByEmailAndProvider(id.userId, id.providerId) 
    } 

    def save(token: Token) { 
    val tokentosave = Json.obj(
     "uuid" -> token.uuid, 
     "email" -> token.email, 
     "creation_time" -> Json.obj("$date" -> token.creationTime), 
     "expiration_time" -> Json.obj("$date" -> token.expirationTime), 
     "isSignUp" -> token.isSignUp) 
    tokens.save(tokentosave) 
    } 

    def findToken(token: String): Option[Token] = { 

    val cursor = tokens.find(Json.obj("uuid" -> token)).cursor[JsObject] 
    val futureuser = cursor.headOption.map { 
     case Some(user) => user 
     case None => false 
    } 
    val jobj = Await.result(futureuser, 5 seconds) 
    jobj match { 
     case x: Boolean => None 
     case obj: JsObject => { 
     println(obj) 
     val uuid = (obj \ "uuid").as[String] 
     val email = (obj \ "email").as[String] 
     val created = (obj \ "creation_time" \ "$date").as[Long] 
     val expire = (obj \ "expiration_time" \ "$date").as[Long] 
     val signup = (obj \ "isSignUp").as[Boolean] 
     val df = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss") 
     Some(new Token(uuid, email, new DateTime(created), new DateTime(expire), signup)) 
     } 
    } 
    } 

    def deleteToken(uuid: String) {} 

    def deleteExpiredTokens() {} 
} 

回答

1

您可以通過使用db.collection.[update][1]upsert=true,而不是insert解決。使用此標誌,它將在呼叫不存在時將第一個元素(查詢)標識的對象插入到呼叫中,並更新現有元素。

所以,與其

collection.insert(savejson) 

嘗試

collection.update(
    Json.obj("userid" -> user.identityId.userId), 
    savejson, 
    Json.obj("upsert" -> true) 
) 
相關問題