From 48b0b71c6301b6eb46c387c47b71d0729cc2f889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Gra=C3=A7a?= Date: Tue, 3 Oct 2023 16:52:15 +0100 Subject: [PATCH 01/12] add test and fix --- .../main/java/org/dspace/content/Bundle.java | 2 +- .../java/org/dspace/content/BundleTest.java | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/content/Bundle.java b/dspace-api/src/main/java/org/dspace/content/Bundle.java index 6c62c3dc913..e5cbdb6ff24 100644 --- a/dspace-api/src/main/java/org/dspace/content/Bundle.java +++ b/dspace-api/src/main/java/org/dspace/content/Bundle.java @@ -126,7 +126,7 @@ public void setPrimaryBitstreamID(Bitstream bitstream) { * Unset the primary bitstream ID of the bundle */ public void unsetPrimaryBitstreamID() { - primaryBitstream = null; + setPrimaryBitstreamID(null); } /** diff --git a/dspace-api/src/test/java/org/dspace/content/BundleTest.java b/dspace-api/src/test/java/org/dspace/content/BundleTest.java index 4ff35f5b4df..13b943b4d6b 100644 --- a/dspace-api/src/test/java/org/dspace/content/BundleTest.java +++ b/dspace-api/src/test/java/org/dspace/content/BundleTest.java @@ -513,6 +513,38 @@ public void testRemoveBitstreamAuth() throws SQLException, AuthorizeException, I } + /** + * Test removeBitstream method and also the unsetPrimaryBitstreamID method, of class Bundle. + */ + @Test + public void testRemoveBitstreamAuthAndUnsetPrimaryBitstreamID() throws IOException, SQLException, AuthorizeException { + // Allow Item WRITE permissions + doNothing().when(authorizeServiceSpy).authorizeAction(context, item, Constants.WRITE); + // Allow Bundle ADD permissions + doNothing().when(authorizeServiceSpy).authorizeAction(context, b, Constants.ADD); + // Allow Bitstream WRITE permissions + doNothing().when(authorizeServiceSpy) + .authorizeAction(any(Context.class), any(Bitstream.class), eq(Constants.WRITE)); + // Allow Bitstream DELETE permissions + doNothing().when(authorizeServiceSpy) + .authorizeAction(any(Context.class), any(Bitstream.class), eq(Constants.DELETE)); + + + context.turnOffAuthorisationSystem(); + //set a value different than default + File f = new File(testProps.get("test.bitstream").toString()); + Bitstream bs = bitstreamService.create(context, new FileInputStream(f)); + bundleService.addBitstream(context, b, bs); + b.setPrimaryBitstreamID(bs); + context.restoreAuthSystemState(); + + assertThat("testRemoveBitstreamAuthAndUnsetPrimaryBitstreamID 0", b.getPrimaryBitstream(), equalTo(bs)); + //remove bitstream + bundleService.removeBitstream(context, b, bs); + //is -1 when not set + assertThat("testRemoveBitstreamAuthAndUnsetPrimaryBitstreamID 1", b.getPrimaryBitstream(), equalTo(null)); + } + /** * Test of update method, of class Bundle. */ From 47ca74bc4220249b95de9b8e71186277c9ac31ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Gra=C3=A7a?= Date: Thu, 19 Oct 2023 08:58:08 +0100 Subject: [PATCH 02/12] unset primary bitstream on bitstream service --- .../main/java/org/dspace/content/BitstreamServiceImpl.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dspace-api/src/main/java/org/dspace/content/BitstreamServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/BitstreamServiceImpl.java index cc89cea33a2..77f10880ea3 100644 --- a/dspace-api/src/main/java/org/dspace/content/BitstreamServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/BitstreamServiceImpl.java @@ -276,6 +276,10 @@ public void delete(Context context, Bitstream bitstream) throws SQLException, Au //Remove our bitstream from all our bundles final List bundles = bitstream.getBundles(); for (Bundle bundle : bundles) { + //We also need to remove the bitstream id when it's set as bundle's primary bitstream + if(bitstream.equals(bundle.getPrimaryBitstream())) { + bundle.unsetPrimaryBitstreamID(); + } bundle.removeBitstream(bitstream); } From 8a531ad0c7e8fdf09fa9a3870024687e6708a9a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Gra=C3=A7a?= Date: Thu, 19 Oct 2023 09:38:01 +0100 Subject: [PATCH 03/12] adding sql expression to fix deleted primary bitstreams from bundle --- ....10.12__Fix-deleted-primary-bitstreams.sql | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.6_2023.10.12__Fix-deleted-primary-bitstreams.sql diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.6_2023.10.12__Fix-deleted-primary-bitstreams.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.6_2023.10.12__Fix-deleted-primary-bitstreams.sql new file mode 100644 index 00000000000..b1739dbd960 --- /dev/null +++ b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.6_2023.10.12__Fix-deleted-primary-bitstreams.sql @@ -0,0 +1,26 @@ +BEGIN; + +-- Remove all primary bitstreams that are marked as deleted +UPDATE bundle +SET primary_bitstream_id = NULL +WHERE primary_bitstream_id IN + ( SELECT bs.uuid + FROM bitstream AS bs + INNER JOIN bundle as bl ON bs.uuid = bl.primary_bitstream_id + WHERE bs.deleted IS TRUE ); + +-- Remove all primary bitstreams that don't make part on bundle's bitstreams +UPDATE bundle +SET primary_bitstream_id = NULL +WHERE primary_bitstream_id IN + ( SELECT bl.primary_bitstream_id + FROM bundle as bl + WHERE bl.primary_bitstream_id IS NOT NULL + AND bl.primary_bitstream_id NOT IN + ( SELECT bitstream_id + FROM bundle2bitstream AS b2b + WHERE b2b.bundle_id = bl.uuid + ) + ); + +COMMIT; \ No newline at end of file From 3255e073fa110a3354f1265853bbf531c677f6ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Gra=C3=A7a?= Date: Thu, 19 Oct 2023 09:58:24 +0100 Subject: [PATCH 04/12] add bundle remove authorization --- .../src/main/java/org/dspace/content/BitstreamServiceImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/dspace-api/src/main/java/org/dspace/content/BitstreamServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/BitstreamServiceImpl.java index 77f10880ea3..5391dcf389a 100644 --- a/dspace-api/src/main/java/org/dspace/content/BitstreamServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/BitstreamServiceImpl.java @@ -276,6 +276,7 @@ public void delete(Context context, Bitstream bitstream) throws SQLException, Au //Remove our bitstream from all our bundles final List bundles = bitstream.getBundles(); for (Bundle bundle : bundles) { + authorizeService.authorizeAction(context, bundle, Constants.REMOVE); //We also need to remove the bitstream id when it's set as bundle's primary bitstream if(bitstream.equals(bundle.getPrimaryBitstream())) { bundle.unsetPrimaryBitstreamID(); From 4a05600194fb9be7e19084f3a9106a0152fd0d80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Gra=C3=A7a?= Date: Thu, 19 Oct 2023 10:16:38 +0100 Subject: [PATCH 05/12] adding missing bundle REMOVE authorization --- dspace-api/src/test/java/org/dspace/content/BundleTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dspace-api/src/test/java/org/dspace/content/BundleTest.java b/dspace-api/src/test/java/org/dspace/content/BundleTest.java index 13b943b4d6b..851d8267ea8 100644 --- a/dspace-api/src/test/java/org/dspace/content/BundleTest.java +++ b/dspace-api/src/test/java/org/dspace/content/BundleTest.java @@ -522,6 +522,8 @@ public void testRemoveBitstreamAuthAndUnsetPrimaryBitstreamID() throws IOExcepti doNothing().when(authorizeServiceSpy).authorizeAction(context, item, Constants.WRITE); // Allow Bundle ADD permissions doNothing().when(authorizeServiceSpy).authorizeAction(context, b, Constants.ADD); + // Allow Bundle REMOVE permissions + doNothing().when(authorizeServiceSpy).authorizeAction(context, b, Constants.REMOVE); // Allow Bitstream WRITE permissions doNothing().when(authorizeServiceSpy) .authorizeAction(any(Context.class), any(Bitstream.class), eq(Constants.WRITE)); From caba4bbb96f56c103c4dd8ac9f9fa5863b40e04c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Gra=C3=A7a?= Date: Thu, 19 Oct 2023 11:16:26 +0100 Subject: [PATCH 06/12] add missing head style check --- .../V7.6_2023.10.12__Fix-deleted-primary-bitstreams.sql | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.6_2023.10.12__Fix-deleted-primary-bitstreams.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.6_2023.10.12__Fix-deleted-primary-bitstreams.sql index b1739dbd960..c97d2246578 100644 --- a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.6_2023.10.12__Fix-deleted-primary-bitstreams.sql +++ b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.6_2023.10.12__Fix-deleted-primary-bitstreams.sql @@ -1,3 +1,11 @@ +-- +-- The contents of this file are subject to the license and copyright +-- detailed in the LICENSE and NOTICE files at the root of the source +-- tree and available online at +-- +-- http://www.dspace.org/license/ +-- + BEGIN; -- Remove all primary bitstreams that are marked as deleted From 74605f159af5e53a3e890f578732a858cef12e51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Gra=C3=A7a?= Date: Thu, 19 Oct 2023 11:42:58 +0100 Subject: [PATCH 07/12] fix style errors --- .../src/main/java/org/dspace/content/BitstreamServiceImpl.java | 2 +- dspace-api/src/test/java/org/dspace/content/BundleTest.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/content/BitstreamServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/BitstreamServiceImpl.java index 5391dcf389a..2746812c1cd 100644 --- a/dspace-api/src/main/java/org/dspace/content/BitstreamServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/BitstreamServiceImpl.java @@ -278,7 +278,7 @@ public void delete(Context context, Bitstream bitstream) throws SQLException, Au for (Bundle bundle : bundles) { authorizeService.authorizeAction(context, bundle, Constants.REMOVE); //We also need to remove the bitstream id when it's set as bundle's primary bitstream - if(bitstream.equals(bundle.getPrimaryBitstream())) { + if (bitstream.equals(bundle.getPrimaryBitstream())) { bundle.unsetPrimaryBitstreamID(); } bundle.removeBitstream(bitstream); diff --git a/dspace-api/src/test/java/org/dspace/content/BundleTest.java b/dspace-api/src/test/java/org/dspace/content/BundleTest.java index 851d8267ea8..4af64b81cb0 100644 --- a/dspace-api/src/test/java/org/dspace/content/BundleTest.java +++ b/dspace-api/src/test/java/org/dspace/content/BundleTest.java @@ -517,7 +517,8 @@ public void testRemoveBitstreamAuth() throws SQLException, AuthorizeException, I * Test removeBitstream method and also the unsetPrimaryBitstreamID method, of class Bundle. */ @Test - public void testRemoveBitstreamAuthAndUnsetPrimaryBitstreamID() throws IOException, SQLException, AuthorizeException { + public void testRemoveBitstreamAuthAndUnsetPrimaryBitstreamID() + throws IOException, SQLException, AuthorizeException { // Allow Item WRITE permissions doNothing().when(authorizeServiceSpy).authorizeAction(context, item, Constants.WRITE); // Allow Bundle ADD permissions From e6d108a94e41e58d6d701f3ef0429fda438e6555 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Gra=C3=A7a?= Date: Mon, 30 Oct 2023 11:27:18 +0000 Subject: [PATCH 08/12] new testDeleteBitstreamAndUnsetPrimaryBitstreamID test for primary bitstream verification --- .../org/dspace/content/BitstreamTest.java | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/dspace-api/src/test/java/org/dspace/content/BitstreamTest.java b/dspace-api/src/test/java/org/dspace/content/BitstreamTest.java index 921e4efcc7d..30ef5f37fb5 100644 --- a/dspace-api/src/test/java/org/dspace/content/BitstreamTest.java +++ b/dspace-api/src/test/java/org/dspace/content/BitstreamTest.java @@ -432,6 +432,55 @@ public void testDeleteAndExpunge() throws IOException, SQLException, AuthorizeEx assertThat("testExpunge 0", bitstreamService.find(context, bitstreamId), nullValue()); } + /** + * Test of delete method, of class Bitstream. + */ + @Test + public void testDeleteBitstreamAndUnsetPrimaryBitstreamID() + throws IOException, SQLException, AuthorizeException { + + context.turnOffAuthorisationSystem(); + + Community owningCommunity = communityService.create(null, context); + Collection collection = collectionService.create(context, owningCommunity); + WorkspaceItem workspaceItem = workspaceItemService.create(context, collection, false); + Item item = installItemService.installItem(context, workspaceItem); + Bundle b = bundleService.create(context, item, "TESTBUNDLE"); + + // Allow Item WRITE permissions + doNothing().when(authorizeServiceSpy).authorizeAction(context, item, Constants.WRITE); + // Allow Bundle ADD permissions + doNothing().when(authorizeServiceSpy).authorizeAction(context, b, Constants.ADD); + // Allow Bundle REMOVE permissions + doNothing().when(authorizeServiceSpy).authorizeAction(context, b, Constants.REMOVE); + // Allow Bitstream WRITE permissions + doNothing().when(authorizeServiceSpy) + .authorizeAction(any(Context.class), any(Bitstream.class), eq(Constants.WRITE)); + // Allow Bitstream DELETE permissions + doNothing().when(authorizeServiceSpy) + .authorizeAction(any(Context.class), any(Bitstream.class), eq(Constants.DELETE)); + + //set a value different than default + File f = new File(testProps.get("test.bitstream").toString()); + + // Create a new bitstream, which we can delete. + Bitstream bs = bitstreamService.create(context, new FileInputStream(f)); + bundleService.addBitstream(context, b, bs); + // set primary bitstream + b.setPrimaryBitstreamID(bs); + context.restoreAuthSystemState(); + + // Test that delete will flag the bitstream as deleted + assertFalse("testDeleteBitstreamAndUnsetPrimaryBitstreamID 0", bs.isDeleted()); + assertThat("testDeleteBitstreamAndUnsetPrimaryBitstreamID 1", b.getPrimaryBitstream(), equalTo(bs)); + // Delete bitstream + bitstreamService.delete(context, bs); + assertTrue("testDeleteBitstreamAndUnsetPrimaryBitstreamID 2", bs.isDeleted()); + + // Now test if the primary bitstream was unset from bundle + assertThat("testDeleteBitstreamAndUnsetPrimaryBitstreamID 3", b.getPrimaryBitstream(), equalTo(null)); + } + /** * Test of retrieve method, of class Bitstream. */ From ad0d22a13a35a2167557efeb5ddea7a3a504424d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Gra=C3=A7a?= Date: Mon, 30 Oct 2023 11:45:12 +0000 Subject: [PATCH 09/12] new testDeleteBitstreamAndUnsetPrimaryBitstreamID test for primary bitstream verification --- .../java/org/dspace/content/BitstreamTest.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/content/BitstreamTest.java b/dspace-api/src/test/java/org/dspace/content/BitstreamTest.java index 30ef5f37fb5..eb3de96d2fd 100644 --- a/dspace-api/src/test/java/org/dspace/content/BitstreamTest.java +++ b/dspace-api/src/test/java/org/dspace/content/BitstreamTest.java @@ -464,18 +464,18 @@ public void testDeleteBitstreamAndUnsetPrimaryBitstreamID() File f = new File(testProps.get("test.bitstream").toString()); // Create a new bitstream, which we can delete. - Bitstream bs = bitstreamService.create(context, new FileInputStream(f)); - bundleService.addBitstream(context, b, bs); + Bitstream delBS = bitstreamService.create(context, new FileInputStream(f)); + bundleService.addBitstream(context, b, delBS); // set primary bitstream - b.setPrimaryBitstreamID(bs); + b.setPrimaryBitstreamID(delBS); context.restoreAuthSystemState(); // Test that delete will flag the bitstream as deleted - assertFalse("testDeleteBitstreamAndUnsetPrimaryBitstreamID 0", bs.isDeleted()); - assertThat("testDeleteBitstreamAndUnsetPrimaryBitstreamID 1", b.getPrimaryBitstream(), equalTo(bs)); + assertFalse("testDeleteBitstreamAndUnsetPrimaryBitstreamID 0", delBS.isDeleted()); + assertThat("testDeleteBitstreamAndUnsetPrimaryBitstreamID 1", b.getPrimaryBitstream(), equalTo(delBS)); // Delete bitstream - bitstreamService.delete(context, bs); - assertTrue("testDeleteBitstreamAndUnsetPrimaryBitstreamID 2", bs.isDeleted()); + bitstreamService.delete(context, delBS); + assertTrue("testDeleteBitstreamAndUnsetPrimaryBitstreamID 2", delBS.isDeleted()); // Now test if the primary bitstream was unset from bundle assertThat("testDeleteBitstreamAndUnsetPrimaryBitstreamID 3", b.getPrimaryBitstream(), equalTo(null)); From a3e506c7f452133e3cc973705d671dba61a469d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Gra=C3=A7a?= Date: Mon, 30 Oct 2023 13:08:53 +0000 Subject: [PATCH 10/12] new testDeleteBitstreamAndUnsetPrimaryBitstreamID remove unnecessary stubs --- .../src/test/java/org/dspace/content/BitstreamTest.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/content/BitstreamTest.java b/dspace-api/src/test/java/org/dspace/content/BitstreamTest.java index eb3de96d2fd..e85a0fc7b78 100644 --- a/dspace-api/src/test/java/org/dspace/content/BitstreamTest.java +++ b/dspace-api/src/test/java/org/dspace/content/BitstreamTest.java @@ -447,10 +447,6 @@ public void testDeleteBitstreamAndUnsetPrimaryBitstreamID() Item item = installItemService.installItem(context, workspaceItem); Bundle b = bundleService.create(context, item, "TESTBUNDLE"); - // Allow Item WRITE permissions - doNothing().when(authorizeServiceSpy).authorizeAction(context, item, Constants.WRITE); - // Allow Bundle ADD permissions - doNothing().when(authorizeServiceSpy).authorizeAction(context, b, Constants.ADD); // Allow Bundle REMOVE permissions doNothing().when(authorizeServiceSpy).authorizeAction(context, b, Constants.REMOVE); // Allow Bitstream WRITE permissions From c0bbd9d91f894fbe26f8cf7c4f166da8ba1cefd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Gra=C3=A7a?= Date: Mon, 30 Oct 2023 22:48:49 +0000 Subject: [PATCH 11/12] make comments more clear to understand --- .../V7.6_2023.10.12__Fix-deleted-primary-bitstreams.sql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.6_2023.10.12__Fix-deleted-primary-bitstreams.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.6_2023.10.12__Fix-deleted-primary-bitstreams.sql index c97d2246578..7a0bae1582d 100644 --- a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.6_2023.10.12__Fix-deleted-primary-bitstreams.sql +++ b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.6_2023.10.12__Fix-deleted-primary-bitstreams.sql @@ -8,7 +8,7 @@ BEGIN; --- Remove all primary bitstreams that are marked as deleted +-- Unset any primary bitstream that is marked as deleted UPDATE bundle SET primary_bitstream_id = NULL WHERE primary_bitstream_id IN @@ -17,7 +17,7 @@ WHERE primary_bitstream_id IN INNER JOIN bundle as bl ON bs.uuid = bl.primary_bitstream_id WHERE bs.deleted IS TRUE ); --- Remove all primary bitstreams that don't make part on bundle's bitstreams +-- Unset any primary bitstream that don't belong to bundle's bitstreams list UPDATE bundle SET primary_bitstream_id = NULL WHERE primary_bitstream_id IN @@ -31,4 +31,4 @@ WHERE primary_bitstream_id IN ) ); -COMMIT; \ No newline at end of file +COMMIT; From 74cce86afcc163c52502892556679e6175fa1948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Gra=C3=A7a?= Date: Mon, 30 Oct 2023 22:49:31 +0000 Subject: [PATCH 12/12] typo --- .../V7.6_2023.10.12__Fix-deleted-primary-bitstreams.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.6_2023.10.12__Fix-deleted-primary-bitstreams.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.6_2023.10.12__Fix-deleted-primary-bitstreams.sql index 7a0bae1582d..9dd2f54a43e 100644 --- a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.6_2023.10.12__Fix-deleted-primary-bitstreams.sql +++ b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.6_2023.10.12__Fix-deleted-primary-bitstreams.sql @@ -17,7 +17,7 @@ WHERE primary_bitstream_id IN INNER JOIN bundle as bl ON bs.uuid = bl.primary_bitstream_id WHERE bs.deleted IS TRUE ); --- Unset any primary bitstream that don't belong to bundle's bitstreams list +-- Unset any primary bitstream that don't belong to bundle's bitstream list UPDATE bundle SET primary_bitstream_id = NULL WHERE primary_bitstream_id IN