From 3741c5236653c90350651a02a65f4d3297a89abc Mon Sep 17 00:00:00 2001 From: Rami Winestock Date: Tue, 12 Dec 2023 12:52:45 +0200 Subject: [PATCH 1/4] Update shared volumes config --- docker/docker-compose.dev.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker/docker-compose.dev.yml b/docker/docker-compose.dev.yml index a8c68e4d..ce659441 100644 --- a/docker/docker-compose.dev.yml +++ b/docker/docker-compose.dev.yml @@ -33,7 +33,8 @@ services: volumes: - npm_data:/data - le_data:/etc/letsencrypt - - ../localconfig:/ext/appsec + - ../open-appsec-agent-deployment/localconfig:/ext/appsec + - ../open-appsec-agent-deployment/logs:/ext/appsec-logs - ../backend:/app - ../frontend:/app/frontend - ../global:/app/global From 80deae99d65b1a52cf99010695aa8e537e6d897d Mon Sep 17 00:00:00 2001 From: Rami Winestock Date: Tue, 12 Dec 2023 13:18:52 +0200 Subject: [PATCH 2/4] Merge branch 'client-side-log-pagination' into open-appsec-integration --- backend/internal/openappsec-log.js | 139 +++++++++++++++++++- frontend/js/app/api.js | 12 +- frontend/js/app/controller.js | 12 +- frontend/js/app/openappsec-log/list/main.js | 29 +++- frontend/js/app/openappsec-log/main.ejs | 7 +- frontend/js/app/openappsec-log/main.js | 114 +++++++++++++--- frontend/js/app/router.js | 3 +- 7 files changed, 280 insertions(+), 36 deletions(-) diff --git a/backend/internal/openappsec-log.js b/backend/internal/openappsec-log.js index a695826a..22def5c3 100755 --- a/backend/internal/openappsec-log.js +++ b/backend/internal/openappsec-log.js @@ -14,7 +14,7 @@ const internalOpenappsecLog = { * @param {String} [search_query] * @returns {Promise} */ - getAll: (access, expand, search_query) => { + getAllold: (access, expand, search_query) => { return access.can('auditlog:list') .then(() => { @@ -37,6 +37,7 @@ const internalOpenappsecLog = { return path.extname(a).localeCompare(path.extname(b)); }); + // Group the log files by their base name const groupedFiles = sortedLogFiles.reduce((groups, file) => { const fileName = path.basename(file, path.extname(file)); if (!groups[fileName]) { @@ -64,7 +65,7 @@ const internalOpenappsecLog = { eventSeverity: json.eventSeverity, eventLevel: json.eventLevel, eventTime: json.eventTime, - eventName: json.eventName + eventName: json.eventName }; wrappedObjects.push(wrappedObject); } catch (err) { @@ -83,7 +84,139 @@ const internalOpenappsecLog = { let groupedFiles = listLogFiles(directoryPath).catch(console.error); return groupedFiles; }); - } + }, + + countTotalLines: async function (directoryPath) { + const files = await fs.promises.readdir(directoryPath); + const logFiles = files.filter(file => path.extname(file).startsWith('.log')); + + let totalLineCount = 0; + + for (const file of logFiles) { + const filePath = path.join(directoryPath, file); + + // Read only the first line of the file + const readStream = fs.createReadStream(filePath); + const rl = readline.createInterface({ input: readStream }); + const firstLine = await new Promise(resolve => { + rl.on('line', line => { + rl.close(); + resolve(line); + }); + }); + + // Check if the first line is a non-data line + try { + JSON.parse(firstLine); + } catch (err) { + continue; // Skip this file if the first line is a non-data line + } + + // If the first line is a data line, read the rest of the file + const content = await fs.promises.readFile(filePath, 'utf8'); + const lines = content.split('\n'); + totalLineCount += lines.length; + } + + return totalLineCount; + }, + + processFile: async function (filePath) { + const content = await fs.promises.readFile(filePath, 'utf8'); + const lines = content.split('\n'); + const dataLines = []; + + for (const line of lines) { + try { + const json = JSON.parse(line); + const groupName = path.basename(filePath, path.extname(filePath)); + const wrappedObject = { + source: groupName, + meta: json, + serviceName: json.eventSource.serviceName, + eventPriority: json.eventPriority, + eventSeverity: json.eventSeverity, + eventLevel: json.eventLevel, + eventTime: json.eventTime, + eventName: json.eventName + }; + dataLines.push(wrappedObject); + } catch (err) { + // Ignore lines that don't contain JSON data + } + } + + return dataLines; + }, + + + getAll: function (access, expand, search_query) { + return access.can('auditlog:list') + .then(async () => { + const directoryPath = '/app/openappsec_files/logs'; + const files = await fs.promises.readdir(directoryPath); + const logFiles = files.filter(file => path.extname(file).startsWith('.log')); + + // Sort the logFiles array + logFiles.sort((a, b) => { + const baseA = path.basename(a, path.extname(a)); + const baseB = path.basename(b, path.extname(b)); + return baseA.localeCompare(baseB, undefined, { numeric: true, sensitivity: 'base' }); + }); + + const wrappedObjects = []; + for (const file of logFiles) { + const filePath = path.join(directoryPath, file); + const dataLines = await this.processFile(filePath); + wrappedObjects.push(...dataLines); + } + + return wrappedObjects; + }); + }, + + + getPage: function (access, expand, search_query, page, perPage) { + return access.can('auditlog:list') + .then(async () => { + const directoryPath = '/app/openappsec_files/logs'; + + let totalDataLines = await this.countTotalLines(directoryPath); + console.log("totalLineCount: " + totalDataLines); + + const files = await fs.promises.readdir(directoryPath); + const logFiles = files.filter(file => path.extname(file).startsWith('.log')); + + // Sort the logFiles array + logFiles.sort((a, b) => { + const baseA = path.basename(a, path.extname(a)); + const baseB = path.basename(b, path.extname(b)); + return baseA.localeCompare(baseB, undefined, { numeric: true, sensitivity: 'base' }); + }); + + const wrappedObjects = []; + let lineCount = 0; + let start = (page - 1) * perPage; + let end = page * perPage; + + for (const file of logFiles) { + if (lineCount >= end) { + break; + } + + const filePath = path.join(directoryPath, file); + const dataLines = await this.processFile(filePath); + const pageDataLines = dataLines.slice(start - lineCount, end - lineCount); + wrappedObjects.push(...pageDataLines); + lineCount += pageDataLines.length; + } + + return { + data: wrappedObjects, + totalDataLines: totalDataLines, + }; + }); + }, }; module.exports = internalOpenappsecLog; diff --git a/frontend/js/app/api.js b/frontend/js/app/api.js index 2c198bf5..6829745a 100644 --- a/frontend/js/app/api.js +++ b/frontend/js/app/api.js @@ -112,7 +112,7 @@ function makeExpansionString(expand) { * @param {String} [query] * @returns {Promise} */ -function getAllObjects(path, expand, query) { +function getAllObjects(path, expand, query, page, perPage) { let params = []; if (typeof expand === 'object' && expand !== null && expand.length) { @@ -123,7 +123,13 @@ function getAllObjects(path, expand, query) { params.push('query=' + query); } - return fetch('get', path + (params.length ? '?' + params.join('&') : '')); + if (page && perPage) { + params.push('page=' + page); + params.push('perPage=' + perPage); + } + + let url = path + (params.length ? '?' + params.join('&') : ''); + return fetch('get', url); } function FileUpload(path, fd) { @@ -724,7 +730,7 @@ module.exports = { */ getAll: function (expand, query) { return getAllObjects('openappsec-log', expand, query); - } + }, }, Reports: { diff --git a/frontend/js/app/controller.js b/frontend/js/app/controller.js index eb9677bb..3bb6a94d 100644 --- a/frontend/js/app/controller.js +++ b/frontend/js/app/controller.js @@ -410,12 +410,18 @@ module.exports = { /** * openappsec Log */ - showOpenappsecLog: function () { + showOpenappsecLogPage: function (page) { + page = parseInt(page) || 1; let controller = this; if (Cache.User.isAdmin()) { require(['./main', './openappsec-log/main'], (App, View) => { - controller.navigate('/openappsec-log'); - App.UI.showAppContent(new View()); + controller.navigate('/openappsec-log/page/' + page); + + // Show the view with the data + App.UI.showAppContent(new View({ + page: page, + perPage: 50 + })); }); } else { this.showDashboard(); diff --git a/frontend/js/app/openappsec-log/list/main.js b/frontend/js/app/openappsec-log/list/main.js index 9d3e26fb..01f5edd4 100755 --- a/frontend/js/app/openappsec-log/list/main.js +++ b/frontend/js/app/openappsec-log/list/main.js @@ -2,9 +2,28 @@ const Mn = require('backbone.marionette'); const ItemView = require('./item'); const template = require('./main.ejs'); -const TableBody = Mn.CollectionView.extend({ - tagName: 'tbody', - childView: ItemView +let TableBody = Mn.CollectionView.extend({ + tagName: 'tbody', + childView: ItemView, + + initialize: function (options) { + this.options = new Backbone.Model(options); + this.page = options.page; + this.perPage = options.perPage; + this.updatePage(); + this.listenTo(this.options, 'change:page', this.updatePage); + }, + + setPage: function (page) { + this.page = page; + this.updatePage(); + this.render(); + }, + + updatePage: function () { + let models = this.collection.models.slice((this.page - 1) * this.perPage, this.page * this.perPage); + this.collection.reset(models); + } }); module.exports = Mn.View.extend({ @@ -21,7 +40,9 @@ module.exports = Mn.View.extend({ onRender: function () { this.showChildView('body', new TableBody({ - collection: this.collection + collection: this.collection, + page: this.options.page, + perPage: this.options.perPage })); } }); diff --git a/frontend/js/app/openappsec-log/main.ejs b/frontend/js/app/openappsec-log/main.ejs index ed36305a..81c0cabc 100755 --- a/frontend/js/app/openappsec-log/main.ejs +++ b/frontend/js/app/openappsec-log/main.ejs @@ -3,14 +3,14 @@

Security Log

-
@@ -19,6 +19,9 @@
+
+ +
diff --git a/frontend/js/app/openappsec-log/main.js b/frontend/js/app/openappsec-log/main.js index 356a8646..f25642a4 100755 --- a/frontend/js/app/openappsec-log/main.js +++ b/frontend/js/app/openappsec-log/main.js @@ -1,35 +1,99 @@ -const Mn = require('backbone.marionette'); -const App = require('../main'); +const Mn = require('backbone.marionette'); +const App = require('../main'); const OpenappsecLogModel = require('../../models/openappsec-log'); -const ListView = require('./list/main'); -const template = require('./main.ejs'); -const ErrorView = require('../error/main'); -const EmptyView = require('../empty/main'); +const ListView = require('./list/main'); +const template = require('./main.ejs'); +const ErrorView = require('../error/main'); +const EmptyView = require('../empty/main'); +const { data } = require('jquery'); +const Controller = require('../controller'); + +let PaginationView = Mn.View.extend({ + tagName: 'ul', + className: 'pagination justify-content-center mt-4 border-top pt-3', + + initialize: function (options) { + this.totalPages = parseInt(options.totalPages) || 1; + this.currentPage = parseInt(options.currentPage) || 1; + this.totalDataLines = parseInt(options.totalDataLines) || 1; + this.maxPageLinks = 15; + }, + + template: _.template( + '
  • ">' + + 'First' + + '
  • ' + + '
  • ">' + + 'Previous' + + '
  • ' + + '<% let startPage = Math.max(1, currentPage - Math.floor(maxPageLinks / 2)); %>' + + '<% let endPage = Math.min(startPage + maxPageLinks - 1, totalPages); %>' + + '<% startPage = Math.max(1, endPage - maxPageLinks + 1); %>' + + '<% for (let i = startPage; i <= endPage; i++) { %>' + + '
  • ">' + + '<%= i %>' + + '
  • ' + + '<% } %>' + + '
  • ">' + + 'Next' + + '
  • ' + + '
  • ">' + + 'Last' + + '
  • ' + + '
  • ' + + 'Total lines: <%= totalDataLines %>' + + '
  • ' + ), + + templateContext: function () { + return { + totalDataLines: this.totalDataLines, + totalPages: this.totalPages, + currentPage: this.currentPage, + maxPageLinks: this.maxPageLinks + }; + } +}); module.exports = Mn.View.extend({ - id: 'openappsec-log', + id: 'openappsec-log', template: template, + + initialize: function (options) { + this.options = options; + // this.listenTo(App, 'openappsec-log:page', this.setPage); + }, ui: { list_region: '.list-region', - dimmer: '.dimmer', - search: '.search-form', - query: 'input[name="source-query"]' + dimmer: '.dimmer', + search: '.search-form', + query: 'input[name="source-query"]', + pagination_region: '.pagination-region' }, fetch: App.Api.OpenappsecLog.getAll, - showData: function(response) { + showData: function (response) { + const totalDataLines = response.length; this.showChildView('list_region', new ListView({ - collection: new OpenappsecLogModel.Collection(response) + collection: new OpenappsecLogModel.Collection(response), + page: this.options.page, + perPage: this.options.perPage + })); + + this.showChildView('pagination_region', new PaginationView({ + totalDataLines: totalDataLines, + totalPages: Math.ceil(totalDataLines / this.options.perPage), + currentPage: this.options.page })); }, - showError: function(err) { + showError: function (err) { this.showChildView('list_region', new ErrorView({ - code: err.code, + code: err.code, message: err.message, - retry: function () { + retry: function () { App.Controller.showOpenappsecLog(); } })); @@ -37,15 +101,16 @@ module.exports = Mn.View.extend({ console.error(err); }, - showEmpty: function() { + showEmpty: function () { this.showChildView('list_region', new EmptyView({ - title: App.i18n('audit-log', 'empty'), + title: App.i18n('audit-log', 'empty'), subtitle: App.i18n('audit-log', 'empty-subtitle') })); }, regions: { - list_region: '@ui.list_region' + list_region: '@ui.list_region', + pagination_region: '@ui.pagination_region' }, events: { @@ -58,15 +123,24 @@ module.exports = Mn.View.extend({ .catch(err => { this.showError(err); }); + }, + + 'click @ui.pagination_region a': function (e) { + e.preventDefault(); + + // get the page number from the link + const newPage = $(e.currentTarget).attr('href').split('/').pop(); + Controller.navigate('/openappsec-log/page/' + newPage, { trigger: true }); } }, onRender: function () { let view = this; + let query = this.ui.query.val() || ''; - view.fetch(['user']) + view.fetch(['user'], query) .then(response => { - if (!view.isDestroyed() && response && response.length) { + if (!view.isDestroyed() && response) { view.showData(response); } else { view.showEmpty(); diff --git a/frontend/js/app/router.js b/frontend/js/app/router.js index d005e582..e782623c 100644 --- a/frontend/js/app/router.js +++ b/frontend/js/app/router.js @@ -13,7 +13,8 @@ module.exports = AppRouter.default.extend({ 'nginx/access': 'showNginxAccess', 'nginx/certificates': 'showNginxCertificates', 'audit-log': 'showAuditLog', - 'openappsec-log': 'showOpenappsecLog', + 'openappsec-log': 'showOpenappsecLogPage', + 'openappsec-log/page/:number': 'showOpenappsecLogPage', 'settings': 'showSettings', '*default': 'showDashboard' } From dbd78e5e039098815e9898d5271cd8dc50359b43 Mon Sep 17 00:00:00 2001 From: Rami Winestock Date: Wed, 13 Dec 2023 17:40:51 +0200 Subject: [PATCH 3/4] Filtered log views --- backend/internal/openappsec-log.js | 86 +-------- .../js/app/openappsec-log/list-all/item.ejs | 43 +++++ .../js/app/openappsec-log/list-all/item.js | 32 ++++ .../js/app/openappsec-log/list-all/main.ejs | 22 +++ .../js/app/openappsec-log/list-all/main.js | 60 ++++++ .../openappsec-log/list-important/item.ejs | 43 +++++ .../app/openappsec-log/list-important/item.js | 32 ++++ .../openappsec-log/list-important/main.ejs | 22 +++ .../app/openappsec-log/list-important/main.js | 43 +++++ .../list-notifications/item.ejs | 32 ++++ .../openappsec-log/list-notifications/item.js | 32 ++++ .../list-notifications/main.ejs | 13 ++ .../openappsec-log/list-notifications/main.js | 43 +++++ frontend/js/app/openappsec-log/list/main.js | 6 - frontend/js/app/openappsec-log/main.ejs | 33 +++- frontend/js/app/openappsec-log/main.js | 172 ++++++++++++++---- frontend/js/app/openappsec-log/pagination.ejs | 23 +++ frontend/js/app/settings/main.ejs | 2 +- frontend/js/models/openappsec-log.js | 25 ++- 19 files changed, 627 insertions(+), 137 deletions(-) create mode 100644 frontend/js/app/openappsec-log/list-all/item.ejs create mode 100644 frontend/js/app/openappsec-log/list-all/item.js create mode 100644 frontend/js/app/openappsec-log/list-all/main.ejs create mode 100644 frontend/js/app/openappsec-log/list-all/main.js create mode 100644 frontend/js/app/openappsec-log/list-important/item.ejs create mode 100644 frontend/js/app/openappsec-log/list-important/item.js create mode 100644 frontend/js/app/openappsec-log/list-important/main.ejs create mode 100644 frontend/js/app/openappsec-log/list-important/main.js create mode 100644 frontend/js/app/openappsec-log/list-notifications/item.ejs create mode 100644 frontend/js/app/openappsec-log/list-notifications/item.js create mode 100644 frontend/js/app/openappsec-log/list-notifications/main.ejs create mode 100644 frontend/js/app/openappsec-log/list-notifications/main.js create mode 100644 frontend/js/app/openappsec-log/pagination.ejs diff --git a/backend/internal/openappsec-log.js b/backend/internal/openappsec-log.js index 22def5c3..74a23adc 100755 --- a/backend/internal/openappsec-log.js +++ b/backend/internal/openappsec-log.js @@ -6,86 +6,6 @@ const { APPSEC_LOG_DIR } = require('../lib/constants'); const internalOpenappsecLog = { - /** - * All logs - * - * @param {Access} access - * @param {Array} [expand] - * @param {String} [search_query] - * @returns {Promise} - */ - getAllold: (access, expand, search_query) => { - return access.can('auditlog:list') - .then(() => { - - const directoryPath = APPSEC_LOG_DIR; - - const readdir = util.promisify(fs.readdir); - const readFile = util.promisify(fs.readFile); - - async function listLogFiles(dir) { - const files = await readdir(dir); - const logFiles = files.filter(file => path.extname(file).startsWith('.log')); - - const sortedLogFiles = logFiles.sort((a, b) => { - const baseA = path.basename(a, path.extname(a)); - const baseB = path.basename(b, path.extname(b)); - - if (baseA < baseB) return -1; - if (baseA > baseB) return 1; - - return path.extname(a).localeCompare(path.extname(b)); - }); - - // Group the log files by their base name - const groupedFiles = sortedLogFiles.reduce((groups, file) => { - const fileName = path.basename(file, path.extname(file)); - if (!groups[fileName]) { - groups[fileName] = []; - } - groups[fileName].push(file); - return groups; - }, {}); - - const wrappedObjects = []; - - for (const [groupName, files] of Object.entries(groupedFiles)) { - for (const file of files) { - try { - const content = await readFile(path.join(dir, file), 'utf8'); - const lines = content.split('\n'); - for (const line of lines) { - try { - const json = JSON.parse(line); - const wrappedObject = { - source: groupName, - meta: json, - serviceName: json.eventSource.serviceName, - eventPriority: json.eventPriority, - eventSeverity: json.eventSeverity, - eventLevel: json.eventLevel, - eventTime: json.eventTime, - eventName: json.eventName - }; - wrappedObjects.push(wrappedObject); - } catch (err) { - // Ignore lines that don't contain JSON data - } - } - } catch (err) { - console.error(`Failed to read file ${file}: ${err.message}`); - } - } - } - wrappedObjects.sort((a, b) => new Date(b.eventTime) - new Date(a.eventTime)); - return wrappedObjects; - } - - let groupedFiles = listLogFiles(directoryPath).catch(console.error); - return groupedFiles; - }); - }, - countTotalLines: async function (directoryPath) { const files = await fs.promises.readdir(directoryPath); const logFiles = files.filter(file => path.extname(file).startsWith('.log')); @@ -153,7 +73,7 @@ const internalOpenappsecLog = { getAll: function (access, expand, search_query) { return access.can('auditlog:list') .then(async () => { - const directoryPath = '/app/openappsec_files/logs'; + const directoryPath = APPSEC_LOG_DIR; const files = await fs.promises.readdir(directoryPath); const logFiles = files.filter(file => path.extname(file).startsWith('.log')); @@ -175,12 +95,10 @@ const internalOpenappsecLog = { }); }, - getPage: function (access, expand, search_query, page, perPage) { return access.can('auditlog:list') .then(async () => { - const directoryPath = '/app/openappsec_files/logs'; - + const directoryPath = APPSEC_LOG_DIR; let totalDataLines = await this.countTotalLines(directoryPath); console.log("totalLineCount: " + totalDataLines); diff --git a/frontend/js/app/openappsec-log/list-all/item.ejs b/frontend/js/app/openappsec-log/list-all/item.ejs new file mode 100644 index 00000000..ecc0214c --- /dev/null +++ b/frontend/js/app/openappsec-log/list-all/item.ejs @@ -0,0 +1,43 @@ + + + <%- formatDbDate(eventTime, 'D-M-YYYY, H:mm') %> + + +
    + <% var sevirityClass = 'bg-success'; + switch (eventSeverity) { + case 'Critical': + sevirityClass = 'bg-danger'; + break; + case 'Warning': + sevirityClass = 'bg-warning'; + break; + case 'Info': + sevirityClass = 'bg-success'; + //sevirityClass = 'bg-info'; + break; + case 'Debug': + sevirityClass = 'bg-success'; + break; + } + %> + <%- eventSeverity %> +
    + +<%- assetName %> +<%- securityAction %> +<%- waapIncidentType %> +<%- httpSourceId %> +<%- sourceIp %> +<%- proxyIp %> +<%- httpHostName %> +<%- httpMethod %> +<%- httpResponseCode %> +<%- httpUriPath %> +<%- protectionName %> +<%- matchedLocation %> +<%- matchedParameter %> +<%- matchedSample %> + + open + diff --git a/frontend/js/app/openappsec-log/list-all/item.js b/frontend/js/app/openappsec-log/list-all/item.js new file mode 100644 index 00000000..009e3a3e --- /dev/null +++ b/frontend/js/app/openappsec-log/list-all/item.js @@ -0,0 +1,32 @@ +const Mn = require('backbone.marionette'); +const Controller = require('../../controller'); +const template = require('./item.ejs'); + +module.exports = Mn.View.extend({ + template: template, + tagName: 'tr', + + ui: { + meta: 'a.meta' + }, + + events: { + 'click @ui.meta': function (e) { + e.preventDefault(); + Controller.showOpenappsecMeta(this.model); + } + }, + + templateContext: { + more: function() { + switch (this.object_type) { + case 'redirection-host': + case 'stream': + case 'proxy-host': + return this.meta.domain_names.join(', '); + } + + return '#' + (this.object_id || '?'); + } + } +}); diff --git a/frontend/js/app/openappsec-log/list-all/main.ejs b/frontend/js/app/openappsec-log/list-all/main.ejs new file mode 100644 index 00000000..184cddd4 --- /dev/null +++ b/frontend/js/app/openappsec-log/list-all/main.ejs @@ -0,0 +1,22 @@ + + Time + Event Severity + Asset Name + Security Action + AppSec Incident Type + Source Identifier + Source IP + Proxy IP + HTTP Host + HTTP Method + HTTP Response Code + HTTP URI Path + Protection Name + Matched Location + Matched Parameter + Matched Sample +   + + + + diff --git a/frontend/js/app/openappsec-log/list-all/main.js b/frontend/js/app/openappsec-log/list-all/main.js new file mode 100644 index 00000000..777d2db7 --- /dev/null +++ b/frontend/js/app/openappsec-log/list-all/main.js @@ -0,0 +1,60 @@ +const Mn = require('backbone.marionette'); +const ItemView = require('./item'); +const template = require('./main.ejs'); + +let TableBody = Mn.CollectionView.extend({ + tagName: 'tbody', + childView: ItemView, + + initialize: function (options) { + this.options = new Backbone.Model(options); + console.log("options: ", options); + // this.page = options.page; + // this.perPage = options.perPage; + this.updatePage(); + // this.listenTo(this.options, 'change:page', this.updatePage); + }, + + updatePage: function () { + let perPage = this.perPage || this.collection.length; + let page = this.page || 1; + let models; + if (this.perPage && this.page) { + console.log('updatePage2'); + models = this.collection.models.slice((page - 1) * perPage, page * perPage); + } else { + console.log('updatePage3'); + + models = this.collection.models; + } + this.collection.reset(models); + } + + // updatePage: function () { + // let perPage = this.perPage || this.collection.length; + // let page = this.page || 1; + // let models = this.collection.models.slice((page - 1) * perPage, page * perPage); + // this.collection.reset(models); + // } +}); + +module.exports = Mn.View.extend({ + tagName: 'table', + className: 'table table-hover table-outline table-vcenter card-table', + template: template, + + regions: { + body: { + el: 'tbody', + replaceElement: true + } + }, + + onRender: function () { + this.showChildView('body', new TableBody({ + collection: this.collection, + // page: this.options.page, + // perPage: this.options.perPage + })); + } +}); diff --git a/frontend/js/app/openappsec-log/list-important/item.ejs b/frontend/js/app/openappsec-log/list-important/item.ejs new file mode 100644 index 00000000..5537babb --- /dev/null +++ b/frontend/js/app/openappsec-log/list-important/item.ejs @@ -0,0 +1,43 @@ + + + <%- formatDbDate(eventTime, 'D-M-YY, H:mm') %> + + +
    + <% var sevirityClass = 'bg-success'; + switch (eventSeverity) { + case 'Critical': + sevirityClass = 'bg-danger'; + break; + case 'Warning': + sevirityClass = 'bg-warning'; + break; + case 'Info': + sevirityClass = 'bg-success'; + //sevirityClass = 'bg-info'; + break; + case 'Debug': + sevirityClass = 'bg-success'; + break; + } + %> + <%- eventSeverity %> +
    + +<%- assetName %> +<%- securityAction %> +<%- waapIncidentType %> +<%- httpSourceId %> +<%- sourceIp %> +<%- proxyIp %> +<%- httpHostName %> +<%- httpMethod %> +<%- httpResponseCode %> +<%- httpUriPath %> +<%- protectionName %> +<%- matchedLocation %> +<%- matchedParameter %> +<%- matchedSample %> + + open + diff --git a/frontend/js/app/openappsec-log/list-important/item.js b/frontend/js/app/openappsec-log/list-important/item.js new file mode 100644 index 00000000..009e3a3e --- /dev/null +++ b/frontend/js/app/openappsec-log/list-important/item.js @@ -0,0 +1,32 @@ +const Mn = require('backbone.marionette'); +const Controller = require('../../controller'); +const template = require('./item.ejs'); + +module.exports = Mn.View.extend({ + template: template, + tagName: 'tr', + + ui: { + meta: 'a.meta' + }, + + events: { + 'click @ui.meta': function (e) { + e.preventDefault(); + Controller.showOpenappsecMeta(this.model); + } + }, + + templateContext: { + more: function() { + switch (this.object_type) { + case 'redirection-host': + case 'stream': + case 'proxy-host': + return this.meta.domain_names.join(', '); + } + + return '#' + (this.object_id || '?'); + } + } +}); diff --git a/frontend/js/app/openappsec-log/list-important/main.ejs b/frontend/js/app/openappsec-log/list-important/main.ejs new file mode 100644 index 00000000..184cddd4 --- /dev/null +++ b/frontend/js/app/openappsec-log/list-important/main.ejs @@ -0,0 +1,22 @@ + + Time + Event Severity + Asset Name + Security Action + AppSec Incident Type + Source Identifier + Source IP + Proxy IP + HTTP Host + HTTP Method + HTTP Response Code + HTTP URI Path + Protection Name + Matched Location + Matched Parameter + Matched Sample +   + + + + diff --git a/frontend/js/app/openappsec-log/list-important/main.js b/frontend/js/app/openappsec-log/list-important/main.js new file mode 100644 index 00000000..0c90551b --- /dev/null +++ b/frontend/js/app/openappsec-log/list-important/main.js @@ -0,0 +1,43 @@ +const Mn = require('backbone.marionette'); +const ItemView = require('./item'); +const template = require('./main.ejs'); + +let TableBody = Mn.CollectionView.extend({ + tagName: 'tbody', + childView: ItemView, + + initialize: function (options) { + this.options = new Backbone.Model(options); + this.page = options.page; + this.perPage = options.perPage; + this.updatePage(); + this.listenTo(this.options, 'change:page', this.updatePage); + }, + + updatePage: function () { + console.log('updatePage'); + let models = this.collection.models.slice((this.page - 1) * this.perPage, this.page * this.perPage); + this.collection.reset(models); + } +}); + +module.exports = Mn.View.extend({ + tagName: 'table', + className: 'table table-hover table-outline table-vcenter card-table', + template: template, + + regions: { + body: { + el: 'tbody', + replaceElement: true + } + }, + + onRender: function () { + this.showChildView('body', new TableBody({ + collection: this.collection, + page: this.options.page, + perPage: this.options.perPage + })); + } +}); diff --git a/frontend/js/app/openappsec-log/list-notifications/item.ejs b/frontend/js/app/openappsec-log/list-notifications/item.ejs new file mode 100644 index 00000000..e901a23e --- /dev/null +++ b/frontend/js/app/openappsec-log/list-notifications/item.ejs @@ -0,0 +1,32 @@ + +<%- formatDbDate(eventTime, 'D-M-YY, H:mm') %> + +
    + <% var sevirityClass = 'bg-success'; + switch (eventSeverity) { + case 'Critical': + sevirityClass = 'bg-danger'; + break; + case 'Warning': + sevirityClass = 'bg-warning'; + break; + case 'Info': + sevirityClass = 'bg-success'; + //sevirityClass = 'bg-info'; + break; + case 'Debug': + sevirityClass = 'bg-success'; + break; + } + %> + <%- eventSeverity %> +
    + +<%- eventPriority %> +<%- eventTopic %> +<%- eventName %> +<%- suggestedRemediation %> +<%- assetName %> + + open + diff --git a/frontend/js/app/openappsec-log/list-notifications/item.js b/frontend/js/app/openappsec-log/list-notifications/item.js new file mode 100644 index 00000000..009e3a3e --- /dev/null +++ b/frontend/js/app/openappsec-log/list-notifications/item.js @@ -0,0 +1,32 @@ +const Mn = require('backbone.marionette'); +const Controller = require('../../controller'); +const template = require('./item.ejs'); + +module.exports = Mn.View.extend({ + template: template, + tagName: 'tr', + + ui: { + meta: 'a.meta' + }, + + events: { + 'click @ui.meta': function (e) { + e.preventDefault(); + Controller.showOpenappsecMeta(this.model); + } + }, + + templateContext: { + more: function() { + switch (this.object_type) { + case 'redirection-host': + case 'stream': + case 'proxy-host': + return this.meta.domain_names.join(', '); + } + + return '#' + (this.object_id || '?'); + } + } +}); diff --git a/frontend/js/app/openappsec-log/list-notifications/main.ejs b/frontend/js/app/openappsec-log/list-notifications/main.ejs new file mode 100644 index 00000000..9092a11a --- /dev/null +++ b/frontend/js/app/openappsec-log/list-notifications/main.ejs @@ -0,0 +1,13 @@ + + Time + Event Severity + Event Priority + Event Topic + Event Name + Suggested Remediation if Applicable + Asset Name +   + + + + \ No newline at end of file diff --git a/frontend/js/app/openappsec-log/list-notifications/main.js b/frontend/js/app/openappsec-log/list-notifications/main.js new file mode 100644 index 00000000..0c90551b --- /dev/null +++ b/frontend/js/app/openappsec-log/list-notifications/main.js @@ -0,0 +1,43 @@ +const Mn = require('backbone.marionette'); +const ItemView = require('./item'); +const template = require('./main.ejs'); + +let TableBody = Mn.CollectionView.extend({ + tagName: 'tbody', + childView: ItemView, + + initialize: function (options) { + this.options = new Backbone.Model(options); + this.page = options.page; + this.perPage = options.perPage; + this.updatePage(); + this.listenTo(this.options, 'change:page', this.updatePage); + }, + + updatePage: function () { + console.log('updatePage'); + let models = this.collection.models.slice((this.page - 1) * this.perPage, this.page * this.perPage); + this.collection.reset(models); + } +}); + +module.exports = Mn.View.extend({ + tagName: 'table', + className: 'table table-hover table-outline table-vcenter card-table', + template: template, + + regions: { + body: { + el: 'tbody', + replaceElement: true + } + }, + + onRender: function () { + this.showChildView('body', new TableBody({ + collection: this.collection, + page: this.options.page, + perPage: this.options.perPage + })); + } +}); diff --git a/frontend/js/app/openappsec-log/list/main.js b/frontend/js/app/openappsec-log/list/main.js index 01f5edd4..a7ef3281 100755 --- a/frontend/js/app/openappsec-log/list/main.js +++ b/frontend/js/app/openappsec-log/list/main.js @@ -14,12 +14,6 @@ let TableBody = Mn.CollectionView.extend({ this.listenTo(this.options, 'change:page', this.updatePage); }, - setPage: function (page) { - this.page = page; - this.updatePage(); - this.render(); - }, - updatePage: function () { let models = this.collection.models.slice((this.page - 1) * this.perPage, this.page * this.perPage); this.collection.reset(models); diff --git a/frontend/js/app/openappsec-log/main.ejs b/frontend/js/app/openappsec-log/main.ejs index 81c0cabc..4beee89c 100755 --- a/frontend/js/app/openappsec-log/main.ejs +++ b/frontend/js/app/openappsec-log/main.ejs @@ -13,14 +13,31 @@ --> -
    -
    -
    -
    - -
    -
    - +
    + + +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    +
    diff --git a/frontend/js/app/openappsec-log/main.js b/frontend/js/app/openappsec-log/main.js index f25642a4..8f2ecad6 100755 --- a/frontend/js/app/openappsec-log/main.js +++ b/frontend/js/app/openappsec-log/main.js @@ -1,8 +1,11 @@ const Mn = require('backbone.marionette'); const App = require('../main'); const OpenappsecLogModel = require('../../models/openappsec-log'); -const ListView = require('./list/main'); +const ListViewTab1 = require('./list-important/main'); +const ListViewTab2 = require('./list-all/main'); +const ListViewTab3 = require('./list-notifications/main'); const template = require('./main.ejs'); +const paginationTemplate = require('./pagination.ejs'); const ErrorView = require('../error/main'); const EmptyView = require('../empty/main'); const { data } = require('jquery'); @@ -19,31 +22,7 @@ let PaginationView = Mn.View.extend({ this.maxPageLinks = 15; }, - template: _.template( - '
  • ">' + - 'First' + - '
  • ' + - '
  • ">' + - 'Previous' + - '
  • ' + - '<% let startPage = Math.max(1, currentPage - Math.floor(maxPageLinks / 2)); %>' + - '<% let endPage = Math.min(startPage + maxPageLinks - 1, totalPages); %>' + - '<% startPage = Math.max(1, endPage - maxPageLinks + 1); %>' + - '<% for (let i = startPage; i <= endPage; i++) { %>' + - '
  • ">' + - '<%= i %>' + - '
  • ' + - '<% } %>' + - '
  • ">' + - 'Next' + - '
  • ' + - '
  • ">' + - 'Last' + - '
  • ' + - '
  • ' + - 'Total lines: <%= totalDataLines %>' + - '
  • ' - ), + template: paginationTemplate, templateContext: function () { return { @@ -61,7 +40,6 @@ module.exports = Mn.View.extend({ initialize: function (options) { this.options = options; - // this.listenTo(App, 'openappsec-log:page', this.setPage); }, ui: { @@ -74,19 +52,84 @@ module.exports = Mn.View.extend({ fetch: App.Api.OpenappsecLog.getAll, - showData: function (response) { - const totalDataLines = response.length; - this.showChildView('list_region', new ListView({ - collection: new OpenappsecLogModel.Collection(response), - page: this.options.page, + showData: function (response, tab = 'tab1') { + + // Filter the response data for each tab + const eventSeverities = ["critical", "high"]; + const tab1Data = response.filter(item => eventSeverities.includes(item.eventSeverity.trim().toLowerCase())); + + const eventNames = ["waap telemetry", "waap attack type telemetry", "ips stats"]; + const tab2Data = response.filter(item => !eventNames.includes(item.eventName.trim().toLowerCase())); + + const eventLevels = ["action item"]; + const tab3Data = response.filter(item => eventLevels.includes(item.eventLevel.trim().toLowerCase())); + + // Store the lengths of the original collections + this.tabCollectionLengths = { + tab1: response.length, + tab2: response.length, + tab3: response.length + }; + + this.tabCollections = { + tab1: new OpenappsecLogModel.Collection(tab1Data), + tab2: new OpenappsecLogModel.Collection(tab2Data), + tab3: new OpenappsecLogModel.Collection(tab3Data) + }; + + this.tabPaginationStates = { + tab1: { page: 1, perPage: this.options.perPage }, + tab2: { page: 1, perPage: this.options.perPage }, + tab3: { page: 1, perPage: this.options.perPage } + }; + + // Define an object mapping for the ListViews + const listViewMapping = { + tab1: ListViewTab1, + tab2: ListViewTab2, + tab3: ListViewTab3 + }; + + // Get the current tab + const currentTab = tab; // Replace this with the actual current tab + + // Select the ListView for the current tab + const CurrentListView = listViewMapping[currentTab]; + + // Show the ListView for the current tab + this.showChildView('list_region', new CurrentListView({ + collection: this.tabCollections[currentTab], + page: 1, perPage: this.options.perPage + // page: this.tabPaginationStates[currentTab].page, + // perPage: this.tabPaginationStates[currentTab].perPage })); - this.showChildView('pagination_region', new PaginationView({ - totalDataLines: totalDataLines, - totalPages: Math.ceil(totalDataLines / this.options.perPage), - currentPage: this.options.page - })); + // const totalDataLines = response.length; + // this.showChildView('list_region', new ListView({ + // collection: this.tabCollections.tab1, + // page: this.tabPaginationStates.tab1.page, + // perPage: this.tabPaginationStates.tab1.perPage + // })); + + // this.showChildView('pagination_region', new PaginationView({ + // totalDataLines: this.tabCollectionLengths.tab1, + // totalPages: Math.ceil(this.tabCollectionLengths.tab1 / this.options.perPage), + // currentPage: this.tabPaginationStates.tab1.page + // })); + + // const totalDataLines = response.length; + // this.showChildView('list_region', new ListView({ + // collection: new OpenappsecLogModel.Collection(response), + // page: this.options.page, + // perPage: this.options.perPage + // })); + + // this.showChildView('pagination_region', new PaginationView({ + // totalDataLines: totalDataLines, + // totalPages: Math.ceil(totalDataLines / this.options.perPage), + // currentPage: this.options.page + // })); }, showError: function (err) { @@ -125,6 +168,8 @@ module.exports = Mn.View.extend({ }); }, + 'click .nav-link': 'onTabClick', + 'click @ui.pagination_region a': function (e) { e.preventDefault(); @@ -134,6 +179,59 @@ module.exports = Mn.View.extend({ } }, + onTabClick: function(event) { + event.preventDefault(); + const selectedTab = event.target.id; + + console.log("selectedTab: ", selectedTab); + + // let ListView; + // switch (selectedTab) { + // case 'tab1': + // ListView = ListViewTab1; + // break; + // case 'tab2': + // ListView = ListViewTab2; + // break; + // case 'tab3': + // ListView = ListViewTab3; + // break; + // default: + // ListView = ListViewTab1; + // } + + let view = this; + let query = this.ui.query.val() || ''; + + view.fetch(['user'], query) + .then(response => { + if (!view.isDestroyed() && response) { + view.showData(response, selectedTab); + } else { + view.showEmpty(); + } + }) + .catch(err => { + view.showError(err); + }) + .then(() => { + view.ui.dimmer.removeClass('active'); + }); + + // this.showChildView('list_region', new ListView({ + // collection: this.tabCollections[selectedTab], + // page: this.tabPaginationStates[selectedTab].page, + // perPage: this.tabPaginationStates[selectedTab].perPage + // })); + + // this.showChildView('pagination_region', new PaginationView({ + // totalDataLines: this.tabCollections[selectedTab].length, + // totalPages: Math.ceil(this.tabCollections[selectedTab].length / this.options.perPage), + // currentPage: this.tabPaginationStates[selectedTab].page + // })); + + }, + onRender: function () { let view = this; let query = this.ui.query.val() || ''; diff --git a/frontend/js/app/openappsec-log/pagination.ejs b/frontend/js/app/openappsec-log/pagination.ejs new file mode 100644 index 00000000..a4885b2e --- /dev/null +++ b/frontend/js/app/openappsec-log/pagination.ejs @@ -0,0 +1,23 @@ +
  • "> + First +
  • +
  • "> + Previous +
  • +<% let startPage = Math.max(1, currentPage - Math.floor(maxPageLinks / 2)); %> +<% let endPage = Math.min(startPage + maxPageLinks - 1, totalPages); %> +<% startPage = Math.max(1, endPage - maxPageLinks + 1); %> +<% for (let i = startPage; i <= endPage; i++) { %> +
  • "> + <%= i %> +
  • +<% } %> +
  • "> + Next +
  • +
  • "> + Last +
  • +
  • + Total lines: <%= totalDataLines %> +
  • \ No newline at end of file diff --git a/frontend/js/app/settings/main.ejs b/frontend/js/app/settings/main.ejs index 8dc37c9f..2031a4fe 100644 --- a/frontend/js/app/settings/main.ejs +++ b/frontend/js/app/settings/main.ejs @@ -8,7 +8,7 @@ diff --git a/frontend/js/models/openappsec-log.js b/frontend/js/models/openappsec-log.js index c929a0bd..5f057538 100755 --- a/frontend/js/models/openappsec-log.js +++ b/frontend/js/models/openappsec-log.js @@ -5,7 +5,30 @@ const model = Backbone.Model.extend({ defaults: function () { return { - name: '' + name: '-', + eventSeverity: '-', + assetName: '-', + securityAction: '-', + waapIncidentType: '-', + httpSourceId: '-', + sourceIp: '-', + // 'Proxy-IP': '-', + proxyIp: '-', + httpHostName: '-', + httpMethod: '-', + // 'HTTP-Response-Code': '-', + httpResponseCode: '-', + httpUriPath: '-', + // 'Protection-Name': '-', + protectionName: '-', + matchedLocation: '-', + matchedParameter: '-', + matchedSample: '-', + eventPriority: '-', + eventTopic: '-', + eventName: '-', + // Suggested Remediation if Applicable + suggestedRemediation: '-' }; } }); From ce84a865f15a09df5e8e1599a7bd1069f76d740f Mon Sep 17 00:00:00 2001 From: Rami Winestock Date: Wed, 13 Dec 2023 21:51:43 +0200 Subject: [PATCH 4/4] Notify policy updates to open-appsec container. UI labels in log. --- backend/internal/nginx-openappsec.js | 69 ++++++++++++++++++- backend/internal/openappsec-log.js | 1 - backend/internal/proxy-host.js | 29 +++++--- backend/lib/constants.js | 4 ++ .../js/app/openappsec-log/list-all/item.ejs | 31 ++------- .../js/app/openappsec-log/list-all/main.ejs | 2 +- .../js/app/openappsec-log/list-all/main.js | 11 --- .../openappsec-log/list-important/item.ejs | 29 +------- .../openappsec-log/list-important/main.ejs | 2 +- .../app/openappsec-log/list-important/main.js | 1 - .../list-notifications/item.ejs | 24 +------ .../openappsec-log/list-notifications/main.js | 1 - frontend/js/app/openappsec-log/main.js | 18 ----- 13 files changed, 102 insertions(+), 120 deletions(-) diff --git a/backend/internal/nginx-openappsec.js b/backend/internal/nginx-openappsec.js index a8806156..1520fbd2 100755 --- a/backend/internal/nginx-openappsec.js +++ b/backend/internal/nginx-openappsec.js @@ -1,3 +1,6 @@ +const util = require('util'); +const execPromise = util.promisify(require('child_process').exec); +const { exec } = require('child_process'); const _ = require('lodash'); const fs = require('fs'); const logger = require('../logger').nginx; @@ -100,7 +103,24 @@ const internalNginxOpenappsec = { (err) => { logger.error('Error generating openappsec config:', err); return Promise.reject(err); + }) + .then(() => { + // Return the notifyPolicyUpdate promise chain + // notify openappsec to apply the policy + return internalNginxOpenappsec.notifyPolicyUpdate().catch((errorMessage) => { + console.error('Error:', errorMessage); + const errorMessageForUI = `Error: Policy couldn’t be applied, open-appsec-agent container is not responding. + Check if open-appec-agent container is running, then apply open-appsec Configuration + again by clicking here: +
    Settings -> open-appsec Advanced -> Save Settings`; + + return Promise.reject(new Error(errorMessageForUI)); }); + }) + .catch((err) => { + logger.error('Error generating openappsec config:', err); + throw err; // Propagate the error to the caller + }); }, /** @@ -122,9 +142,22 @@ const internalNginxOpenappsec = { internalNginxOpenappsec.removeMatchingNodes(openappsecConfig, pattern); fs.writeFileSync(configFilePath, yaml.dump(openappsecConfig)); }) - .catch(err => { + .then(() => { + // Return the notifyPolicyUpdate promise chain + // notify openappsec to apply the policy + return internalNginxOpenappsec.notifyPolicyUpdate().catch((errorMessage) => { + console.error('---Error:', errorMessage); + const errorMessageForUI = `Error: Policy couldn’t be applied, open-appsec-agent container is not responding. + Check if open-appec-agent container is running, then apply open-appsec Configuration + again by clicking here: +
    Settings -> open-appsec Advanced -> Save Settings`; + + return Promise.reject(new Error(errorMessageForUI)); + }); + }) + .catch((err) => { logger.error('Error deleting openappsec config:', err); - return Promise.reject(err); + throw err; // Propagate the error to the caller }); }, @@ -180,6 +213,38 @@ const internalNginxOpenappsec = { } }, + notifyPolicyUpdate: async function() { + if (!constants.USE_NOTIFY_POLICY) { + console.log('USE_NOTIFY_POLICY is false'); + return; + } + let ports = constants.PORTS; + console.log(`Notifying openappsec to apply the policy on ports ${ports}`); + let lastError = null; + + for (let port of ports) { + try { + const command = `curl -s -o /dev/null -w "%{http_code}" ${constants.HOSTURL}:${port}/openappsec/apply-policy`; + console.log(`command: ${command}`); + let { stdout } = await execPromise(command); + if (stdout === '200') { + console.log(`Policy applied successfully on port ${port}`); + return; + } else { + console.log(`Policy Unexpected response code: ${stdout}`); + lastError = new Error(`Unexpected response code: ${stdout}`); + } + } catch (error) { + console.log(`Error notifying openappsec to apply the policy on port ${port}: ${error.message}`); + lastError = error; + } + } + + if (lastError) { + throw lastError; + } + }, + /** * Recursively removes nodes from a JavaScript object based on a pattern. * diff --git a/backend/internal/openappsec-log.js b/backend/internal/openappsec-log.js index 74a23adc..dfdf19e5 100755 --- a/backend/internal/openappsec-log.js +++ b/backend/internal/openappsec-log.js @@ -100,7 +100,6 @@ const internalOpenappsecLog = { .then(async () => { const directoryPath = APPSEC_LOG_DIR; let totalDataLines = await this.countTotalLines(directoryPath); - console.log("totalLineCount: " + totalDataLines); const files = await fs.promises.readdir(directoryPath); const logFiles = files.filter(file => path.extname(file).startsWith('.log')); diff --git a/backend/internal/proxy-host.js b/backend/internal/proxy-host.js index a83413ca..f75607a4 100644 --- a/backend/internal/proxy-host.js +++ b/backend/internal/proxy-host.js @@ -95,9 +95,14 @@ const internalProxyHost = { }); }) .then(row => { - internalNginxOpenappsec.generateConfig(access, row, data) - return row; - }) + return internalNginxOpenappsec.generateConfig(access, row, data) + .then(() => { + return row; + }) + .catch((err) => { + throw new error.ConfigurationError(err.message); + }); + }) .then((row) => { // Audit log data.meta = _.assign({}, data.meta || {}, row.meta); @@ -174,10 +179,14 @@ const internalProxyHost = { } }) .then(row => { - internalNginxOpenappsec.generateConfig(access, row, data); - // internalNginxOpenappsec.updateConfig(row, data) - return row; - }) + return internalNginxOpenappsec.generateConfig(access, row, data) + .then(() => { + return row; + }) + .catch((err) => { + throw new error.ConfigurationError(err.message); + }); + }) .then((row) => { // Add domain_names to the data in case it isn't there, so that the audit log renders correctly. The order is important here. data = _.assign({}, { @@ -316,7 +325,11 @@ const internalProxyHost = { }) .then(() => { // Delete openappsec config - internalNginxOpenappsec.deleteConfig(access, row); + return internalNginxOpenappsec.deleteConfig(access, row) + .catch((err) => { + throw new error.ConfigurationError(err.message); + }); + }) .then(() => { // Delete Nginx Config diff --git a/backend/lib/constants.js b/backend/lib/constants.js index d41a6343..7b961865 100755 --- a/backend/lib/constants.js +++ b/backend/lib/constants.js @@ -2,4 +2,8 @@ module.exports = { APPSEC_CONFIG_FILE_NAME: 'local_policy.yaml', APPSEC_EXT_DIR: '/ext/appsec', APPSEC_LOG_DIR: '/ext/appsec-logs', + USE_NOTIFY_POLICY: true, + PORTS: [7777, 7778], + HOSTURL: 'http://127.0.0.1', + POLICY_PATH: '/etc/cp/conf/local_policy.yaml', }; \ No newline at end of file diff --git a/frontend/js/app/openappsec-log/list-all/item.ejs b/frontend/js/app/openappsec-log/list-all/item.ejs index ecc0214c..087ea989 100644 --- a/frontend/js/app/openappsec-log/list-all/item.ejs +++ b/frontend/js/app/openappsec-log/list-all/item.ejs @@ -1,29 +1,6 @@ - - <%- formatDbDate(eventTime, 'D-M-YYYY, H:mm') %> - - -
    - <% var sevirityClass = 'bg-success'; - switch (eventSeverity) { - case 'Critical': - sevirityClass = 'bg-danger'; - break; - case 'Warning': - sevirityClass = 'bg-warning'; - break; - case 'Info': - sevirityClass = 'bg-success'; - //sevirityClass = 'bg-info'; - break; - case 'Debug': - sevirityClass = 'bg-success'; - break; - } - %> - <%- eventSeverity %> -
    - +<%- formatDbDate(eventTime, 'D-M-YY, H:mm') %> +<%- eventSeverity %> <%- assetName %> <%- securityAction %> <%- waapIncidentType %> @@ -34,10 +11,10 @@ <%- httpMethod %> <%- httpResponseCode %> <%- httpUriPath %> -<%- protectionName %> +<%- eventTopic %> <%- matchedLocation %> <%- matchedParameter %> <%- matchedSample %> open - + \ No newline at end of file diff --git a/frontend/js/app/openappsec-log/list-all/main.ejs b/frontend/js/app/openappsec-log/list-all/main.ejs index 184cddd4..07ad186c 100644 --- a/frontend/js/app/openappsec-log/list-all/main.ejs +++ b/frontend/js/app/openappsec-log/list-all/main.ejs @@ -11,7 +11,7 @@ HTTP Method HTTP Response Code HTTP URI Path - Protection Name + Event Topic Matched Location Matched Parameter Matched Sample diff --git a/frontend/js/app/openappsec-log/list-all/main.js b/frontend/js/app/openappsec-log/list-all/main.js index 777d2db7..55b8bcde 100644 --- a/frontend/js/app/openappsec-log/list-all/main.js +++ b/frontend/js/app/openappsec-log/list-all/main.js @@ -8,7 +8,6 @@ let TableBody = Mn.CollectionView.extend({ initialize: function (options) { this.options = new Backbone.Model(options); - console.log("options: ", options); // this.page = options.page; // this.perPage = options.perPage; this.updatePage(); @@ -20,22 +19,12 @@ let TableBody = Mn.CollectionView.extend({ let page = this.page || 1; let models; if (this.perPage && this.page) { - console.log('updatePage2'); models = this.collection.models.slice((page - 1) * perPage, page * perPage); } else { - console.log('updatePage3'); - models = this.collection.models; } this.collection.reset(models); } - - // updatePage: function () { - // let perPage = this.perPage || this.collection.length; - // let page = this.page || 1; - // let models = this.collection.models.slice((page - 1) * perPage, page * perPage); - // this.collection.reset(models); - // } }); module.exports = Mn.View.extend({ diff --git a/frontend/js/app/openappsec-log/list-important/item.ejs b/frontend/js/app/openappsec-log/list-important/item.ejs index 5537babb..a6f8b3a1 100644 --- a/frontend/js/app/openappsec-log/list-important/item.ejs +++ b/frontend/js/app/openappsec-log/list-important/item.ejs @@ -1,29 +1,6 @@ - - <%- formatDbDate(eventTime, 'D-M-YY, H:mm') %> - - -
    - <% var sevirityClass = 'bg-success'; - switch (eventSeverity) { - case 'Critical': - sevirityClass = 'bg-danger'; - break; - case 'Warning': - sevirityClass = 'bg-warning'; - break; - case 'Info': - sevirityClass = 'bg-success'; - //sevirityClass = 'bg-info'; - break; - case 'Debug': - sevirityClass = 'bg-success'; - break; - } - %> - <%- eventSeverity %> -
    - +<%- formatDbDate(eventTime, 'D-M-YY, H:mm') %> +<%- eventSeverity %> <%- assetName %> <%- securityAction %> <%- waapIncidentType %> @@ -34,7 +11,7 @@ <%- httpMethod %> <%- httpResponseCode %> <%- httpUriPath %> -<%- protectionName %> +<%- eventTopic %> <%- matchedLocation %> <%- matchedParameter %> <%- matchedSample %> diff --git a/frontend/js/app/openappsec-log/list-important/main.ejs b/frontend/js/app/openappsec-log/list-important/main.ejs index 184cddd4..07ad186c 100644 --- a/frontend/js/app/openappsec-log/list-important/main.ejs +++ b/frontend/js/app/openappsec-log/list-important/main.ejs @@ -11,7 +11,7 @@ HTTP Method HTTP Response Code HTTP URI Path - Protection Name + Event Topic Matched Location Matched Parameter Matched Sample diff --git a/frontend/js/app/openappsec-log/list-important/main.js b/frontend/js/app/openappsec-log/list-important/main.js index 0c90551b..a7ef3281 100644 --- a/frontend/js/app/openappsec-log/list-important/main.js +++ b/frontend/js/app/openappsec-log/list-important/main.js @@ -15,7 +15,6 @@ let TableBody = Mn.CollectionView.extend({ }, updatePage: function () { - console.log('updatePage'); let models = this.collection.models.slice((this.page - 1) * this.perPage, this.page * this.perPage); this.collection.reset(models); } diff --git a/frontend/js/app/openappsec-log/list-notifications/item.ejs b/frontend/js/app/openappsec-log/list-notifications/item.ejs index e901a23e..86457f26 100644 --- a/frontend/js/app/openappsec-log/list-notifications/item.ejs +++ b/frontend/js/app/openappsec-log/list-notifications/item.ejs @@ -1,27 +1,5 @@ - <%- formatDbDate(eventTime, 'D-M-YY, H:mm') %> - -
    - <% var sevirityClass = 'bg-success'; - switch (eventSeverity) { - case 'Critical': - sevirityClass = 'bg-danger'; - break; - case 'Warning': - sevirityClass = 'bg-warning'; - break; - case 'Info': - sevirityClass = 'bg-success'; - //sevirityClass = 'bg-info'; - break; - case 'Debug': - sevirityClass = 'bg-success'; - break; - } - %> - <%- eventSeverity %> -
    - +<%- eventSeverity %> <%- eventPriority %> <%- eventTopic %> <%- eventName %> diff --git a/frontend/js/app/openappsec-log/list-notifications/main.js b/frontend/js/app/openappsec-log/list-notifications/main.js index 0c90551b..a7ef3281 100644 --- a/frontend/js/app/openappsec-log/list-notifications/main.js +++ b/frontend/js/app/openappsec-log/list-notifications/main.js @@ -15,7 +15,6 @@ let TableBody = Mn.CollectionView.extend({ }, updatePage: function () { - console.log('updatePage'); let models = this.collection.models.slice((this.page - 1) * this.perPage, this.page * this.perPage); this.collection.reset(models); } diff --git a/frontend/js/app/openappsec-log/main.js b/frontend/js/app/openappsec-log/main.js index 8f2ecad6..cb992877 100755 --- a/frontend/js/app/openappsec-log/main.js +++ b/frontend/js/app/openappsec-log/main.js @@ -182,24 +182,6 @@ module.exports = Mn.View.extend({ onTabClick: function(event) { event.preventDefault(); const selectedTab = event.target.id; - - console.log("selectedTab: ", selectedTab); - - // let ListView; - // switch (selectedTab) { - // case 'tab1': - // ListView = ListViewTab1; - // break; - // case 'tab2': - // ListView = ListViewTab2; - // break; - // case 'tab3': - // ListView = ListViewTab3; - // break; - // default: - // ListView = ListViewTab1; - // } - let view = this; let query = this.ui.query.val() || '';