diff --git a/thehive/app/org/thp/thehive/controllers/v1/Properties.scala b/thehive/app/org/thp/thehive/controllers/v1/Properties.scala index 8c770a85ec..5a06ea1e25 100644 --- a/thehive/app/org/thp/thehive/controllers/v1/Properties.scala +++ b/thehive/app/org/thp/thehive/controllers/v1/Properties.scala @@ -286,6 +286,7 @@ class Properties @Inject() ( .property("owningOrganisation", UMapping.string)( _.authSelect((cases, authContext) => cases.origin.visible(authContext).value(_.name)).readonly ) + .property("procedures", UMapping.entityId.sequence)(_.select(_.procedure.value(_._id)).readonly) .build lazy val caseTemplate: PublicProperties = @@ -361,7 +362,7 @@ class Properties @Inject() ( lazy val procedure: PublicProperties = PublicPropertyListBuilder[Procedure] .property("description", UMapping.string)(_.field.updatable) - .property("occurence", UMapping.date)(_.field.readonly) + .property("occurence", UMapping.date)(_.field.updatable) .build lazy val profile: PublicProperties = diff --git a/thehive/app/org/thp/thehive/controllers/v1/Router.scala b/thehive/app/org/thp/thehive/controllers/v1/Router.scala index 3e4be071e7..473682da80 100644 --- a/thehive/app/org/thp/thehive/controllers/v1/Router.scala +++ b/thehive/app/org/thp/thehive/controllers/v1/Router.scala @@ -149,6 +149,7 @@ class Router @Inject() ( case POST(p"/procedure") => procedureCtrl.create case GET(p"/procedure/$procedureId") => procedureCtrl.get(procedureId) + case PATCH(p"/procedure/$procedureId") => procedureCtrl.update(procedureId) case DELETE(p"/procedure/$procedureId") => procedureCtrl.delete(procedureId) case POST(p"/profile") => profileCtrl.create diff --git a/thehive/app/org/thp/thehive/services/ProcedureSrv.scala b/thehive/app/org/thp/thehive/services/ProcedureSrv.scala index 9b9e8f3007..15e81cdde0 100644 --- a/thehive/app/org/thp/thehive/services/ProcedureSrv.scala +++ b/thehive/app/org/thp/thehive/services/ProcedureSrv.scala @@ -7,7 +7,7 @@ import org.thp.scalligraph.models.{Database, Entity} import org.thp.scalligraph.query.PropertyUpdater import org.thp.scalligraph.services._ import org.thp.scalligraph.traversal.TraversalOps.TraversalOpsDefs -import org.thp.scalligraph.traversal.{Converter, StepLabel, Traversal} +import org.thp.scalligraph.traversal.{Converter, Traversal} import org.thp.thehive.controllers.v1.Conversion._ import org.thp.thehive.models._ import org.thp.thehive.services.ProcedureOps._ @@ -73,16 +73,12 @@ object ProcedureOps { def get(idOrName: EntityIdOrName): Traversal.V[Procedure] = idOrName.fold(traversal.getByIds(_), _ => traversal.limit(0)) - def richProcedure: Traversal[RichProcedure, JMap[String, Any], Converter[RichProcedure, JMap[String, Any]]] = { - val procedure = StepLabel.v[Procedure] - val pattern = StepLabel.v[Pattern] + def richProcedure: Traversal[RichProcedure, JMap[String, Any], Converter[RichProcedure, JMap[String, Any]]] = traversal - .as(procedure) - .in[ProcedurePattern] - .v[Pattern] - .as(pattern) - .select((procedure, pattern)) + .project( + _.by + .by(_.pattern) + ) .domainMap { case (procedure, pattern) => RichProcedure(procedure, pattern) } - } } } diff --git a/thehive/test/org/thp/thehive/controllers/v1/ProcedureCtrlTest.scala b/thehive/test/org/thp/thehive/controllers/v1/ProcedureCtrlTest.scala index f718f66be4..71bf1c8e36 100644 --- a/thehive/test/org/thp/thehive/controllers/v1/ProcedureCtrlTest.scala +++ b/thehive/test/org/thp/thehive/controllers/v1/ProcedureCtrlTest.scala @@ -46,8 +46,42 @@ class ProcedureCtrlTest extends PlaySpecification with TestAppBuilder { ) } - // TODO test update of fields - // description + "update a procedure" in testApp { app => + val request1 = FakeRequest("POST", "/api/v1/procedure/testProcedure3") + .withJsonBody( + Json.toJson( + InputProcedure( + "an old description", + new Date(), + "1", + "T123" + ) + ) + ) + .withHeaders("user" -> "certadmin@thehive.local") + val result1 = app[ProcedureCtrl].create(request1) + val procedureId = contentAsJson(result1).as[OutputProcedure]._id + status(result1) must beEqualTo(201).updateMessage(s => s"$s\n${contentAsString(result1)}") + + val updatedDate = new Date() + val request2 = FakeRequest("PATCH", "/api/v1/procedure/testProcedure3") + .withHeaders("user" -> "certadmin@thehive.local") + .withJsonBody(Json.obj("description" -> "a new description", "occurence" -> updatedDate)) + val result2 = app[ProcedureCtrl].update(procedureId)(request2) + status(result2) must beEqualTo(204).updateMessage(s => s"$s\n${contentAsString(result2)}") + + val request3 = FakeRequest("GET", "/api/v1/procedure/testProcedure3") + .withHeaders("user" -> "certadmin@thehive.local") + val result3 = app[ProcedureCtrl].get(procedureId)(request3) + status(result3) must beEqualTo(200).updateMessage(s => s"$s\n${contentAsString(result3)}") + + val resultProcedure = contentAsJson(result3).as[OutputProcedure] + TestProcedure(resultProcedure) must_=== TestProcedure( + "a new description", + updatedDate, + "T123" + ) + } "delete a procedure" in testApp { app => val request1 = FakeRequest("POST", "/api/v1/procedure/testProcedure3")