From d28094cc792f25932e359ca08ba134f30fbaa595 Mon Sep 17 00:00:00 2001
From: Tanner Prestegard <tanner.prestegard@ligo.org>
Date: Tue, 22 Nov 2016 14:14:16 -0600
Subject: [PATCH] Implementing internal user check for twilio phone calls,
 adding new function for making calls

---
 gracedb/alert.py | 140 +++++++++++++++++++++++++++--------------------
 1 file changed, 81 insertions(+), 59 deletions(-)

diff --git a/gracedb/alert.py b/gracedb/alert.py
index 846a248aa..101f0f0a9 100644
--- a/gracedb/alert.py
+++ b/gracedb/alert.py
@@ -4,6 +4,7 @@ from subprocess import Popen, PIPE, STDOUT
 
 from django.core.mail import EmailMessage
 from django.conf import settings
+from django.contrib.auth.models import Group
 
 import json
 
@@ -31,6 +32,79 @@ def get_twilio_from():
         return from_.phone_number
     raise RuntimeError('Could not determine "from" Twilio phone number')
 
+def make_twilio_calls(event, twilio_recips, alert_type, **kwargs):
+    """
+    USAGE:
+    ------
+        New event created:
+            make_twilio_calls(event, twilio_recips, "create")
+        New label applied to event (Label is a GraceDB model):
+            make_twilio_calls(event, twilio_recips, "label", label=Label)
+
+    Note: twilio_recips is a list of users - we need phone numbers
+          and group memberships for permission checks.
+    """
+    
+    if (alert_type == "create"):
+        # twiml_base_url is the URL of a TwiML Bin
+        # (https://support.twilio.com/hc/en-us/articles/230878368)
+        # with the following content:
+        #
+        #     <?xml version="1.0" encoding="UTF-8"?>
+        #     <Response>
+        #     <Say>
+        #     A {{pipeline}} event with Grace DB ID {{graceid}} was created.
+        #     </Say>
+        #     <Sms>
+        #     A {{pipeline}} event with GraceDB ID {{graceid}} was created.
+        #     https://gracedb-test.ligo.org/events/view/{{graceid}}
+        #     </Sms>
+        #     </Response>
+        twiml_base_url = 'https://handler.twilio.com/twiml/' + settings.TWILIO_CREATE_KEY
+        twiml_url = '{0}?pipeline={1}&graceid={2}'.format(
+            twiml_base_url, event.pipeline.name, event.graceid())
+    elif (alert_type == "label"):
+        # twiml_base_url is the URL of a TwiML Bin
+        # (https://support.twilio.com/hc/en-us/articles/230878368)
+        # with the following content:
+        #
+        #     <?xml version="1.0" encoding="UTF-8"?>
+        #     <Response>
+        #     <Say>
+        #     A {{pipeline}} event with Grace DB ID {{graceid}} was labelled with {{label_lower}}.
+        #     </Say>
+        #     <Sms>
+        #     A {{pipeline}} event with GraceDB ID {{graceid}} was labelled with {{label}}
+        #     https://gracedb-test.ligo.org/events/view/{{graceid}}
+        #     </Sms>
+        #     </Response>
+        twiml_base_url = 'https://handler.twilio.com/twiml/' + settings.TWILIO_LABEL_KEY
+        label = kwargs['label']
+        twiml_url = '{0}?pipeline={1}&graceid={2}&label={3}&label_lower={4}'.format(
+            twiml_base_url, event.pipeline.name, event.graceid(), label.name, label.name.lower())
+    else:
+        log.exception('Failed to process alert_type in make_twilio_calls')
+
+    # Get "from" phone number.
+    from_ = get_twilio_from()
+    
+    # Get LVC user group for checks made below.
+    lvc_group = Group.objects.get(name=settings.LVC_GROUP)
+    
+    # Loop over recipients and make calls.
+    for recip in twilio_recips:
+        try:
+            # Only make calls to LVC members. Non-LVC members shouldn't
+            # even be able to sign up with a phone number, but this is another
+            # safety measure.
+            if lvc_group in recip.user.groups.all():
+                log.info('calling %s', recip.user.username)
+                twilio_client.calls.create(recip.phone, from_, twiml_url, method='GET')
+            else:
+                log.info('user %s is not an LVC member, call not made' % recip.user.username)
+        except:
+            log.exception('Failed to create call')
+
 def issueAlert(event, location, event_url, serialized_object=None):
     issueXMPPAlert(event, location, serialized_object=serialized_object)
     issueEmailAlert(event, event_url)
@@ -87,7 +161,7 @@ def issueAlertForLabel(event, label, doxmpp, serialized_event=None, event_url=No
             if recip.email:
                 profileRecips.append(recip.email)
             if recip.phone:
-                phoneRecips.append(recip.phone)
+                phoneRecips.append(recip)
 
     if event.search:
         subject = "[gracedb] %s / %s / %s / %s" % (label.name, event.pipeline.name, event.search.name, event.graceid())
@@ -115,35 +189,8 @@ def issueAlertForLabel(event, label, doxmpp, serialized_event=None, event_url=No
         email = EmailMessage(subject, message, fromaddress, toaddresses, bccaddresses)
         email.send()
 
-    # twiml_base_url is the URL of a TwiML Bin
-    # (https://support.twilio.com/hc/en-us/articles/230878368)
-    # with the following content:
-    #
-    #     <?xml version="1.0" encoding="UTF-8"?>
-    #     <Response>
-    #     <Say>
-    #     A {{pipeline}} event with Grace DB ID {{graceid}} was labelled with {{label_lower}}.
-    #     </Say>
-    #     <Sms>
-    #     A {{pipeline}} event with GraceDB ID {{graceid}} was labelled with {{label}}
-    #     https://gracedb-test.ligo.org/events/view/{{graceid}}
-    #     </Sms>
-    #     </Response>
-    twiml_base_url = 'https://handler.twilio.com/twiml/EH7a2cef360c90eec301c3bf325ce1790a'
-
-    twiml_url = '{0}?pipeline={1}&graceid={2}&label={3}&label_lower={4}'.format(
-        twiml_base_url, event.pipeline.name, event.graceid(), label.name, label.name.lower())
-    log.info('phoneRecips: %s' % phoneRecips)
-    from_ = get_twilio_from()
-    log.info('from_: %s' % from_)
-    for recip in phoneRecips:
-        log.info('in for loop')
-        try:
-            log.info('issueAlertForLabel: calling %s', recip)
-            twilio_client.calls.create(recip, from_, twiml_url, method='GET')
-        except:
-            log.exception('Failed to create call')
-
+    # Make phone calls.
+    make_twilio_calls(event, phoneRecips, "label", label=label)
 
 def issueEmailAlert(event, event_url):
 
@@ -177,13 +224,13 @@ def issueEmailAlert(event, event_url):
                    if recip.email:
                        bccaddresses.append(recip.email)
                    if recip.phone:
-                       twilio_recips.append(recip.phone)
+                       twilio_recips.append(recip)
                else:
                    if event.far and event.far < trigger.farThresh:
                        if recip.email:
                            bccaddresses.append(recip.email)
                        if recip.phone:
-                           twilio_recips.append(recip.phone)
+                           twilio_recips.append(recip)
     subject = "[gracedb] %s event. ID: %s" % (event.pipeline.name, event.graceid())
     message = """
 New Event
@@ -207,33 +254,8 @@ Event Summary:
     email = EmailMessage(subject, message, fromaddress, toaddresses, bccaddresses)
     email.send()
 
-    #send_mail(subject, message, fromaddress, toaddresses)
-
-    # twiml_base_url is the URL of a TwiML Bin
-    # (https://support.twilio.com/hc/en-us/articles/230878368)
-    # with the following content:
-    #
-    #     <?xml version="1.0" encoding="UTF-8"?>
-    #     <Response>
-    #     <Say>
-    #     A {{pipeline}} event with Grace DB ID {{graceid}} was created.
-    #     </Say>
-    #     <Sms>
-    #     A {{pipeline}} event with GraceDB ID {{graceid}} was created.
-    #     https://gracedb-test.ligo.org/events/view/{{graceid}}
-    #     </Sms>
-    #     </Response>
-    twiml_base_url = 'https://handler.twilio.com/twiml/EHe8ac043be47528c50558954791fb11fe'
-
-    twiml_url = '{0}?pipeline={1}&graceid={2}'.format(
-        twiml_base_url, event.pipeline.name, event.graceid())
-    from_ = get_twilio_from()
-    for recip in twilio_recips:
-        try:
-            log.info('issueEmailAlert: calling %s', recip)
-            twilio_client.calls.create(recip, from_, twiml_url, method='GET')
-        except:
-            log.exception('Failed to create call')
+    # Make phone calls.
+    make_twilio_calls(event, twilio_recips, "create")
 
 def issueXMPPAlert(event, location, alert_type="new", description="", serialized_object=None):
     
-- 
GitLab