예제 #1
0
    def add_content(self, db, encrypted_content):
        """Notifies LCP License Server about new encrypted content

        :param db: Database session
        :type db: sqlalchemy.orm.session.Session

        :param encrypted_content: LCPEncryptionResult object containing information about encrypted content
        :type encrypted_content: LCPEncryptionResult
        """
        with self._configuration_factory.create(
                self._configuration_storage, db, LCPServerConfiguration) as configuration:
            content_location = os.path.join(
                configuration.lcpserver_input_directory, encrypted_content.protected_content_disposition)
            payload = LCPEncryptionResult(
                content_id=encrypted_content.content_id,
                content_encryption_key=encrypted_content.content_encryption_key,
                protected_content_location=content_location,
                protected_content_disposition=encrypted_content.protected_content_disposition,
                protected_content_type=encrypted_content.protected_content_type,
                protected_content_length=encrypted_content.protected_content_length,
                protected_content_sha256=encrypted_content.protected_content_sha256
            )
            path = '/contents/{0}'.format(encrypted_content.content_id)

            self._send_request(configuration, 'put', path, payload, LCPEncryptorResultJSONEncoder)
예제 #2
0
    def test_import_book(self):
        # Arrange
        file_path = '/opt/readium/raw_books/book.epub'
        identifier = '123456789'
        encrypted_content = LCPEncryptionResult(
            content_id='1',
            content_encryption_key='12345',
            protected_content_location='/opt/readium/files/encrypted',
            protected_content_disposition='encrypted_book',
            protected_content_type='application/epub+zip',
            protected_content_length=12345,
            protected_content_sha256='12345')
        lcp_encryptor = create_autospec(spec=LCPEncryptor)
        lcp_encryptor.encrypt = MagicMock(return_value=encrypted_content)
        lcp_server = create_autospec(spec=LCPServer)
        lcp_server.add_content = MagicMock()
        importer = LCPImporter(lcp_encryptor, lcp_server)
        db = create_autospec(spec=sqlalchemy.orm.session.Session)

        # Act
        importer.import_book(db, file_path, identifier)

        # Assert
        lcp_encryptor.encrypt.assert_called_once_with(db, file_path,
                                                      identifier)
        lcp_server.add_content.assert_called_once_with(db, encrypted_content)
예제 #3
0
    def test_add_content(self, _, input_directory):
        # Arrange
        lcp_server = LCPServer(
            self._configuration_storage,
            self._configuration_factory,
            self._hasher_factory,
            self._credential_factory,
        )
        encrypted_content = LCPEncryptionResult(
            content_id=fixtures.CONTENT_ID,
            content_encryption_key="12345",
            protected_content_location="/opt/readium/files/encrypted",
            protected_content_disposition="encrypted_book",
            protected_content_type="application/epub+zip",
            protected_content_length=12345,
            protected_content_sha256="12345",
        )
        expected_protected_content_disposition = os.path.join(
            input_directory, encrypted_content.protected_content_disposition)

        with self._configuration_factory.create(
                self._configuration_storage, self._db,
                LCPServerConfiguration) as configuration:
            configuration.lcpserver_url = fixtures.LCPSERVER_URL
            configuration.lcpserver_user = fixtures.LCPSERVER_USER
            configuration.lcpserver_password = fixtures.LCPSERVER_PASSWORD
            configuration.lcpserver_input_directory = input_directory
            configuration.provider_name = fixtures.PROVIDER_NAME
            configuration.passphrase_hint = fixtures.TEXT_HINT
            configuration.encryption_algorithm = (
                LCPServerConfiguration.DEFAULT_ENCRYPTION_ALGORITHM)

            with requests_mock.Mocker() as request_mock:
                url = urllib.parse.urljoin(
                    fixtures.LCPSERVER_URL,
                    "/contents/{0}".format(fixtures.CONTENT_ID))
                request_mock.put(url)

                # Act
                lcp_server.add_content(self._db, encrypted_content)

                # Assert
                assert request_mock.called == True

                json_request = json.loads(request_mock.last_request.text)
                assert json_request[
                    "content-id"] == encrypted_content.content_id
                assert (json_request["content-encryption-key"] ==
                        encrypted_content.content_encryption_key)
                assert (json_request["protected-content-location"] ==
                        expected_protected_content_disposition)
                assert (json_request["protected-content-disposition"] ==
                        encrypted_content.protected_content_disposition)
                assert (json_request["protected-content-type"] ==
                        encrypted_content.protected_content_type)
                assert (json_request["protected-content-length"] ==
                        encrypted_content.protected_content_length)
                assert (json_request["protected-content-sha256"] ==
                        encrypted_content.protected_content_sha256)
예제 #4
0
    def test_add_content(self, _, input_directory):
        # Arrange
        lcp_server = LCPServer(self._configuration_storage,
                               self._configuration_factory,
                               self._hasher_factory, self._credential_factory)
        encrypted_content = LCPEncryptionResult(
            content_id=fixtures.CONTENT_ID,
            content_encryption_key='12345',
            protected_content_location='/opt/readium/files/encrypted',
            protected_content_disposition='encrypted_book',
            protected_content_type='application/epub+zip',
            protected_content_length=12345,
            protected_content_sha256='12345')
        expected_protected_content_disposition = os.path.join(
            input_directory, encrypted_content.protected_content_disposition)

        with self._configuration_factory.create(
                self._configuration_storage, self._db,
                LCPServerConfiguration) as configuration:
            configuration.lcpserver_url = fixtures.LCPSERVER_URL
            configuration.lcpserver_user = fixtures.LCPSERVER_USER
            configuration.lcpserver_password = fixtures.LCPSERVER_PASSWORD
            configuration.lcpserver_input_directory = input_directory
            configuration.provider_name = fixtures.PROVIDER_NAME
            configuration.passphrase_hint = fixtures.TEXT_HINT
            configuration.encryption_algorithm = LCPServerConfiguration.DEFAULT_ENCRYPTION_ALGORITHM

            with requests_mock.Mocker() as request_mock:
                url = urlparse.urljoin(
                    fixtures.LCPSERVER_URL,
                    '/contents/{0}'.format(fixtures.CONTENT_ID))
                request_mock.put(url)

                # Act
                lcp_server.add_content(self._db, encrypted_content)

                # Assert
                eq_(request_mock.called, True)

                json_request = json.loads(request_mock.last_request.text)
                eq_(json_request['content-id'], encrypted_content.content_id)
                eq_(json_request['content-encryption-key'],
                    encrypted_content.content_encryption_key)
                eq_(json_request['protected-content-location'],
                    expected_protected_content_disposition)
                eq_(json_request['protected-content-disposition'],
                    encrypted_content.protected_content_disposition)
                eq_(json_request['protected-content-type'],
                    encrypted_content.protected_content_type)
                eq_(json_request['protected-content-length'],
                    encrypted_content.protected_content_length)
                eq_(json_request['protected-content-sha256'],
                    encrypted_content.protected_content_sha256)
예제 #5
0
class TestLCPEncryptor(DatabaseTest):
    @parameterized.expand([
        (
            "non_existing_directory",
            fixtures.NOT_EXISTING_BOOK_FILE_PATH,
            fixtures.LCPENCRYPT_NOT_EXISTING_DIRECTORY_RESULT,
            None,
            LCPEncryptionException(
                fixtures.LCPENCRYPT_NOT_EXISTING_DIRECTORY_RESULT.strip()),
            False,
        ),
        (
            "failed_encryption",
            fixtures.NOT_EXISTING_BOOK_FILE_PATH,
            fixtures.LCPENCRYPT_FAILED_ENCRYPTION_RESULT,
            None,
            LCPEncryptionException("Encryption failed"),
        ),
        (
            "successful_encryption",
            fixtures.EXISTING_BOOK_FILE_PATH,
            fixtures.LCPENCRYPT_SUCCESSFUL_ENCRYPTION_RESULT,
            LCPEncryptionResult(
                content_id=fixtures.BOOK_IDENTIFIER,
                content_encryption_key=fixtures.CONTENT_ENCRYPTION_KEY,
                protected_content_location=fixtures.PROTECTED_CONTENT_LOCATION,
                protected_content_disposition=fixtures.
                PROTECTED_CONTENT_DISPOSITION,
                protected_content_type=fixtures.PROTECTED_CONTENT_TYPE,
                protected_content_length=fixtures.PROTECTED_CONTENT_LENGTH,
                protected_content_sha256=fixtures.PROTECTED_CONTENT_SHA256,
            ),
        ),
        (
            "failed_lcp_server_notification",
            fixtures.EXISTING_BOOK_FILE_PATH,
            fixtures.LCPENCRYPT_FAILED_LCPSERVER_NOTIFICATION,
            None,
            LCPEncryptionException(
                fixtures.LCPENCRYPT_FAILED_LCPSERVER_NOTIFICATION.strip()),
        ),
        (
            "successful_lcp_server_notification",
            fixtures.EXISTING_BOOK_FILE_PATH,
            fixtures.LCPENCRYPT_SUCCESSFUL_NOTIFICATION_RESULT,
            LCPEncryptionResult(
                content_id=fixtures.BOOK_IDENTIFIER,
                content_encryption_key=fixtures.CONTENT_ENCRYPTION_KEY,
                protected_content_location=fixtures.PROTECTED_CONTENT_LOCATION,
                protected_content_disposition=fixtures.
                PROTECTED_CONTENT_DISPOSITION,
                protected_content_type=fixtures.PROTECTED_CONTENT_TYPE,
                protected_content_length=fixtures.PROTECTED_CONTENT_LENGTH,
                protected_content_sha256=fixtures.PROTECTED_CONTENT_SHA256,
            ),
        ),
    ])
    def test_local_lcpencrypt(
        self,
        _,
        file_path,
        lcpencrypt_output,
        expected_result,
        expected_exception=None,
        create_file=True,
    ):
        # Arrange
        integration_owner = create_autospec(spec=HasExternalIntegration)
        integration_owner.external_integration = MagicMock(
            return_value=self._integration)
        configuration_storage = ConfigurationStorage(integration_owner)
        configuration_factory = ConfigurationFactory()
        encryptor = LCPEncryptor(configuration_storage, configuration_factory)
        identifier = Identifier(identifier=fixtures.BOOK_IDENTIFIER)

        with configuration_factory.create(
                configuration_storage, self._db,
                LCPEncryptionConfiguration) as configuration:
            configuration.lcpencrypt_location = (
                LCPEncryptionConfiguration.DEFAULT_LCPENCRYPT_LOCATION)

            with Patcher() as patcher:
                patcher.fs.create_file(
                    LCPEncryptionConfiguration.DEFAULT_LCPENCRYPT_LOCATION)

                if create_file:
                    patcher.fs.create_file(file_path)

                with patch("subprocess.check_output"
                           ) as subprocess_check_output_mock:
                    subprocess_check_output_mock.return_value = lcpencrypt_output

                    if expected_exception:
                        with pytest.raises(expected_exception.__class__
                                           ) as exception_metadata:
                            encryptor.encrypt(self._db, file_path,
                                              identifier.identifier)

                        # Assert
                        assert exception_metadata.value == expected_exception
                    else:
                        # Assert
                        result = encryptor.encrypt(self._db, file_path,
                                                   identifier.identifier)
                        assert result == expected_result