From b8fd37a71a46a8c3322666542d1333ad2f48f178 Mon Sep 17 00:00:00 2001 From: Nabil Adouani Date: Fri, 22 Feb 2019 11:12:28 +0100 Subject: [PATCH 01/10] #893 Skip case template section when creating a case from alerts, if there are no case templates --- ui/app/scripts/controllers/alert/AlertListCtrl.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ui/app/scripts/controllers/alert/AlertListCtrl.js b/ui/app/scripts/controllers/alert/AlertListCtrl.js index 05c2c9a57c..ee29cdcb4a 100755 --- a/ui/app/scripts/controllers/alert/AlertListCtrl.js +++ b/ui/app/scripts/controllers/alert/AlertListCtrl.js @@ -315,6 +315,10 @@ CaseTemplateSrv.list() .then(function(templates) { + if(!templates || templates.length === 0) { + return $q.resolve(undefined); + } + // Open template selection dialog var modal = $uibModal.open({ templateUrl: 'views/partials/case/case.templates.selector.html', From aab6ec2d9a6874e7272aec849ac987d5cede42af Mon Sep 17 00:00:00 2001 From: Nabil Adouani Date: Fri, 22 Feb 2019 11:13:31 +0100 Subject: [PATCH 02/10] #890 Fix UiSettingsSrv service injection --- ui/app/scripts/controllers/RootCtrl.js | 4 ++-- ui/app/scripts/controllers/alert/AlertEventCtrl.js | 4 +++- ui/app/scripts/controllers/alert/AlertListCtrl.js | 6 +++--- ui/app/views/partials/alert/event.dialog.html | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/ui/app/scripts/controllers/RootCtrl.js b/ui/app/scripts/controllers/RootCtrl.js index 882465e6b2..acbd718b83 100644 --- a/ui/app/scripts/controllers/RootCtrl.js +++ b/ui/app/scripts/controllers/RootCtrl.js @@ -180,9 +180,9 @@ angular.module('theHiveControllers').controller('RootCtrl', templates: function(){ return $scope.templates; }, - uiSettings: function(UiSettingsSrv) { + uiSettings: ['UiSettingsSrv', function(UiSettingsSrv) { return UiSettingsSrv.all(); - } + }] } }); diff --git a/ui/app/scripts/controllers/alert/AlertEventCtrl.js b/ui/app/scripts/controllers/alert/AlertEventCtrl.js index 1176842eee..1f77b87a15 100644 --- a/ui/app/scripts/controllers/alert/AlertEventCtrl.js +++ b/ui/app/scripts/controllers/alert/AlertEventCtrl.js @@ -1,7 +1,7 @@ (function() { 'use strict'; angular.module('theHiveControllers') - .controller('AlertEventCtrl', function($scope, $rootScope, $state, $uibModal, $uibModalInstance, CustomFieldsCacheSrv, CaseResolutionStatus, AlertingSrv, NotificationSrv, clipboard, event, templates) { + .controller('AlertEventCtrl', function($scope, $rootScope, $state, $uibModal, $uibModalInstance, CustomFieldsCacheSrv, CaseResolutionStatus, AlertingSrv, NotificationSrv, UiSettingsSrv, clipboard, event, templates) { var self = this; var eventId = event.id; @@ -25,6 +25,8 @@ self.similarCasesStats = []; self.customFieldsCache = CustomFieldsCacheSrv; + self.hideEmptyCaseButton = UiSettingsSrv.hideEmptyCaseButton(); + var getTemplateCustomFields = function(customFields) { var result = []; diff --git a/ui/app/scripts/controllers/alert/AlertListCtrl.js b/ui/app/scripts/controllers/alert/AlertListCtrl.js index ee29cdcb4a..ba6c919b31 100755 --- a/ui/app/scripts/controllers/alert/AlertListCtrl.js +++ b/ui/app/scripts/controllers/alert/AlertListCtrl.js @@ -328,10 +328,10 @@ resolve: { templates: function(){ return templates; - }, - uiSettings: function(UiSettingsSrv) { + }, + uiSettings: ['UiSettingsSrv', function(UiSettingsSrv) { return UiSettingsSrv.all(); - } + }] } }); diff --git a/ui/app/views/partials/alert/event.dialog.html b/ui/app/views/partials/alert/event.dialog.html index 84d5c44c2e..c59d144ac4 100644 --- a/ui/app/views/partials/alert/event.dialog.html +++ b/ui/app/views/partials/alert/event.dialog.html @@ -166,7 +166,7 @@

From fe9336aa6e0ae7781c58f1dd37cb494e7e3d33b3 Mon Sep 17 00:00:00 2001 From: Nabil Adouani Date: Fri, 22 Feb 2019 11:37:33 +0100 Subject: [PATCH 03/10] Bump version --- ui/bower.json | 2 +- ui/package.json | 2 +- version.sbt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/bower.json b/ui/bower.json index f56c35e652..cb03f183b9 100644 --- a/ui/bower.json +++ b/ui/bower.json @@ -1,6 +1,6 @@ { "name": "thehive", - "version": "3.3.0-RC3", + "version": "3.3.0-RC4", "license": "AGPL-3.0", "dependencies": { "angular": "1.5.8", diff --git a/ui/package.json b/ui/package.json index fdcc56fab8..ae3a2388f0 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,6 +1,6 @@ { "name": "thehive", - "version": "3.3.0-RC3", + "version": "3.3.0-RC4", "license": "AGPL-3.0", "repository": { "type": "git", diff --git a/version.sbt b/version.sbt index 84cc17b6f1..48660d98a4 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -version in ThisBuild := "3.3.0-RC3" +version in ThisBuild := "3.3.0-RC4" From 99b96d11755aaf36b7021dc7a976de15e9a0851a Mon Sep 17 00:00:00 2001 From: Nabil Adouani Date: Fri, 22 Feb 2019 14:16:51 +0100 Subject: [PATCH 04/10] #894 Debounce the navigation to search page when coming from dashboard items --- .../scripts/directives/dashboard/counter.js | 22 ++++++++++--------- ui/app/scripts/directives/dashboard/donut.js | 11 ++++++---- ui/app/scripts/services/GlobalSearchSrv.js | 4 ++-- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/ui/app/scripts/directives/dashboard/counter.js b/ui/app/scripts/directives/dashboard/counter.js index 6997297622..7c0714581b 100644 --- a/ui/app/scripts/directives/dashboard/counter.js +++ b/ui/app/scripts/directives/dashboard/counter.js @@ -1,6 +1,6 @@ (function() { 'use strict'; - angular.module('theHiveDirectives').directive('dashboardCounter', function($http, $state, DashboardSrv, NotificationSrv, GlobalSearchSrv) { + angular.module('theHiveDirectives').directive('dashboardCounter', function($q, $http, $state, DashboardSrv, NotificationSrv, GlobalSearchSrv) { return { restrict: 'E', scope: { @@ -66,17 +66,19 @@ }; scope.openSearch = function(item) { - if(scope.mode === 'edit') { - return; - } + if(scope.mode === 'edit') { + return; + } - var filters = (scope.options.filters || []).concat(item.serie.filters || []); + var filters = (scope.options.filters || []).concat(item.serie.filters || []); + + $q.resolve(GlobalSearchSrv.saveSection(scope.options.entity, { + search: filters.length === 0 ? '*' : null, + filters: filters + })).then(function() { + $state.go('app.search'); + }); - GlobalSearchSrv.saveSection(scope.options.entity, { - search: filters.length === 0 ? '*' : null, - filters: filters - }); - $state.go('app.search'); }; if (scope.autoload === true) { diff --git a/ui/app/scripts/directives/dashboard/donut.js b/ui/app/scripts/directives/dashboard/donut.js index 078d657031..6b0e2f0d52 100644 --- a/ui/app/scripts/directives/dashboard/donut.js +++ b/ui/app/scripts/directives/dashboard/donut.js @@ -1,6 +1,6 @@ (function() { 'use strict'; - angular.module('theHiveDirectives').directive('dashboardDonut', function(StatSrv, $state, DashboardSrv, NotificationSrv, GlobalSearchSrv) { + angular.module('theHiveDirectives').directive('dashboardDonut', function($q, StatSrv, $state, DashboardSrv, NotificationSrv, GlobalSearchSrv) { return { restrict: 'E', scope: { @@ -93,11 +93,14 @@ value: GlobalSearchSrv.buildDefaultFilterValue(fieldDef, d) }; - GlobalSearchSrv.saveSection(scope.options.entity, { + var filters = (scope.options.filters || []).concat([data]); + + $q.resolve(GlobalSearchSrv.saveSection(scope.options.entity, { search: null, - filters: scope.options.filters.concat([data]) + filters: filters + })).then(function() { + $state.go('app.search'); }); - $state.go('app.search'); } }, donut: { diff --git a/ui/app/scripts/services/GlobalSearchSrv.js b/ui/app/scripts/services/GlobalSearchSrv.js index 994a48c993..3c93648c6b 100644 --- a/ui/app/scripts/services/GlobalSearchSrv.js +++ b/ui/app/scripts/services/GlobalSearchSrv.js @@ -18,7 +18,7 @@ var cfg = this.restore(); return cfg[entity] || {}; - } + }; this.restore = function() { return localStorageService.get('search-section') || { @@ -55,7 +55,7 @@ return { operator: 'any', list: [{text: value.id, label:value.name}] - } + }; } else { switch(fieldDef.type) { case 'number': From c9ca6b228133b91d4a459671afd107ed71b0f574 Mon Sep 17 00:00:00 2001 From: Nabil Adouani Date: Fri, 22 Feb 2019 14:48:40 +0100 Subject: [PATCH 05/10] Update Changelog --- CHANGELOG.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce9ab04631..f1f4ec8472 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,18 @@ # Change Log -## [3.3.0-RC3](https://github.com/TheHive-Project/TheHive/tree/3.3.0-RC3) (2019-02-21) +## [3.3.0-RC4](https://github.com/TheHive-Project/TheHive/tree/3.3.0-RC4) (2019-02-22) +[Full Changelog](https://github.com/TheHive-Project/TheHive/compare/3.3.0-RC3...3.3.0-RC4) + +**Implemented enhancements:** + +- Use empty case modal when merging alerts and no templates are defined [\#893](https://github.com/TheHive-Project/TheHive/issues/893) +**Fixed bugs:** + +- Issue with navigation from dashboard clickable donuts to search page [\#894](https://github.com/TheHive-Project/TheHive/issues/894) +- Hide Empty Case Button Broken [\#890](https://github.com/TheHive-Project/TheHive/issues/890) + +## [3.3.0-RC3](https://github.com/TheHive-Project/TheHive/tree/3.3.0-RC3) (2019-02-21) [Full Changelog](https://github.com/TheHive-Project/TheHive/compare/3.3.0-RC2...3.3.0-RC3) **Implemented enhancements:** @@ -809,4 +820,4 @@ -\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* \ No newline at end of file +\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* From 8206aa7fbbcf141a8ce8f068492654951e318664 Mon Sep 17 00:00:00 2001 From: Nabil Adouani Date: Mon, 4 Mar 2019 16:46:36 +0100 Subject: [PATCH 06/10] #908 Add a text dashboard widget --- ui/app/index.html | 1 + .../dashboard/DashboardViewCtrl.js | 9 +- .../scripts/directives/dashboard/multiline.js | 4 +- ui/app/scripts/directives/dashboard/text.js | 99 +++++++++++++++++++ ui/app/scripts/services/DashboardSrv.js | 12 ++- ui/app/views/directives/dashboard/item.html | 10 +- .../directives/dashboard/text/basic.html | 17 ++++ .../views/directives/dashboard/text/edit.html | 14 +++ .../dashboard/text/serie.filters.html | 25 +++++ .../directives/dashboard/text/series.html | 42 ++++++++ .../views/directives/dashboard/text/view.html | 19 ++++ 11 files changed, 244 insertions(+), 8 deletions(-) create mode 100644 ui/app/scripts/directives/dashboard/text.js create mode 100644 ui/app/views/directives/dashboard/text/basic.html create mode 100644 ui/app/views/directives/dashboard/text/edit.html create mode 100644 ui/app/views/directives/dashboard/text/serie.filters.html create mode 100644 ui/app/views/directives/dashboard/text/series.html create mode 100644 ui/app/views/directives/dashboard/text/view.html diff --git a/ui/app/index.html b/ui/app/index.html index 8946fc036c..c5e868cf1e 100644 --- a/ui/app/index.html +++ b/ui/app/index.html @@ -186,6 +186,7 @@ + diff --git a/ui/app/scripts/controllers/dashboard/DashboardViewCtrl.js b/ui/app/scripts/controllers/dashboard/DashboardViewCtrl.js index 7e3805a96d..d254d4c939 100644 --- a/ui/app/scripts/controllers/dashboard/DashboardViewCtrl.js +++ b/ui/app/scripts/controllers/dashboard/DashboardViewCtrl.js @@ -57,11 +57,11 @@ this.canEditDashboard = function() { return (this.createdBy === this.currentUser.id) || (this.dashboardStatus = 'Shared' && AuthenticationSrv.isAdmin(this.currentUser)); - } + }; this.options = { dashboardAllowedTypes: ['container'], - containerAllowedTypes: ['bar', 'line', 'donut', 'counter', 'multiline'], + containerAllowedTypes: ['bar', 'line', 'donut', 'counter', 'text', 'multiline'], maxColumns: 3, cls: DashboardSrv.typeClasses, labels: { @@ -70,6 +70,7 @@ donut: 'Donut', line: 'Line', counter: 'Counter', + text: 'Text', multiline: 'Multi Lines' }, editLayout: !_.find(this.definition.items, function(row) { @@ -132,9 +133,9 @@ }, 0); }); - } + }; - this.itemInserted = function(item, rows, rowIndex, index) { + this.itemInserted = function(item, rows/*, rowIndex, index*/) { if(!item.id){ item.id = UtilsSrv.guid(); } diff --git a/ui/app/scripts/directives/dashboard/multiline.js b/ui/app/scripts/directives/dashboard/multiline.js index 4c86d6d871..6849c4992a 100644 --- a/ui/app/scripts/directives/dashboard/multiline.js +++ b/ui/app/scripts/directives/dashboard/multiline.js @@ -33,7 +33,7 @@ } return s; - } + }; scope.buildSerie = function(serie, q, index) { return { @@ -166,7 +166,7 @@ }; scope.chart = chart; - }, function(err) { + }, function(/*err*/) { scope.error = true; NotificationSrv.log('Failed to fetch data, please edit the widget definition', 'error'); }); diff --git a/ui/app/scripts/directives/dashboard/text.js b/ui/app/scripts/directives/dashboard/text.js new file mode 100644 index 0000000000..9fdf77c810 --- /dev/null +++ b/ui/app/scripts/directives/dashboard/text.js @@ -0,0 +1,99 @@ +(function() { + 'use strict'; + angular.module('theHiveDirectives').directive('dashboardText', function($q, $http, $state, DashboardSrv, GlobalSearchSrv, NotificationSrv) { + return { + restrict: 'E', + scope: { + filter: '=?', + options: '=', + entity: '=', + autoload: '=', + mode: '=', + refreshOn: '@', + resizeOn: '@', + metadata: '=' + }, + templateUrl: 'views/directives/dashboard/text/view.html', + link: function(scope, elem) { + + scope.error = false; + scope.data = null; + scope.globalQuery = null; + + scope.load = function() { + if(!scope.options.series || scope.options.series.length === 0) { + scope.error = true; + return; + } + + var query = DashboardSrv.buildChartQuery(scope.filter, scope.options.query); + scope.globalQuery = query; + + var stats = { + stats: _.map(scope.options.series || [], function(serie, index) { + var s = { + _agg: serie.agg, + _name: serie.name || 'agg_' + (index + 1), + _query: serie.query || {} + }; + + if(serie.agg !== 'count') { + s._field = serie.field; + } + + return { + model: serie.entity, + query: query, + stats: [s] + }; + }) + }; + + var statsPromise = $http.post('./api/_stats', stats); + + statsPromise.then(function(response) { + scope.error = false; + scope.data = response.data; + + var template = scope.options.template; + Object.keys(scope.data).forEach(function(key){ + var regex = new RegExp('{{' + key + '}}', 'gi'); + + template = template.replace(regex, scope.data[key]); + }); + + scope.content = template; + + }, function(/*err*/) { + scope.error = true; + + NotificationSrv.log('Failed to fetch data, please edit the widget definition', 'error'); + }); + }; + + scope.copyHTML = function() { + var html = elem[0].querySelector('.widget-content').innerHTML; + function listener(e) { + e.clipboardData.setData('text/html', html); + e.clipboardData.setData('text/plain', html); + e.preventDefault(); + } + document.addEventListener('copy', listener); + document.execCommand('copy'); + document.removeEventListener('copy', listener); + } + + if (scope.autoload === true) { + scope.load(); + } + + if (!_.isEmpty(scope.refreshOn)) { + scope.$on(scope.refreshOn, function(event, filter) { + scope.filter = filter; + scope.load(); + }); + } + } + }; + }); +})(); diff --git a/ui/app/scripts/services/DashboardSrv.js b/ui/app/scripts/services/DashboardSrv.js index 6a2bcda5d1..7e0475bbce 100644 --- a/ui/app/scripts/services/DashboardSrv.js +++ b/ui/app/scripts/services/DashboardSrv.js @@ -74,7 +74,8 @@ donut: 'fa-pie-chart', line: 'fa-line-chart', multiline: 'fa-area-chart', - counter: 'fa-calculator' + counter: 'fa-calculator', + text: 'fa-file' }; this.sortOptions = [{ @@ -113,6 +114,14 @@ entity: null } }, + { + type: 'text', + options: { + title: null, + template: null, + entity: null + } + }, { type: 'donut', options: { @@ -234,6 +243,7 @@ this.hasMinimalConfiguration = function(component) { switch (component.type) { case 'multiline': + case 'text': return component.options.series.length === _.without(_.pluck(component.options.series, 'entity'), undefined).length; default: return !!component.options.entity; diff --git a/ui/app/views/directives/dashboard/item.html b/ui/app/views/directives/dashboard/item.html index 08bd60745c..e6f6094b69 100644 --- a/ui/app/views/directives/dashboard/item.html +++ b/ui/app/views/directives/dashboard/item.html @@ -1,7 +1,7 @@

- {{component.options.title || 'No title'}} {{mode}} + {{component.options.title || 'No title'}}

@@ -56,6 +56,14 @@

resize-on="{{resizeOn}}" mode="mode"> + + + + +

+
+
+
+ + +
+
+
diff --git a/ui/app/views/directives/dashboard/text/edit.html b/ui/app/views/directives/dashboard/text/edit.html new file mode 100644 index 0000000000..89ad303eae --- /dev/null +++ b/ui/app/views/directives/dashboard/text/edit.html @@ -0,0 +1,14 @@ + + + + Basic + + + + + + Series + + + + diff --git a/ui/app/views/directives/dashboard/text/serie.filters.html b/ui/app/views/directives/dashboard/text/serie.filters.html new file mode 100644 index 0000000000..ff38f8c3b6 --- /dev/null +++ b/ui/app/views/directives/dashboard/text/serie.filters.html @@ -0,0 +1,25 @@ +
+ Serie's filter +
+
+
+
+ + + + +
+
+
+ +
+
+ diff --git a/ui/app/views/directives/dashboard/text/series.html b/ui/app/views/directives/dashboard/text/series.html new file mode 100644 index 0000000000..04c4a36e0c --- /dev/null +++ b/ui/app/views/directives/dashboard/text/series.html @@ -0,0 +1,42 @@ +
+ No series defined. Add a serie +
+
+
+
+ + + +
+ +
+
+
+ +
+
+ +
+
+ +
+
+
+ +
+
+ diff --git a/ui/app/views/directives/dashboard/text/view.html b/ui/app/views/directives/dashboard/text/view.html new file mode 100644 index 0000000000..c5f6d82b01 --- /dev/null +++ b/ui/app/views/directives/dashboard/text/view.html @@ -0,0 +1,19 @@ +
+
+
+

+
+
Failed to fetch data, please edit the widget definition
+

+
+
+
+
+
+ HTML + Copy +
+
+
+
+
From 42e318a1582f0a8c00b527d0191cdbd55813b6a3 Mon Sep 17 00:00:00 2001 From: Nabil Adouani Date: Mon, 4 Mar 2019 23:47:54 +0100 Subject: [PATCH 07/10] #901 Disable alert import button if no template is set and empty cases are not allowed --- ui/app/views/partials/alert/event.dialog.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/app/views/partials/alert/event.dialog.html b/ui/app/views/partials/alert/event.dialog.html index fb6ef5305f..aab0ea0a91 100644 --- a/ui/app/views/partials/alert/event.dialog.html +++ b/ui/app/views/partials/alert/event.dialog.html @@ -169,7 +169,7 @@

- +

From c7b23a5c70753f408b58b954f13f8e9c4bcd0321 Mon Sep 17 00:00:00 2001 From: To-om Date: Thu, 7 Mar 2019 11:36:05 +0100 Subject: [PATCH 08/10] #666 Update elastic4play to unable wildcard search --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 7040cba8cf..31aac9bee6 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -20,7 +20,7 @@ object Dependencies { val reflections = "org.reflections" % "reflections" % "0.9.11" val zip4j = "net.lingala.zip4j" % "zip4j" % "1.3.2" - val elastic4play = "org.thehive-project" %% "elastic4play" % "1.8.0-1" + val elastic4play = "org.thehive-project" %% "elastic4play" % "1.9.0" val akkaCluster = "com.typesafe.akka" %% "akka-cluster" % "2.5.19" val akkaClusterTools = "com.typesafe.akka" %% "akka-cluster-tools" % "2.5.19" } From 2ce42625f245abbb06ce9ec1f348c9f250440b51 Mon Sep 17 00:00:00 2001 From: To-om Date: Thu, 7 Mar 2019 13:21:35 +0100 Subject: [PATCH 09/10] #912 Add "AddTagToAlert" operation, for responders --- .../cortex/services/ActionOperation.scala | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/thehive-cortex/app/connectors/cortex/services/ActionOperation.scala b/thehive-cortex/app/connectors/cortex/services/ActionOperation.scala index 8a13182648..dad270cbbd 100644 --- a/thehive-cortex/app/connectors/cortex/services/ActionOperation.scala +++ b/thehive-cortex/app/connectors/cortex/services/ActionOperation.scala @@ -61,6 +61,10 @@ case class AddLogToTask(content: String, owner: Option[String], status: ActionOp override def updateStatus(newStatus: Type, newMessage: String): ActionOperation = copy(status = newStatus, message = newMessage) } +case class AddTagToAlert(tag: String, status: ActionOperationStatus.Type = ActionOperationStatus.Waiting, message: String = "") extends ActionOperation { + override def updateStatus(newStatus: ActionOperationStatus.Type, newMessage: String): AddTagToAlert = copy(status = newStatus, message = newMessage) +} + object ActionOperation { val addTagToCaseWrites = Json.writes[AddTagToCase] val addTagToArtifactWrites = Json.writes[AddTagToArtifact] @@ -69,6 +73,7 @@ object ActionOperation { val closeTaskWrites = Json.writes[CloseTask] val markAlertAsReadWrites = Json.writes[MarkAlertAsRead] val addLogToTaskWrites = Json.writes[AddLogToTask] + val addTagToAlertWrites = Json.writes[AddTagToAlert] implicit val actionOperationReads: Reads[ActionOperation] = Reads[ActionOperation](json ⇒ (json \ "type").asOpt[String].fold[JsResult[ActionOperation]](JsError("type is missing in action operation")) { case "AddTagToCase" ⇒ (json \ "tag").validate[String].map(tag ⇒ AddTagToCase(tag)) @@ -85,6 +90,7 @@ object ActionOperation { content ← (json \ "content").validate[String] owner ← (json \ "owner").validateOpt[String] } yield AddLogToTask(content, owner) + case "AddTagToAlert" => (json \ "tag").validate[String].map(tag ⇒ AddTagToAlert(tag)) case other ⇒ JsError(s"Unknown operation $other") }) implicit val actionOperationWrites: Writes[ActionOperation] = Writes[ActionOperation] { @@ -95,6 +101,7 @@ object ActionOperation { case a: CloseTask ⇒ closeTaskWrites.writes(a) case a: MarkAlertAsRead ⇒ markAlertAsReadWrites.writes(a) case a: AddLogToTask ⇒ addLogToTaskWrites.writes(a) + case a: AddTagToAlert ⇒ addTagToAlertWrites.writes(a) case a ⇒ Json.obj("unsupported operation" → a.toString) } } @@ -198,6 +205,15 @@ class ActionOperationSrv @Inject() ( task ← findTaskEntity(entity) _ ← logSrv.create(task, Fields.empty.set("message", content).set("owner", owner.map(JsString))) } yield operation.updateStatus(ActionOperationStatus.Success, "") + case AddTagToAlert(tag, _, _) => + entity match { + case initialAlert: Alert ⇒ + for { + alert ← alertSrv.get(initialAlert.id) + _ ← alertSrv.update(alert.id, Fields.empty.set("tags", Json.toJson((alert.tags() :+ tag).distinct)), ModifyConfig(retryOnConflict = 0, version = Some(alert.version))) + } yield operation.updateStatus(ActionOperationStatus.Success, "") + case _ ⇒ Future.failed(BadRequestError("Alert not found")) + } case o ⇒ Future.successful(operation.updateStatus(ActionOperationStatus.Failure, s"Operation $o not supported")) } } From 55adc90964199a0866cca68166c7a87c6c33c69e Mon Sep 17 00:00:00 2001 From: To-om Date: Thu, 7 Mar 2019 15:42:34 +0100 Subject: [PATCH 10/10] Update changelog --- CHANGELOG.md | 19 ++++++++++++++++++- ui/bower.json | 2 +- ui/package.json | 2 +- version.sbt | 2 +- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 840666dfb1..8a2f869586 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,23 @@ # Change Log -## [3.3.0-RC5](https://github.com/TheHive-Project/TheHive/tree/HEAD) (2019-02-24) +## [3.3.0-RC6](https://github.com/TheHive-Project/TheHive/tree/3.3.0-RC6) (2019-02-07) + +[Full Changelog](https://github.com/TheHive-Project/TheHive/compare/3.3.0-RC5...3.3.0-RC6) + +**Implemented enhancements:** + +- Add Tags to an Alert with Responder [\#912](https://github.com/TheHive-Project/TheHive/issues/912) +- Dashboards - Add text widget [\#908](https://github.com/TheHive-Project/TheHive/issues/908) +- Empty case still available when disabled [\#901](https://github.com/TheHive-Project/TheHive/issues/901) +- Support for filtering Tags by prefix \(using asterisk, % or something\) in search dialog [\#666](https://github.com/TheHive-Project/TheHive/issues/666) + +**Closed issues:** + +- Dynamic \(auto-refresh\) of cases is break in 3.3.0-RC5 [\#907](https://github.com/TheHive-Project/TheHive/issues/907) +- Hostname Artifact [\#900](https://github.com/TheHive-Project/TheHive/issues/900) +- DOS issue: Firefox crashing TheHive [\#899](https://github.com/TheHive-Project/TheHive/issues/899) + +## [3.3.0-RC5](https://github.com/TheHive-Project/TheHive/tree/3.3.0-RC5) (2019-02-23) [Full Changelog](https://github.com/TheHive-Project/TheHive/compare/3.3.0-RC4...3.3.0-RC5) **Implemented enhancements:** diff --git a/ui/bower.json b/ui/bower.json index 6812f70221..038e96e3dd 100644 --- a/ui/bower.json +++ b/ui/bower.json @@ -1,6 +1,6 @@ { "name": "thehive", - "version": "3.3.0-RC5", + "version": "3.3.0-RC6", "license": "AGPL-3.0", "dependencies": { "angular": "1.5.8", diff --git a/ui/package.json b/ui/package.json index f76f7ac094..8fd047fe20 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,6 +1,6 @@ { "name": "thehive", - "version": "3.3.0-RC5", + "version": "3.3.0-RC6", "license": "AGPL-3.0", "repository": { "type": "git", diff --git a/version.sbt b/version.sbt index ff5dcf32d6..ccfbebfa1b 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -version in ThisBuild := "3.3.0-RC5" +version in ThisBuild := "3.3.0-RC6"