diff --git a/celements-filebase/src/main/java/com/celements/filebase/FileItemHelper.java b/celements-filebase/src/main/java/com/celements/filebase/FileItemHelper.java index 36d3b3667..520599960 100644 --- a/celements-filebase/src/main/java/com/celements/filebase/FileItemHelper.java +++ b/celements-filebase/src/main/java/com/celements/filebase/FileItemHelper.java @@ -39,6 +39,7 @@ public FileItem toFileItem(String dirPath, XWikiAttachment att, String storage) dirPath.endsWith("/") ? (dirPath + name) : (dirPath + "/" + name), urlService.getURL(attachmentRef, "download"), urlService.getURL(attachmentRef, "download", query), + urlService.getURL(attachmentRef, "viewattachrev"), storage, "file", (long) att.getFilesize(), diff --git a/celements-filebase/src/main/java/com/celements/filebase/PageAttachmentsController.java b/celements-filebase/src/main/java/com/celements/filebase/PageAttachmentsController.java index 099867b48..f3b58ff71 100644 --- a/celements-filebase/src/main/java/com/celements/filebase/PageAttachmentsController.java +++ b/celements-filebase/src/main/java/com/celements/filebase/PageAttachmentsController.java @@ -35,6 +35,7 @@ import org.springframework.web.server.ResponseStatusException; import org.xwiki.model.reference.AttachmentReference; import org.xwiki.model.reference.DocumentReference; +import org.xwiki.model.reference.SpaceReference; import com.celements.auth.user.User; import com.celements.filebase.dto.DeleteItem; @@ -188,12 +189,9 @@ private AttachmentRequest prepareRequest( EAccessLevel accessLevel) { checkAuth(); User user = modelContext.user().orElse(null); - if (user == null) { - throw new ResponseStatusException(HttpStatus.UNAUTHORIZED); - } DocumentReference docRef = new DocumentReference( docName, - new org.xwiki.model.reference.SpaceReference(spaceName, modelContext.getWikiRef())); + new SpaceReference(spaceName, modelContext.getWikiRef())); if (!rightsAccess.hasAccessLevel(docRef, accessLevel, user)) { throw new ResponseStatusException(HttpStatus.FORBIDDEN); } diff --git a/celements-filebase/src/main/java/com/celements/filebase/dto/FileItem.java b/celements-filebase/src/main/java/com/celements/filebase/dto/FileItem.java index 8f9aae287..334ea9f0f 100644 --- a/celements-filebase/src/main/java/com/celements/filebase/dto/FileItem.java +++ b/celements-filebase/src/main/java/com/celements/filebase/dto/FileItem.java @@ -7,6 +7,7 @@ public record FileItem( String path, String url, String previewUrl, + String historyUrl, String storage, String type, long file_size, diff --git a/celements-filebase/src/test/java/com/celements/filebase/PageAttachmentsControllerTest.java b/celements-filebase/src/test/java/com/celements/filebase/PageAttachmentsControllerTest.java index 59f8a67b8..2ef444493 100644 --- a/celements-filebase/src/test/java/com/celements/filebase/PageAttachmentsControllerTest.java +++ b/celements-filebase/src/test/java/com/celements/filebase/PageAttachmentsControllerTest.java @@ -28,6 +28,7 @@ import com.celements.rights.access.EAccessLevel; import com.celements.rights.access.IRightsAccessFacadeRole; import com.celements.url.UrlService; +import com.fasterxml.jackson.databind.ObjectMapper; import com.xpn.xwiki.doc.XWikiAttachment; import com.xpn.xwiki.doc.XWikiDocument; import com.xpn.xwiki.user.api.XWikiUser; @@ -88,6 +89,7 @@ public void test_list_allowed() throws Exception { expect(docMock.getDocumentReference()).andReturn(docRef).anyTimes(); expect(urlServiceMock.getURL(anyObject(), eq("download"))).andReturn("http://download"); expect(urlServiceMock.getURL(anyObject(), eq("download"), anyString())).andReturn("http://preview"); + expect(urlServiceMock.getURL(anyObject(), eq("viewattachrev"))).andReturn("http://history"); replayDefault(); ListResponse response = pageAttachmentsCtrl.list("MySpace", "MyDoc", "attachments://MySpace/MyDoc"); @@ -97,6 +99,45 @@ public void test_list_allowed() throws Exception { assertEquals("attachments://MySpace/MyDoc", response.dirname()); assertEquals(1, response.files().size()); assertEquals("file.png", response.files().get(0).basename()); + assertEquals("http://history", response.files().get(0).historyUrl()); + assertTrue(new ObjectMapper().writeValueAsString(response.files().get(0)).contains("\"historyUrl\"")); + } + + @Test + public void test_list_anonymousAllowed() throws Exception { + expectGuestCheckAuth(); + expect(modelContextMock.user()).andReturn(Optional.empty()).anyTimes(); + WikiReference wikiRef = new WikiReference("xwiki"); + expect(modelContextMock.getWikiRef()).andReturn(wikiRef).anyTimes(); + DocumentReference docRef = new DocumentReference("MyDoc", new SpaceReference("MySpace", wikiRef)); + expect(rightsAccessMock.hasAccessLevel(eq(docRef), eq(EAccessLevel.VIEW), isNull(User.class))) + .andReturn(true); + XWikiDocument docMock = createDefaultMock(XWikiDocument.class); + expect(modelAccessMock.getOrCreateDocument(eq(docRef))).andReturn(docMock); + expect(attServiceMock.getAttachmentsNameMatch(same(docMock), anyObject())).andReturn(List.of()); + replayDefault(); + ListResponse response = pageAttachmentsCtrl.list("MySpace", "MyDoc", "attachments://MySpace/MyDoc"); + verifyDefault(); + assertNotNull(response); + } + + @Test + public void test_list_anonymousDenied() throws Exception { + expectGuestCheckAuth(); + expect(modelContextMock.user()).andReturn(Optional.empty()).anyTimes(); + WikiReference wikiRef = new WikiReference("xwiki"); + expect(modelContextMock.getWikiRef()).andReturn(wikiRef).anyTimes(); + DocumentReference docRef = new DocumentReference("MyDoc", new SpaceReference("MySpace", wikiRef)); + expect(rightsAccessMock.hasAccessLevel(eq(docRef), eq(EAccessLevel.VIEW), isNull(User.class))) + .andReturn(false); + replayDefault(); + try { + pageAttachmentsCtrl.list("MySpace", "MyDoc", "attachments://MySpace/MyDoc"); + fail("Expected FORBIDDEN"); + } catch (ResponseStatusException rse) { + assertEquals(HttpStatus.FORBIDDEN, rse.getStatus()); + } + verifyDefault(); } @Test @@ -178,4 +219,8 @@ private void expectCheckAuth() throws Exception { expect(userServiceMock.getUser(eq("xwiki:User.test"))).andReturn(userMock).anyTimes(); } + private void expectGuestCheckAuth() throws Exception { + expect(getXContext().getWiki().checkAuth(same(getXContext()))).andReturn(null).anyTimes(); + } + }