def process_mail_creation(self, store, data):
        receiver_id = data['receiver']['id']

        # Do not spool emails if the receiver has opted out of ntfns for this tip.
        if not data['tip']['enable_notifications']:
          log.debug("Discarding emails for %s due to receiver's preference." % receiver_id)
          return

        # https://github.com/globaleaks/GlobaLeaks/issues/798
        # TODO: the current solution is global and configurable only by the admin
        sent_emails = GLSettings.get_mail_counter(receiver_id)
        if sent_emails >= GLSettings.memory_copy.notification_threshold_per_hour:
            log.debug("Discarding emails for receiver %s due to threshold already exceeded for the current hour" %
                      receiver_id)
            return

        GLSettings.increment_mail_counter(receiver_id)
        if sent_emails >= GLSettings.memory_copy.notification_threshold_per_hour:
            log.info("Reached threshold of %d emails with limit of %d for receiver %s" % (
                     sent_emails,
                     GLSettings.memory_copy.notification_threshold_per_hour,
                     receiver_id)
            )

            # simply changing the type of the notification causes
            # to send the notification_limit_reached
            data['type'] = u'receiver_notification_limit_reached'

        data['notification'] = db_get_notification(store, data['receiver']['language'])
        data['node'] = db_admin_serialize_node(store, data['receiver']['language'])

        if not data['node']['allow_unencrypted'] and data['receiver']['pgp_key_status'] != u'enabled':
            return

        subject, body = Templating().get_mail_subject_and_body(data)

        # If the receiver has encryption enabled encrypt the mail body
        if data['receiver']['pgp_key_status'] == u'enabled':
            gpob = GLBPGP()

            try:
                gpob.load_key(data['receiver']['pgp_key_public'])
                body = gpob.encrypt_message(data['receiver']['pgp_key_fingerprint'], body)
            except Exception as excep:
                log.err("Error in PGP interface object (for %s: %s)! (notification+encryption)" %
                        (data['receiver']['username'], str(excep)))

                return
            finally:
                # the finally statement is always called also if
                # except contains a return or a raise
                gpob.destroy_environment()

        mail = models.Mail({
            'address': data['receiver']['mail_address'],
            'subject': subject,
            'body': body
        })

        store.add(mail)
    def process_mail_creation(self, store, data):
        # https://github.com/globaleaks/GlobaLeaks/issues/798
        # TODO: the current solution is global and configurable only by the admin
        receiver_id = data['receiver']['id']
        sent_emails = GLSettings.get_mail_counter(receiver_id)
        if sent_emails >= GLSettings.memory_copy.notification_threshold_per_hour:
            log.debug(
                "Discarding emails for receiver %s due to threshold already exceeded for the current hour"
                % receiver_id)
            return

        GLSettings.increment_mail_counter(receiver_id)
        if sent_emails >= GLSettings.memory_copy.notification_threshold_per_hour:
            log.info(
                "Reached threshold of %d emails with limit of %d for receiver %s"
                % (sent_emails,
                   GLSettings.memory_copy.notification_threshold_per_hour,
                   receiver_id))

            # simply changing the type of the notification causes
            # to send the notification_limit_reached
            data['type'] = u'receiver_notification_limit_reached'

        data['notification'] = db_get_notification(
            store, data['receiver']['language'])
        data['node'] = db_admin_serialize_node(store,
                                               data['receiver']['language'])

        if not data['node']['allow_unencrypted'] and data['receiver'][
                'pgp_key_status'] != u'enabled':
            return

        subject, body = Templating().get_mail_subject_and_body(data)

        # If the receiver has encryption enabled encrypt the mail body
        if data['receiver']['pgp_key_status'] == u'enabled':
            gpob = GLBPGP()

            try:
                gpob.load_key(data['receiver']['pgp_key_public'])
                body = gpob.encrypt_message(
                    data['receiver']['pgp_key_fingerprint'], body)
            except Exception as excep:
                log.err(
                    "Error in PGP interface object (for %s: %s)! (notification+encryption)"
                    % (data['receiver']['username'], str(excep)))

                return
            finally:
                # the finally statement is always called also if
                # except contains a return or a raise
                gpob.destroy_environment()

        mail = models.Mail({
            'address': data['receiver']['mail_address'],
            'subject': subject,
            'body': body
        })

        store.add(mail)
    def process_mail_creation(self, store, data):
        receiver_id = data['receiver']['id']

        # Do not spool emails if the receiver has opted out of ntfns for this tip.
        if not data['tip']['enable_notifications']:
            log.debug("Discarding emails for %s due to receiver's preference.", receiver_id)
            return

        # https://github.com/globaleaks/GlobaLeaks/issues/798
        # TODO: the current solution is global and configurable only by the admin
        sent_emails = GLSettings.get_mail_counter(receiver_id)
        if sent_emails >= GLSettings.memory_copy.notif.notification_threshold_per_hour:
            log.debug("Discarding emails for receiver %s due to threshold already exceeded for the current hour",
                      receiver_id)
            return

        GLSettings.increment_mail_counter(receiver_id)
        if sent_emails >= GLSettings.memory_copy.notif.notification_threshold_per_hour:
            log.info("Reached threshold of %d emails with limit of %d for receiver %s",
                     sent_emails,
                     GLSettings.memory_copy.notif.notification_threshold_per_hour,
                     receiver_id)

            # simply changing the type of the notification causes
            # to send the notification_limit_reached
            data['type'] = u'receiver_notification_limit_reached'

        data['notification'] = self.serialize_config(store, 'notification', data['receiver']['language'])
        data['node'] = self.serialize_config(store, 'node', data['receiver']['language'])

        if not data['node']['allow_unencrypted'] and len(data['receiver']['pgp_key_public']) == 0:
            return

        subject, body = Templating().get_mail_subject_and_body(data)

        # If the receiver has encryption enabled encrypt the mail body
        if data['receiver']['pgp_key_public']:
            body = encrypt_message(data['receiver']['pgp_key_public'], body)

        store.add(models.Mail({
            'address': data['receiver']['mail_address'],
            'subject': subject,
            'body': body
        }))
Example #4
0
def filter_notification_event(notifque):
    """
    :param notifque: the current notification event queue
    :return: a modified queue in the case some email has not to be sent
    Basically performs two filtering; they are defined in:
     1) issue #444
     2) issue #798
    """

    # Here we collect the Storm event of Files having as key the Tip
    files_event_by_tip = {}

    _tmp_list = []
    return_filtered_list = []
    # to be smoked Storm.id
    orm_id_to_be_skipped = []

    for ne in notifque:
        if ne['trigger'] !=  u'Tip':
            continue
        files_event_by_tip.update({ne['tip_info']['id'] : []})

    log.debug("Filtering function: iterating over %d Tip" % len(files_event_by_tip.keys()))
    # not files_event_by_tip contains N keys with an empty list,
    # I'm looping two times because dict has random ordering
    for ne in notifque:

        if GLSettings.memory_copy.disable_receiver_notification_emails:
            orm_id_to_be_skipped.append(ne['orm_id'])
            continue

        if ne['trigger'] != u'File':
            _tmp_list.append(ne)
            continue

        if ne['tip_info']['id'] in files_event_by_tip:
            orm_id_to_be_skipped.append(ne['orm_id'])
        else:
            _tmp_list.append(ne)

    if len(orm_id_to_be_skipped):
        if GLSettings.memory_copy.disable_receiver_notification_emails:
            log.debug("All the %d mails will be marked as sent because the admin has disabled receivers notifications" %
                      len(orm_id_to_be_skipped))
        else:
            log.debug("Filtering function: Marked %d Files notification to be suppressed cause part of a submission" %
                      len(orm_id_to_be_skipped))

    for ne in _tmp_list:
        receiver_id = ne['receiver_info']['id']

        sent_emails = GLSettings.get_mail_counter(receiver_id)

        if sent_emails >= GLSettings.memory_copy.notification_threshold_per_hour:
            log.debug("Discarding email for receiver %s due to threshold already exceeded for the current hour" %
                      receiver_id)
            orm_id_to_be_skipped.append(ne['orm_id'])
            continue

        GLSettings.increment_mail_counter(receiver_id)

        if sent_emails + 1 >= GLSettings.memory_copy.notification_threshold_per_hour:
            log.info("Reached threshold of %d emails with limit of %d for receiver %s" % (
                sent_emails,
                GLSettings.memory_copy.notification_threshold_per_hour,
                receiver_id)
            )

            # Append
            anomalyevent = OD()
            anomalyevent.type = u'receiver_notification_limit_reached'
            anomalyevent.notification_settings = ne.notification_settings
            anomalyevent.node_info = ne.node_info
            anomalyevent.context_info = None
            anomalyevent.receiver_info = ne.receiver_info
            anomalyevent.tip_info = None
            anomalyevent.subevent_info = None
            anomalyevent.orm_id = '0'

            return_filtered_list.append(anomalyevent)

            orm_id_to_be_skipped.append(ne['orm_id'])
            continue

        return_filtered_list.append(ne)

    log.debug("Mails filtering completed passing from #%d to #%d events" %
              (len(notifque), len(return_filtered_list)))

    # return the new list of event and the list of Storm.id
    return return_filtered_list, orm_id_to_be_skipped