Skip to content

Commit

Permalink
Merge branch 'issue-1264' into develop-th4
Browse files Browse the repository at this point in the history
  • Loading branch information
To-om committed Mar 11, 2021
2 parents 7eb1f41 + e5cffb5 commit a04041f
Show file tree
Hide file tree
Showing 40 changed files with 853 additions and 296 deletions.
33 changes: 19 additions & 14 deletions frontend/app/scripts/controllers/case/CaseMainCtrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -253,20 +253,25 @@
});

caseModal.result.then(function(selectedCase) {
CaseSrv.merge({}, {
caseId: $scope.caze.id,
mergedCaseId: selectedCase.id
}, function (merged) {

$state.go('app.case.details', {
caseId: merged.id
});

NotificationSrv.log('The cases have been successfully merged into a new case #' + merged.caseId, 'success');
}, function (response) {
//this.pendingAsync = false;
NotificationSrv.error('Case Merge', response.data, response.status);
});
CaseSrv.merge([$scope.caze._id, selectedCase._id])
.then(function (response) {
var merged = response.data;

$state.go('app.case.details', {
caseId: merged._id
});

NotificationSrv.log('The cases have been successfully merged into a new case #' + merged.number, 'success');
})
.catch(function (response) {
//this.pendingAsync = false;
NotificationSrv.error('Case Merge', response.data, response.status);
})

// CaseSrv.merge({}, {
// caseId: $scope.caze.id,
// mergedCaseId: selectedCase.id
// }, , );
}).catch(function(err) {
if(err && !_.isString(err)) {
NotificationSrv.error('Case Merge', err.data, err.status);
Expand Down
20 changes: 12 additions & 8 deletions frontend/app/scripts/services/api/CaseSrv.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
url: './api/case/:caseId/links',
isArray: true
},
merge: {
method: 'POST',
url: './api/case/:caseId/_merge/:mergedCaseId',
params: {
caseId: '@caseId',
mergedCaseId: '@mergedCaseId',
}
},
// merge: {
// method: 'POST',
// url: './api/case/:caseId/_merge/:mergedCaseId',
// params: {
// caseId: '@caseId',
// mergedCaseId: '@mergedCaseId',
// }
// },
forceRemove: {
method: 'DELETE',
url: './api/case/:caseId/force',
Expand Down Expand Up @@ -94,6 +94,10 @@
return defer.promise;
};

this.merge = function(ids) {
return $http.post('./api/v1/case/_merge/' + ids.join(','));
};

this.bulkUpdate = function(ids, update) {
return $http.patch('./api/case/_bulk', _.extend({ids: ids}, update));
};
Expand Down
2 changes: 1 addition & 1 deletion frontend/app/views/partials/case/case.merge.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ <h4>{{c.title}}</h4>
<div>
<span>
<i class="glyphicon glyphicon-user"></i>
<user-info value="c.owner" field="name"></user-info>
<user-info value="c.assignee" field="name"></user-info>
</span>
<span class="ml-xxs">
<i class="glyphicon glyphicon-calendar"></i>
Expand Down
4 changes: 2 additions & 2 deletions frontend/app/views/partials/case/case.panelinfo.html
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,12 @@ <h3 class="box-title text-primary">
</a>
</span>

<!-- <span class="ml-xxs pull-right">
<span class="ml-xxs pull-right">
<a href ng-click="mergeCase()" class="text-primary noline" uib-tooltip="Merge case">
<i class="text-primary fa fa-compress"></i>
Merge
</a>
</span> -->
</span>

<span class="ml-xxs pull-right" ng-if="!caze.flag || caze.flag == undefined">
<a href ng-click="switchFlag()" class="text-muted noline" uib-tooltip="Flag case">
Expand Down
21 changes: 6 additions & 15 deletions thehive/app/org/thp/thehive/controllers/v0/CaseCtrl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -144,22 +144,14 @@ class CaseCtrl @Inject() (
} yield Results.NoContent
}

def merge(caseIdsOrNumbers: String): Action[AnyContent] =
def merge(caseId: String, caseToMerge: String): Action[AnyContent] =
entrypoint("merge cases")
.authTransaction(db) { implicit request => implicit graph =>
caseIdsOrNumbers
.split(',')
.toSeq
.toTry(c =>
caseSrv
.get(EntityIdOrName(c))
.visible(organisationSrv)
.getOrFail("Case")
)
.map { cases =>
val mergedCase = caseSrv.merge(cases)
Results.Ok(mergedCase.toJson)
}
for {
caze <- caseSrv.get(EntityIdOrName(caseId)).visible(organisationSrv).getOrFail("Case")
toMerge <- caseSrv.get(EntityIdOrName(caseToMerge)).visible(organisationSrv).getOrFail("Case")
merged <- caseSrv.merge(Seq(caze, toMerge))
} yield Results.Created(merged.toJson)
}

def linkedCases(caseIdOrNumber: String): Action[AnyContent] =
Expand All @@ -185,7 +177,6 @@ class PublicCase @Inject() (
caseSrv: CaseSrv,
organisationSrv: OrganisationSrv,
observableSrv: ObservableSrv,
taskSrv: TaskSrv,
userSrv: UserSrv,
customFieldSrv: CustomFieldSrv,
implicit val db: Database
Expand Down
22 changes: 11 additions & 11 deletions thehive/app/org/thp/thehive/controllers/v0/Router.scala
Original file line number Diff line number Diff line change
Expand Up @@ -119,17 +119,17 @@ class Router @Inject() (
case GET(p"/case/artifact/$observableId/similar") => observableCtrl.findSimilar(observableId)
// case POST(p"/case/:caseId/artifact/_search") => observableCtrl.findInCase(caseId)

case GET(p"/case") => caseCtrl.search
case POST(p"/case/_search") => caseCtrl.search
case POST(p"/case/_stats") => caseCtrl.stats
case POST(p"/case") => caseCtrl.create
case GET(p"/case/$caseId") => caseCtrl.get(caseId)
case PATCH(p"/case/_bulk") => caseCtrl.bulkUpdate // Not used by the frontend
case PATCH(p"/case/$caseId") => caseCtrl.update(caseId)
case DELETE(p"/case/$caseId") => caseCtrl.delete(caseId) // Not used by the frontend
case DELETE(p"/case/$caseId/force") => caseCtrl.delete(caseId)
case POST(p"/case/_merge/$caseIds") => caseCtrl.merge(caseIds) // Not implemented in backend and not used by frontend
case GET(p"/case/$caseId/links") => caseCtrl.linkedCases(caseId)
case GET(p"/case") => caseCtrl.search
case POST(p"/case") => caseCtrl.create // Audit ok
case GET(p"/case/$caseId") => caseCtrl.get(caseId)
case PATCH(p"/case/_bulk") => caseCtrl.bulkUpdate // Not used by the frontend
case PATCH(p"/case/$caseId") => caseCtrl.update(caseId) // Audit ok
case POST(p"/case/$caseId/_merge/$toMerge") => caseCtrl.merge(caseId, toMerge)
case POST(p"/case/_search") => caseCtrl.search
case POST(p"/case/_stats") => caseCtrl.stats
case DELETE(p"/case/$caseId") => caseCtrl.delete(caseId) // Not used by the frontend
case DELETE(p"/case/$caseId/force") => caseCtrl.delete(caseId) // Audit ok
case GET(p"/case/$caseId/links") => caseCtrl.linkedCases(caseId)

case GET(p"/config/user") => configCtrl.userList
case GET(p"/config/user/$path") => configCtrl.userGet(path)
Expand Down
40 changes: 27 additions & 13 deletions thehive/app/org/thp/thehive/controllers/v1/CaseCtrl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -133,21 +133,35 @@ class CaseCtrl @Inject() (
} yield Results.NoContent
}

def deleteCustomField(cfId: String): Action[AnyContent] =
entrypoint("delete a custom field")
.authPermittedTransaction(db, Permissions.manageCase) { implicit request => implicit graph =>
for {
_ <-
caseSrv
.caseCustomFieldSrv
.get(EntityIdOrName(cfId))
.filter(_.outV.v[Case].can(Permissions.manageCase))
.existsOrFail
_ <- caseSrv.deleteCustomField(EntityIdOrName(cfId))
} yield Results.NoContent
}

def merge(caseIdsOrNumbers: String): Action[AnyContent] =
entrypoint("merge cases")
.authTransaction(db) { implicit request => implicit graph =>
caseIdsOrNumbers
.split(',')
.toSeq
.toTry(c =>
caseSrv
.get(EntityIdOrName(c))
.visible(organisationSrv)
.getOrFail("Case")
)
.map { cases =>
val mergedCase = caseSrv.merge(cases)
Results.Ok(mergedCase.toJson)
}
for {
cases <-
caseIdsOrNumbers
.split(',')
.toSeq
.toTry(c =>
caseSrv
.get(EntityIdOrName(c))
.visible(organisationSrv)
.getOrFail("Case")
)
mergedCase <- caseSrv.merge(cases)
} yield Results.Created(mergedCase.toJson)
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
package org.thp.thehive.controllers.v1

import org.thp.scalligraph.traversal.TraversalOps.TraversalOpsDefs
import org.thp.scalligraph.traversal.{Converter, Traversal}
import org.thp.thehive.controllers.v1.Conversion._
import org.thp.thehive.models.Procedure
import org.thp.thehive.services.PatternOps._
import org.thp.thehive.services.ProcedureOps._
import play.api.libs.json.JsValue
import play.api.libs.json.{JsNull, JsValue}

import java.util.{Map => JMap}
import java.util.{List => JList, Map => JMap}

trait ProcedureRenderer extends BaseRenderer[Procedure] {
def patternStats: Traversal.V[Procedure] => Traversal[JsValue, JMap[String, Any], Converter[JsValue, JMap[String, Any]]] =
_.pattern.richPattern.domainMap(_.toJson)

def patternParentStats: Traversal.V[Procedure] => Traversal[JsValue, JMap[String, Any], Converter[JsValue, JMap[String, Any]]] =
_.pattern.parent.richPattern.domainMap(_.toJson)
def patternParentStats: Traversal.V[Procedure] => Traversal[JsValue, JList[JMap[String, Any]], Converter[JsValue, JList[JMap[String, Any]]]] =
_.pattern.parent.richPattern.fold.domainMap(_.headOption.fold[JsValue](JsNull)(_.toJson))

def procedureStatsRenderer(extraData: Set[String]): Traversal.V[Procedure] => JsTraversal = { implicit traversal =>
baseRenderer(
Expand Down
13 changes: 7 additions & 6 deletions thehive/app/org/thp/thehive/controllers/v1/Router.scala
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,13 @@ class Router @Inject() (
case POST(p"/auth/totp/unset") => authenticationCtrl.totpUnsetSecret(None)
case POST(p"/auth/totp/unset/$user") => authenticationCtrl.totpUnsetSecret(Some(user))

case POST(p"/case") => caseCtrl.create
case GET(p"/case/$caseId") => caseCtrl.get(caseId)
case PATCH(p"/case/$caseId") => caseCtrl.update(caseId)
case POST(p"/case/_merge/$caseIds") => caseCtrl.merge(caseIds)
case DELETE(p"/case/$caseId") => caseCtrl.delete(caseId)
// case PATCH(p"api/case/_bulk") => caseCtrl.bulkUpdate()
case POST(p"/case") => caseCtrl.create
case GET(p"/case/$caseId") => caseCtrl.get(caseId)
case PATCH(p"/case/$caseId") => caseCtrl.update(caseId)
case POST(p"/case/_merge/$caseIds") => caseCtrl.merge(caseIds)
case DELETE(p"/case/$caseId") => caseCtrl.delete(caseId)
case DELETE(p"/case/customField/$cfId") => caseCtrl.deleteCustomField(cfId)
// case PATCH(p"api/case/_bulk") => caseCtrl.bulkUpdate()
// case POST(p"/case/_stats") => caseCtrl.stats()
// case GET(p"/case/$caseId/links") => caseCtrl.linkedCases(caseId)

Expand Down
Loading

0 comments on commit a04041f

Please sign in to comment.