diff --git a/app/models/yara_rule.py b/app/models/yara_rule.py index 937b6ba..56b21fc 100755 --- a/app/models/yara_rule.py +++ b/app/models/yara_rule.py @@ -185,7 +185,8 @@ def to_dict(self, include_yara_rule_string=None, short=False, include_relationsh yara_dict["owner_user"] = self.owner_user.to_dict() if self.owner_user else None if not short: - revisions = Yara_rule_history.query.filter_by(yara_rule_id=self.id).all() + revision_limit = int(cfg_settings.Cfg_settings.get_setting("FETCH_REVISION_COUNT_LIMIT") or 25) + revisions = Yara_rule_history.query.filter_by(yara_rule_id=self.id).order_by(Yara_rule_history.date_created.desc()).limit(revision_limit).all() comments = Comments.query.filter_by(entity_id=self.id).filter_by( entity_type=ENTITY_MAPPING["SIGNATURE"]).all() files = Files.query.filter_by(entity_id=self.id).filter_by(entity_type=ENTITY_MAPPING["SIGNATURE"]).all() diff --git a/app/routes/releases.py b/app/routes/releases.py index 63062b7..d6d0fde 100644 --- a/app/routes/releases.py +++ b/app/routes/releases.py @@ -149,26 +149,19 @@ def create_release(): db.session.commit() if not release.is_test_release: - history = db.session.query(yara_rule.Yara_rule_history.id, yara_rule.Yara_rule_history.yara_rule_id, - yara_rule.Yara_rule_history.revision).all() - history_mapping = {} - for h in history: - id_, rule_id, revision = h - if not rule_id in history_mapping: - history_mapping[rule_id] = {} - if not revision in history_mapping[rule_id]: - history_mapping[rule_id][revision] = id_ - release_data = release.release_data_dict release_yara_rule_history_list = [] for sig_id in release_data["Signatures"]["Signatures"].keys(): revision = release_data["Signatures"]["Signatures"][sig_id]["revision"] sig_id = int(sig_id) revision = int(revision) - if not sig_id in history_mapping: - history_mapping[sig_id] = {} - if not revision in history_mapping[sig_id]: + revision_entity = db.session.query(yara_rule.Yara_rule_history) \ + .filter_by(yara_rule_id=sig_id) \ + .filter_by(revision=revision) \ + .first() + + if not revision_entity: yr = db.session.query(yara_rule.Yara_rule).get(sig_id) latest = yara_rule.Yara_rule_history( date_created=datetime.datetime.now(), @@ -180,10 +173,10 @@ def create_release(): ) db.session.add(latest) db.session.flush() - history_mapping[sig_id][revision] = latest.id + revision_entity = latest release_yara_rule_history_list.append( - {"yara_rules_history_id": history_mapping[sig_id][revision], "release_id": release.id}) + {"yara_rules_history_id": revision_entity.id, "release_id": release.id}) if release_yara_rule_history_list: app.logger.debug( diff --git a/app/static/js/yara_rule/yara_rule-controller.js b/app/static/js/yara_rule/yara_rule-controller.js index 48d5877..a921f99 100755 --- a/app/static/js/yara_rule/yara_rule-controller.js +++ b/app/static/js/yara_rule/yara_rule-controller.js @@ -273,7 +273,7 @@ angular.module('ThreatKB') }, { name: 'Actions', - width: '160', + width: '180', enableFiltering: false, enableColumnMenu: false, enableSorting: false, @@ -290,6 +290,12 @@ angular.module('ThreatKB') + '' + '' + ' ' + + '' + + '' + + '' + + '' + + ' ' + '' + '' @@ -416,6 +422,11 @@ angular.module('ThreatKB') $scope.view(id); }; + $scope.viewRevision = function (id) { + $scope.yara_rule = Yara_rule.resource.get({id: id, include_yara_string: 1}); + $scope.revision_view(id); + }; + $scope.activateRule = function (id, name) { Yara_rule.activateRule(id).then(function (success) { growl.info("Successfully activated signature " + name, {ttl: 3000}); @@ -660,6 +671,20 @@ angular.module('ThreatKB') }); }; + $scope.revision_view = function (id) { + const revision_view = $uibModal.open({ + templateUrl: 'yara_rule-revision.html', + controller: 'Yara_ruleRevisionViewController', + size: 'lg', + backdrop: 'static', + resolve: { + yara_rule: function () { + return $scope.yara_rule; + } + } + }); + }; + if (openModalForId !== null) { if (openModalForId === "add") { $scope.create(); @@ -1115,6 +1140,43 @@ angular.module('ThreatKB') return Tags.loadTags(query); }; }]) + .controller('Yara_ruleRevisionViewController', ['$scope', '$uibModalInstance', 'yara_rule', '$location', '$window', '$cookies', + function ($scope, $uibModalInstance, yara_rule, $location, $window, $cookies) { + yara_rule.$promise.then( + function (yr) { + $window.document.title = "ThreatKB: " + yr.name; + } + ); + + $scope.selectedRevisions = { + main: null, + compared: null + }; + + $scope.edit = function (id) { + var location = $location.absUrl(); + var last_spot = location.split("/")[location.split("/").length - 1]; + $uibModalInstance.close($scope.yara_rule); + if (isNaN(parseInt(last_spot, 10))) { + $window.location.href = $location.absUrl() + "/" + id; + return; + } else if (!isNaN(parseInt(last_spot, 10)) && last_spot !== id) { + $window.location.href = $location.absUrl().replace(/\/[0-9]+$/, "/" + id); + return; + } + $window.location.href = $location.absUrl(); + }; + + $scope.yara_rule = yara_rule; + + $scope.ok = function () { + $uibModalInstance.close($scope.yara_rule); + }; + + $scope.cancel = function () { + $uibModalInstance.dismiss('cancel'); + }; + }]) .controller('Yara_revisionController', ['$scope', 'Yara_rule', function ($scope, Yara_rule) { $scope.revision_diff = null; diff --git a/app/static/views/yara_rule/yara_rules.html b/app/static/views/yara_rule/yara_rules.html index e90515f..551ef9c 100755 --- a/app/static/views/yara_rule/yara_rules.html +++ b/app/static/views/yara_rule/yara_rules.html @@ -132,6 +132,102 @@ + Toggle full screen + + × + + Edit + + + View Signature Revision(s) + + + + + + Revisions ({{ yara_rule.revisions.length + 1 }}) + + + + View + + + CURRENT @{{ yara_rule.last_revision_date | date:'yyyy-MM-dd' }} + by {{ yara_rule.modified_user.email }} + + + Rev. {{ rev.revision }} @{{ rev.date_created | date:'yyyy-MM-dd' }} + by {{ rev.user.email }} + {{ rev.releases ? ' - Releases: ' + rev.releases : '' }} + + + + + Diff + + None + + Rev. {{ rev.revision }} @{{ rev.date_created | date:'yyyy-MM-dd' }} + by {{ rev.user.email }} + + + + + + + {{ selectedRevisions.main ? selectedRevisions.main.yara_rule_string : yara_rule.yara_rule_string }} + + + + +
{{ selectedRevisions.main ? selectedRevisions.main.yara_rule_string : yara_rule.yara_rule_string }}