Esempio n. 1
0
def lambda_handler(event, context):
    """
    This is the main entry point for performing an action. The action evaluator puts
    an action message on the actions queue and here's where they're popped
    off and dealt with.
    """
    records_table = dynamodb.Table(DYNAMODB_TABLE)

    lambda_init_once()
    for sqs_record in event["Records"]:
        # TODO research max # sqs records / lambda_handler invocation
        action_message = ActionMessage.from_aws_json(sqs_record["body"])

        logger.info("Performing action: action_message = %s", action_message)

        if action_performer := ActionPerformer.get(
                action_message.action_label.value):
            action_performer.perform_action(action_message)
            ActionEvent(
                content_id=action_message.content_key,
                performed_at=datetime.datetime.now(),
                action_label=action_message.action_label.value,
                # v0 Hacks: the label rules model is super mutable we store basically the whole state
                # for each action performed. (~gross but until we have a unique id and version
                # it's what we've got).
                # Right now this just make json blob for action_performer and a list of
                # json blobs for action_rules that we can store and recover if needed.
                action_performer=action_performer.to_aws_json(),
                action_rules=[
                    rule.to_aws_json() for rule in action_message.action_rules
                ],
            ).write_to_table(records_table)
Esempio n. 2
0
 def perform_action(self, message: ActionMessage) -> None:
     parsed_url = self.url
     for (
             replacement_str,
             replacement_func,
     ) in WEBHOOK_ACTION_PERFORMER_REPLACEMENTS.items():
         parsed_url = parsed_url.replace(replacement_str,
                                         replacement_func(message))
     self.call(parsed_url, data=json.dumps(message.to_aws()))
    def test_action_message_serialization_and_deserialization(self):
        enqueue_mini_castle_for_review_action_label = ActionLabel(
            "EnqueueMiniCastleForReview")

        action_rules = [
            ActionRule(
                name="Enqueue Mini-Castle for Review",
                action_label=enqueue_mini_castle_for_review_action_label,
                must_have_labels=set([
                    BankIDClassificationLabel("303636684709969"),
                    ClassificationLabel("true_positive"),
                ]),
                must_not_have_labels=set(
                    [BankedContentIDClassificationLabel("3364504410306721")]),
            ),
        ]

        banked_signal = BankedSignal(
            banked_content_id="4169895076385542",
            bank_id="303636684709969",
            bank_source="te",
        )
        banked_signal.add_classification("true_positive")

        action_message = ActionMessage(
            content_key="images/mini-castle.jpg",
            content_hash=
            "361da9e6cf1b72f5cea0344e5bb6e70939f4c70328ace762529cac704297354a",
            matching_banked_signals=[banked_signal],
            action_label=enqueue_mini_castle_for_review_action_label,
            action_rules=action_rules,
        )

        action_message_aws_json = action_message.to_aws_json()

        action_message_2 = ActionMessage.from_aws_json(action_message_aws_json)

        self.assertEqual(action_message_2.action_label,
                         enqueue_mini_castle_for_review_action_label)
Esempio n. 4
0
def lambda_handler(event, context):
    """
    This lambda is called when one or more matches are found. If a single hash matches
    multiple datasets, this will be called only once.

    Action labels are generated for each match message, then an action is performed
    corresponding to each action label.
    """
    config = ActionEvaluatorConfig.get()

    for sqs_record in event["Records"]:
        # TODO research max # sqs records / lambda_handler invocation
        sqs_record_body = json.loads(sqs_record["body"])
        logger.info("sqs record body %s", sqs_record["body"])
        match_message = MatchMessage.from_aws_json(sqs_record_body["Message"])

        logger.info("Evaluating match_message: %s", match_message)

        action_rules = get_action_rules()

        logger.info("Evaluating against action_rules: %s", action_rules)

        submitted_content = ContentObject.get_from_content_id(
            config.dynamo_db_table, match_message.content_key)

        action_label_to_action_rules = get_actions_to_take(
            match_message,
            action_rules,
            submitted_content.additional_fields,
        )
        action_labels = list(action_label_to_action_rules.keys())
        for action_label in action_labels:
            action_message = ActionMessage.from_match_message_action_label_action_rules_and_additional_fields(
                match_message,
                action_label,
                action_label_to_action_rules[action_label],
                list(submitted_content.additional_fields),
            )

            logger.info("Sending Action message: %s", action_message)
            config.sqs_client.send_message(
                QueueUrl=config.actions_queue_url,
                MessageBody=action_message.to_aws_json(),
            )

        writeback_message = WritebackMessage.from_match_message_and_type(
            match_message, WritebackTypes.SawThisToo)
        writeback_message.send_to_queue(config.sqs_client,
                                        config.writeback_queue_url)

    return {"evaluation_completed": "true"}
Esempio n. 5
0
    def get_example_action_event():
        enqueue_mini_castle_for_review_action_label = ActionLabel(
            TestContentModels.TEST_ACTION_LABEL)
        action_rules = [
            ActionRule(
                name="Enqueue Mini-Castle for Review",
                action_label=enqueue_mini_castle_for_review_action_label,
                must_have_labels=set([
                    ClassificationLabel("true_positive"),
                ]),
                must_not_have_labels=set(),
            ),
        ]

        banked_signal = BankedSignal(
            banked_content_id="4169895076385542",
            bank_id="303636684709969",
            bank_source="te",
        )
        banked_signal.add_classification("true_positive")

        action_performer = WebhookPostActionPerformer(
            name="EnqueueForReview",
            url="https://webhook.site/ff7ebc37-514a-439e-9a03-46f86989e195",
            headers='{"Connection":"keep-alive"}',
            # monitoring page:
            # https://webhook.site/#!/ff7ebc37-514a-439e-9a03-46f86989e195
        )

        action_message = ActionMessage(
            content_key=TestContentModels.TEST_CONTENT_ID,
            content_hash=
            "361da9e6cf1b72f5cea0344e5bb6e70939f4c70328ace762529cac704297354a",
            matching_banked_signals=[banked_signal],
            action_label=enqueue_mini_castle_for_review_action_label,
            action_rules=action_rules,
        )

        return ActionEvent(
            content_id=action_message.content_key,
            performed_at=TestContentModels.TEST_TIME,
            action_label=action_message.action_label.value,
            action_performer=action_performer.to_aws_json(),
            action_rules=[
                rule.to_aws_json() for rule in action_message.action_rules
            ],
        )  # .write_to_table(table)