Commit 556bd33f authored by Roland Denis's avatar Roland Denis
Browse files

Send mail if job offer form is flooded

Mail is sent only when flood is detected, but not for following
submission failures.
parent 694beb7d
Pipeline #4484 passed with stages
in 55 seconds
...@@ -116,6 +116,12 @@ FLOOD_GLOBAL_LIMIT = 10 ...@@ -116,6 +116,12 @@ FLOOD_GLOBAL_LIMIT = 10
FLOOD_LOCAL_TIMEOUT = datetime.timedelta(minutes=5) FLOOD_LOCAL_TIMEOUT = datetime.timedelta(minutes=5)
FLOOD_LOCAL_LIMIT = 3 FLOOD_LOCAL_LIMIT = 3
# Mail config in case of flood
MAIL_SMTP_SERVER = "172.116.101.1"
MAIL_SENDER = "calcul-owner@math.cnrs.fr"
MAIL_RECEIVERS = ["denis@math.univ-lyon1.fr"]
############################################################################### ###############################################################################
class Debug(object): class Debug(object):
""" Debugging parameters. """ """ Debugging parameters. """
...@@ -235,12 +241,8 @@ class FloodChecker(): ...@@ -235,12 +241,8 @@ class FloodChecker():
""" Remove previously created submission file """ """ Remove previously created submission file """
os.remove(os.path.join(FLOOD_PATH, self.file_name)) os.remove(os.path.join(FLOOD_PATH, self.file_name))
def approve_submission(self, client_id): def _read_and_calc_delays(self, client_id):
""" Check if a new submission can be accepted. Return bool and waiting delay. """ """ Read submission files and return new submission delays for the given client """
# First, create a submission file even if it will be deleted if submission is rejected
# It avoids flooding at the exact same time.
self._create_submission_file(client_id)
self._read_files() self._read_files()
# Calculate submission delays # Calculate submission delays
...@@ -248,25 +250,51 @@ class FloodChecker(): ...@@ -248,25 +250,51 @@ class FloodChecker():
local_delay = self._local_submission_delay(client_id) local_delay = self._local_submission_delay(client_id)
delay = max(global_delay, local_delay) delay = max(global_delay, local_delay)
if delay.total_seconds() == 0: # No delay => OK return global_delay, local_delay, delay
return True, delay
def _create_flood_report(self, client_id, global_delay, local_delay):
else: # Otherwise => KO and submission file is removed """ Return message that describe current flooding state for the given client """
flood_details = "[FLOOD] client_id={} client_hash={} global_stats={} global_delay={} local_stats={} local_delay={}".format( return "[FLOOD] client_id={} client_hash={} global_stats={} global_delay={} local_stats={} local_delay={}".format(
pprint.pformat(client_id), pprint.pformat(client_id),
pprint.pformat(self._client_id_hexdigest(client_id)), pprint.pformat(self._client_id_hexdigest(client_id)),
pprint.pformat(self.global_stats), pprint.pformat(self.global_stats),
pprint.pformat(global_delay), pprint.pformat(global_delay),
pprint.pformat(self.local_stats), pprint.pformat(self.local_stats),
pprint.pformat(local_delay), pprint.pformat(local_delay),
) )
print(flood_details, file=sys.stderr)
#TODO: mail def approve_submission(self, client_id):
""" Check if a new submission can be accepted. Return bool and waiting delay. """
# First, check current flooding state so that to avoid spamming mail
# if it has already been reported.
global_delay, local_delay, delay = self._read_and_calc_delays(client_id)
# If flooding was already reported, send new report only to webserver log
if delay.total_seconds() > 0:
flood_report = self._create_flood_report(client_id, global_delay, local_delay)
print(flood_report, file=sys.stderr)
return False, delay
# Then, create a submission file and recheck flood state.
# It avoids flooding at the exact same time.
self._create_submission_file(client_id)
global_delay, local_delay, delay = self._read_and_calc_delays(client_id)
# If new flood is detected, send report to webserver log *and* send a mail.
if delay.total_seconds() > 0:
flood_report = self._create_flood_report(client_id, global_delay, local_delay)
print(flood_report, file=sys.stderr)
self._remove_submission_file() # Send report by mail
import smtplib
with smtplib.SMTP(MAIL_SMTP_SERVER) as smtp:
smtp.sendmail(MAIL_SENDER, MAIL_RECEIVERS, "Subject: Flooding du formulaire d'offre d'emploi\n\n" + flood_report)
return False, delay return False, delay
# No delay => OK
return True, delay
############################################################################### ###############################################################################
class FormData(object): class FormData(object):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment