diff --git a/thehive-backend/conf/routes b/thehive-backend/conf/routes index 2e30f5eaae..ca05053d7d 100644 --- a/thehive-backend/conf/routes +++ b/thehive-backend/conf/routes @@ -26,12 +26,6 @@ GET /api/case/template/:caseTemplateId controllers.CaseTemplateCtrl.g PATCH /api/case/template/:caseTemplateId controllers.CaseTemplateCtrl.update(caseTemplateId) DELETE /api/case/template/:caseTemplateId controllers.CaseTemplateCtrl.delete(caseTemplateId) -POST /api/report/template/_search controllers.ReportTemplateCtrl.find() -POST /api/report/template controllers.ReportTemplateCtrl.create() -GET /api/report/template/:caseTemplateId controllers.ReportTemplateCtrl.get(caseTemplateId) -PATCH /api/report/template/:caseTemplateId controllers.ReportTemplateCtrl.update(caseTemplateId) -DELETE /api/report/template/:caseTemplateId controllers.ReportTemplateCtrl.delete(caseTemplateId) - POST /api/case/artifact/_search controllers.ArtifactCtrl.find() POST /api/case/:caseId/artifact/_search controllers.ArtifactCtrl.findInCase(caseId) POST /api/case/artifact/_stats controllers.ArtifactCtrl.stats() diff --git a/thehive-cortex/app/connectors/cortex/CortexConnector.scala b/thehive-cortex/app/connectors/cortex/CortexConnector.scala index e91ff4a973..a1b0385578 100644 --- a/thehive-cortex/app/connectors/cortex/CortexConnector.scala +++ b/thehive-cortex/app/connectors/cortex/CortexConnector.scala @@ -3,6 +3,7 @@ package connectors.cortex import play.api.{ Configuration, Environment, Logger } import connectors.ConnectorModule +import connectors.cortex.controllers.CortextCtrl class CortexConnector( environment: Environment, diff --git a/thehive-backend/app/models/ReportTemplate.scala b/thehive-cortex/app/connectors/cortex/models/ReportTemplate.scala similarity index 98% rename from thehive-backend/app/models/ReportTemplate.scala rename to thehive-cortex/app/connectors/cortex/models/ReportTemplate.scala index 17f118b208..116a0e741f 100644 --- a/thehive-backend/app/models/ReportTemplate.scala +++ b/thehive-cortex/app/connectors/cortex/models/ReportTemplate.scala @@ -1,17 +1,17 @@ -package models - -import javax.inject.{ Inject, Singleton } - -import play.api.libs.json.JsObject - -import org.elastic4play.models.{ AttributeDef, AttributeFormat ⇒ F, EntityDef, ModelDef } - -trait ReportTemplateAttributes { _: AttributeDef ⇒ - val content = attribute("content", F.textFmt, "Content of the template") - val falvor = attribute("flavor", F.stringFmt, "Flavor of the report (short or long)") - val analyzers = multiAttribute("analyzers", F.stringFmt, "Id of analyzers") -} - -@Singleton -class ReportTemplateModel @Inject() extends ModelDef[ReportTemplateModel, ReportTemplate]("reportTemplate") with ReportTemplateAttributes +package models + +import javax.inject.{ Inject, Singleton } + +import play.api.libs.json.JsObject + +import org.elastic4play.models.{ AttributeDef, AttributeFormat ⇒ F, EntityDef, ModelDef } + +trait ReportTemplateAttributes { _: AttributeDef ⇒ + val content = attribute("content", F.textFmt, "Content of the template") + val falvor = attribute("flavor", F.stringFmt, "Flavor of the report (short or long)") + val analyzers = multiAttribute("analyzers", F.stringFmt, "Id of analyzers") +} + +@Singleton +class ReportTemplateModel @Inject() extends ModelDef[ReportTemplateModel, ReportTemplate]("reportTemplate") with ReportTemplateAttributes class ReportTemplate(model: ReportTemplateModel, attributes: JsObject) extends EntityDef[ReportTemplateModel, ReportTemplate](model, attributes) with ReportTemplateAttributes \ No newline at end of file diff --git a/thehive-backend/app/services/ReportTemplateSrv.scala b/thehive-cortex/app/connectors/cortex/services/ReportTemplaceSrv.scala similarity index 100% rename from thehive-backend/app/services/ReportTemplateSrv.scala rename to thehive-cortex/app/connectors/cortex/services/ReportTemplaceSrv.scala diff --git a/thehive-cortex/app/connectors/cortex/CortextCtrl.scala b/thehive-cortex/app/controllers/CortextCtrl.scala similarity index 73% rename from thehive-cortex/app/connectors/cortex/CortextCtrl.scala rename to thehive-cortex/app/controllers/CortextCtrl.scala index f63fdff475..b40af303d7 100644 --- a/thehive-cortex/app/connectors/cortex/CortextCtrl.scala +++ b/thehive-cortex/app/controllers/CortextCtrl.scala @@ -1,4 +1,4 @@ -package connectors.cortex +package connectors.cortex.controllers import javax.inject.{ Inject, Singleton } @@ -8,7 +8,7 @@ import play.api.Logger import play.api.http.Status import play.api.mvc.Controller import play.api.routing.SimpleRouter -import play.api.routing.sird.{ GET, POST, UrlContext } +import play.api.routing.sird.{ DELETE, GET, PATCH, POST, UrlContext } import org.elastic4play.{ BadRequestError, NotFoundError, Timed } import org.elastic4play.controllers.{ Authenticated, FieldsBodyParser, Renderer } @@ -22,6 +22,7 @@ import connectors.cortex.services.CortexSrv @Singleton class CortextCtrl @Inject() ( + reportTemplateCtrl: ReportTemplateCtrl, cortexSrv: CortexSrv, authenticated: Authenticated, fieldsBodyParser: FieldsBodyParser, @@ -30,13 +31,19 @@ class CortextCtrl @Inject() ( val name = "cortex" val log = Logger(getClass) val router = SimpleRouter { - case POST(p"/job") ⇒ createJob - case GET(p"/job/$jobId<[^/]*>") ⇒ getJob(jobId) - case POST(p"/job/_search") ⇒ findJob - case GET(p"/analyzer/$analyzerId<[^/]*>") ⇒ getAnalyzer(analyzerId) + case POST(p"/job") ⇒ createJob + case GET(p"/job/$jobId<[^/]*>") ⇒ getJob(jobId) + case POST(p"/job/_search") ⇒ findJob + case GET(p"/analyzer/$analyzerId<[^/]*>") ⇒ getAnalyzer(analyzerId) case GET(p"/analyzer/type/$dataType<[^/]*>") ⇒ getAnalyzerFor(dataType) - case GET(p"/analyzer") ⇒ listAnalyzer - case r ⇒ throw NotFoundError(s"${r.uri} not found") + case GET(p"/analyzer") ⇒ listAnalyzer + case POST(p"/report/template/_search") ⇒ reportTemplateCtrl.find() + case POST(p"/report/template") ⇒ reportTemplateCtrl.create() + case GET(p"/report/template/$caseTemplateId<[^/]*>") ⇒ reportTemplateCtrl.get(caseTemplateId) + case PATCH(p"/report/template/$caseTemplateId<[^/]*>") ⇒ reportTemplateCtrl.update(caseTemplateId) + case DELETE(p"/report/template/$caseTemplateId<[^/]*>") ⇒ reportTemplateCtrl.delete(caseTemplateId) + case GET(p"/report/template/content/$analyzerId<[^/]*>/$flavor<[^/]*>") ⇒ reportTemplateCtrl.getContent(analyzerId, flavor) + case r ⇒ throw NotFoundError(s"${r.uri} not found") } @Timed diff --git a/thehive-backend/app/controllers/ReportTemplate.scala b/thehive-cortex/app/controllers/ReportTemplate.scala similarity index 70% rename from thehive-backend/app/controllers/ReportTemplate.scala rename to thehive-cortex/app/controllers/ReportTemplate.scala index 31b1ccfd12..3a6f27835f 100644 --- a/thehive-backend/app/controllers/ReportTemplate.scala +++ b/thehive-cortex/app/controllers/ReportTemplate.scala @@ -1,4 +1,4 @@ -package controllers +package connectors.cortex.controllers import javax.inject.{ Inject, Singleton } @@ -15,6 +15,9 @@ import org.elastic4play.services.AuxSrv import org.elastic4play.services.JsonFormat.queryReads import services.ReportTemplateSrv +import play.api.Logger +import akka.stream.scaladsl.Sink +import akka.stream.Materializer @Singleton class ReportTemplateCtrl @Inject() ( @@ -23,7 +26,10 @@ class ReportTemplateCtrl @Inject() ( authenticated: Authenticated, renderer: Renderer, fieldsBodyParser: FieldsBodyParser, - implicit val ec: ExecutionContext) extends Controller with Status { + implicit val ec: ExecutionContext, + implicit val mat: Materializer) extends Controller with Status { + + lazy val logger = Logger(getClass) @Timed def create = authenticated(Role.admin).async(fieldsBodyParser) { implicit request ⇒ @@ -37,6 +43,21 @@ class ReportTemplateCtrl @Inject() ( .map(reportTemplate ⇒ renderer.toOutput(OK, reportTemplate)) } + @Timed + def getContent(analyzerId: String, flavor: String) = authenticated(Role.read).async { implicit request ⇒ + import QueryDSL._ + val (reportTemplates, total) = reportTemplateSrv.find(and("analyzers" ~= analyzerId, "flavor" ~= flavor), Some("0-1"), Nil) + total.foreach { t ⇒ + if (t > 1) logger.warn(s"Multiple report templates match for analyzer $analyzerId with flavor $flavor") + } + reportTemplates + .runWith(Sink.headOption) + .map { + case Some(reportTemplate) ⇒ Ok(reportTemplate.content()).as("text/html") + case None ⇒ NotFound("") + } + } + @Timed def update(id: String) = authenticated(Role.admin).async(fieldsBodyParser) { implicit request ⇒ reportTemplateSrv.update(id, request.body) diff --git a/ui/app/scripts/services/AnalyzerSrv.js b/ui/app/scripts/services/AnalyzerSrv.js index fe3162e68c..97629be901 100644 --- a/ui/app/scripts/services/AnalyzerSrv.js +++ b/ui/app/scripts/services/AnalyzerSrv.js @@ -2,7 +2,7 @@ 'use strict'; angular.module('theHiveServices') .factory('AnalyzerSrv', function($resource) { - return $resource('/api/analyzer/:analyzerId', {}, { + return $resource('/api/connector/cortex/analyzer/:analyzerId', {}, { query: { method: 'GET', url: '/api/connector/cortex/analyzer', diff --git a/ui/app/scripts/services/ReportTemplateSrv.js b/ui/app/scripts/services/ReportTemplateSrv.js index ca91c7c7be..b7884747a8 100644 --- a/ui/app/scripts/services/ReportTemplateSrv.js +++ b/ui/app/scripts/services/ReportTemplateSrv.js @@ -2,7 +2,7 @@ 'use strict'; angular.module('theHiveServices') .factory('ReportTemplateSrv', function($resource, $http) { - var baseUrl = '/api/report/template'; + var baseUrl = '/api/connector/cortex/report/template'; var resource = $resource(baseUrl, {}, { query: { method: 'POST', @@ -31,12 +31,12 @@ }); }, - save: function(tpl) { + save: function(tpl) { if(tpl.id) { return $http.put(baseUrl + '/' + tpl.id, tpl, {}); } else { return $http.post(baseUrl, tpl, {}); - } + } } }