All Downloads are FREE. Search and download functionalities are using the official Maven repository.

im.actor.server.activation.smtp.SMTPProvider.scala Maven / Gradle / Ivy

The newest version!
package im.actor.server.activation.smtp

import java.nio.file.{ Files, Paths }

import akka.actor.ActorSystem
import akka.http.scaladsl.util.FastFuture
import akka.pattern.ask
import akka.util.Timeout
import cats.data.Xor
import im.actor.config.ActorConfig
import im.actor.env.ActorEnv
import im.actor.server.activation.common.ActivationStateActor.{ ForgetSentCode, Send, SendAck }
import im.actor.server.activation.common._
import im.actor.server.db.DbExtension
import im.actor.server.email.{ Content, EmailConfig, Message, SmtpEmailSender }
import im.actor.server.model.AuthEmailTransaction
import im.actor.server.persist.auth.AuthTransactionRepo
import im.actor.util.misc.EmailUtils.isTestEmail

import scala.concurrent.Future
import scala.concurrent.duration._

private[activation] final class SMTPProvider(system: ActorSystem) extends ActivationProvider with CommonAuthCodes {

  protected implicit val ec = system.dispatcher
  protected val activationConfig = ActivationConfig.load.getOrElse(throw new RuntimeException("Failed to load activation config"))
  protected val db = DbExtension(system).db

  private implicit val timeout = Timeout(20.seconds)

  private val emailConfig = EmailConfig.load.getOrElse(throw new RuntimeException("Failed to load email config"))
  private val emailSender = new SmtpEmailSender(emailConfig)
  private val emailTemplateLocation =
    ActorEnv.getAbsolutePath(Paths.get(ActorConfig.load().getString("services.activation.email.template")))

  private val emailTemplate = new String(Files.readAllBytes(emailTemplateLocation))

  private val smtpStateActor = system.actorOf(ActivationStateActor.props[String, EmailCode](
    repeatLimit = activationConfig.repeatLimit,
    sendAction = (code: EmailCode) ⇒ emailSender.send(
    Message(
      to = code.email,
      subject = s"Actor activation code: ${code.code}",
      content = Content(Some(emailTemplate.replace("$$CODE$$", code.code)), Some(s"Your actor activation code: ${code.code}"))
    )
  ),
    id = (code: EmailCode) ⇒ code.email
  ), "internal-smtp-state")

  override def send(txHash: String, code: Code): Future[CodeFailure Xor Unit] = code match {
    case code: EmailCode ⇒
      if (isTestEmail(code.email)) {
        FastFuture.successful(Xor.right(()))
      } else {
        for {
          resp ← (smtpStateActor ? Send(code)).mapTo[SendAck].map(_.result)
          _ ← createAuthCodeIfNeeded(resp, txHash, code.code)
        } yield resp
      }
    case other ⇒ throw new RuntimeException(s"This provider can't handle code of type: ${other.getClass}")
  }

  override def cleanup(txHash: String): Future[Unit] = {
    for {
      ac ← db.run(AuthTransactionRepo.findChildren(txHash))
      _ = ac match {
        case Some(x: AuthEmailTransaction) ⇒ smtpStateActor ! ForgetSentCode.email(x.email)
        case _                             ⇒
      }
      _ ← deleteAuthCode(txHash)
    } yield ()
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy