Skip to content

Commit

Permalink
#2262 Set updatedAt and updateBy on update
Browse files Browse the repository at this point in the history
  • Loading branch information
To-om committed Nov 29, 2021
1 parent e5a23eb commit df6fc2e
Show file tree
Hide file tree
Showing 21 changed files with 208 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,13 @@ class ActionOperationSrv @Inject() (
case CloseTask() =>
for {
t <- relatedTask.fold[Try[Task with Entity]](Failure(InternalError("Unable to apply action CloseTask without task")))(Success(_))
_ <- taskSrv.get(t).update(_.status, TaskStatus.Completed).getOrFail("Task")
_ <-
taskSrv
.get(t)
.update(_.status, TaskStatus.Completed)
.update(_._updatedAt, Some(new Date))
.update(_._updatedBy, Some(authContext.userId))
.getOrFail("Task")
} yield updateOperation(operation)

case MarkAlertAsRead() =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ class ActionSrv @Inject() (
.update(_.report, cortexJob.report.map(r => Json.toJsObject(r.copy(operations = Nil))))
.update(_.endDate, Some(new Date()))
.update(_.operations, operations.map(o => Json.toJsObject(o)))
.update(_._updatedAt, Some(new Date))
.update(_._updatedBy, Some(authContext.userId))
.getOrFail("Action")
.map { updated =>
auditSrv
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import org.thp.thehive.controllers.v0.Conversion._
import org.thp.thehive.services.OrganisationSrv
import play.api.libs.json.{JsObject, Json}

import java.util.Date
import java.util.zip.{ZipEntry, ZipFile}
import javax.inject.{Inject, Singleton}
import scala.collection.JavaConverters._
Expand Down Expand Up @@ -89,8 +90,12 @@ class AnalyzerTemplateSrv @Inject() (
.flatMap { content =>
db.tryTransaction { implicit graph =>
(for {
updated <- get(EntityName(analyzerId)).update(_.content, content).getOrFail("AnalyzerTemplate")
_ <- auditSrv.analyzerTemplate.update(updated, Json.obj("content" -> content))
updated <- get(EntityName(analyzerId))
.update(_.content, content)
.update(_._updatedAt, Some(new Date))
.update(_._updatedBy, Some(authContext.userId))
.getOrFail("AnalyzerTemplate")
_ <- auditSrv.analyzerTemplate.update(updated, Json.obj("content" -> content))
} yield updated).recoverWith {
case _ =>
for {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ class JobSrv @Inject() (
.update(_.report, report)
.update(_.status, status)
.update(_.endDate, endDate)
.update(_._updatedAt, Some(new Date))
.update(_._updatedBy, Some(authContext.userId))
.getOrFail("Job")
observable <- get(job).observable.getOrFail("Observable")
_ <-
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,13 @@ class MispImportSrv @Inject() (
.when(richObservable.ioc != observable.ioc)(_.update(_.ioc, observable.ioc))
.when(richObservable.sighted != observable.sighted)(_.update(_.sighted, observable.sighted))
.when(richObservable.tags.toSet != observable.tags.toSet)(_.update(_.tags, observable.tags))
.when(
richObservable.message != observable.message ||
richObservable.tlp != observable.tlp ||
richObservable.ioc != observable.ioc ||
richObservable.sighted != observable.sighted ||
richObservable.tags.toSet != observable.tags.toSet
)(_.update(_._updatedAt, Some(new Date)).update(_._updatedBy, Some(authContext.userId)))
.getOrFail("Observable")
} yield ()
}
Expand Down Expand Up @@ -390,7 +397,10 @@ class MispImportSrv @Inject() (
.map(ra => (ra.alert, None, ra.toJson.asInstanceOf[JsObject]))
case Some(richAlert) =>
logger.debug(s"Event ${client.name}#${event.id} have already been imported for organisation ${organisation.name}, updating the alert")
val (updatedAlertTraversal, updatedFields) = (alertSrv.get(richAlert.alert).update(_.read, false), Json.obj("read" -> false))
val (updatedAlertTraversal, updatedFields) = (
alertSrv.get(richAlert.alert).update(_.read, false).update(_._updatedAt, Some(new Date)).update(_._updatedBy, Some(authContext.userId)),
Json.obj("read" -> false)
)
.when(richAlert.title != alert.title)(_.update(_.title, alert.title), _ + ("title" -> JsString(alert.title)))
.when(richAlert.lastSyncDate != alert.lastSyncDate)(
_.update(_.lastSyncDate, alert.lastSyncDate),
Expand Down
46 changes: 36 additions & 10 deletions thehive/app/org/thp/thehive/services/AlertSrv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,11 @@ class AlertSrv @Inject() (
tagsToRemove = get(alert).tags.toSeq.filterNot(t => tags.contains(t.toString))
_ <- tagsToAdd.toTry(alertTagSrv.create(AlertTag(), alert, _))
_ = if (tags.nonEmpty) get(alert).outE[AlertTag].filter(_.otherV.hasId(tagsToRemove.map(_._id): _*)).remove()
_ <- get(alert).update(_.tags, tags.toSeq).getOrFail("Alert")
_ <- get(alert)
.update(_.tags, tags.toSeq)
.update(_._updatedAt, Some(new Date))
.update(_._updatedBy, Some(authContext.userId))
.getOrFail("Alert")
_ <- auditSrv.alert.update(alert, Json.obj("tags" -> tags))
} yield (tagsToAdd, tagsToRemove)

Expand Down Expand Up @@ -186,26 +190,42 @@ class AlertSrv @Inject() (

def markAsUnread(alertId: EntityIdOrName)(implicit graph: Graph, authContext: AuthContext): Try[Unit] =
for {
alert <- get(alertId).update[Boolean](_.read, false).getOrFail("Alert")
_ <- auditSrv.alert.update(alert, Json.obj("read" -> false))
alert <- get(alertId)
.update[Boolean](_.read, false)
.update(_._updatedAt, Some(new Date))
.update(_._updatedBy, Some(authContext.userId))
.getOrFail("Alert")
_ <- auditSrv.alert.update(alert, Json.obj("read" -> false))
} yield ()

def markAsRead(alertId: EntityIdOrName)(implicit graph: Graph, authContext: AuthContext): Try[Unit] =
for {
alert <- get(alertId).update[Boolean](_.read, true).getOrFail("Alert")
_ <- auditSrv.alert.update(alert, Json.obj("read" -> true))
alert <- get(alertId)
.update[Boolean](_.read, true)
.update(_._updatedAt, Some(new Date))
.update(_._updatedBy, Some(authContext.userId))
.getOrFail("Alert")
_ <- auditSrv.alert.update(alert, Json.obj("read" -> true))
} yield ()

def followAlert(alertId: EntityIdOrName)(implicit graph: Graph, authContext: AuthContext): Try[Unit] =
for {
alert <- get(alertId).update[Boolean](_.follow, true).getOrFail("Alert")
_ <- auditSrv.alert.update(alert, Json.obj("follow" -> true))
alert <- get(alertId)
.update[Boolean](_.follow, true)
.update(_._updatedAt, Some(new Date))
.update(_._updatedBy, Some(authContext.userId))
.getOrFail("Alert")
_ <- auditSrv.alert.update(alert, Json.obj("follow" -> true))
} yield ()

def unfollowAlert(alertId: EntityIdOrName)(implicit graph: Graph, authContext: AuthContext): Try[Unit] =
for {
alert <- get(alertId).update[Boolean](_.follow, false).getOrFail("Alert")
_ <- auditSrv.alert.update(alert, Json.obj("follow" -> false))
alert <- get(alertId)
.update[Boolean](_.follow, false)
.update(_._updatedAt, Some(new Date))
.update(_._updatedBy, Some(authContext.userId))
.getOrFail("Alert")
_ <- auditSrv.alert.update(alert, Json.obj("follow" -> false))
} yield ()

def createCase(alert: RichAlert, assignee: Option[User with Entity], organisation: Organisation with Entity)(implicit
Expand Down Expand Up @@ -268,7 +288,13 @@ class AlertSrv @Inject() (
_ <- caseSrv.addTags(`case`, alert.tags.toSet)
_ <- alertCaseSrv.create(AlertCase(), alert, `case`)
_ <- get(alert).update(_.caseId, `case`._id).getOrFail("Alert")
c <- caseSrv.get(`case`).update(_.description, description).getOrFail("Case")
c <-
caseSrv
.get(`case`)
.update(_.description, description)
.update(_._updatedAt, Some(new Date))
.update(_._updatedBy, Some(authContext.userId))
.getOrFail("Case")
details <- Success(
Json.obj(
"customFields" -> get(alert).richCustomFields.toSeq.map(_.toOutput.toJson),
Expand Down
48 changes: 41 additions & 7 deletions thehive/app/org/thp/thehive/services/CaseSrv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,11 @@ class CaseSrv @Inject() (
tagsToRemove = get(`case`).tags.toSeq.filterNot(t => tags.contains(t.toString))
_ <- tagsToAdd.toTry(caseTagSrv.create(CaseTag(), `case`, _))
_ = if (tagsToRemove.nonEmpty) get(`case`).outE[CaseTag].filter(_.otherV.hasId(tagsToRemove.map(_._id): _*)).remove()
_ <- get(`case`).update(_.tags, tags.toSeq).getOrFail("Case")
_ <- get(`case`)
.update(_.tags, tags.toSeq)
.update(_._updatedAt, Some(new Date))
.update(_._updatedBy, Some(authContext.userId))
.getOrFail("Case")
_ <- auditSrv.`case`.update(`case`, Json.obj("tags" -> tags))
} yield (tagsToAdd, tagsToRemove)

Expand Down Expand Up @@ -310,13 +314,23 @@ class CaseSrv @Inject() (
`case`: Case with Entity,
impactStatus: ImpactStatus with Entity
)(implicit graph: Graph, authContext: AuthContext): Try[Unit] = {
get(`case`).update(_.impactStatus, Some(impactStatus.value)).outE[CaseImpactStatus].remove()
get(`case`)
.update(_.impactStatus, Some(impactStatus.value))
.update(_._updatedAt, Some(new Date))
.update(_._updatedBy, Some(authContext.userId))
.outE[CaseImpactStatus]
.remove()
caseImpactStatusSrv.create(CaseImpactStatus(), `case`, impactStatus)
auditSrv.`case`.update(`case`, Json.obj("impactStatus" -> impactStatus.value))
}

def unsetImpactStatus(`case`: Case with Entity)(implicit graph: Graph, authContext: AuthContext): Try[Unit] = {
get(`case`).update(_.impactStatus, None).outE[CaseImpactStatus].remove()
get(`case`)
.update(_.impactStatus, None)
.update(_._updatedAt, Some(new Date))
.update(_._updatedBy, Some(authContext.userId))
.outE[CaseImpactStatus]
.remove()
auditSrv.`case`.update(`case`, Json.obj("impactStatus" -> JsNull))
}

Expand All @@ -330,24 +344,44 @@ class CaseSrv @Inject() (
`case`: Case with Entity,
resolutionStatus: ResolutionStatus with Entity
)(implicit graph: Graph, authContext: AuthContext): Try[Unit] = {
get(`case`).update(_.resolutionStatus, Some(resolutionStatus.value)).outE[CaseResolutionStatus].remove()
get(`case`)
.update(_.resolutionStatus, Some(resolutionStatus.value))
.update(_._updatedAt, Some(new Date))
.update(_._updatedBy, Some(authContext.userId))
.outE[CaseResolutionStatus]
.remove()
caseResolutionStatusSrv.create(CaseResolutionStatus(), `case`, resolutionStatus)
auditSrv.`case`.update(`case`, Json.obj("resolutionStatus" -> resolutionStatus.value))
}

def unsetResolutionStatus(`case`: Case with Entity)(implicit graph: Graph, authContext: AuthContext): Try[Unit] = {
get(`case`).update(_.resolutionStatus, None).outE[CaseResolutionStatus].remove()
get(`case`)
.update(_.resolutionStatus, None)
.update(_._updatedAt, Some(new Date))
.update(_._updatedBy, Some(authContext.userId))
.outE[CaseResolutionStatus]
.remove()
auditSrv.`case`.update(`case`, Json.obj("resolutionStatus" -> JsNull))
}

def assign(`case`: Case with Entity, user: User with Entity)(implicit graph: Graph, authContext: AuthContext): Try[Unit] = {
get(`case`).update(_.assignee, Some(user.login)).outE[CaseUser].remove()
get(`case`)
.update(_.assignee, Some(user.login))
.update(_._updatedAt, Some(new Date))
.update(_._updatedBy, Some(authContext.userId))
.outE[CaseUser]
.remove()
caseUserSrv.create(CaseUser(), `case`, user)
auditSrv.`case`.update(`case`, Json.obj("owner" -> user.login))
}

def unassign(`case`: Case with Entity)(implicit graph: Graph, authContext: AuthContext): Try[Unit] = {
get(`case`).update(_.assignee, None).outE[CaseUser].remove()
get(`case`)
.update(_.assignee, None)
.update(_._updatedAt, Some(new Date))
.update(_._updatedBy, Some(authContext.userId))
.outE[CaseUser]
.remove()
auditSrv.`case`.update(`case`, Json.obj("owner" -> JsNull))
}

Expand Down
6 changes: 5 additions & 1 deletion thehive/app/org/thp/thehive/services/CaseTemplateSrv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,11 @@ class CaseTemplateSrv @Inject() (
tagsToRemove = get(caseTemplate).tags.toSeq.filterNot(t => tags.contains(t.toString))
_ <- tagsToAdd.toTry(caseTemplateTagSrv.create(CaseTemplateTag(), caseTemplate, _))
_ = if (tags.nonEmpty) get(caseTemplate).outE[CaseTemplateTag].filter(_.otherV.hasId(tagsToRemove.map(_._id): _*)).remove()
_ <- get(caseTemplate).update(_.tags, tags.toSeq).getOrFail("CaseTemplate")
_ <- get(caseTemplate)
.update(_.tags, tags.toSeq)
.update(_._updatedAt, Some(new Date))
.update(_._updatedBy, Some(authContext.userId))
.getOrFail("CaseTemplate")
_ <- auditSrv.caseTemplate.update(caseTemplate, Json.obj("tags" -> tags))
} yield (tagsToAdd, tagsToRemove)

Expand Down
17 changes: 15 additions & 2 deletions thehive/app/org/thp/thehive/services/ConfigSrv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import org.thp.thehive.services.notification.NotificationSrv
import org.thp.thehive.services.notification.triggers.Trigger
import play.api.libs.json.{JsValue, Reads}

import java.util.Date
import javax.inject.{Inject, Singleton}
import scala.util.Try

Expand All @@ -33,7 +34,13 @@ class ConfigSrv @Inject() (

def setConfigValue(organisationName: EntityIdOrName, name: String, value: JsValue)(implicit graph: Graph, authContext: AuthContext): Try[Unit] =
getConfigValue(organisationName, name) match {
case Some(config) => get(config).update(_.value, value).domainMap(_ => ()).getOrFail("Config")
case Some(config) =>
get(config)
.update(_.value, value)
.update(_._updatedAt, Some(new Date))
.update(_._updatedBy, Some(authContext.userId))
.domainMap(_ => ())
.getOrFail("Config")
case None =>
for {
createdConfig <- createEntity(Config(name, value))
Expand All @@ -54,7 +61,13 @@ class ConfigSrv @Inject() (

def setConfigValue(userName: EntityIdOrName, name: String, value: JsValue)(implicit graph: Graph, authContext: AuthContext): Try[Unit] =
getConfigValue(userName, name) match {
case Some(config) => get(config).update(_.value, value).domainMap(_ => ()).getOrFail("Config")
case Some(config) =>
get(config)
.update(_.value, value)
.update(_._updatedAt, Some(new Date))
.update(_._updatedBy, Some(authContext.userId))
.domainMap(_ => ())
.getOrFail("Config")
case None =>
for {
createdConfig <- createEntity(Config(name, value))
Expand Down
4 changes: 3 additions & 1 deletion thehive/app/org/thp/thehive/services/DashboardSrv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import org.thp.thehive.services.OrganisationOps._
import org.thp.thehive.services.UserOps._
import play.api.libs.json.{JsObject, Json}

import java.util.{List => JList, Map => JMap}
import java.util.{Date, List => JList, Map => JMap}
import javax.inject.{Inject, Singleton}
import scala.util.{Success, Try}

Expand Down Expand Up @@ -52,6 +52,8 @@ class DashboardSrv @Inject() (organisationSrv: OrganisationSrv, userSrv: UserSrv
.inE[OrganisationDashboard]
.filter(_.outV.v[Organisation].getEntity(org))
.update(_.writable, writable)
.update(_._updatedAt, Some(new Date))
.update(_._updatedBy, Some(authContext.userId))
.fold
.getOrFail("Dashboard")
.flatMap {
Expand Down
6 changes: 5 additions & 1 deletion thehive/app/org/thp/thehive/services/LocalKeyAuthSrv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import org.thp.thehive.services.UserOps._
import play.api.Configuration
import play.api.mvc.RequestHeader

import java.util.Base64
import java.util.{Base64, Date}
import javax.inject.{Inject, Provider, Singleton}
import scala.concurrent.ExecutionContext
import scala.util.{Failure, Random, Success, Try}
Expand Down Expand Up @@ -45,6 +45,8 @@ class LocalKeyAuthSrv(
userSrv
.get(EntityIdOrName(username))
.update(_.apikey, Some(newKey))
.update(_._updatedAt, Some(new Date))
.update(_._updatedBy, Some(authContext.userId))
.domainMap(_ => newKey)
.getOrFail("User")
}
Expand All @@ -61,6 +63,8 @@ class LocalKeyAuthSrv(
userSrv
.get(EntityIdOrName(username))
.update(_.apikey, None)
.update(_._updatedAt, Some(new Date))
.update(_._updatedBy, Some(authContext.userId))
.domainMap(_ => ())
.getOrFail("User")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import org.thp.thehive.models.User
import play.api.mvc.RequestHeader
import play.api.{Configuration, Logger}

import java.util.Date
import javax.inject.{Inject, Singleton}
import scala.util.{Failure, Success, Try}

Expand Down Expand Up @@ -62,6 +63,8 @@ class LocalPasswordAuthSrv(db: Database, userSrv: UserSrv, localUserSrv: LocalUs
userSrv
.get(EntityIdOrName(username))
.update(_.password, Some(hashPassword(newPassword)))
.update(_._updatedAt, Some(new Date))
.update(_._updatedBy, Some(authContext.userId))
.getOrFail("User")
.map(_ => ())
}
Expand Down
Loading

0 comments on commit df6fc2e

Please sign in to comment.