diff --git a/flowspec/helpers.py b/flowspec/helpers.py index 20c90183c59dd732c4e2c83b68df3a42ab4d1e0a..fd250e674915f121f6cc1cdec3206ffac3c62c6c 100644 --- a/flowspec/helpers.py +++ b/flowspec/helpers.py @@ -37,3 +37,32 @@ def get_peer_techc_mails(user, peer): logger.info("helpers::get_peer_techc_mails(): additional_mail="+str(additional_mail)) logger.info("helpers::get_peer_techc_mails(): techmails_list="+str(techmails_list)) return mail + +def helper_list_unique(mylist): + seen = set() + return [x for x in mylist if not (x in seen or seen.add(x))] + +def get_peer_techc_mails__multiple(user, peer_list): + logger.info("helpers::get_peer_techc_mails__mulitple(): user="+str(user)+", peer_list="+str(peer_list)) + mail = [] + additional_mail = [] + techmails_list = [] + user_mail = '%s' % user.email + user_mail = user_mail.split(';') + techmails = [] + for peer in peer_list: + techmails = peer.techc_emails.all() + if techmails: + for techmail in techmails: + techmails_list.append(techmail.email) + if settings.NOTIFY_ADMIN_MAILS: + additional_mail = settings.NOTIFY_ADMIN_MAILS + additional_mail=helper_list_unique(additional_mail) + techmails_list=helper_list_unique(techmails_list) + mail.extend(additional_mail) + mail.extend(techmails_list) + logger.info("helpers::get_peer_techc_mails__multiple(): additional_mail="+str(additional_mail)) + logger.info("helpers::get_peer_techc_mails__multiple(): techmails_list="+str(techmails_list)) + mail=helper_list_unique(mail) + return mail + diff --git a/flowspec/models.py b/flowspec/models.py index e3a1c197ca7c3ee91e5385b1b0b3cf4064d7aa85..e7f96da31285adc2a2317c54e0f1e32cd8bc7a8a 100644 --- a/flowspec/models.py +++ b/flowspec/models.py @@ -24,7 +24,7 @@ from django.contrib.sites.models import Site from django.utils.translation import ugettext_lazy as _ from django.core.urlresolvers import reverse -from flowspec.helpers import send_new_mail, get_peer_techc_mails +from flowspec.helpers import send_new_mail, get_peer_techc_mails, get_peer_techc_mails__multiple from utils import proxy as PR from ipaddr import * import datetime @@ -202,10 +202,8 @@ class Route(models.Model): except Exception: raise ValidationError(_('Invalid network address format at Source Field')) - def commit_add(self, *args, **kwargs): - logger.info("model::commit_add(): route="+str(self)+", kwargs="+str(kwargs)) - status_initial = self.status - logger.info("model::commit_add(): route="+str(self)+", status_initial="+str(status_initial)) + def helper_get_matching_peers(self): + if not settings.MAIL_NOTIFICATION_TO_ALL_MATCHING_PEERS: peers = self.applier.get_profile().peers.all() username = None for peer in peers: @@ -220,8 +218,27 @@ class Route(models.Model): peer = username.peer_tag else: peer = None + return ([username], [peer]) # username is a peer, and peer = username.peer_tag + else: + all_peers = Peer.objects.all() + matched_peers = [] + matched_peer_tags = [] + for peer in all_peers: + for network in peer.networks.all(): + net = IPNetwork(network) + if IPNetwork(self.destination) in net: + matched_peers.append(peer) + matched_peer_tags.append(peer.peer_tag) + return (matched_peers, matched_peer_tags) + + + def commit_add(self, *args, **kwargs): + logger.info("model::commit_add(): route="+str(self)+", kwargs="+str(kwargs)) + status_initial = self.status + logger.info("model::commit_add(): route="+str(self)+", status_initial="+str(status_initial)) + peer2 = self.helper_get_matching_peers() msg1 = "[%s] Adding rule %s. Please wait..." % (self.applier.username, self.name) - send_message(msg1, peer) + send_message_multiple(msg1, peer2[1]) logger.info("model::commit_add(): "+str(msg1)) response = add.delay(self) logger.info('model::commit_add(): Got add job id: %s' % response) @@ -231,13 +248,15 @@ class Route(models.Model): reverse('edit-route', kwargs={'route_slug': self.name}) ) mail_body = render_to_string( + # ../templates/rule_action.txt 'rule_action.txt', { 'route': self, 'address': self.requesters_address, 'action': 'creation', 'url': admin_url, - 'peer': username + 'peer_list': peer2[0], + 'peer_list_length_greater_one': len(peer2[0])>1 } ) user_mail = '%s' % self.applier.email @@ -246,7 +265,7 @@ class Route(models.Model): settings.EMAIL_SUBJECT_PREFIX + 'Rule %s creation request submitted by %s' % (self.name, self.applier.username), mail_body, settings.SERVER_EMAIL, user_mail, - get_peer_techc_mails(self.applier, username) + get_peer_techc_mails__multiple(self.applier, peer2[0]) ) d = { 'clientip': '%s' % self.requesters_address, @@ -255,27 +274,10 @@ class Route(models.Model): logger.info(mail_body, extra=d) def commit_edit(self, *args, **kwargs): - peers = self.applier.get_profile().peers.all() - username = None - for peer in peers: - if username: - break - for network in peer.networks.all(): - net = IPNetwork(network) - if IPNetwork(self.destination) in net: - username = peer - break - if username: - peer = username.peer_tag - else: - peer = None - send_message( - '[%s] Editing rule %s. Please wait...' % - ( - self.applier.username, - self.name - ), peer - ) + peer2 = self.helper_get_matching_peers() + msg1 = "[%s] Editing rule %s. Please wait..." % (self.applier.username, self.name) + send_message_multiple(msg1, peer2[1]) + logger.info("model::commit_edit(): "+str(msg1)) response = edit.delay(self) logger.info('Got edit job id: %s' % response) fqdn = Site.objects.get_current().domain @@ -293,7 +295,8 @@ class Route(models.Model): 'address': self.requesters_address, 'action': 'edit', 'url': admin_url, - 'peer': username + 'peer_list': peer2[0], + 'peer_list_length_greater_one': len(peer2[0])>1 } ) user_mail = '%s' % self.applier.email @@ -301,7 +304,7 @@ class Route(models.Model): send_new_mail( settings.EMAIL_SUBJECT_PREFIX + 'Rule %s edit request submitted by %s' % (self.name, self.applier.username), mail_body, settings.SERVER_EMAIL, user_mail, - get_peer_techc_mails(self.applier, username) + get_peer_techc_mails__multiple(self.applier, peer2[0]) ) d = { 'clientip': self.requesters_address, @@ -312,32 +315,15 @@ class Route(models.Model): def commit_delete(self, *args, **kwargs): logger.info("model::commit_delete(): route="+str(self)+", kwargs="+str(kwargs)) - username = None reason_text = '' reason = '' if "reason" in kwargs: reason = kwargs['reason'] reason_text = 'Reason: %s.' % reason - peers = self.applier.get_profile().peers.all() - for peer in peers: - if username: - break - for network in peer.networks.all(): - net = IPNetwork(network) - if IPNetwork(self.destination) in net: - username = peer - break - if username: - peer = username.peer_tag - else: - peer = None - send_message( - '[%s] Suspending rule %s. %sPlease wait...' % ( - self.applier.username, - self.name, - reason_text - ), peer - ) + peer2 = self.helper_get_matching_peers() + msg1 = "[%s] Suspending rule %s. %sPlease wait..." % (self.applier.username, self.name, reason_text) + send_message_multiple(msg1, peer2[1]) + logger.info("model::commit_delete(): "+str(msg1)) response = delete.delay(self, reason=reason) logger.info('Got delete job id: %s' % response) fqdn = Site.objects.get_current().domain @@ -355,7 +341,8 @@ class Route(models.Model): 'address': self.requesters_address, 'action': 'removal', 'url': admin_url, - 'peer': username + 'peer_list': peer2[0], + 'peer_list_length_greater_one': len(peer2[0])>1 } ) user_mail = '%s' % self.applier.email @@ -365,7 +352,7 @@ class Route(models.Model): mail_body, settings.SERVER_EMAIL, user_mail, - get_peer_techc_mails(self.applier, username) + get_peer_techc_mails__multiple(self.applier, peer2[0]) ) d = { 'clientip': self.requesters_address, @@ -657,3 +644,12 @@ def send_message(msg, user): tube_message = json.dumps({'message': str(msg), 'username': peer}) b.put(tube_message) b.close() + +def send_message_multiple(msg, user_list): + for peer in user_list: + b = beanstalkc.Connection() + b.use(settings.POLLS_TUBE) + tube_message = json.dumps({'message': str(msg), 'username': peer}) + b.put(tube_message) + b.close() + diff --git a/templates/rule_action.txt b/templates/rule_action.txt index e88b2d5dece2e4a3857678e16249e4b24487ca76..a4af8cada8c0b2f0eb9493e00c5039d3c1447fe8 100644 --- a/templates/rule_action.txt +++ b/templates/rule_action.txt @@ -1,6 +1,6 @@ {% load tofqdn %}{% ifequal action 'expires' %}Rule {{route.name}} expires {% ifequal expiration_days 0 %}today{% else%}in {{expiration_days}} day{{ expiration_days|pluralize }}{% endifequal %}{% else %}A new rule {{action}} job has spawned -Peer: {{peer.peer_name}} +{% if peer_list %}{% if peer_list_length_greater_one %}Peers: {% else %}Peer: {% endif %}{% for peer in peer_list%}{{peer.peer_name}} {% endfor %}{% endif %} User {{route.applier.username}} requested the {{action}} of the following rule from address {{address}} {% if address|tofqdn %}({{address|tofqdn}}){% endif %}: Rule name: {{route.name}}{% endifequal %} @@ -23,4 +23,3 @@ Comments: {% if route.comments %}{{route.comments}}{% else %}-{% endif %} Expires: {% ifequal action 'removal' %}Now, removal requested{%else%}{{route.expires}}{% endifequal %} Rule url: {{url}} -