From 6eb6ad29d32d5182a73953de073412f129ff5b93 Mon Sep 17 00:00:00 2001 From: PrahlM93 Date: Mon, 28 Mar 2016 20:27:18 -0400 Subject: [PATCH 1/3] Filtered API Output --- postmaster/static/js/admins.js | 62 +++++++++------------------------ postmaster/static/js/aliases.js | 21 +++++------ postmaster/static/js/configs.js | 16 ++++++--- postmaster/static/js/domains.js | 16 ++++----- postmaster/static/js/logs.js | 8 ++--- postmaster/static/js/users.js | 19 +++++----- postmaster/static/js/utils.js | 19 ++++++++++ 7 files changed, 74 insertions(+), 87 deletions(-) diff --git a/postmaster/static/js/admins.js b/postmaster/static/js/admins.js index 05a854c..a776baf 100644 --- a/postmaster/static/js/admins.js +++ b/postmaster/static/js/admins.js @@ -12,14 +12,13 @@ function newAdmin(username, password, name) { 'name': name }), - success: function (data) { + success: function (response) { addStatusMessage('success', 'The administrator was added successfully'); fillInTable(); }, - error: function (data) { - // The jQuery('div />') is a work around to encode all html characters - addStatusMessage('error', jQuery('
').text(jQuery.parseJSON(data.responseText).message).html()); + error: function (response) { + addStatusMessage('error', filterText(jQuery.parseJSON(response.responseText).message)); } }); } @@ -32,14 +31,13 @@ function deleteAdmin (id) { url: '/api/v1/admins/' + id, type: 'delete', - success: function (data) { + success: function (response) { addStatusMessage('success', 'The administrator was successfully removed'); fillInTable(); }, - error: function (data) { - // The jQuery('div />') is a work around to encode all html characters - addStatusMessage('error', jQuery('
').text(jQuery.parseJSON(data.responseText).message).html()); + error: function (response) { + addStatusMessage('error', filterText(jQuery.parseJSON(response.responseText).message)); } }); } @@ -61,35 +59,6 @@ function adminEventListeners () { adminPassword.tooltip(); adminName.tooltip(); - adminPassword.editable({ - type: 'password', - mode: 'inline', - anim: 100, - - ajaxOptions: { - type: 'PUT', - dataType: 'JSON', - contentType: 'application/json' - }, - - params: function (params) { - return JSON.stringify({'password': params.value}) - }, - - display: function () { - $(this).html('●●●●●●●●'); - }, - - error: function (response) { - // The jQuery('div />') is a work around to encode all html characters - addStatusMessage('error', jQuery('
').text(jQuery.parseJSON(response.responseText).message).html()); - }, - - success: function () { - addStatusMessage('success', 'The administrator\'s password was changed successfully'); - } - }); - adminUsername.editable({ type: 'text', mode: 'inline', @@ -106,12 +75,11 @@ function adminEventListeners () { }, display: function (value) { - $(this).html(value.toLowerCase()); + $(this).html(filterText(value.toLowerCase())); }, error: function (response) { - // The jQuery('div />') is a work around to encode all html characters - addStatusMessage('error', jQuery('
').text(jQuery.parseJSON(response.responseText).message).html()); + addStatusMessage('error', filterText(jQuery.parseJSON(response.responseText).message)); }, success: function () { @@ -139,8 +107,7 @@ function adminEventListeners () { }, error: function (response) { - // The jQuery('div />') is a work around to encode all html characters - addStatusMessage('error', jQuery('
').text(jQuery.parseJSON(response.responseText).message).html()); + addStatusMessage('error', filterText(jQuery.parseJSON(response.responseText).message)); }, success: function () { @@ -163,9 +130,12 @@ function adminEventListeners () { return JSON.stringify({ 'name': params.value }) }, + display: function (value) { + $(this).html(filterText(value)); + }, + error: function (response) { - // The jQuery('div />') is a work around to encode all html characters - addStatusMessage('error', jQuery('
').text(jQuery.parseJSON(response.responseText).message).html()); + addStatusMessage('error', filterText(jQuery.parseJSON(response.responseText).message)); }, success: function () { @@ -263,9 +233,9 @@ function fillInTable () { var html = ''; tableRow.length == 0 ? html += '' : null; - html += '' + item.username + '\ + html += '' + filterText(item.username) + '\ ●●●●●●●●\ - ' + item.name + '\ + ' + filterText(item.name) + '\ Delete'; tableRow.length == 0 ? html += '' : null; tableRow.length == 0 ? insertTableRow(html) : tableRow.html(html); diff --git a/postmaster/static/js/aliases.js b/postmaster/static/js/aliases.js index 527edf4..a01b55b 100644 --- a/postmaster/static/js/aliases.js +++ b/postmaster/static/js/aliases.js @@ -12,14 +12,13 @@ function newAlias(source, destination) { 'destination': destination }), - success: function (data) { + success: function (response) { addStatusMessage('success', 'The alias was added successfully'); fillInTable(); }, - error: function (data) { - // The jQuery('div />') is a work around to encode all html characters - addStatusMessage('error', jQuery('
').text(jQuery.parseJSON(data.responseText).message).html()); + error: function (response) { + addStatusMessage('error', filterText(jQuery.parseJSON(response.responseText).message)); } }); } @@ -37,9 +36,8 @@ function deleteAlias (id) { fillInTable(); }, - error: function (data) { - // The jQuery('div />') is a work around to encode all html characters - addStatusMessage('error', jQuery('
').text(jQuery.parseJSON(data.responseText).message).html()); + error: function (response) { + addStatusMessage('error', filterText(jQuery.parseJSON(response.responseText).message)); } }); } @@ -156,8 +154,8 @@ function fillInTable () { var html = ''; tableRow.length == 0 ? html += '' : null; - html += '' + item.source + '\ - ' + item.destination + '\ + html += '' + filterText(item.source) + '\ + ' + filterText(item.destination) + '\ Delete'; tableRow.length == 0 ? html += '' : null; tableRow.length == 0 ? insertTableRow(html) : tableRow.html(html); @@ -206,11 +204,10 @@ $(document).ready(function () { return JSON.stringify({ 'value': params.value }) }; $.fn.editable.defaults.error = function (response) { - // The jQuery('div />') is a work around to encode all html characters - addStatusMessage('error', jQuery('
').text(jQuery.parseJSON(response.responseText).message).html()); + addStatusMessage('error', filterText(jQuery.parseJSON(response.responseText).message)); }; $.fn.editable.defaults.display = function (value) { - $(this).html(value.toLowerCase()); + $(this).html(filterText(value.toLowerCase())); }; // When hitting the back/forward buttons, reload the table diff --git a/postmaster/static/js/configs.js b/postmaster/static/js/configs.js index 2bde8a6..98ac87d 100644 --- a/postmaster/static/js/configs.js +++ b/postmaster/static/js/configs.js @@ -17,7 +17,11 @@ function configEventListeners () { configTextItems.unbind(); configTextItems.tooltip(); - configTextItems.editable(); + configTextItems.editable({ + display: function (value) { + $(this).html(filterText(value)); + } + }); configLogFile.unbind(); configLogFile.tooltip(); @@ -26,6 +30,9 @@ function configEventListeners () { // Sets the Mail Database Auditing to True in the UI $('td:contains("Mail Database Auditing")').next('td').children('a').text('True'); addStatusMessage('success', 'The setting was changed successfully'); + }, + display: function (value) { + $(this).html(filterText(value)); } }); } @@ -65,8 +72,8 @@ function fillInTable () { } tableRow.length == 0 ? html += '' : null; - html += '' + item.setting + '\ - ' + (item.value != null ? item.value : '') + ''; + html += '' + filterText(item.setting) + '\ + ' + (item.value != null ? filterText(item.value) : '') + ''; tableRow.length == 0 ? html += '' : null; tableRow.length == 0 ? appendTableRow(html) : tableRow.html(html); @@ -112,8 +119,7 @@ $(document).ready(function () { return JSON.stringify({ 'value': params.value }) }; $.fn.editable.defaults.error = function (response) { - // The jQuery('div />') is a work around to encode all html characters - addStatusMessage('error', jQuery('
').text(jQuery.parseJSON(response.responseText).message).html()); + addStatusMessage('error', filterText(jQuery.parseJSON(response.responseText).message)); }; $.fn.editable.defaults.success = function () { addStatusMessage('success', 'The setting was changed successfully'); diff --git a/postmaster/static/js/domains.js b/postmaster/static/js/domains.js index f3f03ce..8cc128c 100644 --- a/postmaster/static/js/domains.js +++ b/postmaster/static/js/domains.js @@ -8,14 +8,13 @@ function newDomain(name) { contentType: 'application/json', data: JSON.stringify({ 'name': name }), - success: function (data) { + success: function (response) { addStatusMessage('success', 'The domain was added successfully.'); fillInTable(); }, - error: function (data) { - // The jQuery('div />') is a work around to encode all html characters - addStatusMessage('error', jQuery('
').text(jQuery.parseJSON(data.responseText).message).html()); + error: function (response) { + addStatusMessage('error', filterText(jQuery.parseJSON(response.responseText).message)); } }); } @@ -33,14 +32,13 @@ function deleteDomain (id) { type: 'delete', contentType: 'application/json', - success: function (data) { + success: function (response) { addStatusMessage('success', 'The domain was successfully removed.'); fillInTable(); }, - error: function (data) { - // The jQuery('div />') is a work around to encode all html characters - addStatusMessage('error', jQuery('
').text(jQuery.parseJSON(data.responseText).message).html()); + error: function (response) { + addStatusMessage('error', filterText(jQuery.parseJSON(response.responseText).message)); } }); } @@ -130,7 +128,7 @@ function fillInTable(filter) { var html = ''; tableRow.length == 0 ? html += '' : null; - html += '' + item.name + '\ + html += '' + filterText(item.name) + '\ Delete'; tableRow.length == 0 ? html += '' : null; tableRow.length == 0 ? insertTableRow(html) : tableRow.html(html); diff --git a/postmaster/static/js/logs.js b/postmaster/static/js/logs.js index beb890c..a91d394 100644 --- a/postmaster/static/js/logs.js +++ b/postmaster/static/js/logs.js @@ -30,9 +30,9 @@ function fillInTable() { var html = ''; tableRow.length == 0 ? html += '' : null; - html += '' + dateFormatFromISO(item.timestamp) + '\ - ' + item.admin + '\ - ' + item.message + ''; + html += '' + filterText(dateFormatFromISO(item.timestamp)) + '\ + ' + filterText(item.admin) + '\ + ' + filterText(item.message) + ''; tableRow.length == 0 ? html += '' : null; tableRow.length == 0 ? appendTableRow(html) : tableRow.html(html); @@ -47,7 +47,7 @@ function fillInTable() { .fail(function (jqxhr, textStatus, error) { // Remove the loading spinner manageSpinner(false); - addStatusMessage('error', JSON.parse(jqxhr.responseText)['message']); + addStatusMessage('error', filterText(JSON.parse(jqxhr.responseText)['message'])); }); } diff --git a/postmaster/static/js/users.js b/postmaster/static/js/users.js index 11c037e..129b098 100644 --- a/postmaster/static/js/users.js +++ b/postmaster/static/js/users.js @@ -11,14 +11,13 @@ function newUser(email, password) { 'password': password }), - success: function (data) { + success: function (response) { addStatusMessage('success', 'The user was added successfully'); fillInTable(); }, - error: function (data) { - // The jQuery('div />') is a work around to encode all html characters - addStatusMessage('error', jQuery('
').text(jQuery.parseJSON(data.responseText).message).html()); + error: function (response) { + addStatusMessage('error', filterText(jQuery.parseJSON(response.responseText).message)); } }); } @@ -31,14 +30,13 @@ function deleteUser (id) { url: '/api/v1/users/' + id, type: 'delete', - success: function (data) { + success: function (response) { addStatusMessage('success', 'The user was successfully removed'); fillInTable(); }, - error: function (data) { - // The jQuery('div />') is a work around to encode all html characters - addStatusMessage('error', jQuery('
').text(jQuery.parseJSON(data.responseText).message).html()); + error: function (response) { + addStatusMessage('error', filterText(jQuery.parseJSON(response.responseText).message)); } }); } @@ -74,8 +72,7 @@ function userEventListeners () { }, error: function (response) { - // The jQuery('div />') is a work around to encode all html characters - addStatusMessage('error', jQuery('
').text(jQuery.parseJSON(response.responseText).message).html()); + addStatusMessage('error', filterText(jQuery.parseJSON(response.responseText).message)); }, success: function () { @@ -164,7 +161,7 @@ function fillInTable () { var html = ''; tableRow.length == 0 ? html += '' : null; - html += '' + item.email + '\ + html += '' + filterText(item.email) + '\ ●●●●●●●●\ Delete'; tableRow.length == 0 ? html += '' : null; diff --git a/postmaster/static/js/utils.js b/postmaster/static/js/utils.js index 1cdd342..fdba53e 100644 --- a/postmaster/static/js/utils.js +++ b/postmaster/static/js/utils.js @@ -16,6 +16,25 @@ function getUrlVars() { } +// Inspired from https://github.com/janl/mustache.js/blob/master/mustache.js +function filterText(text) { + var entityMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '/': '/', + '`': '`', + '=': '=' + }; + + return String(text).replace(/[&<>"'`=\/]/g, function fromEntityMap (s) { + return entityMap[s]; + }); +} + + function changePage(obj, e) { if (history.pushState) { From aed32fd8f96686bc2ed7d5abe9b5a41d1ed2e0bb Mon Sep 17 00:00:00 2001 From: PrahlM93 Date: Mon, 28 Mar 2016 20:45:36 -0400 Subject: [PATCH 2/3] Misc fixes --- config.py | 4 ++-- manage.py | 6 +++--- tests/conftest.py | 1 - 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/config.py b/config.py index 28492af..1fff187 100644 --- a/config.py +++ b/config.py @@ -13,10 +13,10 @@ class BaseConfiguration(object): WTF_CSRF_ENABLED = False # Make this random (used to generate session keys) SECRET_KEY = 'e9987dce48df3ce98542529fd074d9e9f9cd40e66fc6c4c2' - basedir = path.abspath(path.dirname(__file__)) SQLALCHEMY_TRACK_MODIFICATIONS = True SQLALCHEMY_DATABASE_URI = 'mysql://root:vagrant@localhost:3306/servermail' - SQLALCHEMY_MIGRATE_REPO = path.join(basedir, 'db_repository') + basedir = path.abspath(path.dirname(__file__)) + SQLALCHEMY_MIGRATE_REPO = path.join(basedir, 'db/migrations') class TestConfiguration(BaseConfiguration): diff --git a/manage.py b/manage.py index 743f686..4370a2c 100644 --- a/manage.py +++ b/manage.py @@ -30,9 +30,9 @@ def createdb(): """Runs the db init, db migrate, db upgrade commands automatically, and adds the default configuration settings if they are missing""" if not os.path.isdir('db/migrations'): - flask_migrate.init(directory='db/migrations') - flask_migrate.migrate(directory='db/migrations') - flask_migrate.upgrade(directory='db/migrations') + flask_migrate.init(directory=app.config['SQLALCHEMY_MIGRATE_REPO']) + flask_migrate.migrate(directory=app.config['SQLALCHEMY_MIGRATE_REPO']) + flask_migrate.upgrade(directory=app.config['SQLALCHEMY_MIGRATE_REPO']) add_default_configuration_settings() diff --git a/tests/conftest.py b/tests/conftest.py index 4939490..2a5b6c5 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,7 +3,6 @@ from postmaster.utils import add_default_configuration_settings app.config.from_object('config.TestConfiguration') -SQLALCHEMY_DATABASE_URI = app.config['SQLALCHEMY_DATABASE_URI'] def initialize(): try: From 4bb0841f7bda329990c6c4626304a6d0458622e4 Mon Sep 17 00:00:00 2001 From: PrahlM93 Date: Mon, 28 Mar 2016 20:46:41 -0400 Subject: [PATCH 3/3] Update requirements --- requirements.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index cd8b4fc..85e6cad 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ alembic==0.8.5 -astroid==1.4.4 +astroid==1.4.5 bcrypt==2.0.0 cffi==1.5.2 colorama==0.3.7 @@ -25,13 +25,13 @@ passlib==1.6.5 pbr==1.8.1 py==1.4.31 pycparser==2.14 -pylint==1.5.4 +pylint==1.5.5 pytest==2.9.1 pytest-cov==2.2.1 python-editor==0.5 python-ldap==2.4.25 six==1.10.0 SQLAlchemy==1.0.12 -Werkzeug==0.11.4 +Werkzeug==0.11.5 wrapt==1.10.6 WTForms==2.1