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)
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)
def _create_lcp_importer(self, collection): """Creates a new instance of LCPImporter :param collection: Collection object :type collection: Collection :return: New instance of LCPImporter :rtype: LCPImporter """ configuration_storage = CollectionConfigurationStorage( self, collection) configuration_factory = ConfigurationFactory() hasher_factory = HasherFactory() credential_factory = LCPCredentialFactory() lcp_encryptor = LCPEncryptor(configuration_storage, configuration_factory) lcp_server = LCPServer( configuration_storage, configuration_factory, hasher_factory, credential_factory, ) lcp_importer = LCPImporter(lcp_encryptor, lcp_server) return lcp_importer
def setup(self, mock_search=True): super(TestLCPServer, self).setup() self._lcp_collection = self._collection( protocol=ExternalIntegration.LCP) self._integration = self._lcp_collection.external_integration integration_owner = create_autospec(spec=HasExternalIntegration) integration_owner.external_integration = MagicMock( return_value=self._integration) self._configuration_storage = ConfigurationStorage(integration_owner) self._configuration_factory = ConfigurationFactory() self._hasher_factory = HasherFactory() self._credential_factory = LCPCredentialFactory() self._lcp_server = LCPServer(self._configuration_storage, self._configuration_factory, self._hasher_factory, self._credential_factory)
def _create_lcp_server(self): """Creates a new instance of LCPServer :return: New instance of LCPServer :rtype: LCPServer """ configuration_storage = ConfigurationStorage(self) configuration_factory = ConfigurationFactory() hasher_factory = HasherFactory() credential_factory = LCPCredentialFactory() lcp_server = LCPServer(configuration_storage, configuration_factory, hasher_factory, credential_factory) return lcp_server
def create(self, integration_association): """Creates a new instance of LCPServer :param integration_association: Association with an external integration :type integration_association: core.model.configuration.HasExternalIntegration :return: New instance of LCPServer :rtype: LCPServer """ configuration_storage = ConfigurationStorage(integration_association) configuration_factory = ConfigurationFactory() hasher_factory = HasherFactory() credential_factory = LCPCredentialFactory() lcp_server = LCPServer(configuration_storage, configuration_factory, hasher_factory, credential_factory) return lcp_server
class TestLCPServer(DatabaseTest): def setup(self, mock_search=True): super(TestLCPServer, self).setup() self._lcp_collection = self._collection( protocol=ExternalIntegration.LCP) self._integration = self._lcp_collection.external_integration integration_owner = create_autospec(spec=HasExternalIntegration) integration_owner.external_integration = MagicMock( return_value=self._integration) self._configuration_storage = ConfigurationStorage(integration_owner) self._configuration_factory = ConfigurationFactory() self._hasher_factory = HasherFactory() self._credential_factory = LCPCredentialFactory() self._lcp_server = LCPServer(self._configuration_storage, self._configuration_factory, self._hasher_factory, self._credential_factory) @parameterized.expand([('empty_input_directory', ''), ('non_empty_input_directory', '/tmp/encrypted_books')]) 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) @parameterized.expand([ ('none_rights', None, None, None, None), ('license_start', datetime.datetime(2020, 01, 01, 00, 00, 00), None, None, None), ('license_end', None, datetime.datetime(2020, 12, 31, 23, 59, 59), None, None), ('max_printable_pages', None, None, 10, None), ('max_printable_pages_empty_max_copiable_pages', None, None, 10, ''), ('empty_max_printable_pages', None, None, '', None), ('max_copiable_pages', None, None, None, 1024), ('empty_max_printable_pages_max_copiable_pages', None, None, '', 1024), ('empty_max_copiable_pages', None, None, None, ''), ('dates', datetime.datetime(2020, 01, 01, 00, 00, 00), datetime.datetime(2020, 12, 31, 23, 59, 59), None, None), ('full_rights', datetime.datetime(2020, 01, 01, 00, 00, 00), datetime.datetime(2020, 12, 31, 23, 59, 59), 10, 1024), ]) def test_generate_license(self, _, license_start, license_end, max_printable_pages, max_copiable_pages): # Arrange patron = self._patron() expected_patron_id = '52a190d1-cd69-4794-9d7a-1ec50392697f' expected_patron_passphrase = '52a190d1-cd69-4794-9d7a-1ec50392697a' expected_patron_key = self._hasher_factory \ .create(LCPServerConfiguration.DEFAULT_ENCRYPTION_ALGORITHM) \ .hash(expected_patron_passphrase) 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.provider_name = fixtures.PROVIDER_NAME configuration.passphrase_hint = fixtures.TEXT_HINT configuration.encryption_algorithm = LCPServerConfiguration.DEFAULT_ENCRYPTION_ALGORITHM configuration.max_printable_pages = max_printable_pages configuration.max_copiable_pages = max_copiable_pages self._credential_factory.get_patron_id = MagicMock( return_value=expected_patron_id) self._credential_factory.get_patron_passphrase = MagicMock( return_value=expected_patron_passphrase) with requests_mock.Mocker() as request_mock: url = urlparse.urljoin( fixtures.LCPSERVER_URL, '/contents/{0}/license'.format(fixtures.CONTENT_ID)) request_mock.post(url, json=fixtures.LCPSERVER_LICENSE) # Act license = self._lcp_server.generate_license( self._db, fixtures.CONTENT_ID, patron, license_start, license_end) # Assert eq_(request_mock.called, True) eq_(license, fixtures.LCPSERVER_LICENSE) json_request = json.loads(request_mock.last_request.text) eq_(json_request['provider'], fixtures.PROVIDER_NAME) eq_(json_request['user']['id'], expected_patron_id) eq_(json_request['encryption']['user_key']['text_hint'], fixtures.TEXT_HINT) eq_(json_request['encryption']['user_key']['hex_value'], expected_patron_key) if license_start is not None: eq_(json_request['rights']['start'], utils.format_datetime(license_start)) if license_end is not None: eq_(json_request['rights']['end'], utils.format_datetime(license_end)) if max_printable_pages is not None and max_printable_pages != '': eq_(json_request['rights']['print'], max_printable_pages) if max_copiable_pages is not None and max_copiable_pages != '': eq_(json_request['rights']['copy'], max_copiable_pages) all_rights_fields_are_empty = all( map( lambda rights_field: rights_field is None or rights_field == '', [ license_start, license_end, max_printable_pages, max_copiable_pages ])) if all_rights_fields_are_empty: eq_('rights' in json_request, False) self._credential_factory.get_patron_id.assert_called_once_with( self._db, patron) self._credential_factory.get_patron_passphrase.assert_called_once_with( self._db, patron)
class TestLCPServer(DatabaseTest): def setup_method(self): super(TestLCPServer, self).setup_method() self._lcp_collection = self._collection( protocol=ExternalIntegration.LCP) self._integration = self._lcp_collection.external_integration integration_owner = create_autospec(spec=HasExternalIntegration) integration_owner.external_integration = MagicMock( return_value=self._integration) self._configuration_storage = ConfigurationStorage(integration_owner) self._configuration_factory = ConfigurationFactory() self._hasher_factory = HasherFactory() self._credential_factory = LCPCredentialFactory() self._lcp_server = LCPServer( self._configuration_storage, self._configuration_factory, self._hasher_factory, self._credential_factory, ) @parameterized.expand([ ("empty_input_directory", ""), ("non_empty_input_directory", "/tmp/encrypted_books"), ]) 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) @parameterized.expand([ ("none_rights", None, None, None, None), ( "license_start", datetime.datetime(2020, 1, 1, 00, 00, 00), None, None, None, ), ( "license_end", None, datetime.datetime(2020, 12, 31, 23, 59, 59), None, None, ), ("max_printable_pages", None, None, 10, None), ("max_printable_pages_empty_max_copiable_pages", None, None, 10, ""), ("empty_max_printable_pages", None, None, "", None), ("max_copiable_pages", None, None, None, 1024), ("empty_max_printable_pages_max_copiable_pages", None, None, "", 1024), ("empty_max_copiable_pages", None, None, None, ""), ( "dates", datetime.datetime(2020, 1, 1, 00, 00, 00), datetime.datetime(2020, 12, 31, 23, 59, 59), None, None, ), ( "full_rights", datetime.datetime(2020, 1, 1, 00, 00, 00), datetime.datetime(2020, 12, 31, 23, 59, 59), 10, 1024, ), ]) def test_generate_license(self, _, license_start, license_end, max_printable_pages, max_copiable_pages): # Arrange patron = self._patron() expected_patron_id = "52a190d1-cd69-4794-9d7a-1ec50392697f" expected_patron_passphrase = "52a190d1-cd69-4794-9d7a-1ec50392697a" expected_patron_key = self._hasher_factory.create( LCPServerConfiguration.DEFAULT_ENCRYPTION_ALGORITHM).hash( expected_patron_passphrase) 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.provider_name = fixtures.PROVIDER_NAME configuration.passphrase_hint = fixtures.TEXT_HINT configuration.encryption_algorithm = ( LCPServerConfiguration.DEFAULT_ENCRYPTION_ALGORITHM) configuration.max_printable_pages = max_printable_pages configuration.max_copiable_pages = max_copiable_pages self._credential_factory.get_patron_id = MagicMock( return_value=expected_patron_id) self._credential_factory.get_patron_passphrase = MagicMock( return_value=expected_patron_passphrase) with requests_mock.Mocker() as request_mock: url = urllib.parse.urljoin( fixtures.LCPSERVER_URL, "/contents/{0}/license".format(fixtures.CONTENT_ID), ) request_mock.post(url, json=fixtures.LCPSERVER_LICENSE) # Act license = self._lcp_server.generate_license( self._db, fixtures.CONTENT_ID, patron, license_start, license_end) # Assert assert request_mock.called == True assert license == fixtures.LCPSERVER_LICENSE json_request = json.loads(request_mock.last_request.text) assert json_request["provider"] == fixtures.PROVIDER_NAME assert json_request["user"]["id"] == expected_patron_id assert (json_request["encryption"]["user_key"]["text_hint"] == fixtures.TEXT_HINT) assert (json_request["encryption"]["user_key"]["hex_value"] == expected_patron_key) if license_start is not None: assert json_request["rights"][ "start"] == utils.format_datetime(license_start) if license_end is not None: assert json_request["rights"][ "end"] == utils.format_datetime(license_end) if max_printable_pages is not None and max_printable_pages != "": assert json_request["rights"][ "print"] == max_printable_pages if max_copiable_pages is not None and max_copiable_pages != "": assert json_request["rights"]["copy"] == max_copiable_pages all_rights_fields_are_empty = all([ rights_field is None or rights_field == "" for rights_field in [ license_start, license_end, max_printable_pages, max_copiable_pages, ] ]) if all_rights_fields_are_empty: assert ("rights" in json_request) == False self._credential_factory.get_patron_id.assert_called_once_with( self._db, patron) self._credential_factory.get_patron_passphrase.assert_called_once_with( self._db, patron)