def testSendEmailInvalidRegion(self):
     with self.assertRaises(ValueError) as cm:
         ses_utils.sendEmail(subject="subject",
                             body="body",
                             toAddresses=("*****@*****.**", ),
                             region="region",
                             sender="*****@*****.**")
     self.assertIn(
         "Region 'region' provided does not exist in known SES region "
         "endpoints set.", cm.exception.message)
Example #2
0
def sendWelcomeEmail(toAddress):
  subject = config.get("registration", "subject")
  body = open(resource_filename(htm.it.__name__, os.path.join("../conf",
    config.get("registration", "body")))).read()
  body = body.replace("\n", "\r\n") # Ensure windows newlines

  serverUrl = web.ctx.env['HTTP_HOST']
  templated = dict(apiKey=config.get("security", "apikey"),
                   serverUrl=serverUrl)

  try:
    ses_utils.sendEmail(subject=subject.format(**templated),
                        body=body.format(**templated),
                        toAddresses=[toAddress])
  except BotoServerError:
    raise web.badrequest("Invalid email address.")
    def testSendEmailAwsCredentialsNoMessageID(self, sesConnectionMock):
        subject = "subject"
        body = "body"
        toAddresses = ("*****@*****.**", )
        region = "us-west-2"
        sender = "*****@*****.**"

        connMock = Mock(spec_set=SESConnection)
        sesConnectionMock.return_value = connMock
        connMock.send_email.return_value = {}

        messageID = ses_utils.sendEmail(subject=subject,
                                        body=body,
                                        toAddresses=toAddresses,
                                        region=region,
                                        sender=sender)

        self.assertIsNone(messageID)
        connMock.send_email.assert_called_once_with(source=sender,
                                                    subject=subject,
                                                    body=body,
                                                    to_addresses=toAddresses)
        args = sesConnectionMock.call_args[1]
        self.assertEqual(args["aws_access_key_id"], "a")
        self.assertEqual(args["aws_secret_access_key"], "b")
    def testSendEmailDefaultSenderWithMessageID(self, sesConnectionMock):
        subject = "subject"
        body = "body"
        toAddresses = ("*****@*****.**", )
        region = "us-west-2"
        sender = "*****@*****.**"

        connMock = Mock(spec_set=SESConnection)
        sesConnectionMock.return_value = connMock
        connMock.send_email.return_value = {
            "SendEmailResponse": {
                "SendEmailResult": {
                    "MessageId": "messageID"
                }
            }
        }

        messageID = ses_utils.sendEmail(subject=subject,
                                        body=body,
                                        toAddresses=toAddresses,
                                        region=region,
                                        sender=sender)

        self.assertEqual(messageID, "messageID")
        connMock.send_email.assert_called_once_with(source=sender,
                                                    subject=subject,
                                                    body=body,
                                                    to_addresses=toAddresses)
Example #5
0
def sendWelcomeEmail(toAddress):
    subject = config.get("registration", "subject")
    body = open(
        resource_filename(
            htm.it.__name__,
            os.path.join("../conf", config.get("registration",
                                               "body")))).read()
    body = body.replace("\n", "\r\n")  # Ensure windows newlines

    serverUrl = web.ctx.env['HTTP_HOST']
    templated = dict(apiKey=config.get("security", "apikey"),
                     serverUrl=serverUrl)

    try:
        ses_utils.sendEmail(subject=subject.format(**templated),
                            body=body.format(**templated),
                            toAddresses=[toAddress])
    except BotoServerError:
        raise web.badrequest("Invalid email address.")
    def testSendEmailNoRegionOrSender(self, sesConnectionMock):
        subject = "subject"
        body = "body"
        toAddresses = ("*****@*****.**", )

        connMock = Mock(spec_set=SESConnection)
        sesConnectionMock.return_value = connMock
        connMock.send_email.return_value = {}

        messageID = ses_utils.sendEmail(subject=subject,
                                        body=body,
                                        toAddresses=toAddresses)

        self.assertIsNone(messageID)
        connMock.send_email.assert_called_once_with(source="*****@*****.**",
                                                    subject=subject,
                                                    body=body,
                                                    to_addresses=toAddresses)
        args = sesConnectionMock.call_args[1]
        self.assertEqual(args["aws_access_key_id"], "mockKeyId")
        self.assertEqual(args["aws_secret_access_key"], "mockKey")
    def sendNotificationEmail(self, engine, settingObj, notificationObj):
        """ Send notification email through Amazon SES

        :param engine: SQLAlchemy engine object
        :type engine: sqlalchemy.engine.Engine
        :param settingObj: Device settings
        :type settingObj: NotificationSettings
        :param notificationObj: Notification
        :type notificationObj: Notification

        See conf/notification-body.tpl (or relevant notification body
        configuration value) for template value.  Values are substituted using
        python's `str.format(**data)` function where `data` is a dict
        containing the following keys:

        ============ ===========
        Key          Description
        ============ ===========
        notification Notification instance
        data         MetricData row that triggered notification
        date         Formatted date (%A, %B %d, %Y)
        time         Formatted time (%I:%M %p (%Z))
        unit         Canonical unit for metric value
        ============ ===========
    """

        subject = htm.it.app.config.get("notifications", "subject")

        bodyType = "default"
        with engine.connect() as conn:
            metricObj = repository.getMetric(conn, notificationObj.metric)
        if metricObj.datasource == "custom":
            bodyType = "custom"

        body = open(
            resource_filename(
                htm.it.__name__,
                os.path.join(
                    "../../conf",
                    htm.it.app.config.get("notifications",
                                          "body_" + bodyType)))).read()
        body = body.replace("\n", "\r\n")  # Ensure windows newlines

        # Template variable storage (to be expanded in call to str.format())
        templated = dict(notification=notificationObj)

        # Metric
        templated["metric"] = metricObj

        # Instance
        templated["instance"] = metricObj.tag_name or metricObj.server

        # Date/time
        templated["timestampUTC"] = notificationObj.timestamp.strftime(
            "%A, %B %d, %Y %I:%M %p")
        localtime = localizedTimestamp(notificationObj.timestamp)
        templated["timestampLocal"] = localtime.strftime(
            "%A, %B %d, %Y %I:%M %p")
        templated["timezoneLocal"] = localtime.strftime("%Z")

        # Region
        templated["region"] = _getCurrentRegion()

        self._log.info(
            "NOTIFICATION=%s SERVER=%s METRICID=%s METRIC=%s DEVICE=%s "
            "RECIPIENT=%s Sending email. " %
            (notificationObj.uid, metricObj.server, metricObj.uid,
             metricObj.name, settingObj.uid, settingObj.email_addr))

        try:
            # Send through SES
            messageId = ses_utils.sendEmail(
                subject=subject.format(**templated),
                body=body.format(**templated),
                toAddresses=settingObj.email_addr)

            if messageId is not None:
                # Record AWS SES Message ID
                with engine.connect() as conn:
                    repository.updateNotificationMessageId(
                        conn, notificationObj.uid, messageId)

                    self._log.info(
                        "NOTIFICATION=%s SESMESSAGEID=%s Email sent. " %
                        (notificationObj.uid, messageId))

        except BotoServerError:
            self._log.exception("Unable to send email.")
  def sendNotificationEmail(self, engine, settingObj, notificationObj):
    """ Send notification email through Amazon SES

        :param engine: SQLAlchemy engine object
        :type engine: sqlalchemy.engine.Engine
        :param settingObj: Device settings
        :type settingObj: NotificationSettings
        :param notificationObj: Notification
        :type notificationObj: Notification

        See conf/notification-body.tpl (or relevant notification body
        configuration value) for template value.  Values are substituted using
        python's `str.format(**data)` function where `data` is a dict
        containing the following keys:

        ============ ===========
        Key          Description
        ============ ===========
        notification Notification instance
        data         MetricData row that triggered notification
        date         Formatted date (%A, %B %d, %Y)
        time         Formatted time (%I:%M %p (%Z))
        unit         Canonical unit for metric value
        ============ ===========
    """

    subject = htm.it.app.config.get("notifications", "subject")

    bodyType = "default"
    with engine.connect() as conn:
      metricObj = repository.getMetric(conn, notificationObj.metric)
    if metricObj.datasource == "custom":
      bodyType = "custom"

    body = open(resource_filename(htm.it.__name__, os.path.join("../../conf",
      htm.it.app.config.get("notifications", "body_" + bodyType)))).read()
    body = body.replace("\n", "\r\n") # Ensure windows newlines

    # Template variable storage (to be expanded in call to str.format())
    templated = dict(notification=notificationObj)

    # Metric
    templated["metric"] = metricObj

    # Instance
    templated["instance"] = metricObj.tag_name or metricObj.server

    # Date/time
    templated["timestampUTC"] = notificationObj.timestamp.strftime(
                                  "%A, %B %d, %Y %I:%M %p")
    localtime = localizedTimestamp(notificationObj.timestamp)
    templated["timestampLocal"] = localtime.strftime(
                                    "%A, %B %d, %Y %I:%M %p")
    templated["timezoneLocal"] = localtime.strftime("%Z")

    # Region
    templated["region"] = _getCurrentRegion()


    self._log.info("NOTIFICATION=%s SERVER=%s METRICID=%s METRIC=%s DEVICE=%s "
                   "RECIPIENT=%s Sending email. " % (notificationObj.uid,
                   metricObj.server, metricObj.uid, metricObj.name,
                   settingObj.uid, settingObj.email_addr))

    try:
      # Send through SES
      messageId = ses_utils.sendEmail(subject=subject.format(**templated),
                                      body=body.format(**templated),
                                      toAddresses=settingObj.email_addr)

      if messageId is not None:
        # Record AWS SES Message ID
        with engine.connect() as conn:
          repository.updateNotificationMessageId(conn,
                                                 notificationObj.uid,
                                                 messageId)

          self._log.info("NOTIFICATION=%s SESMESSAGEID=%s Email sent. " % (
                         notificationObj.uid, messageId))


    except BotoServerError:
      self._log.exception("Unable to send email.")