From f51f9bd90b8c813ddb0b0856a215cb501ed62953 Mon Sep 17 00:00:00 2001 From: PrahlM93 Date: Sat, 2 Apr 2016 16:37:18 -0400 Subject: [PATCH] Ensure log file path is configured before logging errors * Now checks if the log file path is defined before writing errors to the log file * Moves the log file outside of the Blueprint and into postmaster.utils --- postmaster/apiv1/admins.py | 2 +- postmaster/apiv1/aliases.py | 2 +- postmaster/apiv1/configs.py | 3 ++- postmaster/apiv1/domains.py | 2 +- postmaster/apiv1/users.py | 2 +- postmaster/apiv1/utils.py | 49 +------------------------------------ postmaster/utils.py | 48 +++++++++++++++++++++++++++++++++++- postmaster/views/common.py | 2 +- 8 files changed, 55 insertions(+), 55 deletions(-) diff --git a/postmaster/apiv1/admins.py b/postmaster/apiv1/admins.py index 8cf6bf4..21ff864 100644 --- a/postmaster/apiv1/admins.py +++ b/postmaster/apiv1/admins.py @@ -9,10 +9,10 @@ from flask_login import login_required, current_user from postmaster import db, bcrypt from postmaster.models import Admins, Configs +from postmaster.utils import json_logger from ..decorators import json_wrap, paginate from ..errors import ValidationError, GenericError from . import apiv1 -from utils import json_logger @apiv1.route("/admins", methods=["GET"]) diff --git a/postmaster/apiv1/aliases.py b/postmaster/apiv1/aliases.py index 0346d84..e3dd8ec 100644 --- a/postmaster/apiv1/aliases.py +++ b/postmaster/apiv1/aliases.py @@ -9,10 +9,10 @@ from flask_login import login_required, current_user from postmaster import db from postmaster.models import VirtualAliases +from postmaster.utils import json_logger from ..decorators import json_wrap, paginate from ..errors import ValidationError, GenericError from . import apiv1 -from utils import json_logger from sqlalchemy import or_ diff --git a/postmaster/apiv1/configs.py b/postmaster/apiv1/configs.py index 205260c..006f24c 100644 --- a/postmaster/apiv1/configs.py +++ b/postmaster/apiv1/configs.py @@ -9,10 +9,11 @@ from flask_login import login_required, current_user from postmaster import db from postmaster.models import Configs +from postmaster.utils import json_logger from ..decorators import json_wrap, paginate from ..errors import ValidationError, GenericError from . import apiv1 -from utils import json_logger, is_config_update_valid +from utils import is_config_update_valid @apiv1.route("/configs", methods=["GET"]) diff --git a/postmaster/apiv1/domains.py b/postmaster/apiv1/domains.py index 3917991..464807c 100644 --- a/postmaster/apiv1/domains.py +++ b/postmaster/apiv1/domains.py @@ -9,10 +9,10 @@ from flask_login import login_required, current_user from postmaster import db from postmaster.models import VirtualDomains +from postmaster.utils import json_logger from ..decorators import json_wrap, paginate from ..errors import ValidationError, GenericError from . import apiv1 -from utils import json_logger @apiv1.route("/domains", methods=["GET"]) diff --git a/postmaster/apiv1/users.py b/postmaster/apiv1/users.py index 869bea7..5526205 100644 --- a/postmaster/apiv1/users.py +++ b/postmaster/apiv1/users.py @@ -9,10 +9,10 @@ from flask_login import login_required, current_user from postmaster import db from postmaster.models import VirtualUsers, VirtualAliases, Configs +from postmaster.utils import json_logger from ..decorators import json_wrap, paginate from ..errors import ValidationError, GenericError from . import apiv1 -from utils import json_logger @apiv1.route("/users", methods=["GET"]) diff --git a/postmaster/apiv1/utils.py b/postmaster/apiv1/utils.py index 1a2e54d..deb0da7 100644 --- a/postmaster/apiv1/utils.py +++ b/postmaster/apiv1/utils.py @@ -7,8 +7,7 @@ import os from re import match from mmap import mmap -from json import dumps, loads -from datetime import datetime +from json import loads from ..errors import ValidationError from postmaster import db from postmaster.models import Configs @@ -67,52 +66,6 @@ def is_config_update_valid(setting, value, valid_value_regex): raise ValidationError('An invalid setting value was supplied') - return False - - -def maildb_auditing_enabled(): - """ Returns a bool based on if mail db auditing is enabled - """ - auditingSetting = Configs.query.filter_by( - setting='Mail Database Auditing').first().value - return auditingSetting == 'True' - - -def login_auditing_enabled(): - """ Returns a bool based on if mail db auditing is enabled - """ - auditingSetting = Configs.query.filter_by( - setting='Login Auditing').first().value - return auditingSetting == 'True' - - -def json_logger(category, admin, message): - """ - Takes a category (typically error or audit), a log message and the responsible - user. It then appends it with an ISO 8601 UTC timestamp to a JSON formatted log file - """ - logPath = Configs.query.filter_by(setting='Log File').first().value - if (category == 'audit' and maildb_auditing_enabled()) or\ - (category == 'auth' and login_auditing_enabled()) or\ - (category == 'error'): - try: - with open(logPath, mode='a+') as logFile: - logFile.write("{}\n".format(dumps( - { - 'category': category, - 'message': message, - 'admin': admin, - 'timestamp': datetime.utcnow().isoformat() + 'Z' - }, - sort_keys=True))) - logFile.close() - except IOError: - raise ValidationError( - 'The log could not be written to "{0}". \ - Verify that the path exists and is writeable.'.format( - os.getcwd().replace('\\', '/') + '/' + logPath)) - - def get_logs_dict(numLines=50, reverseOrder=False): """ Returns the JSON formatted log file as a dict diff --git a/postmaster/utils.py b/postmaster/utils.py index f927cfa..403c75a 100644 --- a/postmaster/utils.py +++ b/postmaster/utils.py @@ -7,10 +7,12 @@ import ldap from struct import unpack from re import search, sub, IGNORECASE +from json import dumps +from datetime import datetime +from os import getcwd from wtforms.validators import StopValidation as WtfStopValidation from postmaster import db, models, bcrypt from postmaster.errors import ValidationError -from apiv1.utils import json_logger def row2dict(row): @@ -64,6 +66,49 @@ def getAlias(source): return None +def maildb_auditing_enabled(): + """ Returns a bool based on if mail db auditing is enabled + """ + auditing_setting = models.Configs.query.filter_by( + setting='Mail Database Auditing').first().value + return auditing_setting == 'True' + + +def login_auditing_enabled(): + """ Returns a bool based on if mail db auditing is enabled + """ + auditing_setting = models.Configs.query.filter_by( + setting='Login Auditing').first().value + return auditing_setting == 'True' + + +def json_logger(category, admin, message): + """ + Takes a category (typically error or audit), a log message and the responsible + user. It then appends it with an ISO 8601 UTC timestamp to a JSON formatted log file + """ + log_path = models.Configs.query.filter_by(setting='Log File').first().value + if log_path and ((category == 'error') or + (category == 'audit' and maildb_auditing_enabled()) or + (category == 'auth' and login_auditing_enabled())): + try: + with open(log_path, mode='a+') as log_file: + log_file.write("{}\n".format(dumps( + { + 'category': category, + 'message': message, + 'admin': admin, + 'timestamp': datetime.utcnow().isoformat() + 'Z' + }, + sort_keys=True))) + log_file.close() + except IOError: + raise ValidationError( + 'The log could not be written to "{0}". \ + Verify that the path exists and is writeable.'.format( + getcwd().replace('\\', '/') + '/' + log_path)) + + def add_default_configuration_settings(): """ Adds the default configuration settings to the database if they aren't present. This is to be used from manage.py when creating the database. @@ -130,6 +175,7 @@ def add_default_configuration_settings(): except Exception: db.session.rollback() + def add_ldap_user_to_db(username, display_name): """ Adds an LDAP user stub in the Admins table of the database for flask_login """ diff --git a/postmaster/views/common.py b/postmaster/views/common.py index c712b21..d24d0b1 100644 --- a/postmaster/views/common.py +++ b/postmaster/views/common.py @@ -9,7 +9,7 @@ from jinja2 import evalcontextfilter, Markup, escape from postmaster import app, forms, models, login_manager from postmaster.utils import get_wtforms_errors -from postmaster.apiv1.utils import json_logger +from postmaster.utils import json_logger common = Blueprint('common', __name__)