Skip to content

Commit

Permalink
#1454 Add queries and controler for shares in v1
Browse files Browse the repository at this point in the history
  • Loading branch information
To-om committed Jan 6, 2021
1 parent adb899f commit 9e47467
Show file tree
Hide file tree
Showing 12 changed files with 383 additions and 39 deletions.
48 changes: 48 additions & 0 deletions dto/src/main/scala/org/thp/thehive/dto/v1/Share.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.thp.thehive.dto.v1

import org.thp.thehive.dto.v1.ObservablesFilter.ObservablesFilter
import org.thp.thehive.dto.v1.TasksFilter.TasksFilter
import play.api.libs.json.{Format, Json, Writes}

import java.util.Date

case class InputShare(organisationName: String, profile: String, tasks: TasksFilter, observables: ObservablesFilter)

object TasksFilter extends Enumeration {
type TasksFilter = Value

val all: TasksFilter = Value("all")
val none: TasksFilter = Value("none")

implicit val format: Format[TasksFilter] = Json.formatEnum(TasksFilter)
}

object ObservablesFilter extends Enumeration {
type ObservablesFilter = Value

val all: ObservablesFilter = Value("all")
val none: ObservablesFilter = Value("none")

implicit val format: Format[ObservablesFilter] = Json.formatEnum(ObservablesFilter)
}

object InputShare {
implicit val writes: Writes[InputShare] = Json.writes[InputShare]
}

case class OutputShare(
_id: String,
_type: String,
_createdBy: String,
_updatedBy: Option[String] = None,
_createdAt: Date,
_updatedAt: Option[Date] = None,
caseId: String,
profileName: String,
organisationName: String,
owner: Boolean
)

object OutputShare {
implicit val format: Format[OutputShare] = Json.format[OutputShare]
}
3 changes: 2 additions & 1 deletion thehive/app/org/thp/thehive/controllers/v0/ShareCtrl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,8 @@ class ShareCtrl @Inject() (
val shares = caseSrv
.get(EntityIdOrName(caseId))
.shares
.filter(_.organisation.filterNot(_.get(request.organisation)).visible)
.visible
.filterNot(_.get(request.organisation))
.richShare
.toSeq

Expand Down
6 changes: 4 additions & 2 deletions thehive/app/org/thp/thehive/controllers/v1/CaseCtrl.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.thp.thehive.controllers.v1

import javax.inject.{Inject, Named, Singleton}
import org.thp.scalligraph.controllers.{Entrypoint, FieldsParser}
import org.thp.scalligraph.models.{Database, Entity}
import org.thp.scalligraph.query.{ParamQuery, PropertyUpdater, PublicProperties, Query}
Expand All @@ -14,10 +13,12 @@ import org.thp.thehive.services.AlertOps._
import org.thp.thehive.services.CaseOps._
import org.thp.thehive.services.CaseTemplateOps._
import org.thp.thehive.services.OrganisationOps._
import org.thp.thehive.services.ShareOps._
import org.thp.thehive.services.UserOps._
import org.thp.thehive.services._
import play.api.mvc.{Action, AnyContent, Results}

import javax.inject.{Inject, Named, Singleton}
import scala.util.{Success, Try}

@Singleton
Expand Down Expand Up @@ -58,7 +59,8 @@ class CaseCtrl @Inject() (
Query[Traversal.V[Case], Traversal.V[Observable]]("observables", (caseSteps, authContext) => caseSteps.observables(authContext)),
Query[Traversal.V[Case], Traversal.V[User]]("assignableUsers", (caseSteps, authContext) => caseSteps.assignableUsers(authContext)),
Query[Traversal.V[Case], Traversal.V[Organisation]]("organisations", (caseSteps, authContext) => caseSteps.organisations.visible(authContext)),
Query[Traversal.V[Case], Traversal.V[Alert]]("alerts", (caseSteps, authContext) => caseSteps.alert.visible(authContext))
Query[Traversal.V[Case], Traversal.V[Alert]]("alerts", (caseSteps, authContext) => caseSteps.alert.visible(authContext)),
Query[Traversal.V[Case], Traversal.V[Share]]("shares", (caseSteps, authContext) => caseSteps.shares.visible(authContext))
)

def create: Action[AnyContent] =
Expand Down
8 changes: 8 additions & 0 deletions thehive/app/org/thp/thehive/controllers/v1/Conversion.scala
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,14 @@ object Conversion {
.transform
}

implicit val shareOutput: Renderer.Aux[RichShare, OutputShare] = Renderer.toJson[RichShare, OutputShare](
_.into[OutputShare]
.withFieldComputed(_._id, _.share._id.toString)
.withFieldConst(_._type, "Share")
.withFieldComputed(_.caseId, _.caseId.toString)
.transform
)

implicit val profileOutput: Renderer.Aux[Profile with Entity, OutputProfile] = Renderer.toJson[Profile with Entity, OutputProfile](profile =>
profile
.asInstanceOf[Profile]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ class ObservableCtrl @Inject() (
(observableSteps, authContext) => observableSteps.filteredSimilar.visible(authContext)
),
Query[Traversal.V[Observable], Traversal.V[Case]]("case", (observableSteps, _) => observableSteps.`case`),
Query[Traversal.V[Observable], Traversal.V[Alert]]("alert", (observableSteps, _) => observableSteps.alert)
Query[Traversal.V[Observable], Traversal.V[Alert]]("alert", (observableSteps, _) => observableSteps.alert),
Query[Traversal.V[Observable], Traversal.V[Share]]("shares", (observableSteps, authContext) => observableSteps.shares.visible(authContext))
)

def create(caseId: String): Action[AnyContent] =
Expand Down
26 changes: 16 additions & 10 deletions thehive/app/org/thp/thehive/controllers/v1/Properties.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import org.thp.thehive.services.ObservableOps._
import org.thp.thehive.services.OrganisationOps._
import org.thp.thehive.services.TagOps._
import org.thp.thehive.services.TaskOps._
import org.thp.thehive.services.ShareOps._
import org.thp.thehive.services.UserOps._
import org.thp.thehive.services._
import play.api.libs.json.{JsObject, JsValue, Json}
Expand Down Expand Up @@ -193,10 +194,7 @@ class Properties @Inject() (
.property("pap", UMapping.int)(_.field.updatable)
.property("status", UMapping.enum[CaseStatus.type])(_.field.updatable)
.property("summary", UMapping.string.optional)(_.field.updatable)
.property("actionRequired", UMapping.boolean)(_
.authSelect((t, auth) => t.isActionRequired(auth))
.readonly
)
.property("actionRequired", UMapping.boolean)(_.authSelect((t, auth) => t.isActionRequired(auth)).readonly)
.property("assignee", UMapping.string.optional)(_.select(_.user.value(_.login)).custom { (_, login, vertex, _, graph, authContext) =>
for {
c <- caseSrv.get(vertex)(graph).getOrFail("Case")
Expand Down Expand Up @@ -407,6 +405,17 @@ class Properties @Inject() (
.property("permissions", UMapping.string.set)(_.field.updatable)
.build

lazy val share: PublicProperties =
PublicPropertyListBuilder[Share]
.property("caseId", UMapping.entityId)(_.select(_.`case`._id).readonly)
.property("caseNumber", UMapping.int)(_.select(_.`case`.value(_.number)).readonly)
.property("organisationId", UMapping.entityId)(_.select(_.organisation._id).readonly)
.property("organisationName", UMapping.string)(_.select(_.organisation.value(_.name)).readonly)
.property("profileId", UMapping.entityId)(_.select(_.profile._id).readonly)
.property("profileName", UMapping.string)(_.select(_.profile.value(_.name)).readonly)
.property("owner", UMapping.boolean)(_.field.readonly)
.build

lazy val task: PublicProperties =
PublicPropertyListBuilder[Task]
.property("title", UMapping.string)(_.field.updatable)
Expand All @@ -433,12 +442,9 @@ class Properties @Inject() (
}
.map(_ => Json.obj("assignee" -> value))
})
.property("actionRequired", UMapping.boolean)(_
.authSelect((t, authContext) => {
t.actionRequired(authContext)
})
.readonly
)
.property("actionRequired", UMapping.boolean)(_.authSelect { (t, authContext) =>
t.actionRequired(authContext)
}.readonly)
.build

lazy val log: PublicProperties =
Expand Down
35 changes: 21 additions & 14 deletions thehive/app/org/thp/thehive/controllers/v1/Router.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class Router @Inject() (
// permissionCtrl: PermissionCtrl,
profileCtrl: ProfileCtrl,
taskCtrl: TaskCtrl,
// shareCtrl: ShareCtrl,
shareCtrl: ShareCtrl,
userCtrl: UserCtrl,
statusCtrl: StatusCtrl
// streamCtrl: StreamCtrl,
Expand Down Expand Up @@ -58,7 +58,7 @@ class Router @Inject() (
case PATCH(p"/observable/_bulk") => observableCtrl.bulkUpdate
case PATCH(p"/observable/$observableId") => observableCtrl.update(observableId)
// case GET(p"/observable/$observableId/similar") => observableCtrl.findSimilar(observableId)
// case POST(p"/observable/$observableId/shares") => shareCtrl.shareObservable(observableId)
case POST(p"/observable/$observableId/shares") => shareCtrl.shareObservable(observableId)

case GET(p"/caseTemplate") => caseTemplateCtrl.list
case POST(p"/caseTemplate") => caseTemplateCtrl.create
Expand All @@ -83,18 +83,25 @@ class Router @Inject() (
case GET(p"/organisation/$organisationId") => organisationCtrl.get(organisationId)
case PATCH(p"/organisation/$organisationId") => organisationCtrl.update(organisationId)

// case GET(p"/share") => shareCtrl.list
// case POST(p"/share") => shareCtrl.create
// case GET(p"/share/$shareId") => shareCtrl.get(shareId)
// case PATCH(p"/share/$shareId") => shareCtrl.update(shareId)

case GET(p"/task") => taskCtrl.list
case POST(p"/task") => taskCtrl.create
case GET(p"/task/$taskId") => taskCtrl.get(taskId)
case PATCH(p"/task/$taskId") => taskCtrl.update(taskId)
case GET(p"/task/$taskId/actionRequired") => taskCtrl.isActionRequired(taskId)
case PUT(p"/task/$taskId/actionRequired/$orgaId") => taskCtrl.actionRequired(taskId, orgaId, required = true)
case PUT(p"/task/$taskId/actionDone/$orgaId") => taskCtrl.actionRequired(taskId, orgaId, required = false)
case DELETE(p"/case/shares") => shareCtrl.removeShares()
case POST(p"/case/$caseId/shares") => shareCtrl.shareCase(caseId)
case DELETE(p"/case/$caseId/shares") => shareCtrl.removeShares(caseId)
case DELETE(p"/task/$taskId/shares") => shareCtrl.removeTaskShares(taskId)
case DELETE(p"/observable/$observableId/shares") => shareCtrl.removeObservableShares(observableId)
case GET(p"/case/$caseId/shares") => shareCtrl.listShareCases(caseId)
case GET(p"/case/$caseId/task/$taskId/shares") => shareCtrl.listShareTasks(caseId, taskId)
case GET(p"/case/$caseId/observable/$observableId/shares") => shareCtrl.listShareObservables(caseId, observableId)
case POST(p"/case/task/$taskId/shares") => shareCtrl.shareTask(taskId)
case DELETE(p"/case/share/$shareId") => shareCtrl.removeShare(shareId)
case PATCH(p"/case/share/$shareId") => shareCtrl.updateShare(shareId)

case GET(p"/task") => taskCtrl.list
case POST(p"/task") => taskCtrl.create
case GET(p"/task/$taskId") => taskCtrl.get(taskId)
case PATCH(p"/task/$taskId") => taskCtrl.update(taskId)
case GET(p"/task/$taskId/actionRequired") => taskCtrl.isActionRequired(taskId)
case PUT(p"/task/$taskId/actionRequired/$orgaId") => taskCtrl.actionRequired(taskId, orgaId, required = true)
case PUT(p"/task/$taskId/actionDone/$orgaId") => taskCtrl.actionRequired(taskId, orgaId, required = false)
// POST /case/:caseId/task/_search controllers.TaskCtrl.findInCase(caseId)
// POST /case/task/_stats controllers.TaskCtrl.stats()

Expand Down
Loading

0 comments on commit 9e47467

Please sign in to comment.