From c3504dea6e8a98dbdb261a45dd9168e8fe6bdb79 Mon Sep 17 00:00:00 2001 From: hongwei Date: Wed, 6 Aug 2025 13:25:40 +0200 Subject: [PATCH] refactor/used Apache Commons Email instead of LiftMail- step6 --- .../build_container_develop_branch.yml | 2 +- .../main/scala/bootstrap/liftweb/Boot.scala | 23 ++++++------ .../code/api/util/NotificationUtil.scala | 17 +++++---- .../bankconnectors/LocalMappedConnector.scala | 32 +++++++++++------ .../code/snippet/ConsumerRegistration.scala | 35 +++++++++---------- 5 files changed, 57 insertions(+), 52 deletions(-) diff --git a/.github/workflows/build_container_develop_branch.yml b/.github/workflows/build_container_develop_branch.yml index d3f355042..4400d8cd3 100644 --- a/.github/workflows/build_container_develop_branch.yml +++ b/.github/workflows/build_container_develop_branch.yml @@ -6,7 +6,7 @@ on: workflow_dispatch: push: branches: - - develop + - * env: ## Sets environment variable diff --git a/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala b/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala index 64dd6fc2c..9ae42172e 100644 --- a/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala +++ b/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala @@ -46,6 +46,7 @@ import code.api.util.ApiRole.CanCreateEntitlementAtAnyBank import code.api.util.ErrorMessages.MandatoryPropertyIsNotSet import code.api.util._ import code.api.util.migration.Migration +import code.api.util.CommonsEmailWrapper import code.api.util.migration.Migration.DbFunction import code.apicollection.ApiCollection import code.apicollectionendpoint.ApiCollectionEndpoint @@ -692,10 +693,6 @@ class Boot extends MdcLoggable { case e: ExceptionInInitializerError => logger.warn(s"BankAccountCreationListener Exception: $e") } -// Mailer.devModeSend.default.set( (m : MimeMessage) => { -// logger.info("Would have sent email if not in dev mode: " + m.getContent) -// }) - LiftRules.exceptionHandler.prepend{ case(_, r, e) if e.isInstanceOf[NullPointerException] && e.getMessage.contains("Looking for Connection Identifier") => { logger.error(s"Exception being returned to browser when processing url is ${r.request.uri}, method is ${r.request.method}, exception detail is $e", e) @@ -879,7 +876,7 @@ class Boot extends MdcLoggable { } private def sendExceptionEmail(exception: Throwable): Unit = { - import Mailer.{From, PlainMailBodyType, Subject, To} + import net.liftweb.util.Helpers.now val outputStream = new java.io.ByteArrayOutputStream @@ -898,18 +895,18 @@ class Boot extends MdcLoggable { //technically doesn't work for all valid email addresses so this will mess up if someone tries to send emails to "foo,bar"@example.com val to = toAddressesString.split(",").toList - val toParams = to.map(To(_)) - val params = PlainMailBodyType(error) :: toParams - //this is an async call - Mailer.sendMail( - From(from), - Subject(s"you got an exception on $host"), - params :_* + val emailContent = CommonsEmailWrapper.EmailContent( + from = from, + to = to, + subject = s"you got an exception on $host", + textContent = Some(error) ) + + //this is an async call∆∆ + CommonsEmailWrapper.sendTextEmail(emailContent) } - //if Mailer.sendMail wasn't called (note: this actually isn't checking if the mail failed to send as that is being done asynchronously) if(mailSent.isEmpty) logger.warn(s"Exception notification failed: $mailSent") } diff --git a/obp-api/src/main/scala/code/api/util/NotificationUtil.scala b/obp-api/src/main/scala/code/api/util/NotificationUtil.scala index 8b8f95e4a..cc2e52160 100644 --- a/obp-api/src/main/scala/code/api/util/NotificationUtil.scala +++ b/obp-api/src/main/scala/code/api/util/NotificationUtil.scala @@ -6,8 +6,7 @@ import code.users.Users import code.util.Helper.MdcLoggable import com.openbankproject.commons.model.User import net.liftweb.common.Box -import net.liftweb.util.Mailer -import net.liftweb.util.Mailer._ + import scala.collection.immutable.List @@ -27,14 +26,14 @@ object NotificationUtil extends MdcLoggable { | |Cheers |""".stripMargin - val params = PlainMailBodyType(bodyOfMessage) :: List(To(user.emailAddress)) - val subjectOfMessage = "You have been granted the role" - //this is an async call - Mailer.sendMail( - From(from), - Subject(subjectOfMessage), - params :_* + val emailContent = CommonsEmailWrapper.EmailContent( + from = from, + to = List(user.emailAddress), + subject = s"You have been granted the role: ${entitlement.roleName}", + textContent = Some(bodyOfMessage) ) + //this is an async call + CommonsEmailWrapper.sendTextEmail(emailContent) } if(mailSent.isEmpty) { val info = diff --git a/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala b/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala index 19fcd715f..8b121c586 100644 --- a/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala +++ b/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala @@ -79,8 +79,7 @@ import net.liftweb.json import net.liftweb.json.{JArray, JBool, JObject, JValue} import net.liftweb.mapper._ import net.liftweb.util.Helpers.{hours, now, time, tryo} -import net.liftweb.util.Mailer.{From, PlainMailBodyType, Subject, To} -import net.liftweb.util.{Helpers, Mailer} +import net.liftweb.util.Helpers import org.mindrot.jbcrypt.BCrypt import scalikejdbc.DB.CPContext import scalikejdbc.{ConnectionPool, ConnectionPoolSettings, MultipleConnectionPoolContext, DB => scalikeDB, _} @@ -381,8 +380,13 @@ object LocalMappedConnector extends Connector with MdcLoggable { val hashedPassword = createHashedPassword(challengeAnswer) APIUtil.getEmailsByUserId(userId) map { pair => - val params = PlainMailBodyType(s"Your OTP challenge : ${challengeAnswer}") :: List(To(pair._2)) - Mailer.sendMail(From("challenge@tesobe.com"), Subject("Challenge"), params: _*) + val emailContent = CommonsEmailWrapper.EmailContent( + from = "challenge@tesobe.com", + to = List(pair._2), + subject = "Challenge", + textContent = Some(s"Your OTP challenge : ${challengeAnswer}") + ) + CommonsEmailWrapper.sendTextEmail(emailContent) } hashedPassword case Some(StrongCustomerAuthentication.SMS) | Some(StrongCustomerAuthentication.SMS_OTP) => @@ -5183,12 +5187,13 @@ object LocalMappedConnector extends Connector with MdcLoggable { _ <- Future{ scaMethod match { case v if v == StrongCustomerAuthentication.EMAIL.toString => // Send the email - val params = PlainMailBodyType(userAuthContextUpdate.challenge) :: List(To(customer.email)) - Mailer.sendMail( - From("challenge@tesobe.com"), - Subject("Challenge request"), - params :_* + val emailContent = CommonsEmailWrapper.EmailContent( + from = "challenge@tesobe.com", + to = List(customer.email), + subject = "Challenge request", + textContent = Some(userAuthContextUpdate.challenge) ) + CommonsEmailWrapper.sendTextEmail(emailContent) case v if v == StrongCustomerAuthentication.SMS.toString => // Not implemented case _ => // Not handled } @@ -5209,8 +5214,13 @@ object LocalMappedConnector extends Connector with MdcLoggable { callContext: Option[CallContext] ): OBPReturnType[Box[String]] = { if (scaMethod == StrongCustomerAuthentication.EMAIL){ // Send the email - val params = PlainMailBodyType(message) :: List(To(recipient)) - Mailer.sendMail(From("challenge@tesobe.com"), Subject("OBP Consent Challenge"), params :_*) + val emailContent = CommonsEmailWrapper.EmailContent( + from = "challenge@tesobe.com", + to = List(recipient), + subject = "OBP Consent Challenge", + textContent = Some(message) + ) + CommonsEmailWrapper.sendTextEmail(emailContent) Future{(Full("Success"), callContext)} } else if (scaMethod == StrongCustomerAuthentication.SMS){ // Send the SMS for { diff --git a/obp-api/src/main/scala/code/snippet/ConsumerRegistration.scala b/obp-api/src/main/scala/code/snippet/ConsumerRegistration.scala index 0e25cf923..b79da7d55 100644 --- a/obp-api/src/main/scala/code/snippet/ConsumerRegistration.scala +++ b/obp-api/src/main/scala/code/snippet/ConsumerRegistration.scala @@ -28,7 +28,7 @@ package code.snippet import java.util import code.api.{Constant, DirectLogin} -import code.api.util.{APIUtil, ErrorMessages, KeycloakAdmin, X509} +import code.api.util.{APIUtil, ErrorMessages, KeycloakAdmin, X509, CommonsEmailWrapper} import code.consumer.Consumers import code.model.dataAccess.AuthUser import code.model.{Consumer, _} @@ -424,18 +424,19 @@ class ConsumerRegistration extends MdcLoggable { s"Direct Login Documentation: ${oauthDocumentationUrl} \n" + s"$registrationMoreInfoText: $registrationMoreInfoUrl" - val params = PlainMailBodyType(registrationMessage) :: List(To(registered.developerEmail.get)) - val webuiRegisterConsumerSuccessMssageEmail : String = getWebUiPropsValue( "webui_register_consumer_success_message_email", "Thank you for registering to use the Open Bank Project API.") - //this is an async call - Mailer.sendMail( - From(from), - Subject(webuiRegisterConsumerSuccessMssageEmail), - params :_* + val emailContent = CommonsEmailWrapper.EmailContent( + from = from, + to = List(registered.developerEmail.get), + subject = webuiRegisterConsumerSuccessMssageEmail, + textContent = Some(registrationMessage) ) + + //this is an async call + CommonsEmailWrapper.sendTextEmail(emailContent) } if(mailSent.isEmpty) @@ -445,8 +446,6 @@ class ConsumerRegistration extends MdcLoggable { // This is to let the system administrators / API managers know that someone has registered a consumer key. def notifyRegistrationOccurred(registered : Consumer) = { - import net.liftweb.util.Mailer - import net.liftweb.util.Mailer._ val mailSent = for { // e.g mail.api.consumer.registered.sender.address=no-reply@example.com @@ -465,18 +464,18 @@ class ConsumerRegistration extends MdcLoggable { //technically doesn't work for all valid email addresses so this will mess up if someone tries to send emails to "foo,bar"@example.com val to = toAddressesString.split(",").toList - val toParams = to.map(To(_)) - val params = PlainMailBodyType(registrationMessage) :: toParams + + val emailContent = CommonsEmailWrapper.EmailContent( + from = from, + to = to, + subject = s"New API user registered on $thisApiInstance", + textContent = Some(registrationMessage) + ) //this is an async call - Mailer.sendMail( - From(from), - Subject(s"New API user registered on $thisApiInstance"), - params :_* - ) + CommonsEmailWrapper.sendTextEmail(emailContent) } - //if Mailer.sendMail wasn't called (note: this actually isn't checking if the mail failed to send as that is being done asynchronously) if(mailSent.isEmpty) this.logger.warn(s"API consumer registration failed: $mailSent")