예제 #1
0
파일: main.py 프로젝트: aunger/d43-catalog
def handle(event, context):
    """
    Triggered by adding a file to the cdn.door43.org/temp S3 folder
    :param dict event:
    :param context:
    """
    wipe_temp(ignore_errors=True)
    global logger
    signer = Signer(ENC_PRIV_PEM_PATH, PUB_KEY_PATH)
    handler = SigningHandler(event, context, logger, signer)
    handler.run()
예제 #2
0
    def test_signing_handler_already_signed(self, mock_reporter):
        event = self.create_event()
        mock_s3 = MockS3Handler()
        mock_db = MockDynamodbHandler()
        mock_db._load_db(
            os.path.join(self.resources_dir, 'db/valid_signed.json'))
        mock_logger = MockLogger()
        original_record = mock_db.get_item({'repo_name': 'en_obs'}).copy()
        self.assertFalse(original_record['signed'])

        mock_api = MockAPI(os.path.join(self.resources_dir, 'cdn'),
                           'https://cdn.door43.org')

        signer = SigningHandler(event,
                                None,
                                logger=mock_logger,
                                signer=self.mock_signer,
                                s3_handler=mock_s3,
                                dynamodb_handler=mock_db,
                                url_exists_handler=mock_api.url_exists,
                                download_handler=mock_api.download_file)

        result = signer.run()
        self.assertTrue(result)

        updated_record = mock_db.get_item({'repo_name': 'en_obs'}).copy()
        self.assertTrue(updated_record['signed'])
예제 #3
0
    def test_signing_handler_text_wrong_key(self, mock_reporter):
        event = self.create_event()

        mock_db = MockDynamodbHandler()
        mock_db._load_db(
            os.path.join(self.resources_dir, 'db/valid_unsigned.json'))

        mock_s3 = MockS3Handler()
        mock_s3._load_path(os.path.join(self.resources_dir, 'cdn'))

        mock_api = MockAPI(os.path.join(self.resources_dir, 'cdn'),
                           'https://cdn.door43.org')

        mock_logger = MockLogger()

        # TRICKY: a wrong signing key will result in failed verification
        self.mock_signer._fail_verification()
        signer = SigningHandler(event,
                                None,
                                logger=mock_logger,
                                signer=self.mock_signer,
                                s3_handler=mock_s3,
                                dynamodb_handler=mock_db,
                                url_exists_handler=mock_api.url_exists,
                                download_handler=mock_api.download_file)
        result = signer.run()

        self.assertTrue(result)
        for f in mock_s3._recent_uploads:
            # assert nothing was uploaded to production
            self.assertTrue(f.startswith('temp/'))
            self.assertFalse(f.endswith('.sig'))
        self.assertIn('The signature was not successfully verified.',
                      mock_logger._messages)
예제 #4
0
    def test_signing_handler_s3(self, mock_reporter):
        mock_s3 = MockS3Handler()
        mock_s3._load_path(os.path.join(self.resources_dir, 'cdn'))

        mock_db = MockDynamodbHandler()
        mock_db._load_db(
            os.path.join(self.resources_dir, 'db/valid_unsigned.json'))

        mock_logger = MockLogger()

        mock_api = MockAPI(os.path.join(self.resources_dir, 'cdn'),
                           'https://cdn.door43.org/')

        event = self.create_event()

        original_item = mock_db.get_item({'repo_name': 'en_obs'}).copy()
        self.assertIn('signed', original_item)
        self.assertFalse(original_item['signed'])

        global_headers = HeaderReader([('last-modified',
                                        'Fri, 03 Jun 2017 20:23:12 GMT'),
                                       ('content-length', 12345)])

        signer = SigningHandler(event,
                                None,
                                logger=mock_logger,
                                signer=self.mock_signer,
                                s3_handler=mock_s3,
                                dynamodb_handler=mock_db,
                                url_exists_handler=mock_api.url_exists,
                                download_handler=mock_api.download_file,
                                url_headers_handler=lambda url: global_headers)
        result = signer.run()
        self.assertTrue(result)

        self.assertTrue(len(mock_s3._recent_uploads) > 0)
        has_prod_uploads = False
        for key in mock_s3._recent_uploads:
            # assert prod uploads have signatures
            if not key.startswith('temp/') and not key.endswith('.sig'):
                has_prod_uploads = True
                self.assertIn('{}.sig'.format(key), mock_s3._recent_uploads)
        self.assertTrue(has_prod_uploads)

        updated_item = mock_db.get_item({'repo_name': 'en_obs'}).copy()
        assert_object_not_equals(self, updated_item, original_item)
        assert_object_equals_file(
            self, json.loads(updated_item['package']),
            os.path.join(self.resources_dir,
                         'db/expected_signed_package.json'))

        self.assertIn(
            'Skipping chapter obs:01 missing url https://cdn.door43.org/en/obs/v4/32kbps/en_obs_01_32kbps.mp3',
            mock_logger._messages)
        self.assertTrue(updated_item['signed'])
예제 #5
0
    def test_signing_handler_text_no_records(self, mock_reporter):
        event = self.create_event()
        mock_db = MockDynamodbHandler()
        mock_s3 = MockS3Handler()

        mock_api = MockAPI(os.path.join(self.resources_dir, 'cdn'),
                           'https://cdn.door43.org')

        handler = SigningHandler(event,
                                 None,
                                 logger=MockLogger(),
                                 signer=self.mock_signer,
                                 s3_handler=mock_s3,
                                 dynamodb_handler=mock_db,
                                 url_exists_handler=mock_api.url_exists,
                                 download_handler=mock_api.download_file)
        result = handler.run()
        self.assertFalse(result)
예제 #6
0
    def test_signing_handler_text_missing_file(self, mock_url_headers,
                                               mock_reporter):
        """
        Signing will continue to run even if a file is missing.
        The missing file will just be ignored.
        :return:
        """
        mock_url_headers.return_value = HeaderReader([
            ('last-modified', 'Fri, 03 Jun 2017 20:23:12 GMT'),
            ('content-length', 12345)
        ])

        mock_instance = MagicMock()
        mock_instance.add_error = MagicMock()
        mock_reporter.return_value = mock_instance

        event = self.create_event()

        mock_db = MockDynamodbHandler()
        mock_db._load_db(
            os.path.join(self.resources_dir, 'db/valid_unsigned.json'))

        mock_api = MockAPI(os.path.join(self.resources_dir, 'cdn'),
                           'https://cdn.door43.org')

        mock_logger = MockLogger()
        mock_s3 = MockS3Handler()

        signer = SigningHandler(event,
                                None,
                                logger=mock_logger,
                                signer=self.mock_signer,
                                s3_handler=mock_s3,
                                dynamodb_handler=mock_db,
                                url_exists_handler=mock_api.url_exists,
                                download_handler=mock_api.download_file)
        result = signer.run()
        self.assertTrue(result)
        mock_instance.add_error.assert_called_once_with(
            'The file "obs.zip" could not be downloaded: File not found for key: temp/en_obs/f8a8d8d757/en/obs/v4/obs.zip'
        )
예제 #7
0
    def test_signing_handler_invalid_manifest(self, mock_reporter):
        mock_instance = MagicMock()
        mock_instance.add_error = MagicMock()
        mock_reporter.return_value = mock_instance

        event = self.create_event()
        mock_db = MockDynamodbHandler()
        mock_db._load_db(os.path.join(self.resources_dir, 'db/invalid.json'))

        mock_s3 = MockS3Handler()
        mock_s3._load_path(os.path.join(self.resources_dir, 'cdn'))

        mock_api = MockAPI(os.path.join(self.resources_dir, 'cdn'),
                           'https://cdn.door43.org')

        mock_logger = MockLogger()

        signer = SigningHandler(event,
                                None,
                                logger=mock_logger,
                                signer=self.mock_signer,
                                s3_handler=mock_s3,
                                dynamodb_handler=mock_db,
                                url_exists_handler=mock_api.url_exists,
                                download_handler=mock_api.download_file)
        result = signer.run()

        self.assertTrue(result)
        for f in mock_s3._recent_uploads:
            # assert nothing was uploaded to production
            self.assertTrue(f.startswith('temp/'))
            self.assertFalse(f.endswith('.sig'))
        # self.assertIn('Skipping unit-test. Bad Manifest: No JSON object could be decoded', mock_logger._messages)
        mock_instance.add_error.assert_called_once_with(
            'Skipping unit-test. Bad Manifest: No JSON object could be decoded'
        )