Skip to content

Commit

Permalink
#1849 Make shared dashboard writable
Browse files Browse the repository at this point in the history
  • Loading branch information
To-om committed Mar 18, 2021
1 parent eaf95af commit 283d79e
Show file tree
Hide file tree
Showing 8 changed files with 26 additions and 19 deletions.
3 changes: 2 additions & 1 deletion dto/src/main/scala/org/thp/thehive/dto/v0/Dashboard.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ case class OutputDashboard(
title: String,
description: String,
status: String,
definition: String
definition: String,
writable: Boolean
)

object OutputDashboard {
Expand Down
3 changes: 2 additions & 1 deletion dto/src/main/scala/org/thp/thehive/dto/v1/Dashboard.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ case class OutputDashboard(
title: String,
description: String,
status: String,
definition: String
definition: String,
writable: Boolean
)

object OutputDashboard {
Expand Down
11 changes: 5 additions & 6 deletions thehive/app/org/thp/thehive/controllers/v0/DashboardCtrl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,9 @@ class DashboardCtrl @Inject() (
def delete(dashboardId: String): Action[AnyContent] =
entrypoint("delete dashboard")
.authTransaction(db) { implicit request => implicit graph =>
userSrv
.current
.dashboards
dashboardSrv
.get(EntityIdOrName(dashboardId))
.canUpdate
.getOrFail("Dashboard")
.map { dashboard =>
dashboardSrv.remove(dashboard)
Expand Down Expand Up @@ -109,9 +108,9 @@ class PublicDashboard @Inject() (

val pageQuery: ParamQuery[OutputParam] = Query.withParam[OutputParam, Traversal.V[Dashboard], IteratorOutput](
"page",
(range, dashboardSteps, _) => dashboardSteps.richPage(range.from, range.to, withTotal = true)(_.richDashboard)
(range, dashboardSteps, authContext) => dashboardSteps.richPage(range.from, range.to, withTotal = true)(_.richDashboard(authContext))
)
override val outputQuery: Query = Query.output[RichDashboard, Traversal.V[Dashboard]](_.richDashboard)
override val outputQuery: Query = Query.outputWithContext[RichDashboard, Traversal.V[Dashboard]](_.richDashboard(_))
val publicProperties: PublicProperties = PublicPropertyListBuilder[Dashboard]
.property("title", UMapping.string)(_.field.updatable)
.property("description", UMapping.string)(_.field.updatable)
Expand All @@ -122,7 +121,7 @@ class PublicDashboard @Inject() (
case (_, "Shared", vertex, graph, authContext) =>
for {
dashboard <- dashboardSrv.get(vertex)(graph).filter(_.user.current(authContext)).getOrFail("Dashboard")
_ <- dashboardSrv.share(dashboard, authContext.organisation, writable = false)(graph, authContext)
_ <- dashboardSrv.share(dashboard, authContext.organisation, writable = true)(graph, authContext)
} yield Json.obj("status" -> "Shared")

case (_, "Private", vertex, graph, authContext) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ class DashboardCtrl @Inject() (

override val pageQuery: ParamQuery[OutputParam] = Query.withParam[OutputParam, Traversal.V[Dashboard], IteratorOutput](
"page",
(range, dashboardSteps, _) => dashboardSteps.richPage(range.from, range.to, withTotal = true)(_.richDashboard)
(range, dashboardSteps, authContext) => dashboardSteps.richPage(range.from, range.to, withTotal = true)(_.richDashboard(authContext))
)
override val outputQuery: Query = Query.output[RichDashboard, Traversal.V[Dashboard]](_.richDashboard)
override val outputQuery: Query = Query.outputWithContext[RichDashboard, Traversal.V[Dashboard]](_.richDashboard(_))

def create: Action[AnyContent] =
entrypoint("create dashboard")
Expand Down Expand Up @@ -95,10 +95,9 @@ class DashboardCtrl @Inject() (
def delete(dashboardId: String): Action[AnyContent] =
entrypoint("delete dashboard")
.authTransaction(db) { implicit request => implicit graph =>
userSrv
.current
.dashboards
dashboardSrv
.get(EntityIdOrName(dashboardId))
.canUpdate
.getOrFail("Dashboard")
.map { dashboard =>
dashboardSrv.remove(dashboard)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ class Properties @Inject() (
case (_, "Shared", vertex, graph, authContext) =>
for {
dashboard <- dashboardSrv.get(vertex)(graph).filter(_.user.current(authContext)).getOrFail("Dashboard")
_ <- dashboardSrv.share(dashboard, authContext.organisation, writable = false)(graph, authContext)
_ <- dashboardSrv.share(dashboard, authContext.organisation, writable = true)(graph, authContext)
} yield Json.obj("status" -> "Shared")

case (_, "Private", vertex, graph, authContext) =>
Expand Down
3 changes: 2 additions & 1 deletion thehive/app/org/thp/thehive/models/Dashboard.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ case class OrganisationDashboard(writable: Boolean)

case class RichDashboard(
dashboard: Dashboard with Entity,
organisationShares: Map[String, Boolean]
organisationShares: Map[String, Boolean],
writable: Boolean
) {
def _id: EntityIdOrName = dashboard._id
def _createdBy: String = dashboard._createdBy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,10 @@ class TheHiveSchemaDefinition @Inject() extends Schema with UpdatableSchema {
Success(())
}
.removeProperty(model = "Log", propertyName = "deleted", usedOnlyByThisModel = true)
.updateGraph("Make shared dashboard writable", "Dashboard") { traversal =>
traversal.outE("OrganisationDashboard").raw.property("writable", true).iterate()
Success(())
}

val reflectionClasses = new Reflections(
new ConfigurationBuilder()
Expand Down
10 changes: 6 additions & 4 deletions thehive/app/org/thp/thehive/services/DashboardSrv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ class DashboardSrv @Inject() (organisationSrv: OrganisationSrv, userSrv: UserSrv
createdDashboard <- createEntity(dashboard)
user <- userSrv.current.getOrFail("User")
_ <- dashboardUserSrv.create(DashboardUser(), createdDashboard, user)
_ <- auditSrv.dashboard.create(createdDashboard, RichDashboard(createdDashboard, Map.empty).toJson)
} yield RichDashboard(createdDashboard, Map.empty)
richDashboard = RichDashboard(createdDashboard, Map.empty, writable = true)
_ <- auditSrv.dashboard.create(createdDashboard, richDashboard.toJson)
} yield richDashboard

override def update(
traversal: Traversal.V[Dashboard],
Expand Down Expand Up @@ -107,14 +108,15 @@ object DashboardOps {
.fold
.domainMap(_.map { case (writable, orgs) => (orgs.value[String]("name"), writable) })

def richDashboard: Traversal[RichDashboard, JMap[String, Any], Converter[RichDashboard, JMap[String, Any]]] =
def richDashboard(implicit authContext: AuthContext): Traversal[RichDashboard, JMap[String, Any], Converter[RichDashboard, JMap[String, Any]]] =
traversal
.project(
_.by
.by(_.organisationShares)
.by(_.choose(_.canUpdate, true, false))
)
.domainMap {
case (dashboard, organisationShares) => RichDashboard(dashboard, organisationShares.toMap)
case (dashboard, organisationShares, writable) => RichDashboard(dashboard, organisationShares.toMap, writable)
}

}
Expand Down

0 comments on commit 283d79e

Please sign in to comment.