Skip to content

Commit

Permalink
Merge pull request #1 from TheHive-Project/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
zpriddy authored Feb 14, 2019
2 parents cd436ea + 69c7473 commit bd1b7ba
Show file tree
Hide file tree
Showing 15 changed files with 85 additions and 33 deletions.
11 changes: 7 additions & 4 deletions thehive-backend/app/models/Artifact.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package models

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

import javax.inject.{ Inject, Provider, Singleton }
import scala.concurrent.{ ExecutionContext, Future }
import scala.util.Success

Expand All @@ -12,6 +12,7 @@ import play.api.libs.json.JsValue.jsValueToJsLookup
import play.api.libs.json.Json.toJsFieldJsValueWrapper
import play.api.libs.json._

import akka.stream.scaladsl.Sink
import akka.stream.{ IOResult, Materializer }
import akka.{ Done, NotUsed }
import models.JsonFormat.artifactStatusFormat
Expand Down Expand Up @@ -114,9 +115,11 @@ class ArtifactModel @Inject() (
override def getStats(entity: BaseEntity): Future[JsObject] = {
entity match {
case artifact: Artifact
val (_, total) = artifactSrv.get.findSimilar(artifact, Some("0-0"), Nil)
total.failed.foreach(t logger.error("Artifact.getStats error", t))
total.map { t Json.obj("seen" t) }
val (similarArtifacts, total) = artifactSrv.get.findSimilar(artifact, Some("0-1"), Seq("-ioc"))
for {
ioc similarArtifacts.runWith(Sink.headOption).map(_.fold(false)(_.ioc()))
t total
} yield Json.obj("seen" t, "ioc" ioc)
case _ Future.successful(JsObject.empty)
}
}
Expand Down
2 changes: 1 addition & 1 deletion thehive-backend/app/services/AlertSrv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ class AlertSrv(

def update(alert: Alert, fields: Fields, modifyConfig: ModifyConfig)(implicit authContext: AuthContext): Future[Alert] = {
val follow = fields.getBoolean("follow").getOrElse(alert.follow())
val newStatus = if (follow) AlertStatus.Updated else alert.status()
val newStatus = if (follow && alert.status() != AlertStatus.New) AlertStatus.Updated else alert.status()
val updatedAlert = updateSrv(alert, fields.set("status", Json.toJson(newStatus)), modifyConfig)
alert.caze() match {
case Some(caseId) if follow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,18 @@ class ActionOperationSrv @Inject() (
}
}

def findArtifactEntity(entity: BaseEntity): Future[Artifact] = {
import org.elastic4play.services.QueryDSL._

(entity, entity.model) match {
case (a: Artifact, _) Future.successful(a)
case (_, model: ChildModelDef[_, _, _, _])
findSrv(model.parentModel, "_id" ~= entity.parentId.getOrElse(throw InternalError(s"Child entity $entity has no parent ID")), Some("0-1"), Nil)
._1.runWith(Sink.head).flatMap(findArtifactEntity _)
case _ Future.failed(BadRequestError("Artifact not found"))
}
}

def execute(entity: BaseEntity, operation: ActionOperation)(implicit authContext: AuthContext): Future[ActionOperation] = {
if (operation.status == ActionOperationStatus.Waiting) {
Retry()(classOf[VersionConflictEngineException]) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,14 @@ class CortexActionSrv @Inject() (

def findResponderFor(entityType: String, entityId: String): Future[Seq[Responder]] = {
for {
(tlp, pap) getEntity(entityType, entityId)
.flatMap(actionOperationSrv.findCaseEntity)
.map { caze (caze.tlp(), caze.pap()) }
.recover { case _ (0L, 0L) }
entity getEntity(entityType, entityId)
artifactTlp actionOperationSrv
.findArtifactEntity(entity)
.map(a Some(a.tlp()))
.recover { case _ None }
(tlp, pap) actionOperationSrv.findCaseEntity(entity)
.map { caze (artifactTlp.getOrElse(caze.tlp()), caze.pap()) }
.recover { case _ (artifactTlp.getOrElse(0L), 0L) }
query = Json.obj(
"dataTypeList" s"thehive:$entityType")
responders findResponders(query)
Expand Down
6 changes: 5 additions & 1 deletion ui/app/scripts/controllers/alert/AlertEventCtrl.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(function() {
'use strict';
angular.module('theHiveControllers')
.controller('AlertEventCtrl', function($scope, $rootScope, $state, $uibModal, $uibModalInstance, CustomFieldsCacheSrv, CaseResolutionStatus, AlertingSrv, NotificationSrv, event, templates) {
.controller('AlertEventCtrl', function($scope, $rootScope, $state, $uibModal, $uibModalInstance, CustomFieldsCacheSrv, CaseResolutionStatus, AlertingSrv, NotificationSrv, clipboard, event, templates) {
var self = this;
var eventId = event.id;

Expand Down Expand Up @@ -254,6 +254,10 @@
}
};

self.copyId = function(id) {
clipboard.copyText(id);
};

self.load();
});
})();
12 changes: 8 additions & 4 deletions ui/app/scripts/controllers/case/CaseDetailsCtrl.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(function() {
'use strict';

angular.module('theHiveControllers').controller('CaseDetailsCtrl', function($scope, $state, $uibModal, CaseTabsSrv, UserInfoSrv, PSearchSrv) {
angular.module('theHiveControllers').controller('CaseDetailsCtrl', function($scope, $state, $uibModal, CaseTabsSrv, UserInfoSrv, TagSrv, PSearchSrv) {

CaseTabsSrv.activateTab($state.current.data.tab);

Expand Down Expand Up @@ -98,6 +98,10 @@
itemId: attachment.case_task.id
});
};

$scope.getCaseTags = function(query) {
return TagSrv.fromCases(query);
};
});

angular.module('theHiveControllers').controller('CaseCustomFieldsCtrl', function($scope, $uibModal, CustomFieldsCacheSrv) {
Expand All @@ -108,13 +112,13 @@
return {
name: name,
order: definition.order
}
};
}), function(item){
return item.order;
}), 'name');

return result;
}
};

$scope.getCustomFieldName = function(fieldDef) {
return 'customFields.' + fieldDef.reference + '.' + fieldDef.type;
Expand Down Expand Up @@ -178,4 +182,4 @@
};
});

})();
})();
19 changes: 12 additions & 7 deletions ui/app/scripts/controllers/case/CaseObservablesItemCtrl.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(function () {
'use strict';
angular.module('theHiveControllers').controller('CaseObservablesItemCtrl',
function ($scope, $state, $stateParams, $q, $filter, $timeout, $document, CaseTabsSrv, CaseArtifactSrv, CortexSrv, PSearchSrv, AnalyzerSrv, NotificationSrv, VersionSrv, appConfig) {
function ($scope, $state, $stateParams, $q, $filter, $timeout, $document, CaseTabsSrv, CaseArtifactSrv, CortexSrv, PSearchSrv, AnalyzerSrv, NotificationSrv, VersionSrv, TagSrv, appConfig) {
var observableId = $stateParams.itemId,
observableName = 'observable-' + observableId;

Expand Down Expand Up @@ -57,7 +57,7 @@
$scope.initScope(observable);

}, function (response) {
NotificationSrv.error('artifactDetails', response.data, response.status);
NotificationSrv.error('ObservableDetails', response.data, response.status);
CaseTabsSrv.activateTab('observables');
});

Expand Down Expand Up @@ -129,7 +129,7 @@
}, function (observable) {
$scope.artifact = observable;
}, function (response) {
NotificationSrv.error('artifactDetails', response.data, response.status);
NotificationSrv.error('ObservableDetails', response.data, response.status);
CaseTabsSrv.activateTab('observables');
});
}
Expand Down Expand Up @@ -195,8 +195,9 @@
artifactId: $scope.artifact.id
}, field, function (response) {
$scope.artifact = response.toJSON();
NotificationSrv.log('Observable has been updated', 'success');
}, function (response) {
NotificationSrv.error('artifactDetails', response.data, response.status);
NotificationSrv.error('ObservableDetails', response.data, response.status);
});
};

Expand All @@ -211,7 +212,7 @@
$scope.runAnalyzer = function (analyzerName, serverId) {
var artifactName = $scope.artifact.data || $scope.artifact.attachment.name;

var promise = serverId ? $q.resolve(serverId) : CortexSrv.getServers([analyzerName])
var promise = serverId ? $q.resolve(serverId) : CortexSrv.getServers([analyzerName]);

promise.then(function (serverId) {
return $scope._runAnalyzer(serverId, analyzerName, $scope.artifact.id);
Expand Down Expand Up @@ -254,8 +255,8 @@
$scope.obsResponders = responders;
})
.catch(function(err) {
NotificationSrv.error('observablesList', response.data, response.status);
})
NotificationSrv.error('observablesList', err.data, err.status);
});
};

$scope.runResponder = function(responderId, responderName, artifact) {
Expand All @@ -271,6 +272,10 @@
});
};

$scope.getTags = function(query) {
return TagSrv.fromObservables(query);
};

}
);

Expand Down
3 changes: 2 additions & 1 deletion ui/app/scripts/directives/updatableTags.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
'scope': {
'value': '=?',
'onUpdate': '&',
'active': '=?'
'active': '=?',
'source': '='
}
};
});
Expand Down
2 changes: 1 addition & 1 deletion ui/app/views/directives/search/alert.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
<div class="mt-xs wrap">
<strong>Status:</strong>
<div>
<span class="label label-default" ng-class="{'label-danger': value.status==='New', 'label-warning': value.status === 'Update'}">{{value.status}}</span>
<span class="label label-default" ng-class="{'label-danger': value.status==='New', 'label-warning': value.status === 'Updated'}">{{value.status}}</span>
</div>
</div>
<div class="mt-xs wrap">
Expand Down
1 change: 1 addition & 0 deletions ui/app/views/directives/updatable-tags.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<span ng-show="updatable.updating">
<div class="form-group">
<tags-input class="ti-input-sm" min-length="2" ng-model="value" placeholder="Add labels" replace-spaces-with-dashes="false">
<auto-complete ng-if="source" min-length="1" debounceDelay="400" source="source($query)"></auto-complete>
</tags-input>
</div>
<div class="form-group">
Expand Down
8 changes: 7 additions & 1 deletion ui/app/views/partials/alert/event.dialog.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<div class="modal-header bg-primary">
<h3 class="modal-title">Alert Preview <span class="label label-default" ng-class="{'label-danger': dialog.event.status==='New', 'label-warning': dialog.event.status === 'Updated'}">{{dialog.event.status}}</span></h3>
<h3 class="modal-title">
Alert Preview <span class="label label-default" ng-class="{'label-danger': dialog.event.status==='New', 'label-warning': dialog.event.status === 'Updated'}">{{dialog.event.status}}</span>
</h3>
</div>
<div class="modal-body">
<div class="row text-center" ng-show="dialog.loading">
Expand All @@ -17,6 +19,10 @@ <h4 class="text-primary">
</h4>
<div class="mt-xxs">
<span>
<strong><i class="fa fa-copy"></i> ID: </strong>
<span><a href ng-click="dialog.copyId(dialog.event.id)">{{dialog.event.id}}</a></span>
</span>
<span class="ml-xxs">
<strong><i class="fa fa-calendar"></i> Date: </strong>
<span>{{dialog.event.date | showDate}}</span>
</span>
Expand Down
2 changes: 1 addition & 1 deletion ui/app/views/partials/alert/list.html
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ <h3 class="box-title">List of alerts ({{$vm.list.total || 0}} of {{alertEvents.c
<span><a href ng-click="$vm.addFilterValue('type', event.type)">{{::event.type}}</a></span>
</td>
<td>
<span class="clickable label label-default" ng-class="{'label-danger': event.status==='New', 'label-warning': event.status === 'Update'}" ng-click="$vm.addFilterValue('status', event.status)">{{::event.status}}</span>
<span class="clickable label label-default" ng-class="{'label-danger': event.status==='New', 'label-warning': event.status === 'Updated'}" ng-click="$vm.addFilterValue('status', event.status)">{{::event.status}}</span>
</td>
<td class="wrap">
<div class="case-title">
Expand Down
4 changes: 2 additions & 2 deletions ui/app/views/partials/case/case.details.html
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ <h4 class="vpad10 text-primary">Summary</h4>
</dd>
</dl>

<dl class="dl-horizontal clear">
<dl class="dl-horizontal">
<dt class="pull-left">Tags</dt>
<dd>
<updatable-tags on-update="updateField('tags', getTags(newValue))" value="caze.tags"></updatable-tags>
<updatable-tags on-update="updateField('tags', getTags(newValue))" value="caze.tags" source="getCaseTags"></updatable-tags>
</dd>
</dl>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ <h4 class="vpad10 text-primary">
</dd>
</dl>

<dl class="dl-horizontal clear">
<dt class="pull-left">Labels</dt>
<dl class="dl-horizontal">
<dt class="pull-left">Tags</dt>
<dd>
<updatable-tags value="artifact.tags" on-update="updateField('tags', getLabels(newValue))"></updatable-tags>
<updatable-tags value="artifact.tags" on-update="updateField('tags', getLabels(newValue))" source="getTags"></updatable-tags>
</dd>
</dl>

Expand All @@ -91,17 +91,24 @@ <h4 class="vpad10 text-primary">Links</h4>
<table ng-if="similarArtifacts.length > 0" class="table table-hover">
<thead>
<tr>
<th width="10">IOC</th>
<th>TLP</th>
<th>Case</th>
<th>Date added</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="a in similarArtifacts" style="cursor: pointer;" ng-click="openArtifact(a)" uib-tooltip="{{a.message}}" tooltip-popup-delay="500" tooltip-placement="bottom">
<td align="center">
<span class="clickable fa"
ng-class="{true: 'fa-star', false: 'fa-star-o'}[a.ioc]"
tooltip-popup-delay="500"
tooltip-placement="bottom"></span>
</td>
<td>
<tlp value="a.tlp"></tlp>
</td>
<td>[{{a.dataType}}]: {{a.data}}<br> #{{a.case.caseId}} - {{a.case.title}}
<td>[{{a.dataType}}]: {{a.data || a.attachment.name}}<br> #{{a.case.caseId}} - {{a.case.title}}
</td>
<td>{{a.startDate | showDate}}</td>
</tr>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,19 @@ <h4>Observable List ({{artifacts.total || 0}} of {{artifactStats.count}})</h4>
<span ng-click="addFilterValue('sighted', artifact.sighted)" ng-if="artifact.sighted" class="clickable fa fa-toggle-on" uib-tooltip="has been sighted" tooltip-popup-delay="500" tooltip-placement="bottom"></span>
</td>
<td>
<span uib-tooltip="{{artifact.stats.seen}} related artifact(s)" tooltip-popup-delay="500" tooltip-placement="bottom" ng-if="artifact.stats.seen > 0" class="glyphicon glyphicon-eye-open"></span>
<span
uib-tooltip="{{artifact.stats.seen}} related artifact(s)"
tooltip-placement="bottom"
ng-if="artifact.stats.seen > 0"
class="glyphicon glyphicon-eye-open"
ng-class="{'text-danger': artifact.stats.ioc}"></span>
</td>
<td>
<a href ng-click="addFilterValue('dataType', artifact.dataType)"><span ng-bind="artifact.dataType"></span></a>
</td>
<td class="wrap">
<div class="wrap clickable" ng-click="openArtifact(artifact)" uib-tooltip="{{artifact.message}}" tooltip-placement="top-left">
{{(artifact.data | fang) || (artifact.attachment.name | fang)}}
{{(artifact.data | fang) || (artifact.attachment.name | fang)}}
</div>
<div class="case-tags flexwrap mt-xxs">
<span class="mr-xxxs text-muted"><i class="fa fa-tags"></i></span>
Expand Down

0 comments on commit bd1b7ba

Please sign in to comment.