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/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) {
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
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: