CVE-2023-37911: Exposure of Resource to Wrong Sphere (CWE-668)
value: XWiki Platform is a generic wiki platform offering runtime services for applications built on top of it. Starting in version 9.4-rc-1 and prior to versions 14.10.8 and 15.3-rc-1, when a document has been deleted and re-created, it is possible for users with view right on the re-created document but not on the deleted document to view the contents of the deleted document. Such a situation might arise when rights were added to the deleted document. This can be exploited through the diff feature and, partially, through the REST API by using versions such as `deleted:1` (where the number counts the deletions in the wiki and is thus guessable). Given sufficient rights, the attacker can also re-create the deleted document, thus extending the scope to any deleted document as long as the attacker has edit right in the location of the deleted document. This vulnerability has been patched in XWiki 14.10.8 and 15.3 RC1 by properly checking rights when deleted revisions of a document are accessed. The only workaround is to regularly clean deleted documents to minimize the potential exposure. Extra care should be taken when deleting sensitive documents that are protected individually (and not, e.g., by being placed in a protected space) or deleting a protected space as a whole.
CWE description: The product exposes a resource to the wrong control sphere, providing unintended actors with inappropriate access to the resource.
CVSS v3 base score: 6.5
Published: 2023-10-25T18:17Z
Repository: https://github.com/xwiki/xwiki-platform
Language: Java
Files changed: xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/api/Document.java, xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/api/XWiki.java, xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/api/DocumentTest.java, xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/api/XWikiTest.java
Commit date: 2023-04-04 18:59:31 +0200
Commit message: XWIKI-20685: Check access on the revision provider in the script API

Diff: diff --git a/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/api/Document.java b/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/api/Document.java
index c7626f8607dd2..140824b7df59c 100644
--- a/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/api/Document.java
+++ b/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/api/Document.java
@@ -29,10 +29,11 @@
 import java.util.Locale;
 import java.util.Map;
 import java.util.Vector;
 
 import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.lang.exception.ExceptionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.suigeneris.jrcs.diff.DifferentiationFailedException;
 import org.suigeneris.jrcs.diff.delta.Delta;
@@ -50,10 +51,11 @@
 import org.xwiki.model.reference.ObjectReference;
 import org.xwiki.model.reference.PageReference;
 import org.xwiki.rendering.block.XDOM;
 import org.xwiki.rendering.parser.ParseException;
 import org.xwiki.rendering.syntax.Syntax;
+import org.xwiki.security.authorization.AuthorizationException;
 import org.xwiki.security.authorization.Right;
 import org.xwiki.stability.Unstable;
 import org.xwiki.user.CurrentUserReference;
 import org.xwiki.user.UserReference;
 import org.xwiki.user.UserReferenceResolver;
@@ -3163,24 +3165,30 @@ public void rename(DocumentReference newReference, List<DocumentReference> backl
 
     /**
      * Allow to easily access any revision of a document
      *
      * @param revision the version to access
-     * @return the document corresponding to the requested revision or {@code null} if the revision does not exist.
+     * @return the document corresponding to the requested revision or {@code null} if the revision does not exist or
+     * access is denied.
      */
     public Document getDocumentRevision(String revision)
     {
         try {
-            XWikiDocument documentRevision = getDocumentRevisionProvider().getRevision(this.doc, revision);
+            DocumentRevisionProvider revisionProvider = getDocumentRevisionProvider();
+            revisionProvider.checkAccess(Right.VIEW, CurrentUserReference.INSTANCE, getDocumentReference(), revision);
+            XWikiDocument documentRevision = revisionProvider.getRevision(this.doc, revision);
 
             return documentRevision != null ? new Document(documentRevision, this.context) : null;
+        } catch (AuthorizationException e) {
+            LOGGER.info("Access denied for loading revision [{}] of document [{}]: [{}]", revision,
+                getDocumentReferenceWithLocale(), ExceptionUtils.getRootCauseMessage(e));
         } catch (Exception e) {
             LOGGER.error("Failed to load revision [{}] of document [{}]", revision, getDocumentReferenceWithLocale(),
                 e);
-
-            return null;
         }
+
+        return null;
     }
 
     /**
      * Allow to easily access the previous revision of a document
      *
diff --git a/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/api/XWiki.java b/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/api/XWiki.java
index 7c6b79b4b494a..8d1221273bde7 100644
--- a/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/api/XWiki.java
+++ b/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/api/XWiki.java
@@ -44,12 +44,14 @@
 import org.xwiki.model.reference.PageReference;
 import org.xwiki.model.reference.SpaceReference;
 import org.xwiki.model.reference.WikiReference;
 import org.xwiki.rendering.renderer.PrintRendererFactory;
 import org.xwiki.rendering.syntax.Syntax;
+import org.xwiki.security.authorization.AuthorizationException;
 import org.xwiki.security.authorization.ContextualAuthorizationManager;
 import org.xwiki.security.authorization.Right;
+import org.xwiki.user.CurrentUserReference;
 
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
 import com.xpn.xwiki.doc.DocumentRevisionProvider;
 import com.xpn.xwiki.doc.XWikiDeletedDocument;
@@ -656,16 +658,21 @@ public Document getDocument(Document doc, String rev) throws XWikiException
      */
     public Document getDocument(DocumentReference reference, String revision) throws XWikiException
     {
         try {
             if (reference != null && getContextualAuthorizationManager().hasAccess(Right.VIEW, reference)) {
-                XWikiDocument documentRevision = getDocumentRevisionProvider().getRevision(reference, revision);
+                DocumentRevisionProvider revisionProvider = getDocumentRevisionProvider();
+                revisionProvider.checkAccess(Right.VIEW, CurrentUserReference.INSTANCE, reference, revision);
+                XWikiDocument documentRevision = revisionProvider.getRevision(reference, revision);
 
                 if (documentRevision != null) {
                     return new Document(documentRevision, this.context);
                 }
             }
+        } catch (AuthorizationException e) {
+            LOGGER.info("Access denied for loading revision [{}] of document [{}]: [{}]", revision, reference,
+                ExceptionUtils.getRootCauseMessage(e));
         } catch (Exception e) {
             LOGGER.error("Failed to access revision [{}] of document {}", revision, reference, e);
         }
 
         return null;
diff --git a/xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/api/DocumentTest.java b/xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/api/DocumentTest.java
index a1ebacd7700e6..49df27a7dc752 100644
--- a/xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/api/DocumentTest.java
+++ b/xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/api/DocumentTest.java
@@ -20,27 +20,34 @@
 package com.xpn.xwiki.api;
 
 import java.util.List;
 
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 import org.xwiki.component.manager.ComponentLookupException;
 import org.xwiki.component.util.DefaultParameterizedType;
 import org.xwiki.model.document.DocumentAuthors;
 import org.xwiki.model.internal.document.SafeDocumentAuthors;
 import org.xwiki.model.reference.DocumentReference;
 import org.xwiki.model.reference.ObjectReference;
 import org.xwiki.observation.ObservationManager;
+import org.xwiki.security.authorization.AuthorizationException;
 import org.xwiki.security.authorization.AuthorizationManager;
 import org.xwiki.security.authorization.Right;
+import org.xwiki.test.LogLevel;
+import org.xwiki.test.junit5.LogCaptureExtension;
 import org.xwiki.test.junit5.mockito.MockComponent;
 import org.xwiki.test.mockito.MockitoComponentManager;
 import org.xwiki.user.CurrentUserReference;
 import org.xwiki.user.UserReference;
 import org.xwiki.user.UserReferenceResolver;
 
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.doc.DocumentRevisionProvider;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.objects.BaseObject;
 import com.xpn.xwiki.objects.BaseProperty;
 import com.xpn.xwiki.test.MockitoOldcore;
 import com.xpn.xwiki.test.junit5.mockito.InjectMockitoOldcore;
@@ -54,10 +61,11 @@
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.ArgumentMatchers.same;
+import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -72,10 +80,13 @@
     private UserReferenceResolver<CurrentUserReference> currentUserReferenceUserReferenceResolver;
 
     @MockComponent
     private ObservationManager observationManager;
 
+    @RegisterExtension
+    private LogCaptureExtension logCapture = new LogCaptureExtension(LogLevel.INFO);
+
     @Test
     void toStringReturnsFullName()
     {
         XWikiDocument doc = new XWikiDocument(new DocumentReference("Wiki", "Space", "Page"));
         assertEquals("Space.Page", new Document(doc, new XWikiContext()).toString());
@@ -388,6 +399,34 @@ void getAuthors()
         obtainedAuthors = document.getAuthors();
         assertSame(documentAuthors, obtainedAuthors);
         verify(mockAuthorizationManager, times(2)).hasAccess(Right.PROGRAM, userReference, currentDocReference);
         verify(currentDoc).clone();
     }
+
+    @ParameterizedTest
+    @ValueSource(booleans = { false, true })
+    void getDocumentRevision(boolean allowAccess, MockitoComponentManager componentManager) throws Exception
+    {
+        DocumentReference documentReference = new DocumentReference("Wiki", "Space", "Page");
+        XWikiDocument xWikiDocument = new XWikiDocument(documentReference);
+        Document document = new Document(xWikiDocument, this.oldcore.getXWikiContext());
+        DocumentRevisionProvider revisionProvider =
+            componentManager.registerMockComponent(DocumentRevisionProvider.class);
+        String revision = "42.1";
+        XWikiDocument revisionDocument = mock(XWikiDocument.class);
+        when(revisionProvider.getRevision(xWikiDocument, revision)).thenReturn(revisionDocument);
+        String deniedMessage = "Denied";
+        if (!allowAccess) {
+            doThrow(new AuthorizationException(deniedMessage)).when(revisionProvider)
+                .checkAccess(Right.VIEW, CurrentUserReference.INSTANCE, documentReference, revision);
+            assertNull(document.getDocumentRevision(revision));
+            assertEquals(1, this.logCapture.size());
+            assertEquals(String.format("Access denied for loading revision [%s] of document [%s()]: "
+                    + "[AuthorizationException: %s]", revision,
+                documentReference, deniedMessage), this.logCapture.getMessage(0));
+        } else {
+            assertEquals(new Document(revisionDocument, this.oldcore.getXWikiContext()),
+                document.getDocumentRevision(revision));
+        }
+        verify(revisionProvider).checkAccess(Right.VIEW, CurrentUserReference.INSTANCE, documentReference, revision);
+    }
 }
diff --git a/xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/api/XWikiTest.java b/xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/api/XWikiTest.java
index bd068122a1dfd..57c6d8d4189c1 100644
--- a/xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/api/XWikiTest.java
+++ b/xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/api/XWikiTest.java
@@ -21,21 +21,27 @@
 
 import java.util.Calendar;
 
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 import org.xwiki.model.reference.DocumentReference;
 import org.xwiki.observation.ObservationManager;
 import org.xwiki.rendering.renderer.PrintRendererFactory;
 import org.xwiki.rendering.syntax.Syntax;
+import org.xwiki.security.authorization.AuthorizationException;
+import org.xwiki.security.authorization.ContextualAuthorizationManager;
+import org.xwiki.security.authorization.Right;
 import org.xwiki.test.junit5.mockito.MockComponent;
 import org.xwiki.test.mockito.MockitoComponentManager;
 import org.xwiki.user.CurrentUserReference;
 import org.xwiki.user.UserReferenceResolver;
 
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.doc.DocumentRevisionProvider;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.doc.XWikiDocumentArchive;
 import com.xpn.xwiki.test.MockitoOldcore;
 import com.xpn.xwiki.test.junit5.mockito.OldcoreTest;
 import com.xpn.xwiki.test.reference.ReferenceComponentList;
@@ -43,10 +49,13 @@
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 /**
  * Unit tests for {@link com.xpn.xwiki.api.XWiki}.
  * 
@@ -54,10 +63,12 @@
  */
 @OldcoreTest
 @ReferenceComponentList
 public class XWikiTest
 {
+    private static final DocumentReference DOCUMENT_REFERENCE = new DocumentReference("xwiki", "MilkyWay", "Fidis");
+
     @MockComponent
     private UserReferenceResolver<CurrentUserReference> currentUserReferenceUserReferenceResolver;
 
     @MockComponent
     private ObservationManager observationManager;
@@ -76,12 +87,11 @@ public void setup(MockitoOldcore mockitoOldcore) throws XWikiException
         when(mockRightService.hasAccessLevel(any(), any(), any(), any())).thenReturn(true);
         when(mockitoOldcore.getMockVersioningStore().getXWikiDocumentArchive(any(), any()))
             .thenReturn(new XWikiDocumentArchive());
 
         xWikiContext.setUser("Redtail");
-        this.apiDocument =
-            new Document(new XWikiDocument(new DocumentReference("xwiki", "MilkyWay", "Fidis")), xWikiContext);
+        this.apiDocument = new Document(new XWikiDocument(DOCUMENT_REFERENCE), xWikiContext);
         this.apiDocument.getDocument().setCreator("c" + xWikiContext.getUser());
         this.apiDocument.getDocument().setAuthor("a" + xWikiContext.getUser());
         this.apiDocument.save();
         xWikiContext.setUser("Earth");
     }
@@ -132,6 +142,36 @@ public void getAvailableRendererSyntax(MockitoComponentManager componentManager)
         assertEquals(Syntax.PLAIN_1_0, this.apiXWiki.getAvailableRendererSyntax("Plain", "1.0"));
         assertEquals(Syntax.PLAIN_1_0, this.apiXWiki.getAvailableRendererSyntax("plain", null));
         assertNull(this.apiXWiki.getAvailableRendererSyntax("plai", "1.0"));
         assertNull(this.apiXWiki.getAvailableRendererSyntax("plai", null));
     }
+
+    @ParameterizedTest
+    @ValueSource(booleans = { false, true })
+    void getDocumentRevision(boolean allowAccess, MockitoOldcore mockitoOldcore) throws Exception
+    {
+        DocumentRevisionProvider revisionProvider =
+            mockitoOldcore.getMocker().registerMockComponent(DocumentRevisionProvider.class);
+        ContextualAuthorizationManager contextualAuthorizationManager =
+            mockitoOldcore.getMockContextualAuthorizationManager();
+
+        XWikiDocument deletedDocument = new XWikiDocument(DOCUMENT_REFERENCE);
+        deletedDocument.setContent("Deleted");
+        String revision = "deleted:1";
+        when(revisionProvider.getRevision(DOCUMENT_REFERENCE, revision)).thenReturn(deletedDocument);
+
+        when(contextualAuthorizationManager.hasAccess(Right.VIEW, DOCUMENT_REFERENCE)).thenReturn(true);
+
+        if (!allowAccess) {
+            doThrow(new AuthorizationException("Denied")).when(revisionProvider)
+                .checkAccess(Right.VIEW, CurrentUserReference.INSTANCE, DOCUMENT_REFERENCE, revision);
+            assertNull(this.apiXWiki.getDocument(DOCUMENT_REFERENCE, revision));
+        } else {
+            assertEquals(new Document(deletedDocument, mockitoOldcore.getXWikiContext()),
+                this.apiXWiki.getDocument(DOCUMENT_REFERENCE, revision));
+        }
+
+        verify(revisionProvider, times(allowAccess ? 1 : 0)).getRevision(DOCUMENT_REFERENCE, revision);
+        verify(revisionProvider).checkAccess(Right.VIEW, CurrentUserReference.INSTANCE, DOCUMENT_REFERENCE, revision);
+        verify(contextualAuthorizationManager).hasAccess(Right.VIEW, DOCUMENT_REFERENCE);
+    }
 }

Vulnerable code:      * @return the document corresponding to the requested revision or {@code null} if the revision does not exist.
            XWikiDocument documentRevision = getDocumentRevisionProvider().getRevision(this.doc, revision);

            return null;
                XWikiDocument documentRevision = getDocumentRevisionProvider().getRevision(reference, revision);
        this.apiDocument =
            new Document(new XWikiDocument(new DocumentReference("xwiki", "MilkyWay", "Fidis")), xWikiContext);
Fixed code: import org.apache.commons.lang.exception.ExceptionUtils;
import org.xwiki.security.authorization.AuthorizationException;
     * @return the document corresponding to the requested revision or {@code null} if the revision does not exist or
     * access is denied.
            DocumentRevisionProvider revisionProvider = getDocumentRevisionProvider();
            revisionProvider.checkAccess(Right.VIEW, CurrentUserReference.INSTANCE, getDocumentReference(), revision);
            XWikiDocument documentRevision = revisionProvider.getRevision(this.doc, revision);
        } catch (AuthorizationException e) {
            LOGGER.info("Access denied for loading revision [{}] of document [{}]: [{}]", revision,
                getDocumentReferenceWithLocale(), ExceptionUtils.getRootCauseMessage(e));

        return null;
import org.xwiki.security.authorization.AuthorizationException;
import org.xwiki.user.CurrentUserReference;
                DocumentRevisionProvider revisionProvider = getDocumentRevisionProvider();
                revisionProvider.checkAccess(Right.VIEW, CurrentUserReference.INSTANCE, reference, revision);
                XWikiDocument documentRevision = revisionProvider.getRevision(reference, revision);
        } catch (AuthorizationException e) {
            LOGGER.info("Access denied for loading revision [{}] of document [{}]: [{}]", revision, reference,
                ExceptionUtils.getRootCauseMessage(e));
import org.junit.jupiter.api.extension.RegisterExtension;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.xwiki.security.authorization.AuthorizationException;
import org.xwiki.test.LogLevel;
import org.xwiki.test.junit5.LogCaptureExtension;
import com.xpn.xwiki.doc.DocumentRevisionProvider;
import static org.mockito.Mockito.doThrow;
    @RegisterExtension
    private LogCaptureExtension logCapture = new LogCaptureExtension(LogLevel.INFO);


    @ParameterizedTest
    @ValueSource(booleans = { false, true })
    void getDocumentRevision(boolean allowAccess, MockitoComponentManager componentManager) throws Exception
    {
        DocumentReference documentReference = new DocumentReference("Wiki", "Space", "Page");
        XWikiDocument xWikiDocument = new XWikiDocument(documentReference);
        Document document = new Document(xWikiDocument, this.oldcore.getXWikiContext());
        DocumentRevisionProvider revisionProvider =
            componentManager.registerMockComponent(DocumentRevisionProvider.class);
        String revision = "42.1";
        XWikiDocument revisionDocument = mock(XWikiDocument.class);
        when(revisionProvider.getRevision(xWikiDocument, revision)).thenReturn(revisionDocument);
        String deniedMessage = "Denied";
        if (!allowAccess) {
            doThrow(new AuthorizationException(deniedMessage)).when(revisionProvider)
                .checkAccess(Right.VIEW, CurrentUserReference.INSTANCE, documentReference, revision);
            assertNull(document.getDocumentRevision(revision));
            assertEquals(1, this.logCapture.size());
            assertEquals(String.format("Access denied for loading revision [%s] of document [%s()]: "
                    + "[AuthorizationException: %s]", revision,
                documentReference, deniedMessage), this.logCapture.getMessage(0));
        } else {
            assertEquals(new Document(revisionDocument, this.oldcore.getXWikiContext()),
                document.getDocumentRevision(revision));
        }
        verify(revisionProvider).checkAccess(Right.VIEW, CurrentUserReference.INSTANCE, documentReference, revision);
    }
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.xwiki.security.authorization.AuthorizationException;
import org.xwiki.security.authorization.ContextualAuthorizationManager;
import org.xwiki.security.authorization.Right;
import com.xpn.xwiki.doc.DocumentRevisionProvider;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
    private static final DocumentReference DOCUMENT_REFERENCE = new DocumentReference("xwiki", "MilkyWay", "Fidis");

        this.apiDocument = new Document(new XWikiDocument(DOCUMENT_REFERENCE), xWikiContext);

    @ParameterizedTest
    @ValueSource(booleans = { false, true })
    void getDocumentRevision(boolean allowAccess, MockitoOldcore mockitoOldcore) throws Exception
    {
        DocumentRevisionProvider revisionProvider =
            mockitoOldcore.getMocker().registerMockComponent(DocumentRevisionProvider.class);
        ContextualAuthorizationManager contextualAuthorizationManager =
            mockitoOldcore.getMockContextualAuthorizationManager();

        XWikiDocument deletedDocument = new XWikiDocument(DOCUMENT_REFERENCE);
        deletedDocument.setContent("Deleted");
        String revision = "deleted:1";
        when(revisionProvider.getRevision(DOCUMENT_REFERENCE, revision)).thenReturn(deletedDocument);

        when(contextualAuthorizationManager.hasAccess(Right.VIEW, DOCUMENT_REFERENCE)).thenReturn(true);

        if (!allowAccess) {
            doThrow(new AuthorizationException("Denied")).when(revisionProvider)
                .checkAccess(Right.VIEW, CurrentUserReference.INSTANCE, DOCUMENT_REFERENCE, revision);
            assertNull(this.apiXWiki.getDocument(DOCUMENT_REFERENCE, revision));
        } else {
            assertEquals(new Document(deletedDocument, mockitoOldcore.getXWikiContext()),
                this.apiXWiki.getDocument(DOCUMENT_REFERENCE, revision));
        }

        verify(revisionProvider, times(allowAccess ? 1 : 0)).getRevision(DOCUMENT_REFERENCE, revision);
        verify(revisionProvider).checkAccess(Right.VIEW, CurrentUserReference.INSTANCE, DOCUMENT_REFERENCE, revision);
        verify(contextualAuthorizationManager).hasAccess(Right.VIEW, DOCUMENT_REFERENCE);
    }