diff --git a/baseTemplate/templates/baseTemplate/index.html b/baseTemplate/templates/baseTemplate/index.html index 057203e17..065e30264 100755 --- a/baseTemplate/templates/baseTemplate/index.html +++ b/baseTemplate/templates/baseTemplate/index.html @@ -558,6 +558,7 @@ diff --git a/emailPremium/static/emailPremium/emailPremium.js b/emailPremium/static/emailPremium/emailPremium.js index 356fb1fca..e2a7f3e09 100644 --- a/emailPremium/static/emailPremium/emailPremium.js +++ b/emailPremium/static/emailPremium/emailPremium.js @@ -666,8 +666,292 @@ app.controller('emailPage', function($scope,$http, $timeout, $window) { }; - - }); -/* Java script code for Email Page */ \ No newline at end of file +/* Java script code for Email Page */ + + +/* Java script code for SpamAssassin */ + +app.controller('SpamAssassin', function($scope, $http, $timeout, $window) { + + $scope.SpamAssassinNotifyBox = true; + $scope.SpamAssassinInstallBox = true; + $scope.SpamAssassinLoading = true; + $scope.failedToStartInallation = true; + $scope.couldNotConnect = true; + $scope.SpamAssassinSuccessfullyInstalled = true; + $scope.installationFailed = true; + + + + $scope.installSpamAssassin = function(){ + + $scope.SpamAssassinNotifyBox = true; + $scope.SpamAssassinInstallBox = true; + $scope.SpamAssassinLoading = false; + $scope.failedToStartInallation = true; + $scope.couldNotConnect = true; + $scope.SpamAssassinSuccessfullyInstalled = true; + $scope.installationFailed = true; + + url = "/emailPremium/installSpamAssassin"; + + var data = {}; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + + + if(response.data.status === 1){ + + $scope.SpamAssassinNotifyBox = true; + $scope.SpamAssassinInstallBox = false; + $scope.SpamAssassinLoading = false; + $scope.failedToStartInallation = true; + $scope.couldNotConnect = true; + $scope.SpamAssassinSuccessfullyInstalled = true; + $scope.installationFailed = true; + + getRequestStatus(); + + } + else{ + $scope.errorMessage = response.data.error_message; + + $scope.SpamAssassinNotifyBox = false; + $scope.SpamAssassinInstallBox = true; + $scope.SpamAssassinLoading = true; + $scope.failedToStartInallation = false; + $scope.couldNotConnect = true; + $scope.SpamAssassinSuccessfullyInstalled = true; + } + + } + function cantLoadInitialDatas(response) { + + $scope.SpamAssassinNotifyBox = false; + $scope.SpamAssassinInstallBox = false; + $scope.SpamAssassinLoading = true; + $scope.failedToStartInallation = true; + $scope.couldNotConnect = false; + $scope.SpamAssassinSuccessfullyInstalled = true; + $scope.installationFailed = true; + } + + }; + + function getRequestStatus(){ + + $scope.SpamAssassinNotifyBox = true; + $scope.SpamAssassinInstallBox = false; + $scope.SpamAssassinLoading = false; + $scope.failedToStartInallation = true; + $scope.couldNotConnect = true; + $scope.SpamAssassinSuccessfullyInstalled = true; + $scope.installationFailed = true; + + url = "/emailPremium/installStatusSpamAssassin"; + + var data = {}; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + + + if(response.data.abort === 0){ + + $scope.SpamAssassinNotifyBox = true; + $scope.SpamAssassinInstallBox = false; + $scope.SpamAssassinLoading = false; + $scope.failedToStartInallation = true; + $scope.couldNotConnect = true; + $scope.SpamAssassinSuccessfullyInstalled = true; + $scope.installationFailed = true; + + $scope.requestData = response.data.requestStatus; + $timeout(getRequestStatus,1000); + } + else{ + // Notifications + $timeout.cancel(); + $scope.SpamAssassinNotifyBox = false; + $scope.SpamAssassinInstallBox = false; + $scope.SpamAssassinLoading = true; + $scope.failedToStartInallation = true; + $scope.couldNotConnect = true; + + $scope.requestData = response.data.requestStatus; + + if(response.data.installed === 0) { + $scope.installationFailed = false; + $scope.errorMessage = response.data.error_message; + }else{ + $scope.SpamAssassinSuccessfullyInstalled = false; + $timeout(function() { $window.location.reload(); }, 3000); + } + + } + + } + function cantLoadInitialDatas(response) { + + $scope.SpamAssassinNotifyBox = false; + $scope.SpamAssassinInstallBox = false; + $scope.SpamAssassinLoading = true; + $scope.failedToStartInallation = true; + $scope.couldNotConnect = false; + $scope.SpamAssassinSuccessfullyInstalled = true; + $scope.installationFailed = true; + + + } + + } + + ///// SpamAssassin configs + + var report_safe = false; + + + $('#report_safe').change(function() { + report_safe = $(this).prop('checked'); + }); + + fetchSpamAssassinSettings(); + function fetchSpamAssassinSettings(){ + + $scope.SpamAssassinLoading = false; + + $('#report_safe').bootstrapToggle('off'); + + url = "/emailPremium/fetchSpamAssassinSettings"; + + var data = {}; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + + $scope.SpamAssassinLoading = true; + + if(response.data.fetchStatus === 1){ + + if(response.data.installed === 1) { + + if (response.data.report_safe === 1) { + $('#report_safe').bootstrapToggle('on'); + } + + $scope.required_hits = response.data.required_hits; + $scope.rewrite_header = response.data.rewrite_header; + $scope.required_score = response.data.required_score; + + } + + } + + } + function cantLoadInitialDatas(response) { + $scope.SpamAssassinLoading = true; + } + + } + + + ///// + + /// Save SpamAssassin Changes + + $scope.failedToSave = true; + $scope.successfullySaved = true; + + $scope.saveSpamAssassinConfigurations = function () { + + $scope.failedToSave = true; + $scope.successfullySaved = true; + $scope.SpamAssassinLoading = false; + $scope.couldNotConnect = true; + + + url = "/emailPremium/saveSpamAssassinConfigurations"; + + var data = { + report_safe:report_safe, + required_hits:$scope.required_hits, + rewrite_header:$scope.rewrite_header, + required_score:$scope.required_score + }; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + + + if(response.data.saveStatus === 1){ + + $scope.failedToSave = true; + $scope.successfullySaved = false; + $scope.SpamAssassinLoading = true; + $scope.couldNotConnect = true; + + } + else{ + $scope.errorMessage = response.data.error_message; + + $scope.failedToSave = false; + $scope.successfullySaved = true; + $scope.SpamAssassinLoading = true; + $scope.couldNotConnect = true; + } + + } + function cantLoadInitialDatas(response) { + $scope.failedToSave = true; + $scope.successfullySaved = false; + $scope.SpamAssassinLoading = true; + $scope.couldNotConnect = true; + } + + + }; + +}); \ No newline at end of file diff --git a/emailPremium/templates/emailPremium/SpamAssassin.html b/emailPremium/templates/emailPremium/SpamAssassin.html new file mode 100644 index 000000000..274fbd24c --- /dev/null +++ b/emailPremium/templates/emailPremium/SpamAssassin.html @@ -0,0 +1,157 @@ +{% extends "baseTemplate/index.html" %} +{% load i18n %} +{% block title %}{% trans "SpamAssassin - CyberPanel" %}{% endblock %} +{% block content %} + +{% load static %} +{% get_current_language as LANGUAGE_CODE %} + + + +
+
+

{% trans "SpamAssassin Configurations!" %}

+

{% trans "On this page you can configure SpamAssassin settings." %}

+
+ +
+
+

+ {% trans "SpamAssassin" %} +

+ +
+
+ + {% if checkIfSpamAssassinInstalled == 0 %} + +
+

{% trans "SpamAssassin is not installed " %} +

+
+ + + +
+ +
+ +
+

{% trans "Failed to start installation, Error message: " %} {$ errorMessage $}

+
+ +
+

{% trans "Could not connect. Please refresh this page." %}

+
+ +
+

{% trans "Installation failed." %} {$ errorMessage $}

+
+ +
+

{% trans "SpamAssassin successfully installed, refreshing page in 3 seconds.." %}

+
+
+
+ + +
+ +
+
+
+

{% trans "Winter is coming, but so is SpamAssassin." %}

+
+
+ +
+
+
+
+ + + + {% else %} + +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ + +
+ +
+ + +
+
+ + + +
+ +
+ +
+

{% trans "Failed to save SpamAssassin configurations. Error message: " %} {$ errorMessage $}

+
+ +
+

{% trans "SpamAssassin configurations successfully saved." %}

+
+ +
+

{% trans "Could not connect. Please refresh this page." %}

+
+ +
+
+ + +
+
+ + {% endif %} + + + +
+
+
+
+ + +
+ + +{% endblock %} \ No newline at end of file diff --git a/emailPremium/urls.py b/emailPremium/urls.py index 7e42bf025..a22b563df 100644 --- a/emailPremium/urls.py +++ b/emailPremium/urls.py @@ -22,6 +22,14 @@ urlpatterns = [ url(r'^getEmailLogs$', views.getEmailLogs, name='getEmailLogs'), url(r'^flushEmailLogs$', views.flushEmailLogs, name='flushEmailLogs'), + ## SpamAssassin + + url(r'^SpamAssassin$', views.spamAssassinHome, name='SpamAssassin'), + + url(r'^installSpamAssassin$', views.installSpamAssassin, name='installSpamAssassin'), + url(r'^installStatusSpamAssassin$', views.installStatusSpamAssassin, name='installStatusSpamAssassin'), + url(r'^fetchSpamAssassinSettings$', views.fetchSpamAssassinSettings, name='fetchSpamAssassinSettings'), + url(r'^saveSpamAssassinConfigurations$', views.saveSpamAssassinConfigurations, name='saveSpamAssassinConfigurations'), diff --git a/emailPremium/views.py b/emailPremium/views.py index c11a07dc6..aa6ba2f6c 100644 --- a/emailPremium/views.py +++ b/emailPremium/views.py @@ -10,9 +10,16 @@ from websiteFunctions.models import Websites from loginSystem.views import loadLoginPage import plogical.CyberCPLogFileWriter as logging import json -from .models import DomainLimits, EmailLimits, EmailLogs +from .models import DomainLimits, EmailLimits from math import ceil from postfixSenderPolicy.client import cacheClient +import thread +from plogical.mailUtilities import mailUtilities +import subprocess +import shlex +from plogical.virtualHostUtilities import virtualHostUtilities +from random import randint + # Create your views here. @@ -572,4 +579,236 @@ def flushEmailLogs(request): except KeyError,msg: dic = {'statusa': 0, 'error_message': str(msg)} json_data = json.dumps(dic) + return HttpResponse(json_data) + + +### SpamAssassin + +def spamAssassinHome(request): + try: + val = request.session['userID'] + + checkIfSpamAssassinInstalled = 0 + + if mailUtilities.checkIfSpamAssassinInstalled() == 1: + checkIfSpamAssassinInstalled = 1 + + return render(request, 'emailPremium/SpamAssassin.html',{'checkIfSpamAssassinInstalled': checkIfSpamAssassinInstalled}) + + except KeyError: + return redirect(loadLoginPage) + +def installSpamAssassin(request): + try: + val = request.session['userID'] + try: + thread.start_new_thread(mailUtilities.installSpamAssassin, ('Install','SpamAssassin')) + final_json = json.dumps({'status': 1, 'error_message': "None"}) + return HttpResponse(final_json) + except BaseException,msg: + final_dic = {'status': 0, 'error_message': str(msg)} + final_json = json.dumps(final_dic) + return HttpResponse(final_json) + except KeyError: + final_dic = {'status': 0, 'error_message': "Not Logged In, please refresh the page or login again."} + final_json = json.dumps(final_dic) + return HttpResponse(final_json) + +def installStatusSpamAssassin(request): + try: + val = request.session['userID'] + try: + if request.method == 'POST': + + command = "sudo cat " + mailUtilities.spamassassinInstallLogPath + installStatus = subprocess.check_output(shlex.split(command)) + + if installStatus.find("[200]")>-1: + + execPath = "sudo python " + virtualHostUtilities.cyberPanel + "/plogical/mailUtilities.py" + + execPath = execPath + " configureSpamAssassin" + + output = subprocess.check_output(shlex.split(execPath)) + + if output.find("1,None") > -1: + pass + else: + final_json = json.dumps({ + 'error_message': "Failed to install SpamAssassin configurations.", + 'requestStatus': installStatus, + 'abort': 1, + 'installed': 0, + }) + return HttpResponse(final_json) + + final_json = json.dumps({ + 'error_message': "None", + 'requestStatus': installStatus, + 'abort':1, + 'installed': 1, + }) + return HttpResponse(final_json) + elif installStatus.find("[404]") > -1: + + final_json = json.dumps({ + 'abort':1, + 'installed':0, + 'error_message': "None", + 'requestStatus': installStatus, + }) + return HttpResponse(final_json) + + else: + final_json = json.dumps({ + 'abort':0, + 'error_message': "None", + 'requestStatus': installStatus, + }) + return HttpResponse(final_json) + + + except BaseException,msg: + final_dic = {'abort':1,'installed':0, 'error_message': str(msg)} + final_json = json.dumps(final_dic) + return HttpResponse(final_json) + except KeyError: + final_dic = {'abort':1,'installed':0, 'error_message': "Not Logged In, please refresh the page or login again."} + final_json = json.dumps(final_dic) + return HttpResponse(final_json) + + +def fetchSpamAssassinSettings(request): + try: + val = request.session['userID'] + + try: + if request.method == 'POST': + + report_safe = 0 + required_hits = '5.0' + rewrite_header = 'Subject [SPAM]' + required_score = '5' + + confPath = "/etc/mail/spamassassin/local.cf" + + if mailUtilities.checkIfSpamAssassinInstalled() == 1: + + command = "sudo cat " + confPath + + data = subprocess.check_output(shlex.split(command)).splitlines() + + for items in data: + if items.find('report_safe ') > -1: + if items.find('0') > -1: + report_safe = 0 + continue + else: + report_safe = 1 + if items.find('rewrite_header ') > -1: + tempData = items.split(' ') + rewrite_header = tempData[1] + " " + tempData[2].strip('\n') + continue + if items.find('required_score ') > -1: + required_score = items.split(' ')[1].strip('\n') + continue + if items.find('required_hits ') > -1: + required_hits = items.split(' ')[1].strip('\n') + continue + + final_dic = {'fetchStatus': 1, + 'installed': 1, + 'report_safe': report_safe, + 'rewrite_header': rewrite_header, + 'required_score': required_score, + 'required_hits': required_hits, + } + + else: + final_dic = {'fetchStatus': 1, + 'installed': 0} + + + + final_json = json.dumps(final_dic) + return HttpResponse(final_json) + + + except BaseException,msg: + final_dic = {'fetchStatus': 0, 'error_message': str(msg)} + final_json = json.dumps(final_dic) + + return HttpResponse(final_json) + + + return render(request,'managePHP/editPHPConfig.html') + except KeyError: + return redirect(loadLoginPage) + +def saveSpamAssassinConfigurations(request): + try: + val = request.session['userID'] + try: + if request.method == 'POST': + + data = json.loads(request.body) + + report_safe = data['report_safe'] + required_hits = data['required_hits'] + rewrite_header = data['rewrite_header'] + required_score = data['required_score'] + + if report_safe == True: + report_safe = "report_safe 1" + else: + report_safe = "report_safe 0" + + print report_safe + + required_hits = "required_hits " + required_hits + rewrite_header = "rewrite_header " + rewrite_header + required_score = "required_score " + required_score + + + ## writing data temporary to file + + + tempConfigPath = "/home/cyberpanel/" + str(randint(1000, 9999)) + + confPath = open(tempConfigPath, "w") + + confPath.writelines(report_safe + "\n") + confPath.writelines(required_hits + "\n") + confPath.writelines(rewrite_header + "\n") + confPath.writelines(required_score + "\n") + + confPath.close() + + ## save configuration data + + execPath = "sudo python " + virtualHostUtilities.cyberPanel + "/plogical/mailUtilities.py" + + execPath = execPath + " saveSpamAssassinConfigs --tempConfigPath " + tempConfigPath + + output = subprocess.check_output(shlex.split(execPath)) + + if output.find("1,None") > -1: + data_ret = {'saveStatus': 1, 'error_message': "None"} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + else: + data_ret = {'saveStatus': 0, 'error_message': output} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + + except BaseException,msg: + data_ret = {'saveStatus': 0, 'error_message': str(msg)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + except KeyError,msg: + logging.CyberCPLogFileWriter.writeToFile(str(msg)) + data_ret = {'saveStatus': 0, 'error_message': str(msg)} + json_data = json.dumps(data_ret) return HttpResponse(json_data) \ No newline at end of file diff --git a/firewall/urls.py b/firewall/urls.py index aede4bf14..d580b7632 100644 --- a/firewall/urls.py +++ b/firewall/urls.py @@ -40,10 +40,5 @@ urlpatterns = [ url(r'^enableDisableRuleFile', views.enableDisableRuleFile, name='enableDisableRuleFile'), - ## SpamAssassin - - url(r'^spamAssassin', views.spamAssassin, name='spamAssassin'), - - ] \ No newline at end of file diff --git a/firewall/views.py b/firewall/views.py index be753b042..a963954b7 100644 --- a/firewall/views.py +++ b/firewall/views.py @@ -37,20 +37,6 @@ def firewallHome(request): except KeyError: return redirect(loadLoginPage) -def spamAssassin(request): - try: - userID = request.session['userID'] - - admin = Administrator.objects.get(pk=userID) - - if admin.type == 3: - return HttpResponse("You don't have enough priviliges to access this page.") - - return render(request,'firewall/spamassassin.html') - except KeyError: - return redirect(loadLoginPage) - - def getCurrentRules(request): try: diff --git a/plogical/mailUtilities.py b/plogical/mailUtilities.py index 5ebb6d40b..71061b458 100644 --- a/plogical/mailUtilities.py +++ b/plogical/mailUtilities.py @@ -17,6 +17,7 @@ from websiteFunctions.models import Websites class mailUtilities: installLogPath = "/home/cyberpanel/openDKIMInstallLog" + spamassassinInstallLogPath = "/home/cyberpanel/spamassassinInstallLogPath" cyberPanelHome = "/home/cyberpanel" @staticmethod @@ -366,6 +367,159 @@ milter_default_action = accept except BaseException,msg: logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [restartServices]") + @staticmethod + def installSpamAssassin(install, SpamAssassin): + try: + + mailUtilities.checkHome() + + command = 'sudo yum install spamassassin -y' + + cmd = shlex.split(command) + + with open(mailUtilities.spamassassinInstallLogPath, 'w') as f: + res = subprocess.call(cmd, stdout=f) + + if res == 1: + writeToFile = open(mailUtilities.spamassassinInstallLogPath, 'a') + writeToFile.writelines("Can not be installed.[404]\n") + writeToFile.close() + logging.CyberCPLogFileWriter.writeToFile("[Could not Install SpamAssassin.]") + return 0 + else: + writeToFile = open(mailUtilities.spamassassinInstallLogPath, 'a') + writeToFile.writelines("SpamAssassin Installed.[200]\n") + writeToFile.close() + + return 1 + except BaseException, msg: + writeToFile = open(mailUtilities.spamassassinInstallLogPath, 'a') + writeToFile.writelines("Can not be installed.[404]\n") + writeToFile.close() + logging.CyberCPLogFileWriter.writeToFile(str(msg) + "[installSpamAssassin]") + + @staticmethod + def checkIfSpamAssassinInstalled(): + try: + + path = "/etc/mail/spamassassin/local.cf" + + command = "sudo cat " + path + res = subprocess.call(shlex.split(command)) + + if res == 1: + return 0 + else: + return 1 + + except BaseException, msg: + logging.CyberCPLogFileWriter.writeToFile( + str(msg) + " [checkIfSpamAssassinInstalled]") + return 0 + + @staticmethod + def configureSpamAssassin(): + try: + + command = "groupadd spamd" + subprocess.call(shlex.split(command)) + + command = "useradd -g spamd -s /bin/false -d /var/log/spamassassin spamd" + subprocess.call(shlex.split(command)) + + ## + + command = "chown spamd:spamd /var/log/spamassassin" + subprocess.call(shlex.split(command)) + + command = "systemctl enable spamassassin" + subprocess.call(shlex.split(command)) + + command = "systemctl start spamassassin" + subprocess.call(shlex.split(command)) + + ## Configuration to postfix + + postfixConf = '/etc/postfix/master.cf' + data = open(postfixConf, 'r').readlines() + + writeToFile = open(postfixConf, 'w') + checker = 1 + + for items in data: + if items.find('smtp') > - 1 and items.find('inet') > - 1 and items.find('smtpd') > - 1 and checker == 1: + writeToFile.writelines(items.strip('\n') + ' -o content_filter=spamassassin\n') + checker = 0 + else: + writeToFile.writelines(items) + + writeToFile.writelines('spamassassin unix - n n - - pipe flags=R user=spamd argv=/usr/bin/spamc -e /usr/sbin/sendmail -oi -f ${sender} ${recipient}') + writeToFile.close() + + command = 'systemctl restart postfix' + subprocess.call(shlex.split(command)) + + + print "1,None" + return + + + except OSError, msg: + logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [configureSpamAssassin]") + print "0," + str(msg) + return + except BaseException, msg: + logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [configureSpamAssassin]") + print "0," + str(msg) + return + + @staticmethod + def saveSpamAssassinConfigs(tempConfigPath): + try: + + data = open(tempConfigPath).readlines() + os.remove(tempConfigPath) + + confFile = "/etc/mail/spamassassin/local.cf" + confData = open(confFile).readlines() + + conf = open(confFile, 'w') + + rsCheck = 0 + + for items in confData: + + if items.find('report_safe ') > -1: + conf.writelines(data[0]) + continue + elif items.find('required_hits ') > -1: + conf.writelines(data[1]) + continue + elif items.find('rewrite_header ') > -1: + conf.writelines(data[2]) + continue + elif items.find('required_score ') > -1: + conf.writelines(data[3]) + rsCheck = 1 + continue + + if rsCheck == 0: + conf.writelines(data[3]) + + + conf.close() + + command = 'systemctl restart spamassassin' + subprocess.call(shlex.split(command)) + + print "1,None" + return + + except BaseException, msg: + logging.CyberCPLogFileWriter.writeToFile( + str(msg) + " [saveSpamAssassinConfigs]") + print "0," + str(msg) + def main(): @@ -374,6 +528,7 @@ def main(): parser.add_argument('--domain', help='Domain name!') parser.add_argument('--userName', help='Email Username!') parser.add_argument('--password', help='Email password!') + parser.add_argument('--tempConfigPath', help='Temporary Configuration Path!') @@ -385,6 +540,10 @@ def main(): mailUtilities.generateKeys(args.domain) elif args.function == "configureOpenDKIM": mailUtilities.configureOpenDKIM() + elif args.function == "configureSpamAssassin": + mailUtilities.configureSpamAssassin() + elif args.function == "saveSpamAssassinConfigs": + mailUtilities.saveSpamAssassinConfigs(args.tempConfigPath) if __name__ == "__main__": main() \ No newline at end of file diff --git a/postfixSenderPolicy/accept_traffic.py b/postfixSenderPolicy/accept_traffic.py index e77ed7d80..9f164ff94 100755 --- a/postfixSenderPolicy/accept_traffic.py +++ b/postfixSenderPolicy/accept_traffic.py @@ -81,7 +81,7 @@ class HandleRequest(multi.Thread): #logging.writeToFile('Email Monthly Used: ' + str(emailObj.monthlyUsed)) if domainObj.limitStatus == 1 and emailObj.limitStatus == 1: - if emailObj.monthlyLimits < emailObj.monthlyUsed or emailObj.hourlyLimits < emailObj.hourlyUsed: + if emailObj.monthlyLimits <= emailObj.monthlyUsed or emailObj.hourlyLimits <= emailObj.hourlyUsed: logging.writeToFile(emailAddress + ' either exceeded monthly or hourly sending limit.') self.connection.sendall('action=defer_if_permit Service temporarily unavailable\n\n') else: