From 56d33c541eeea2e8e302d7ee62149ec1015a311e Mon Sep 17 00:00:00 2001 From: SDugo Date: Mon, 8 Feb 2021 18:40:27 +0100 Subject: [PATCH 1/2] Added support for Bearer token on Webhook class Webhook class now supports the addition of an optional "token". It needs to be declared at the same level that "url" on the application.conf file. If the parameter exists within a webhook definition, its value will be added to an Authorization header. Else, the send() function of the Webhook class won't include this header on the POST request. An example of configuration on the application.conf would be as follows: webhooks { myLocalWebHook { url = "http://localhost/webhook" token = "xxxxxxxxxxxxxxxxxx" } } --- thehive-backend/app/services/WebHook.scala | 29 ++++++++++++++++------ 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/thehive-backend/app/services/WebHook.scala b/thehive-backend/app/services/WebHook.scala index 78b85a59da..279d24c7da 100644 --- a/thehive-backend/app/services/WebHook.scala +++ b/thehive-backend/app/services/WebHook.scala @@ -9,17 +9,29 @@ import scala.util.{Failure, Success, Try} import play.api.{Configuration, Logger} import play.api.libs.json.JsObject import play.api.libs.ws.WSRequest +import play.api.http.HeaderNames import org.elastic4play.services.AuxSrv -case class WebHook(name: String, ws: WSRequest)(implicit ec: ExecutionContext) { +case class WebHook(name: String, ws: WSRequest, wsToken: Option[String] = None)(implicit ec: ExecutionContext) { private[WebHook] lazy val logger = Logger(getClass.getName + "." + name) - def send(obj: JsObject): Unit = ws.post(obj).onComplete { - case Success(resp) if resp.status / 100 != 2 ⇒ logger.error(s"WebHook returns status ${resp.status} ${resp.statusText}") - case Failure(_: ConnectException) ⇒ logger.error(s"Connection to WebHook $name error") - case Failure(error) ⇒ logger.error("WebHook call error", error) - case _ ⇒ + def send(obj: JsObject): Unit = { + if (wsToken != None) { + ws.withHttpHeaders(HeaderNames.AUTHORIZATION -> s"Bearer ${wsToken.get}").post(obj).onComplete { + case Success(resp) if resp.status / 100 != 2 ⇒ logger.error(s"WebHook returns status ${resp.status} ${resp.statusText}") + case Failure(_: ConnectException) ⇒ logger.error(s"Connection to WebHook $name error") + case Failure(error) ⇒ logger.error("WebHook call error", error) + case _ ⇒ + } + } else { + ws.post(obj).onComplete { + case Success(resp) if resp.status / 100 != 2 ⇒ logger.error(s"WebHook returns status ${resp.status} ${resp.statusText}") + case Failure(_: ConnectException) ⇒ logger.error(s"Connection to WebHook $name error") + case Failure(error) ⇒ logger.error("WebHook call error", error) + case _ ⇒ + } + } } } @@ -31,8 +43,9 @@ class WebHooks(webhooks: Seq[WebHook], auxSrv: AuxSrv, implicit val ec: Executio name ← cfg.subKeys whConfig ← Try(cfg.get[Configuration](name)).toOption url ← whConfig.getOptional[String]("url") + token ← Some(whConfig.getOptional[String]("token")) instanceWS = whWS.withConfig(whConfig).url(url) - } yield WebHook(name, instanceWS)(ec), auxSrv, ec) + } yield WebHook(name, instanceWS, token)(ec), auxSrv, ec) } def send(obj: JsObject): Unit = @@ -44,4 +57,4 @@ class WebHooks(webhooks: Seq[WebHook], auxSrv: AuxSrv, implicit val ec: Executio .map(o ⇒ obj + ("object" → o)) .fallbackTo(Future.successful(obj)) .foreach(o ⇒ webhooks.foreach(_.send(o))) -} +} \ No newline at end of file From bc906aa7851f9d310574acb0b4cfdce385c26bc2 Mon Sep 17 00:00:00 2001 From: SDugo Date: Sat, 27 Feb 2021 16:59:20 +0100 Subject: [PATCH 2/2] Update WebHook.scala Added the optional parameter "tokenName", with a "Bearer" default value. --- thehive-backend/app/services/WebHook.scala | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/thehive-backend/app/services/WebHook.scala b/thehive-backend/app/services/WebHook.scala index 279d24c7da..8b9e648eca 100644 --- a/thehive-backend/app/services/WebHook.scala +++ b/thehive-backend/app/services/WebHook.scala @@ -13,12 +13,12 @@ import play.api.http.HeaderNames import org.elastic4play.services.AuxSrv -case class WebHook(name: String, ws: WSRequest, wsToken: Option[String] = None)(implicit ec: ExecutionContext) { +case class WebHook(name: String, ws: WSRequest, wsToken: Option[String] = None, wsTokenName: Option[String])(implicit ec: ExecutionContext) { private[WebHook] lazy val logger = Logger(getClass.getName + "." + name) def send(obj: JsObject): Unit = { if (wsToken != None) { - ws.withHttpHeaders(HeaderNames.AUTHORIZATION -> s"Bearer ${wsToken.get}").post(obj).onComplete { + ws.withHttpHeaders(HeaderNames.AUTHORIZATION -> s"${wsTokenName.getOrElse("Bearer")} ${wsToken.get}").post(obj).onComplete { case Success(resp) if resp.status / 100 != 2 ⇒ logger.error(s"WebHook returns status ${resp.status} ${resp.statusText}") case Failure(_: ConnectException) ⇒ logger.error(s"Connection to WebHook $name error") case Failure(error) ⇒ logger.error("WebHook call error", error) @@ -44,8 +44,9 @@ class WebHooks(webhooks: Seq[WebHook], auxSrv: AuxSrv, implicit val ec: Executio whConfig ← Try(cfg.get[Configuration](name)).toOption url ← whConfig.getOptional[String]("url") token ← Some(whConfig.getOptional[String]("token")) + tokenName ← Some(whConfig.getOptional[String]("tokenName")) instanceWS = whWS.withConfig(whConfig).url(url) - } yield WebHook(name, instanceWS, token)(ec), auxSrv, ec) + } yield WebHook(name, instanceWS, token, tokenName)(ec), auxSrv, ec) } def send(obj: JsObject): Unit =