• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Scala PasswordInfo类代码示例

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

本文整理汇总了Scala中com.mohiva.play.silhouette.api.util.PasswordInfo的典型用法代码示例。如果您正苦于以下问题:Scala PasswordInfo类的具体用法?Scala PasswordInfo怎么用?Scala PasswordInfo使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。



在下文中一共展示了PasswordInfo类的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Scala代码示例。

示例1: PasswordHasherSHA256

//设置package包名称以及导入依赖的类
package controllers

import java.nio.charset.StandardCharsets

import com.mohiva.play.silhouette.api.util.{PasswordHasher, PasswordInfo}
import org.apache.directory.api.ldap.model.constants.LdapSecurityConstants
import org.apache.directory.api.ldap.model.password.PasswordUtil


class PasswordHasherSHA256 extends PasswordHasher{
  override def id: String = "SHA-256"

  override def hash(plainPassword: String): PasswordInfo = {
    PasswordInfo(hasher = id, password = plainPassword)
  }

  //TODO: Here might be an oversight. It seems to be to complicated.
  override def matches(passwordInfo: PasswordInfo, suppliedPassword: String): Boolean = {
    val suppliedStoragePW =  PasswordUtil.createStoragePassword(
      suppliedPassword,
      LdapSecurityConstants.getAlgorithm(passwordInfo.hasher)
    )

    val suppliedPW = new String(PasswordUtil.splitCredentials(suppliedStoragePW).getPassword,StandardCharsets.UTF_8)
    val storedPW = passwordInfo.password

    suppliedPW.equals(storedPW)
  }
} 
开发者ID:wirvomgut,项目名称:curo,代码行数:30,代码来源:PasswordHasherSHA256.scala


示例2: ChangePasswordController

//设置package包名称以及导入依赖的类
package controllers

import javax.inject.Inject

import com.mohiva.play.silhouette.api._
import com.mohiva.play.silhouette.api.exceptions.ProviderException
import com.mohiva.play.silhouette.api.repositories.AuthInfoRepository
import com.mohiva.play.silhouette.api.util.{ Credentials, PasswordHasherRegistry, PasswordInfo }
import com.mohiva.play.silhouette.impl.providers.CredentialsProvider
import models.services.UserService
import play.api.i18n.{ I18nSupport, Messages, MessagesApi }
import play.api.libs.concurrent.Execution.Implicits._
import play.api.mvc.Controller
import utils.auth.{ DefaultEnv, WithProvider }

import scala.concurrent.Future

class ChangePasswordController @Inject() (
  val messagesApi: MessagesApi,
  silhouette: Silhouette[DefaultEnv],
  userService: UserService,
  credentialsProvider: CredentialsProvider,
  authInfoRepository: AuthInfoRepository,
  passwordHasherRegistry: PasswordHasherRegistry
)
  extends Controller with I18nSupport {

  def view = silhouette.SecuredAction(WithProvider[DefaultEnv#A](CredentialsProvider.ID)) { implicit request =>
    Ok(views.html.changePassword(new myform.MyChangePasswordForm(), request.identity))
  }

  def submit = silhouette.SecuredAction(WithProvider[DefaultEnv#A](CredentialsProvider.ID)).async { implicit request =>
    new myform.MyChangePasswordForm().bindFromRequest match {
      case form: myform.MyChangePasswordForm => Future.successful(BadRequest(views.html.changePassword(form, request.identity)))
      case data: myform.MyChangePasswordFormData => {
        val (currentPassword, newPassword) = (data.currentPassword, data.newPassword)
        val credentials = Credentials(request.identity.email.getOrElse(""), currentPassword)
        credentialsProvider.authenticate(credentials).flatMap { loginInfo =>
          val passwordInfo = passwordHasherRegistry.current.hash(newPassword)
          authInfoRepository.update[PasswordInfo](loginInfo, passwordInfo).map { _ =>
            Redirect(routes.ChangePasswordController.view()).flashing("success" -> Messages("password.changed"))
          }
        }.recover {
          case e: ProviderException =>
            Redirect(routes.ChangePasswordController.view()).flashing("error" -> Messages("current.password.invalid"))
        }
      }
    }
  }
} 
开发者ID:serversideapps,项目名称:silhmojs,代码行数:51,代码来源:ChangePasswordController.scala


示例3: ResetPasswordController

//设置package包名称以及导入依赖的类
package controllers

import java.util.UUID
import javax.inject.Inject

import com.mohiva.play.silhouette.api._
import com.mohiva.play.silhouette.api.repositories.AuthInfoRepository
import com.mohiva.play.silhouette.api.util.{ PasswordHasherRegistry, PasswordInfo }
import com.mohiva.play.silhouette.impl.providers.CredentialsProvider
import models.services.{ AuthTokenService, UserService }
import play.api.i18n.{ I18nSupport, Messages, MessagesApi }
import play.api.libs.concurrent.Execution.Implicits._
import play.api.mvc.Controller
import utils.auth.DefaultEnv

import scala.concurrent.Future

class ResetPasswordController @Inject() (
  val messagesApi: MessagesApi,
  silhouette: Silhouette[DefaultEnv],
  userService: UserService,
  authInfoRepository: AuthInfoRepository,
  passwordHasherRegistry: PasswordHasherRegistry,
  authTokenService: AuthTokenService
)
  extends Controller with I18nSupport {

  def view(token: UUID) = silhouette.UnsecuredAction.async { implicit request =>
    authTokenService.validate(token).map {
      case Some(authToken) => Ok(views.html.resetPassword(new myform.MyResetPasswordForm(), token))
      case None => Redirect(routes.SignInController.view()).flashing("error" -> Messages("invalid.reset.link"))
    }
  }

  def submit(token: UUID) = silhouette.UnsecuredAction.async { implicit request =>
    authTokenService.validate(token).flatMap {
      case Some(authToken) =>
        new myform.MyResetPasswordForm().bindFromRequest match {
          case form: myform.MyResetPasswordForm => Future.successful(BadRequest(views.html.resetPassword(form, token)))
          case data: myform.MyResetPasswordFormData => userService.retrieve(authToken.userID).flatMap {
            case Some(user) if user.loginInfo.providerID == CredentialsProvider.ID =>
              val passwordInfo = passwordHasherRegistry.current.hash(data.password)
              authInfoRepository.update[PasswordInfo](user.loginInfo, passwordInfo).map { _ =>
                Redirect(routes.SignInController.view()).flashing("success" -> Messages("password.reset"))
              }
            case _ => Future.successful(Redirect(routes.SignInController.view()).flashing("error" -> Messages("invalid.reset.link")))
          }
        }
      case None => Future.successful(Redirect(routes.SignInController.view()).flashing("error" -> Messages("invalid.reset.link")))
    }
  }
} 
开发者ID:serversideapps,项目名称:silhmojs,代码行数:53,代码来源:ResetPasswordController.scala


示例4: PasswordInfoQueries

//设置package包名称以及导入依赖的类
package models.queries

import com.mohiva.play.silhouette.api.LoginInfo
import com.mohiva.play.silhouette.api.util.PasswordInfo
import jdub.async.{ Row, Statement }
import jdub.async.queries.BaseQueries
import org.joda.time.LocalDateTime

object PasswordInfoQueries extends BaseQueries[PasswordInfo] {
  override protected val tableName = "password_info"
  override protected val columns = Seq("provider", "key", "hasher", "password", "salt", "created")
  override protected def idColumns = Seq("provider", "key")
  override protected val searchColumns = Seq("key")

  val getById = GetById
  val removeById = RemoveById

  case class CreatePasswordInfo(l: LoginInfo, p: PasswordInfo) extends Statement {
    override val sql = insertSql
    override val values = Seq(l.providerID, l.providerKey) ++ toDataSeq(p)
  }

  case class UpdatePasswordInfo(l: LoginInfo, p: PasswordInfo) extends Statement {
    override val sql = s"update $tableName set hasher = ?, password = ?, salt = ?, created = ? where provider = ? and key = ?"
    override val values = toDataSeq(p) ++ Seq(l.providerID, l.providerKey)
  }

  override protected def fromRow(row: Row) = PasswordInfo(
    hasher = row.as[String]("hasher"),
    password = row.as[String]("password"),
    salt = row.asOpt[String]("salt")
  )

  override protected def toDataSeq(p: PasswordInfo) = Seq(p.hasher, p.password, p.salt, new LocalDateTime())
} 
开发者ID:laurinka,项目名称:golfmit,代码行数:36,代码来源:PasswordInfoQueries.scala


示例5: PasswordHasherMD5

//设置package包名称以及导入依赖的类
package controllers

import java.nio.charset.StandardCharsets

import com.mohiva.play.silhouette.api.util.{PasswordHasher, PasswordInfo}
import org.apache.directory.api.ldap.model.constants.LdapSecurityConstants
import org.apache.directory.api.ldap.model.password.PasswordUtil


class PasswordHasherMD5 extends PasswordHasher{
  override def id: String = "MD5"

  override def hash(plainPassword: String): PasswordInfo = {
    PasswordInfo(hasher = id, password = plainPassword)
  }

  //TODO: Here might be an oversight. It seems to be to complicated.
  override def matches(passwordInfo: PasswordInfo, suppliedPassword: String): Boolean = {
    val suppliedStoragePW =  PasswordUtil.createStoragePassword(
      suppliedPassword,
      LdapSecurityConstants.getAlgorithm(passwordInfo.hasher)
    )

    val suppliedPW = new String(PasswordUtil.splitCredentials(suppliedStoragePW).getPassword,StandardCharsets.UTF_8)
    val storedPW = passwordInfo.password

    suppliedPW.equals(storedPW)
  }
} 
开发者ID:wirvomgut,项目名称:curo,代码行数:30,代码来源:PasswordHasherMD5.scala


示例6: Profile

//设置package包名称以及导入依赖的类
package models

import java.util.UUID

import play.api.libs.json.Json
import com.mohiva.play.silhouette.api.{Identity, LoginInfo}
import com.mohiva.play.silhouette.api.util.PasswordInfo
import com.mohiva.play.silhouette.impl.providers.OAuth1Info

case class Profile(
                    loginInfo:LoginInfo,
                    confirmed: Boolean,
                    email:Option[String],
                    firstName: Option[String],
                    lastName: Option[String],
                    fullName: Option[String],
                    passwordInfo:Option[PasswordInfo],
                    oauth1Info: Option[OAuth1Info],
                    avatarUrl: Option[String]) {
}

case class User(id: UUID, profiles: List[Profile]) extends Identity {
  def profileFor(loginInfo:LoginInfo) = profiles.find(_.loginInfo == loginInfo)
  def fullName(loginInfo:LoginInfo) = profileFor(loginInfo).flatMap(_.fullName)
}

object User {
  implicit val passwordInfoJsonFormat = Json.format[PasswordInfo]
  implicit val oauth1InfoJsonFormat = Json.format[OAuth1Info]
  implicit val profileJsonFormat = Json.format[Profile]
  implicit val userJsonFormat = Json.format[User]
} 
开发者ID:tm-sukehiro,项目名称:play-hands-on,代码行数:33,代码来源:User.scala


示例7: PasswordInfoDAO

//设置package包名称以及导入依赖的类
package models.daos

import com.mohiva.play.silhouette.api.LoginInfo
import com.mohiva.play.silhouette.api.util.PasswordInfo
import com.mohiva.play.silhouette.impl.daos.DelegableAuthInfoDAO
import com.mongodb.casbah.Imports
import com.mongodb.casbah.Imports._
import models.Database


class PasswordInfoDAO extends DelegableAuthInfoDAO[PasswordInfo] with AuthInfoDAO[PasswordInfo] {



  override def convertToDB(loginInfo: LoginInfo, authInfo: PasswordInfo) : DBObject = {
    MongoDBObject(
      "providerID" -> loginInfo.providerID,
      "providerKey" -> loginInfo.providerKey,
      "hasher" -> authInfo.hasher,
      "password" -> authInfo.password,
      "salt" -> authInfo.salt
    )
  }

  override def loadFromDB(dbAuthInfo : DBObject) : PasswordInfo = {
    PasswordInfo(
      Database.loadString(dbAuthInfo, "hasher"),
      Database.loadString(dbAuthInfo, "password"),
      Database.loadOptionalString(dbAuthInfo, "salt")
    )
  }
  override def data: Imports.MongoCollection = Database.db("authInfo")

} 
开发者ID:Bastcloa,项目名称:testJenkins,代码行数:35,代码来源:PasswordInfoDAO.scala


示例8: Profile

//设置package包名称以及导入依赖的类
package models

import java.util.UUID

import com.mohiva.play.silhouette.api.{Identity, LoginInfo}
import com.mohiva.play.silhouette.api.util.PasswordInfo
import com.mohiva.play.silhouette.impl.providers.OAuth1Info
import play.api.libs.json.Json



case class Profile(
                    loginInfo:LoginInfo,
                    confirmed: Boolean,
                    email:Option[String],
                    firstName: Option[String],
                    lastName: Option[String],
                    fullName: Option[String],
                    passwordInfo:Option[PasswordInfo],
                    oauth1Info: Option[OAuth1Info],
                    avatarUrl: Option[String])

object Profile {
  implicit val passwordInfoJsonFormat = Json.format[PasswordInfo]
  implicit val oauth1InfoJsonFormat = Json.format[OAuth1Info]
  implicit val profileJsonFormat = Json.format[Profile]
}

case class User(id: UUID, profiles: List[Profile]) extends Identity {
  def profileFor(loginInfo:LoginInfo) = profiles.find(_.loginInfo == loginInfo)
  def fullName(loginInfo:LoginInfo) = profileFor(loginInfo).flatMap(_.fullName)
}

object User {
  implicit val userJsonFormat = Json.format[User]
} 
开发者ID:k19862217,项目名称:book-shoes-api,代码行数:37,代码来源:User.scala


示例9: PasswordInfoService

//设置package包名称以及导入依赖的类
package services

import java.time.LocalDateTime

import com.mohiva.play.silhouette.api.LoginInfo
import com.mohiva.play.silhouette.api.util.PasswordInfo
import com.mohiva.play.silhouette.persistence.daos.DelegableAuthInfoDAO
import db.DbContext
import repositories.{PasswordInfoRepository, UserPasswordInfo}
import scala.concurrent.{ExecutionContext, Future}

class PasswordInfoService(val ctx: DbContext, userService: UserService)(implicit val executionContext: ExecutionContext) extends DelegableAuthInfoDAO[PasswordInfo] with PasswordInfoRepository {
  import ctx._

  override def add(loginInfo: LoginInfo, authInfo: PasswordInfo) = {
    userService.findUserByProvideKey(loginInfo.providerKey) flatMap {
      case Some(user) => run(pwInfo.insert(lift(
        UserPasswordInfo(
          user.id,
          authInfo.hasher,
          authInfo.password,
           Some("salt"),
          LocalDateTime.now()
        )
      )))
        .map(_ => authInfo)
      case None => Future(authInfo)
    }

  }

  override def find(loginInfo: LoginInfo) = {
    userService.findUserByProvideKey(loginInfo.providerKey) flatMap {
      case Some(user) => {
        for {
          e <- run(byUserId(user.id)).map(_.headOption)
        } yield {
          Some(PasswordInfo(e.get.hasher, e.get.password, e.get.salt))
        }
      }
      case None => Future(None)
    }
  }

  override def remove(loginInfo: LoginInfo) = ???

  override def save(loginInfo: LoginInfo, authInfo: PasswordInfo) = ???

  override def update(loginInfo: LoginInfo, authInfo: PasswordInfo) = ???
} 
开发者ID:iriddhi,项目名称:mis,代码行数:51,代码来源:PasswordInfoService.scala


示例10: User

//设置package包名称以及导入依赖的类
package models

import java.util.{Date, UUID}

import com.mohiva.play.silhouette.api.util.PasswordInfo
import com.mohiva.play.silhouette.api.{Identity, LoginInfo}
import com.mohiva.play.silhouette.impl.providers.OAuth1Info
import org.joda.time.DateTime
import play.api.libs.json.Json


case class User(
                id: UUID = UUID.randomUUID(),
                loginInfo: LoginInfo,
                confirmed: Boolean,
                email: Option[String],
                phone: Option[String],
                firstName: Option[String] = None,
                lastName: Option[String] = None,
                passwordInfo: Option[PasswordInfo],
                oauth1Info: Option[OAuth1Info],
                created: Date = new Date()) extends Identity {

  def fullName(loginInfo: LoginInfo): Option[String] = for {
    f <- firstName
    l <- lastName
  } yield f + " " + l

  def uuidStr: String = id.toString
}

object User {
  implicit val passwordInfoJsonFormat = Json.format[PasswordInfo]
  implicit val oauth1InfoJsonFormat = Json.format[OAuth1Info]
  implicit val userJsonFormat = Json.format[User]

  val COLLECTION_NAME = "users"
}

case class UserToken(id: UUID, userId: UUID, email: String, expirationTime: DateTime, isSignUp: Boolean) {
  def isExpired: Boolean = expirationTime.isBeforeNow
}

object UserToken {
  implicit val toJson = Json.format[UserToken]

  val COLLECTION_NAME = "tokens"

  def create(userId: UUID, email: String, isSignUp: Boolean) =
    UserToken(UUID.randomUUID(), userId, email, new DateTime().plusHours(12), isSignUp)
} 
开发者ID:fsanaulla,项目名称:Silh,代码行数:52,代码来源:User.scala


示例11: InMemoryPasswordAuthInfoStore

//设置package包名称以及导入依赖的类
package stores

import com.google.inject.{Singleton, Inject}
import com.mohiva.play.silhouette.api.LoginInfo
import com.mohiva.play.silhouette.api.util.PasswordInfo
import com.mohiva.play.silhouette.persistence.daos.DelegableAuthInfoDAO

import scala.collection.mutable
import scala.concurrent.Future

@Singleton
class InMemoryPasswordAuthInfoStore @Inject()() extends DelegableAuthInfoDAO[PasswordInfo] {
  val store = mutable.Map.empty[LoginInfo, PasswordInfo]

  override def find(loginInfo: LoginInfo): Future[Option[PasswordInfo]] = {
    Future.successful(store.get(loginInfo))
  }

  override def save(loginInfo: LoginInfo, passwordInfo: PasswordInfo): Future[PasswordInfo] = {
    store += (loginInfo -> passwordInfo)
    Future.successful(passwordInfo)
  }

  override def update(loginInfo: LoginInfo, passwordInfo: PasswordInfo): Future[PasswordInfo] = {
    store.get(loginInfo) match {
      case Some(_) =>
        save(loginInfo, passwordInfo)
      case None =>
        Future.failed(new Exception(s"cannot update $loginInfo, it does not exist"))
    }
  }

  override def add(loginInfo: LoginInfo, passwordInfo: PasswordInfo): Future[PasswordInfo] = {
    store.get(loginInfo) match {
      case None =>
        save(loginInfo, passwordInfo)
      case Some(_) =>
        Future.failed(new Exception(s"cannot add $loginInfo, it already exists"))
    }
  }

  override def remove(loginInfo: LoginInfo): Future[Unit] = {
    store -= loginInfo
    Future.successful(())
  }
} 
开发者ID:pequalsnp,项目名称:portroyal,代码行数:47,代码来源:InMemoryPasswordAuthInfoStore.scala


示例12: PasswordInfoDAO

//设置package包名称以及导入依赖的类
package models.daos

import javax.inject.Inject

import com.mohiva.play.silhouette.api.LoginInfo
import com.mohiva.play.silhouette.api.util.PasswordInfo
import com.mohiva.play.silhouette.impl.daos.DelegableAuthInfoDAO
import models.daos.tables.DAOSlick
import play.api.db.slick.DatabaseConfigProvider
import play.api.libs.concurrent.Execution.Implicits._

import scala.concurrent.Future

class PasswordInfoDAO @Inject()(protected val dbConfigProvider: DatabaseConfigProvider)
  extends DelegableAuthInfoDAO[PasswordInfo] with DAOSlick {

  import driver.api._

  def find(loginInfo: LoginInfo): Future[Option[PasswordInfo]] = {
    val query = passwords.filter(_.email === loginInfo.providerKey)
    db.run(query.result.headOption).map { dbPasswordInfoOption =>
      dbPasswordInfoOption.map(dbPasswordInfo =>
        PasswordInfo(dbPasswordInfo.hash, dbPasswordInfo.password, dbPasswordInfo.salt))
    }
  }

  def add(loginInfo: LoginInfo, authInfo: PasswordInfo) = save(loginInfo, authInfo)

  def save(loginInfo: LoginInfo, authInfo: PasswordInfo): Future[PasswordInfo] = {
    val dbPasswordInfo = DBPasswordInfo(authInfo.hasher, authInfo.password, authInfo.salt, loginInfo.providerKey)
    val query = passwords.insertOrUpdate(dbPasswordInfo)
    db.run(query).map(_ => authInfo)
  }

  def update(loginInfo: LoginInfo, authInfo: PasswordInfo) = save(loginInfo, authInfo)

  def remove(loginInfo: LoginInfo): Future[Unit] = {
    val query = passwords.filter(_.email === loginInfo.providerKey)
    db.run(query.delete).map(_ => ())
  }
} 
开发者ID:wjglerum,项目名称:bamboesmanager,代码行数:42,代码来源:PasswordInfoDAO.scala


示例13: PasswordAuthInfoDAO

//设置package包名称以及导入依赖的类
package models.daos

import javax.inject.Inject

import com.mohiva.play.silhouette.api.LoginInfo
import com.mohiva.play.silhouette.api.util.{PasswordHasher, PasswordInfo}
import com.mohiva.play.silhouette.persistence.daos.DelegableAuthInfoDAO
import org.example.project.schema.{Account, Query}
import xyz.mattclifton.autoquery.components.UpdateValue
import play.api.libs.concurrent.Execution.Implicits._

import scala.concurrent.Future

class PasswordAuthInfoDAO @Inject() (query: Query, passwordHasher: PasswordHasher) extends DelegableAuthInfoDAO[PasswordInfo] {
  def find(loginInfo: LoginInfo): Future[Option[PasswordInfo]] = {
    Future(getAccount(loginInfo).flatMap(toPasswordInfo(_)))
  }

  def update(loginInfo: LoginInfo, authInfo: PasswordInfo): Future[PasswordInfo] = {
    getAccount(loginInfo).map(account => {
      query.updateAccounts(
        filter = _.apply(ids = Seq(account.id)),
        values = _.apply(passwordHash = UpdateValue(Option(authInfo.password)), passwordSalt = UpdateValue(authInfo.salt))).execute()
    })

    Future(authInfo)
  }

  def remove(loginInfo: LoginInfo): Future[Unit] = {
    getAccount(loginInfo).map(account => {
      query.updateAccounts(
        filter = _.apply(ids = Seq(account.id)),
        values = _.apply(passwordHash = UpdateValue(None), passwordSalt = UpdateValue(None))).execute()
    })

    Future({})
  }

  def save(loginInfo: LoginInfo, authInfo: PasswordInfo): Future[PasswordInfo] = {
    update(loginInfo, authInfo)
  }

  def add(loginInfo: LoginInfo, authInfo: PasswordInfo): Future[PasswordInfo] = {
    update(loginInfo, authInfo)
  }

  private def getAccount(loginInfo: LoginInfo): Option[Account] = {
    query.getAccountProviders(
      filter = _.apply(providerIdAndProviderKey = Some(_.apply(Seq(loginInfo.providerID), Seq(loginInfo.providerKey)))),
      include = s => Seq(s.account)).execute().headOption.map(_.account)
  }

  private def toPasswordInfo(account: Account): Option[PasswordInfo] = {
    account.passwordHash.map(hash => PasswordInfo(passwordHasher.id, hash, account.passwordSalt))
  }
} 
开发者ID:lynx44,项目名称:play_autoquery_template,代码行数:57,代码来源:PasswordAuthInfoDAO.scala



注:本文中的com.mohiva.play.silhouette.api.util.PasswordInfo类示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Scala ReactiveMongoComponents类代码示例发布时间:2022-05-23
下一篇:
Scala HttpEntity类代码示例发布时间:2022-05-23
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap