From bfda484e0c5b4ed069f3ea88ddf5682cfef0abe4 Mon Sep 17 00:00:00 2001 From: To-om Date: Thu, 7 Jan 2021 09:33:34 +0100 Subject: [PATCH] #1734 Rewrite case handling duration --- .../thp/thehive/controllers/v0/CaseCtrl.scala | 65 ++----------------- .../thehive/controllers/v1/Properties.scala | 65 ++----------------- .../org/thp/thehive/services/CaseSrv.scala | 16 ++++- 3 files changed, 23 insertions(+), 123 deletions(-) diff --git a/thehive/app/org/thp/thehive/controllers/v0/CaseCtrl.scala b/thehive/app/org/thp/thehive/controllers/v0/CaseCtrl.scala index f8fcd8aeed..3e6782c2ff 100644 --- a/thehive/app/org/thp/thehive/controllers/v0/CaseCtrl.scala +++ b/thehive/app/org/thp/thehive/controllers/v0/CaseCtrl.scala @@ -345,66 +345,11 @@ class PublicCase @Inject() ( } yield Json.obj("customFields" -> values) case _ => Failure(BadRequestError("Invalid custom fields format")) }) - .property("computed.handlingDurationInDays", UMapping.long)( - _.select( - _.coalesceIdent( - _.has(_.endDate) - .sack( - (_: JLong, endDate: JLong) => endDate, - _.by(_.value(_.endDate).graphMap[Long, JLong, Converter[Long, JLong]](_.getTime, Converter.long)) - ) - .sack((_: Long) - (_: JLong), _.by(_.value(_.startDate).graphMap[Long, JLong, Converter[Long, JLong]](_.getTime, Converter.long))) - .sack((_: Long) / (_: Long), _.by(_.constant(86400000L))) - .sack[Long], - _.constant(0L) - ) - ).readonly - ) - .property("computed.handlingDurationInHours", UMapping.long)( - _.select( - _.coalesceIdent( - _.has(_.endDate) - .sack( - (_: JLong, endDate: JLong) => endDate, - _.by(_.value(_.endDate).graphMap[Long, JLong, Converter[Long, JLong]](_.getTime, Converter.long)) - ) - .sack((_: Long) - (_: JLong), _.by(_.value(_.startDate).graphMap[Long, JLong, Converter[Long, JLong]](_.getTime, Converter.long))) - .sack((_: Long) / (_: Long), _.by(_.constant(3600000L))) - .sack[Long], - _.constant(0L) - ) - ).readonly - ) - .property("computed.handlingDurationInMinutes", UMapping.long)( - _.select( - _.coalesceIdent( - _.has(_.endDate) - .sack( - (_: JLong, endDate: JLong) => endDate, - _.by(_.value(_.endDate).graphMap[Long, JLong, Converter[Long, JLong]](_.getTime, Converter.long)) - ) - .sack((_: Long) - (_: JLong), _.by(_.value(_.startDate).graphMap[Long, JLong, Converter[Long, JLong]](_.getTime, Converter.long))) - .sack((_: Long) / (_: Long), _.by(_.constant(60000L))) - .sack[Long], - _.constant(0L) - ) - ).readonly - ) - .property("computed.handlingDurationInSeconds", UMapping.long)( - _.select( - _.coalesceIdent( - _.has(_.endDate) - .sack( - (_: JLong, endDate: JLong) => endDate, - _.by(_.value(_.endDate).graphMap[Long, JLong, Converter[Long, JLong]](_.getTime, Converter.long)) - ) - .sack((_: Long) - (_: JLong), _.by(_.value(_.startDate).graphMap[Long, JLong, Converter[Long, JLong]](_.getTime, Converter.long))) - .sack((_: Long) / (_: Long), _.by(_.constant(1000L))) - .sack[Long], - _.constant(0L) - ) - ).readonly - ) + .property("computed.handlingDuration", UMapping.long)(_.select(_.handlingDuration).readonly) + .property("computed.handlingDurationInSeconds", UMapping.long)(_.select(_.handlingDuration.math("_ / 1000").domainMap(_.toLong)).readonly) + .property("computed.handlingDurationInMinutes", UMapping.long)(_.select(_.handlingDuration.math("_ / 60000").domainMap(_.toLong)).readonly) + .property("computed.handlingDurationInHours", UMapping.long)(_.select(_.handlingDuration.math("_ / 3600000").domainMap(_.toLong)).readonly) + .property("computed.handlingDurationInDays", UMapping.long)(_.select(_.handlingDuration.math("_ / 86400000").domainMap(_.toLong)).readonly) .property("viewingOrganisation", UMapping.string)( _.authSelect((cases, authContext) => cases.organisations.visible(authContext).value(_.name)).readonly ) diff --git a/thehive/app/org/thp/thehive/controllers/v1/Properties.scala b/thehive/app/org/thp/thehive/controllers/v1/Properties.scala index 8295730f8a..d600a93b5f 100644 --- a/thehive/app/org/thp/thehive/controllers/v1/Properties.scala +++ b/thehive/app/org/thp/thehive/controllers/v1/Properties.scala @@ -281,66 +281,11 @@ class Properties @Inject() ( } yield Json.obj("customFields" -> values) case _ => Failure(BadRequestError("Invalid custom fields format")) }) - .property("computed.handlingDurationInDays", UMapping.long)( - _.select( - _.coalesceIdent( - _.has(_.endDate) - .sack( - (_: JLong, endDate: JLong) => endDate, - _.by(_.value(_.endDate).graphMap[Long, JLong, Converter[Long, JLong]](_.getTime, Converter.long)) - ) - .sack((_: Long) - (_: JLong), _.by(_.value(_.startDate).graphMap[Long, JLong, Converter[Long, JLong]](_.getTime, Converter.long))) - .sack((_: Long) / (_: Long), _.by(_.constant(86400000L))) - .sack[Long], - _.constant(0L) - ) - ).readonly - ) - .property("computed.handlingDurationInHours", UMapping.long)( - _.select( - _.coalesceIdent( - _.has(_.endDate) - .sack( - (_: JLong, endDate: JLong) => endDate, - _.by(_.value(_.endDate).graphMap[Long, JLong, Converter[Long, JLong]](_.getTime, Converter.long)) - ) - .sack((_: Long) - (_: JLong), _.by(_.value(_.startDate).graphMap[Long, JLong, Converter[Long, JLong]](_.getTime, Converter.long))) - .sack((_: Long) / (_: Long), _.by(_.constant(3600000L))) - .sack[Long], - _.constant(0L) - ) - ).readonly - ) - .property("computed.handlingDurationInMinutes", UMapping.long)( - _.select( - _.coalesceIdent( - _.has(_.endDate) - .sack( - (_: JLong, endDate: JLong) => endDate, - _.by(_.value(_.endDate).graphMap[Long, JLong, Converter[Long, JLong]](_.getTime, Converter.long)) - ) - .sack((_: Long) - (_: JLong), _.by(_.value(_.startDate).graphMap[Long, JLong, Converter[Long, JLong]](_.getTime, Converter.long))) - .sack((_: Long) / (_: Long), _.by(_.constant(60000L))) - .sack[Long], - _.constant(0L) - ) - ).readonly - ) - .property("computed.handlingDurationInSeconds", UMapping.long)( - _.select( - _.coalesceIdent( - _.has(_.endDate) - .sack( - (_: JLong, endDate: JLong) => endDate, - _.by(_.value(_.endDate).graphMap[Long, JLong, Converter[Long, JLong]](_.getTime, Converter.long)) - ) - .sack((_: Long) - (_: JLong), _.by(_.value(_.startDate).graphMap[Long, JLong, Converter[Long, JLong]](_.getTime, Converter.long))) - .sack((_: Long) / (_: Long), _.by(_.constant(1000L))) - .sack[Long], - _.constant(0L) - ) - ).readonly - ) + .property("computed.handlingDuration", UMapping.long)(_.select(_.handlingDuration).readonly) + .property("computed.handlingDurationInSeconds", UMapping.long)(_.select(_.handlingDuration.math("_ / 1000").domainMap(_.toLong)).readonly) + .property("computed.handlingDurationInMinutes", UMapping.long)(_.select(_.handlingDuration.math("_ / 60000").domainMap(_.toLong)).readonly) + .property("computed.handlingDurationInHours", UMapping.long)(_.select(_.handlingDuration.math("_ / 3600000").domainMap(_.toLong)).readonly) + .property("computed.handlingDurationInDays", UMapping.long)(_.select(_.handlingDuration.math("_ / 86400000").domainMap(_.toLong)).readonly) .property("viewingOrganisation", UMapping.string)( _.authSelect((cases, authContext) => cases.organisations.visible(authContext).value(_.name)).readonly ) diff --git a/thehive/app/org/thp/thehive/services/CaseSrv.scala b/thehive/app/org/thp/thehive/services/CaseSrv.scala index 291a1147af..d29415c808 100644 --- a/thehive/app/org/thp/thehive/services/CaseSrv.scala +++ b/thehive/app/org/thp/thehive/services/CaseSrv.scala @@ -1,6 +1,7 @@ package org.thp.thehive.services import java.util.{Map => JMap} +import java.lang.{Long => JLong} import akka.actor.ActorRef import javax.inject.{Inject, Named, Singleton} @@ -12,7 +13,7 @@ import org.thp.scalligraph.models._ import org.thp.scalligraph.query.PropertyUpdater import org.thp.scalligraph.services._ import org.thp.scalligraph.traversal.TraversalOps._ -import org.thp.scalligraph.traversal.{Converter, StepLabel, Traversal} +import org.thp.scalligraph.traversal.{Converter, IdentityConverter, StepLabel, Traversal} import org.thp.scalligraph.{CreateError, EntityIdOrName, EntityName, RichOptionTry, RichSeq} import org.thp.thehive.controllers.v1.Conversion._ import org.thp.thehive.dto.v1.InputCustomFieldValue @@ -557,9 +558,18 @@ object CaseOps { def isActionRequired(implicit authContext: AuthContext): Traversal[Boolean, Boolean, Converter.Identity[Boolean]] = traversal.choose(_.share(authContext).outE[ShareTask].has(_.actionRequired, true), true, false) + def handlingDuration: Traversal[Long, Long, IdentityConverter[Long]] = + traversal.coalesceIdent( + _.has(_.endDate) + .sack( + (_: JLong, importDate: JLong) => importDate, + _.by(_.value(_.endDate).graphMap[Long, JLong, Converter[Long, JLong]](_.getTime, Converter.long)) + ) + .sack((_: Long) - (_: JLong), _.by(_._createdAt.graphMap[Long, JLong, Converter[Long, JLong]](_.getTime, Converter.long))) + .sack[Long], + _.constant(0L) + ) } - -// implicit class CaseCustomFieldsOpsDefs(traversal: Traversal.E[CaseCustomField]) extends CustomFieldValueOpsDefs(traversal) } class CaseIntegrityCheckOps @Inject() (@Named("with-thehive-schema") val db: Database, val service: CaseSrv) extends IntegrityCheckOps[Case] {