CVE-2022-23617 (published 2022-02-09T21:15Z)

XWiki Platform is a generic wiki platform offering runtime services for applications built on top of it. In affected versions any user with edit right can copy the content of a page it does not have access to by using it as template of a new page. This issue has been patched in XWiki 13.2CR1 and 12.10.6. Users are advised to update. There are no known workarounds for this issue.

Severity: MEDIUM
CVSS v2 base score: 4.0 (AV:N/AC:L/Au:S/C:P/I:N/A:N)
CVSS v3 base score: 6.5, MEDIUM (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N)

Weakness information:
cwe_id: CWE-862
cwe_name: Missing Authorization
description: The product does not perform an authorization check when an actor attempts to access a resource or perform an action.
extended_description: 
            Assuming a user with a given identity, authorization is the process of determining whether that user can access a given resource, based on the user's privileges and any permissions or other access-control specifications that apply to the resource.
            When access control checks are not applied, users are able to access data or perform actions that they should not be allowed to perform. This can lead to a wide range of problems, including information exposures, denial of service, and arbitrary code execution.
         
         

Fix information:
repo_url: https://github.com/xwiki/xwiki-platform
commit_details: repo_url: https://github.com/xwiki/xwiki-platform
author: Thomas Mortagne
author_date: 2021-03-15 12:10:38+01:00
msg: XWIKI-18430: Wrong handling of template documents
* improve retro compatibility with future 12.10.x versions
repository: repo_url: https://github.com/xwiki/xwiki-platform
repo_name: xwiki/xwiki-platform
description: The XWiki platform
repo_language: Java
owner: xwiki
file_changes: filename: CreateAction.java
change_type: ModificationType.MODIFY
diff: @@ -32,7 +32,6 @@
 import org.xwiki.component.annotation.Component;
 import org.xwiki.csrf.CSRFToken;
 import org.xwiki.model.reference.DocumentReference;
-import org.xwiki.model.reference.DocumentReferenceResolver;
 import org.xwiki.model.reference.EntityReferenceSerializer;
 import org.xwiki.model.reference.SpaceReference;
 import org.xwiki.security.authorization.ContextualAuthorizationManager;
@@ -97,11 +96,6 @@ public class CreateAction extends XWikiAction
      */
     private static final String LOCAL_SERIALIZER_HINT = "local";
 
-    /**
-     * Current entity reference resolver hint.
-     */
-    private static final String CURRENT_MIXED_RESOLVER_HINT = "currentmixed";
-
     /**
      * The action to perform when creating a new page from a template.
      *
@@ -277,14 +271,6 @@ private void doCreate(XWikiContext context, XWikiDocument newDocument, boolean i
         }
     }
 
-    /**
-     * @return the resolver uses to resolve references received in request parameters
-     */
-    private DocumentReferenceResolver<String> getCurrentMixedDocumentReferenceResolver()
-    {
-        return Utils.getComponent(DocumentReferenceResolver.TYPE_STRING, CURRENT_MIXED_RESOLVER_HINT);
-    }
-
     /**
      * Initialize and save the new document before editing it. Follow the steps done by the Save action.
      * 
@@ -312,7 +298,7 @@ private void initAndSaveDocument(XWikiContext context, XWikiDocument newDocument
 
         // Set the parent field.
         if (!StringUtils.isEmpty(parent)) {
-            DocumentReference parentReference = this.currentmixedReferenceResolver.resolve(parent);
+            DocumentReference parentReference = getCurrentMixedDocumentReferenceResolver().resolve(parent);
             newDocument.setParentReference(parentReference);
         }
 

programming_language: Java
filename: XWikiAction.java
change_type: ModificationType.MODIFY
diff: @@ -153,13 +153,6 @@ public abstract class XWikiAction implements LegacyAction
     @Inject
     protected Execution execution;
 
-    @Inject
-    protected ContextualAuthorizationManager autorization;
-
-    @Inject
-    @Named("currentmixed")
-    protected DocumentReferenceResolver<String> currentmixedReferenceResolver;
-
     /**
      * Indicate if the action allow asynchronous display (among which the XWiki initialization).
      */
@@ -170,6 +163,13 @@ public abstract class XWikiAction implements LegacyAction
      */
     protected boolean handleRedirectObject = false;
 
+    @Inject
+    @Named("currentmixed")
+    private DocumentReferenceResolver<String> currentmixedReferenceResolver;
+
+    @Inject
+    private ContextualAuthorizationManager autorization;
+
     private ContextualLocalizationManager localization;
 
     private JobProgressManager progress;
@@ -201,6 +201,24 @@ protected ContextualLocalizationManager getLocalization()
         return this.localization;
     }
 
+    /**
+     * @since 12.10.6
+     * @since 13.2RC1
+     */
+    protected DocumentReferenceResolver<String> getCurrentMixedDocumentReferenceResolver()
+    {
+        return this.currentmixedReferenceResolver;
+    }
+
+    /**
+     * @since 12.10.6
+     * @since 13.2RC1
+     */
+    protected ContextualAuthorizationManager getContextualAuthorizationManager()
+    {
+        return this.autorization;
+    }
+
     protected String localizePlainOrKey(String key, Object... parameters)
     {
         return StringUtils.defaultString(getLocalization().getTranslationPlain(key, parameters), key);
@@ -1158,10 +1176,10 @@ protected void setContentLength(XWikiResponse response, long length)
     protected DocumentReference resolveTemplate(String template)
     {
         if (StringUtils.isNotBlank(template)) {
-            DocumentReference templateReference = this.currentmixedReferenceResolver.resolve(template);
+            DocumentReference templateReference = getCurrentMixedDocumentReferenceResolver().resolve(template);
 
             // Make sure the current user have access to the template document before copying it
-            if (this.autorization.hasAccess(Right.VIEW, templateReference)) {
+            if (getContextualAuthorizationManager().hasAccess(Right.VIEW, templateReference)) {
                 return templateReference;
             }
         }

programming_language: Java
repo_url: https://github.com/xwiki/xwiki-platform
commit_details: repo_url: https://github.com/xwiki/xwiki-platform
author: Thomas Mortagne
author_date: 2021-03-12 17:00:38+01:00
msg: XWIKI-18430: Page content is revealed to users that don't have rights if used as a template for the creation of another page
repository: repo_url: https://github.com/xwiki/xwiki-platform
repo_name: xwiki/xwiki-platform
description: The XWiki platform
repo_language: Java
owner: xwiki
file_changes: filename: AdminAction.java
change_type: ModificationType.MODIFY
diff: @@ -129,7 +129,7 @@ public String render(XWikiContext context) throws XWikiException
             }
             context.put("tdoc", tdoc2);
             try {
-                tdoc2.readFromTemplate(peform, context);
+                readFromTemplate(tdoc2, peform.getTemplate(), context);
             } catch (XWikiException e) {
                 if (e.getCode() == XWikiException.ERROR_XWIKI_APP_DOCUMENT_NOT_EMPTY) {
                     context.put("exception", e);

programming_language: Java
filename: CreateAction.java
change_type: ModificationType.MODIFY
diff: @@ -299,7 +299,6 @@ private void initAndSaveDocument(XWikiContext context, XWikiDocument newDocument
         String parent) throws XWikiException
     {
         XWiki xwiki = context.getWiki();
-        DocumentReferenceResolver<String> resolver = getCurrentMixedDocumentReferenceResolver();
 
         // Set the locale and default locale, considering that we're creating the original version of the document
         // (not a translation).
@@ -309,12 +308,11 @@ private void initAndSaveDocument(XWikiContext context, XWikiDocument newDocument
         }
 
         // Copy the template.
-        DocumentReference templateReference = resolver.resolve(template);
-        newDocument.readFromTemplate(templateReference, context);
+        readFromTemplate(newDocument, template, context);
 
         // Set the parent field.
         if (!StringUtils.isEmpty(parent)) {
-            DocumentReference parentReference = resolver.resolve(parent);
+            DocumentReference parentReference = this.currentmixedReferenceResolver.resolve(parent);
             newDocument.setParentReference(parentReference);
         }
 

programming_language: Java
filename: EditAction.java
change_type: ModificationType.MODIFY
diff: @@ -102,7 +102,7 @@ protected XWikiDocument prepareEditedDocument(XWikiContext context) throws XWiki
         EditForm editForm = (EditForm) context.getForm();
 
         // Update the edited document based on the template specified on the request.
-        editedDocument.readFromTemplate(editForm, context);
+        readFromTemplate(editedDocument, editForm.getTemplate(), context);
 
         // The default values from the template can be overwritten by additional request parameters.
         updateDocumentTitleAndContentFromRequest(editedDocument, context);

programming_language: Java
filename: InlineAction.java
change_type: ModificationType.MODIFY
diff: @@ -82,7 +82,7 @@ public String render(XWikiContext context) throws XWikiException
                 doc2.setDefaultLanguage(context.getWiki().getLanguagePreference(context));
             }
             try {
-                doc2.readFromTemplate(peform, context);
+                readFromTemplate(doc2, peform.getTemplate(), context);
             } catch (XWikiException e) {
                 if (e.getCode() == XWikiException.ERROR_XWIKI_APP_DOCUMENT_NOT_EMPTY) {
                     return "docalreadyexists";
@@ -93,7 +93,7 @@ public String render(XWikiContext context) throws XWikiException
                 context.put("cdoc", doc2);
             } else {
                 XWikiDocument cdoc2 = cdoc.clone();
-                cdoc2.readFromTemplate(peform, context);
+                readFromTemplate(cdoc2, peform.getTemplate(), context);
                 context.put("cdoc", cdoc2);
             }
 

programming_language: Java
filename: SaveAction.java
change_type: ModificationType.MODIFY
diff: @@ -193,7 +193,7 @@ public boolean save(XWikiContext context) throws XWikiException
         }
 
         try {
-            tdoc.readFromTemplate(form.getTemplate(), context);
+            readFromTemplate(tdoc, form.getTemplate(), context);
         } catch (XWikiException e) {
             if (e.getCode() == XWikiException.ERROR_XWIKI_APP_DOCUMENT_NOT_EMPTY) {
                 context.put("exception", e);
@@ -569,7 +569,9 @@ private boolean isAsync(XWikiRequest request)
 
     private Job startCreateJob(EntityReference entityReference, EditForm editForm) throws XWikiException
     {
-        if (StringUtils.isBlank(editForm.getTemplate())) {
+        DocumentReference templateReference = resolveTemplate(editForm.getTemplate());
+
+        if (templateReference == null) {
             // No template specified, nothing more to do.
             return null;
         }
@@ -585,9 +587,6 @@ private Job startCreateJob(EntityReference entityReference, EditForm editForm) t
         // Set the target document.
         request.setEntityReferences(Arrays.asList(entityReference));
         // Set the template to use.
-        DocumentReferenceResolver<String> resolver =
-            Utils.getComponent(DocumentReferenceResolver.TYPE_STRING, "currentmixed");
-        EntityReference templateReference = resolver.resolve(editForm.getTemplate());
         request.setTemplateReference(templateReference);
         // We`ve already created and populated the fields of the target document, focus only on the remaining children
         // specified in the template.

programming_language: Java
filename: XWikiAction.java
change_type: ModificationType.MODIFY
diff: @@ -29,6 +29,7 @@
 import java.util.Vector;
 
 import javax.inject.Inject;
+import javax.inject.Named;
 import javax.script.ScriptContext;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
@@ -80,6 +81,8 @@
 import org.xwiki.resource.entity.EntityResourceReference;
 import org.xwiki.resource.internal.DefaultResourceReferenceHandlerChain;
 import org.xwiki.script.ScriptContextManager;
+import org.xwiki.security.authorization.ContextualAuthorizationManager;
+import org.xwiki.security.authorization.Right;
 import org.xwiki.stability.Unstable;
 import org.xwiki.template.TemplateManager;
 import org.xwiki.velocity.VelocityManager;
@@ -150,6 +153,13 @@ public abstract class XWikiAction implements LegacyAction
     @Inject
     protected Execution execution;
 
+    @Inject
+    protected ContextualAuthorizationManager autorization;
+
+    @Inject
+    @Named("currentmixed")
+    protected DocumentReferenceResolver<String> currentmixedReferenceResolver;
+
     /**
      * Indicate if the action allow asynchronous display (among which the XWiki initialization).
      */
@@ -1136,4 +1146,53 @@ protected void setContentLength(XWikiResponse response, long length)
         // Set the content length in the response
         response.setContentLengthLong(length);
     }
+
+    /**
+     * Helper used resolve the template passed to the action if the current user have access to it.
+     * 
+     * @param template the template to copy
+     * @return the reference of the template if not empty and the current user have access to it
+     * @since 12.10.6
+     * @since 13.2RC1
+     */
+    protected DocumentReference resolveTemplate(String template)
+    {
+        if (StringUtils.isNotBlank(template)) {
+            DocumentReference templateReference = this.currentmixedReferenceResolver.resolve(template);
+
+            // Make sure the current user have access to the template document before copying it
+            if (this.autorization.hasAccess(Right.VIEW, templateReference)) {
+                return templateReference;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Helper used by various actions to initialize a document by copying a template to it.
+     * 
+     * @param document the document to update
+     * @param template the template to copy
+     * @param context the XWiki context
+     * @return true if the document was updated, false otherwise (for example when the current user does not have view
+     *         right on the template document)
+     * @throws XWikiException when failing to copy the template
+     * @since 12.10.6
+     * @since 13.2RC1
+     */
+    @Unstable
+    protected boolean readFromTemplate(XWikiDocument document, String template, XWikiContext context)
+        throws XWikiException
+    {
+        DocumentReference templateReference = resolveTemplate(template);
+
+        if (templateReference != null) {
+            document.readFromTemplate(templateReference, context);
+
+            return true;
+        }
+
+        return false;
+    }
 }

programming_language: Java
filename: CreateActionTest.java
change_type: ModificationType.MODIFY
diff: @@ -28,9 +28,8 @@
 
 import javax.inject.Provider;
 
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 import org.xwiki.model.reference.DocumentReference;
 import org.xwiki.model.reference.EntityReference;
 import org.xwiki.model.reference.SpaceReference;
@@ -40,17 +39,20 @@
 import org.xwiki.query.QueryManager;
 import org.xwiki.security.authorization.Right;
 import org.xwiki.test.annotation.ComponentList;
+import org.xwiki.test.junit5.mockito.InjectMockComponents;
 
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.objects.BaseObject;
-import com.xpn.xwiki.test.MockitoOldcoreRule;
+import com.xpn.xwiki.test.MockitoOldcore;
+import com.xpn.xwiki.test.junit5.mockito.InjectMockitoOldcore;
+import com.xpn.xwiki.test.junit5.mockito.OldcoreTest;
 import com.xpn.xwiki.test.reference.ReferenceComponentList;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -65,13 +67,15 @@
  */
 @ComponentList
 @ReferenceComponentList
-public class CreateActionTest
+@OldcoreTest
+class CreateActionTest
 {
-    @Rule
-    public MockitoOldcoreRule oldcore = new MockitoOldcoreRule();
+    @InjectMockitoOldcore
+    MockitoOldcore oldcore;
 
     XWikiURLFactory mockURLFactory;
 
+    @InjectMockComponents
     CreateAction action;
 
     XWikiContext context;
@@ -82,46 +86,44 @@
 
     Query mockTemplateProvidersQuery;
 
-    @Before
-    public void setUp() throws Exception
+    @BeforeEach
+    public void beforeEach() throws Exception
     {
-        context = oldcore.getXWikiContext();
+        this.context = this.oldcore.getXWikiContext();
 
-        Utils.setComponentManager(oldcore.getMocker());
+        Utils.setComponentManager(this.oldcore.getMocker());
 
         QueryManager mockSecureQueryManager =
-            oldcore.getMocker().registerMockComponent((Type) QueryManager.class, "secure");
+            this.oldcore.getMocker().registerMockComponent((Type) QueryManager.class, "secure");
 
-        mockTemplateProvidersQuery = mock(Query.class);
-        when(mockSecureQueryManager.createQuery(any(), any())).thenReturn(mockTemplateProvidersQuery);
-        when(mockTemplateProvidersQuery.execute()).thenReturn(Collections.emptyList());
+        this.mockTemplateProvidersQuery = mock(Query.class);
+        when(mockSecureQueryManager.createQuery(any(), any())).thenReturn(this.mockTemplateProvidersQuery);
+        when(this.mockTemplateProvidersQuery.execute()).thenReturn(Collections.emptyList());
 
-        when(oldcore.getMockContextualAuthorizationManager().hasAccess(any(Right.class), any(EntityReference.class)))
-            .thenReturn(true);
+        when(this.oldcore.getMockContextualAuthorizationManager().hasAccess(any(Right.class),
+            any(EntityReference.class))).thenReturn(true);
 
         Provider<DocumentReference> mockDocumentReferenceProvider =
-            oldcore.getMocker().registerMockComponent(DocumentReference.TYPE_PROVIDER);
+            this.oldcore.getMocker().registerMockComponent(DocumentReference.TYPE_PROVIDER);
         when(mockDocumentReferenceProvider.get())
             .thenReturn(new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome"));
 
-        mockURLFactory = mock(XWikiURLFactory.class);
-        context.setURLFactory(mockURLFactory);
+        this.mockURLFactory = mock(XWikiURLFactory.class);
+        this.context.setURLFactory(this.mockURLFactory);
 
-        action = new CreateAction();
+        this.mockRequest = mock(XWikiRequest.class);
+        this.context.setRequest(this.mockRequest);
 
-        mockRequest = mock(XWikiRequest.class);
-        context.setRequest(mockRequest);
+        this.mockResponse = mock(XWikiResponse.class);
+        this.context.setResponse(this.mockResponse);
 
-        mockResponse = mock(XWikiResponse.class);
-        context.setResponse(mockResponse);
-
-        when(mockRequest.get("type")).thenReturn("plain");
+        when(this.mockRequest.get("type")).thenReturn("plain");
 
         this.oldcore.getMocker().registerMockComponent(ObservationManager.class);
     }
 
     @Test
-    public void newDocumentFromURL() throws Exception
+    void newDocumentFromURL() throws Exception
     {
         // new document = xwiki:X.Y
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("X"), "Y");
@@ -144,7 +146,7 @@ public void newDocumentFromURL() throws Exception
     }
 
     @Test
-    public void newDocumentButNonTerminalFromURL() throws Exception
+    void newDocumentButNonTerminalFromURL() throws Exception
     {
         // new document = xwiki:X.Y
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("X"), "Y");
@@ -170,7 +172,7 @@ public void newDocumentButNonTerminalFromURL() throws Exception
     }
 
     @Test
-    public void newDocumentFromURLWhenNoType() throws Exception
+    void newDocumentFromURLWhenNoType() throws Exception
     {
         // No type has been set by the user
         when(mockRequest.get("type")).thenReturn(null);
@@ -193,7 +195,7 @@ public void newDocumentFromURLWhenNoType() throws Exception
     }
 
     @Test
-    public void newDocumentWebHomeTopLevelFromURL() throws Exception
+    void newDocumentWebHomeTopLevelFromURL() throws Exception
     {
         // new document = xwiki:X.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("X"), "WebHome");
@@ -217,7 +219,7 @@ public void newDocumentWebHomeTopLevelFromURL() throws Exception
     }
 
     @Test
-    public void newDocumentWebHomeFromURL() throws Exception
+    void newDocumentWebHomeFromURL() throws Exception
     {
         // new document = xwiki:X.Y.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("X", "Y"), "WebHome");
@@ -242,7 +244,7 @@ public void newDocumentWebHomeFromURL() throws Exception
     }
 
     @Test
-    public void newDocumentWebHomeButTerminalFromURL() throws Exception
+    void newDocumentWebHomeButTerminalFromURL() throws Exception
     {
         // new document = xwiki:X.Y.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("X", "Y"), "WebHome");
@@ -269,7 +271,7 @@ public void newDocumentWebHomeButTerminalFromURL() throws Exception
     }
 
     @Test
-    public void newDocumentWebHomeTopLevelSpaceButTerminalFromURL() throws Exception
+    void newDocumentWebHomeTopLevelSpaceButTerminalFromURL() throws Exception
     {
         // new document = xwiki:X.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("X"), "WebHome");
@@ -294,12 +296,11 @@ public void newDocumentWebHomeTopLevelSpaceButTerminalFromURL() throws Exception
         // none was able to be deducted from the given information. The user needs to specify more info in order to
         // continue.
         // We should not get this far so no redirect should be done, just the template will be rendered.
-        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(),
-            any(), any(XWikiContext.class));
+        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(), any(), any(XWikiContext.class));
     }
 
     @Test
-    public void existingDocumentFromUINoName() throws Exception
+    void existingDocumentFromUINoName() throws Exception
     {
         // current document = xwiki:Main.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
@@ -320,12 +321,11 @@ public void existingDocumentFromUINoName() throws Exception
         assertEquals("create", result);
 
         // We should not get this far so no redirect should be done, just the template will be rendered.
-        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(),
-            any(), any(XWikiContext.class));
+        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(), any(), any(XWikiContext.class));
     }
 
     @Test
-    public void existingDocumentFromUI() throws Exception
+    void existingDocumentFromUI() throws Exception
     {
         // current document = xwiki:Main.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
@@ -353,7 +353,7 @@ public void existingDocumentFromUI() throws Exception
     }
 
     @Test
-    public void existingDocumentFromUICheckEscaping() throws Exception
+    void existingDocumentFromUICheckEscaping() throws Exception
     {
         // current document = xwiki:Main.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
@@ -381,7 +381,7 @@ public void existingDocumentFromUICheckEscaping() throws Exception
     }
 
     @Test
-    public void existingDocumentTerminalFromUI() throws Exception
+    void existingDocumentTerminalFromUI() throws Exception
     {
         // current document = xwiki:Main.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
@@ -410,7 +410,7 @@ public void existingDocumentTerminalFromUI() throws Exception
     }
 
     @Test
-    public void existingDocumentTerminalFromUICheckEscaping() throws Exception
+    void existingDocumentTerminalFromUICheckEscaping() throws Exception
     {
         // current document = xwiki:Main.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
@@ -439,7 +439,7 @@ public void existingDocumentTerminalFromUICheckEscaping() throws Exception
     }
 
     @Test
-    public void existingDocumentTerminalFromUIButAlreadyExisting() throws Exception
+    void existingDocumentTerminalFromUIButAlreadyExisting() throws Exception
     {
         // current document = xwiki:Main.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
@@ -473,12 +473,11 @@ public void existingDocumentTerminalFromUIButAlreadyExisting() throws Exception
         assertEquals(XWikiException.ERROR_XWIKI_APP_DOCUMENT_NOT_EMPTY, exception.getCode());
 
         // We should not get this far so no redirect should be done, just the template will be rendered.
-        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(),
-            any(), any(XWikiContext.class));
+        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(), any(), any(XWikiContext.class));
     }
 
     @Test
-    public void notExistingDocumentFromUIButNameTooLong() throws Exception
+    void notExistingDocumentFromUIButNameTooLong() throws Exception
     {
         // current document = xwiki:Main.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
@@ -505,12 +504,11 @@ public void notExistingDocumentFromUIButNameTooLong() throws Exception
         assertEquals(XWikiException.ERROR_XWIKI_APP_DOCUMENT_PATH_TOO_LONG, exception.getCode());
 
         // We should not get this far so no redirect should be done, just the template will be rendered.
-        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(),
-            any(), any(XWikiContext.class));
+        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(), any(), any(XWikiContext.class));
     }
 
     @Test
-    public void notExistingDocumentFromUIButSpaceTooLong() throws Exception
+    void notExistingDocumentFromUIButSpaceTooLong() throws Exception
     {
         // current document = xwiki:Main.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
@@ -537,12 +535,11 @@ public void notExistingDocumentFromUIButSpaceTooLong() throws Exception
         assertEquals(XWikiException.ERROR_XWIKI_APP_DOCUMENT_PATH_TOO_LONG, exception.getCode());
 
         // We should not get this far so no redirect should be done, just the template will be rendered.
-        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(),
-            any(), any(XWikiContext.class));
+        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(), any(), any(XWikiContext.class));
     }
 
     @Test
-    public void existingDocumentFromUITopLevelDocument() throws Exception
+    void existingDocumentFromUITopLevelDocument() throws Exception
     {
         // current document = xwiki:Main.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
@@ -573,7 +570,7 @@ public void existingDocumentFromUITopLevelDocument() throws Exception
      */
 
     @Test
-    public void existingDocumentFromUIDeprecated() throws Exception
+    void existingDocumentFromUIDeprecated() throws Exception
     {
         // current document = xwiki:Main.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
@@ -601,7 +598,7 @@ public void existingDocumentFromUIDeprecated() throws Exception
     }
 
     @Test
-    public void existingDocumentFromUIDeprecatedCheckEscaping() throws Exception
+    void existingDocumentFromUIDeprecatedCheckEscaping() throws Exception
     {
         // current document = xwiki:Main.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
@@ -630,7 +627,7 @@ public void existingDocumentFromUIDeprecatedCheckEscaping() throws Exception
     }
 
     @Test
-    public void existingDocumentNonTerminalFromUIDeprecated() throws Exception
+    void existingDocumentNonTerminalFromUIDeprecated() throws Exception
     {
         // current document = xwiki:Main.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
@@ -658,7 +655,7 @@ public void existingDocumentNonTerminalFromUIDeprecated() throws Exception
     }
 
     @Test
-    public void existingDocumentNonTerminalFromUIDeprecatedIgnoringPage() throws Exception
+    void existingDocumentNonTerminalFromUIDeprecatedIgnoringPage() throws Exception
     {
         // current document = xwiki:Main.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
@@ -688,7 +685,7 @@ public void existingDocumentNonTerminalFromUIDeprecatedIgnoringPage() throws Exc
     }
 
     @Test
-    public void existingDocumentNonTerminalFromUIDeprecatedCheckEscaping() throws Exception
+    void existingDocumentNonTerminalFromUIDeprecatedCheckEscaping() throws Exception
     {
         // current document = xwiki:Main.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
@@ -721,7 +718,7 @@ public void existingDocumentNonTerminalFromUIDeprecatedCheckEscaping() throws Ex
      */
 
     @Test
-    public void existingDocumentFromUITemplateProviderExistingButNoneSelected() throws Exception
+    void existingDocumentFromUITemplateProviderExistingButNoneSelected() throws Exception
     {
         // current document = xwiki:Main.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
@@ -737,7 +734,7 @@ public void existingDocumentFromUITemplateProviderExistingButNoneSelected() thro
 
         // Mock 1 existing template provider
         mockExistingTemplateProviders("XWiki.MyTemplateProvider",
-            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST);
+            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList());
 
         // Run the action
         String result = action.render(context);
@@ -748,8 +745,7 @@ public void existingDocumentFromUITemplateProviderExistingButNoneSelected() thro
         assertEquals("create", result);
 
         // We should not get this far so no redirect should be done, just the template will be rendered.
-        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(),
-            any(), any(XWikiContext.class));
+        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(), any(), any(XWikiContext.class));
     }
 
     /**
@@ -845,7 +841,7 @@ private void mockTemplateDocumentExisting(String templateDocumentFullName,
     }
 
     @Test
-    public void existingDocumentFromUITemplateProviderSpecified() throws Exception
+    void existingDocumentFromUITemplateProviderSpecified() throws Exception
     {
         // current document = xwiki:Main.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
@@ -863,7 +859,7 @@ public void existingDocumentFromUITemplateProviderSpecified() throws Exception
 
         // Mock 1 existing template provider
         mockExistingTemplateProviders(templateProviderFullName,
-            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST);
+            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList());
 
         // Run the action
         String result = action.render(context);
@@ -879,7 +875,7 @@ public void existingDocumentFromUITemplateProviderSpecified() throws Exception
     }
 
     @Test
-    public void existingDocumentFromUITemplateProviderSpecifiedRestrictionExists() throws Exception
+    void existingDocumentFromUITemplateProviderSpecifiedRestrictionExists() throws Exception
     {
         // current document = xwiki:Main.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
@@ -915,7 +911,7 @@ public void existingDocumentFromUITemplateProviderSpecifiedRestrictionExists() t
     }
 
     @Test
-    public void existingDocumentFromUITemplateProviderSpecifiedRestrictionExistsOnParentSpace() throws Exception
+    void existingDocumentFromUITemplateProviderSpecifiedRestrictionExistsOnParentSpace() throws Exception
     {
         // current document = xwiki:Main.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
@@ -953,7 +949,7 @@ public void existingDocumentFromUITemplateProviderSpecifiedRestrictionExistsOnPa
     }
 
     @Test
-    public void existingDocumentFromUITemplateProviderSpecifiedButNotAllowed() throws Exception
+    void existingDocumentFromUITemplateProviderSpecifiedButNotAllowed() throws Exception
     {
         // current document = xwiki:Main.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
@@ -988,12 +984,11 @@ public void existingDocumentFromUITemplateProviderSpecifiedButNotAllowed() throw
         assertEquals(XWikiException.ERROR_XWIKI_APP_TEMPLATE_NOT_AVAILABLE, exception.getCode());
 
         // We should not get this far so no redirect should be done, just the template will be rendered.
-        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(),
-            any(), any(XWikiContext.class));
+        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(), any(), any(XWikiContext.class));
     }
 
     @Test
-    public void newDocumentFromURLTemplateProviderSpecifiedButNotAllowed() throws Exception
+    void newDocumentFromURLTemplateProviderSpecifiedButNotAllowed() throws Exception
     {
         // new document = xwiki:X.Y
         DocumentReference documentReference =
@@ -1027,12 +1022,11 @@ public void newDocumentFromURLTemplateProviderSpecifiedButNotAllowed() throws Ex
         assertEquals(XWikiException.ERROR_XWIKI_APP_TEMPLATE_NOT_AVAILABLE, exception.getCode());
 
         // We should not get this far so no redirect should be done, just the template will be rendered.
-        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(),
-            any(), any(XWikiContext.class));
+        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(), any(), any(XWikiContext.class));
     }
 
     @Test
-    public void newDocumentWebHomeFromURLTemplateProviderSpecifiedButNotAllowed() throws Exception
+    void newDocumentWebHomeFromURLTemplateProviderSpecifiedButNotAllowed() throws Exception
     {
         // new document = xwiki:X.Y.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("X", "Y"), "WebHome");
@@ -1065,12 +1059,11 @@ public void newDocumentWebHomeFromURLTemplateProviderSpecifiedButNotAllowed() th
         assertEquals(XWikiException.ERROR_XWIKI_APP_TEMPLATE_NOT_AVAILABLE, exception.getCode());
 
         // We should not get this far so no redirect should be done, just the template will be rendered.
-        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(),
-            any(), any(XWikiContext.class));
+        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(), any(), any(XWikiContext.class));
     }
 
     @Test
-    public void newDocumentWebHomeFromURLTemplateProviderSpecifiedTerminal() throws Exception
+    void newDocumentWebHomeFromURLTemplateProviderSpecifiedTerminal() throws Exception
     {
         // new document = xwiki:X.Y.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("X", "Y"), "WebHome");
@@ -1086,7 +1079,8 @@ public void newDocumentWebHomeFromURLTemplateProviderSpecifiedTerminal() throws
 
         // Mock 1 existing template provider
         mockExistingTemplateProviders(templateProviderFullName,
-            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST, true);
+            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList(),
+            true);
 
         // Run the action
         String result = action.render(context);
@@ -1103,8 +1097,7 @@ public void newDocumentWebHomeFromURLTemplateProviderSpecifiedTerminal() throws
     }
 
     @Test
-    public void newDocumentWebHomeFromURLTemplateProviderSpecifiedTerminalOverriddenFromUIToNonTerminal()
-        throws Exception
+    void newDocumentWebHomeFromURLTemplateProviderSpecifiedTerminalOverriddenFromUIToNonTerminal() throws Exception
     {
         // new document = xwiki:X.Y.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("X", "Y"), "WebHome");
@@ -1121,7 +1114,8 @@ public void newDocumentWebHomeFromURLTemplateProviderSpecifiedTerminalOverridden
 
         // Mock 1 existing template provider
         mockExistingTemplateProviders(templateProviderFullName,
-            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST, true);
+            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList(),
+            true);
 
         // Run the action
         String result = action.render(context);
@@ -1138,7 +1132,7 @@ public void newDocumentWebHomeFromURLTemplateProviderSpecifiedTerminalOverridden
     }
 
     @Test
-    public void newDocumentFromURLTemplateProviderSpecifiedNonTerminal() throws Exception
+    void newDocumentFromURLTemplateProviderSpecifiedNonTerminal() throws Exception
     {
         // new document = xwiki:X.Y
         DocumentReference documentReference = new DocumentReference("xwiki", "X", "Y");
@@ -1154,7 +1148,7 @@ public void newDocumentFromURLTemplateProviderSpecifiedNonTerminal() throws Exce
 
         // Mock 1 existing template provider
         mockExistingTemplateProviders(templateProviderFullName,
-            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST,
+            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList(),
             false);
 
         // Run the action
@@ -1172,7 +1166,7 @@ public void newDocumentFromURLTemplateProviderSpecifiedNonTerminal() throws Exce
     }
 
     @Test
-    public void newDocumentFromURLTemplateProviderSpecifiedNonTerminalButOverriddenFromUITerminal() throws Exception
+    void newDocumentFromURLTemplateProviderSpecifiedNonTerminalButOverriddenFromUITerminal() throws Exception
     {
         // new document = xwiki:X.Y
         DocumentReference documentReference = new DocumentReference("xwiki", "X", "Y");
@@ -1189,7 +1183,7 @@ public void newDocumentFromURLTemplateProviderSpecifiedNonTerminalButOverriddenF
 
         // Mock 1 existing template provider
         mockExistingTemplateProviders(templateProviderFullName,
-            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST,
+            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList(),
             false);
 
         // Run the action
@@ -1207,7 +1201,7 @@ public void newDocumentFromURLTemplateProviderSpecifiedNonTerminalButOverriddenF
     }
 
     @Test
-    public void existingDocumentFromUITemplateSpecified() throws Exception
+    void existingDocumentFromUITemplateSpecified() throws Exception
     {
         // current document = xwiki:Main.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
@@ -1243,7 +1237,7 @@ public void existingDocumentFromUITemplateSpecified() throws Exception
     }
 
     @Test
-    public void existingDocumentFromUITemplateProviderSpecifiedTerminal() throws Exception
+    void existingDocumentFromUITemplateProviderSpecifiedTerminal() throws Exception
     {
         // current document = xwiki:Main.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
@@ -1262,7 +1256,8 @@ public void existingDocumentFromUITemplateProviderSpecifiedTerminal() throws Exc
 
         // Mock 1 existing template provider that creates terminal documents.
         mockExistingTemplateProviders(templateProviderFullName,
-            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST, true);
+            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList(),
+            true);
 
         // Run the action
         String result = action.render(context);
@@ -1279,7 +1274,7 @@ public void existingDocumentFromUITemplateProviderSpecifiedTerminal() throws Exc
     }
 
     @Test
-    public void existingDocumentFromUITemplateProviderSpecifiedTerminalOverridenFromUIToNonTerminal() throws Exception
+    void existingDocumentFromUITemplateProviderSpecifiedTerminalOverridenFromUIToNonTerminal() throws Exception
     {
         // current document = xwiki:Main.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
@@ -1299,7 +1294,8 @@ public void existingDocumentFromUITemplateProviderSpecifiedTerminalOverridenFrom
 
         // Mock 1 existing template provider that creates terminal documents.
         mockExistingTemplateProviders(templateProviderFullName,
-            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST, true);
+            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList(),
+            true);
 
         // Run the action
         String result = action.render(context);
@@ -1316,7 +1312,7 @@ public void existingDocumentFromUITemplateProviderSpecifiedTerminalOverridenFrom
     }
 
     @Test
-    public void existingDocumentFromUITemplateProviderSpecifiedNonTerminal() throws Exception
+    void existingDocumentFromUITemplateProviderSpecifiedNonTerminal() throws Exception
     {
         // current document = xwiki:Main.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
@@ -1335,7 +1331,7 @@ public void existingDocumentFromUITemplateProviderSpecifiedNonTerminal() throws
 
         // Mock 1 existing template provider that creates terminal documents.
         mockExistingTemplateProviders(templateProviderFullName,
-            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST,
+            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList(),
             false);
 
         // Run the action
@@ -1353,7 +1349,7 @@ public void existingDocumentFromUITemplateProviderSpecifiedNonTerminal() throws
     }
 
     @Test
-    public void existingDocumentFromUITemplateProviderSpecifiedNonTerminalOverridenFromUIToTerminal() throws Exception
+    void existingDocumentFromUITemplateProviderSpecifiedNonTerminalOverridenFromUIToTerminal() throws Exception
     {
         // current document = xwiki:Main.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
@@ -1373,7 +1369,7 @@ public void existingDocumentFromUITemplateProviderSpecifiedNonTerminalOverridenF
 
         // Mock 1 existing template provider that creates terminal documents.
         mockExistingTemplateProviders(templateProviderFullName,
-            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST,
+            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList(),
             false);
 
         // Run the action
@@ -1391,7 +1387,7 @@ public void existingDocumentFromUITemplateProviderSpecifiedNonTerminalOverridenF
     }
 
     @Test
-    public void newDocumentWebHomeFromURLTemplateProviderSpecifiedButOldPageType() throws Exception
+    void newDocumentWebHomeFromURLTemplateProviderSpecifiedButOldPageType() throws Exception
     {
         // new document = xwiki:X.Y.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("X", "Y"), "WebHome");
@@ -1407,7 +1403,7 @@ public void newDocumentWebHomeFromURLTemplateProviderSpecifiedButOldPageType() t
 
         // Mock 1 existing template provider
         mockExistingTemplateProviders(templateProviderFullName,
-            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST, null,
+            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList(), null,
             "page");
 
         // Run the action
@@ -1426,7 +1422,7 @@ public void newDocumentWebHomeFromURLTemplateProviderSpecifiedButOldPageType() t
     }
 
     @Test
-    public void newDocumentWebHomeFromURLTemplateProviderSpecifiedButOldPageTypeButOverriddenFromUIToNonTerminal()
+    void newDocumentWebHomeFromURLTemplateProviderSpecifiedButOldPageTypeButOverriddenFromUIToNonTerminal()
         throws Exception
     {
         // new document = xwiki:X.Y.WebHome
@@ -1444,7 +1440,7 @@ public void newDocumentWebHomeFromURLTemplateProviderSpecifiedButOldPageTypeButO
 
         // Mock 1 existing template provider
         mockExistingTemplateProviders(templateProviderFullName,
-            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST, null,
+            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList(), null,
             "page");
 
         // Run the action
@@ -1463,7 +1459,7 @@ public void newDocumentWebHomeFromURLTemplateProviderSpecifiedButOldPageTypeButO
     }
 
     @Test
-    public void existingDocumentFromUITemplateProviderSpecifiedButOldSpaceType() throws Exception
+    void existingDocumentFromUITemplateProviderSpecifiedButOldSpaceType() throws Exception
     {
         // current document = xwiki:Main.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
@@ -1481,7 +1477,7 @@ public void existingDocumentFromUITemplateProviderSpecifiedButOldSpaceType() thr
 
         // Mock 1 existing template provider
         mockExistingTemplateProviders(templateProviderFullName,
-            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST, null,
+            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList(), null,
             "space");
 
         // Run the action
@@ -1500,8 +1496,7 @@ public void existingDocumentFromUITemplateProviderSpecifiedButOldSpaceType() thr
     }
 
     @Test
-    public void existingDocumentFromUITemplateProviderSpecifiedButOldSpaceTypeButOverridenFromUIToTerminal()
-        throws Exception
+    void existingDocumentFromUITemplateProviderSpecifiedButOldSpaceTypeButOverridenFromUIToTerminal() throws Exception
     {
         // current document = xwiki:Main.WebHome
         DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("Main"), "WebHome");
@@ -1520,7 +1515,7 @@ public void existingDocumentFromUITemplateProviderSpecifiedButOldSpaceTypeButOve
 
         // Mock 1 existing template provider
         mockExistingTemplateProviders(templateProviderFullName,
-            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST, null,
+            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList(), null,
             "space");
 
         // Run the action
@@ -1538,7 +1533,7 @@ public void existingDocumentFromUITemplateProviderSpecifiedButOldSpaceTypeButOve
     }
 
     @Test
-    public void newDocumentWebHomeFromURLTemplateProviderSpecifiedWithSaveAndEdit() throws Exception
+    void newDocumentWebHomeFromURLTemplateProviderSpecifiedWithSaveAndEdit() throws Exception
     {
         // Mock the document to create.
         DocumentReference documentReference = new DocumentReference("xwiki", "X", "Y");
@@ -1559,11 +1554,11 @@ public void newDocumentWebHomeFromURLTemplateProviderSpecifiedWithSaveAndEdit()
         this.context.setUserReference(userReference);
 
         // Mock the creation request.
-        when(mockRequest.getParameter("spaceReference")).thenReturn("X");
-        when(mockRequest.getParameter("name")).thenReturn("Y");
-        when(mockRequest.getParameter("title")).thenReturn("Yippee");
+        when(this.mockRequest.getParameter("spaceReference")).thenReturn("X");
+        when(this.mockRequest.getParameter("name")).thenReturn("Y");
+        when(this.mockRequest.getParameter("title")).thenReturn("Yippee");
         String templateProviderFullName = "XWiki.MyTemplateProvider";
-        when(mockRequest.getParameter("templateprovider")).thenReturn(templateProviderFullName);
+        when(this.mockRequest.getParameter("templateprovider")).thenReturn(templateProviderFullName);
 
         // Mock the template provider.
         mockExistingTemplateProviders(templateProviderFullName,

programming_language: Java
filename: SaveActionTest.java
change_type: ModificationType.MODIFY
diff: @@ -24,18 +24,27 @@
 
 import javax.inject.Named;
 
-import org.apache.commons.lang.time.DateUtils;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.suigeneris.jrcs.rcs.Version;
 import org.xwiki.configuration.ConfigurationSource;
 import org.xwiki.context.Execution;
+import org.xwiki.job.Job;
 import org.xwiki.model.reference.DocumentReference;
 import org.xwiki.model.validation.EntityNameValidation;
 import org.xwiki.model.validation.EntityNameValidationConfiguration;
 import org.xwiki.model.validation.EntityNameValidationManager;
+import org.xwiki.refactoring.job.CreateRequest;
+import org.xwiki.refactoring.script.RefactoringScriptService;
+import org.xwiki.refactoring.script.RequestFactory;
+import org.xwiki.script.service.ScriptService;
+import org.xwiki.security.authorization.ContextualAuthorizationManager;
+import org.xwiki.security.authorization.Right;
 import org.xwiki.test.annotation.ComponentList;
+import org.xwiki.test.junit5.mockito.InjectComponentManager;
+import org.xwiki.test.junit5.mockito.InjectMockComponents;
 import org.xwiki.test.junit5.mockito.MockComponent;
+import org.xwiki.test.mockito.MockitoComponentManager;
 
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
@@ -54,6 +63,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -65,13 +75,16 @@
 @ComponentList
 @ReferenceComponentList
 @OldcoreTest(mockXWiki = false)
-public class SaveActionTest
+class SaveActionTest
 {
     private static final DocumentReference USER_REFERENCE = new DocumentReference("xwiki", "XWiki", "FooBar");
 
     @InjectMockitoOldcore
     private MockitoOldcore oldcore;
 
+    @InjectComponentManager
+    private MockitoComponentManager componentManager;
+
     @MockComponent
     private EntityNameValidationManager entityNameValidationManager;
 
@@ -85,11 +98,15 @@
     @Named("xwikiproperties")
     private ConfigurationSource propertiesConf;
 
+    @MockComponent
+    private ContextualAuthorizationManager autorization;
+
     @MockComponent
     private DocumentRevisionProvider documentRevisionProvider;
 
     private XWikiContext context;
 
+    @InjectMockComponents
     private SaveAction saveAction;
 
     private XWikiRequest mockRequest;
@@ -107,30 +124,28 @@
     @BeforeEach
     void setup()
     {
-        this.saveAction = new SaveAction();
-
-        context = oldcore.getXWikiContext();
+        this.context = this.oldcore.getXWikiContext();
 
-        xWiki = mock(XWiki.class);
-        context.setWiki(this.xWiki);
+        this.xWiki = mock(XWiki.class);
+        this.context.setWiki(this.xWiki);
 
-        mockRequest = mock(XWikiRequest.class);
-        context.setRequest(mockRequest);
+        this.mockRequest = mock(XWikiRequest.class);
+        this.context.setRequest(this.mockRequest);
 
-        mockResponse = mock(XWikiResponse.class);
-        context.setResponse(mockResponse);
+        this.mockResponse = mock(XWikiResponse.class);
+        this.context.setResponse(this.mockResponse);
 
-        mockDocument = mock(XWikiDocument.class);
-        context.setDoc(mockDocument);
+        this.mockDocument = mock(XWikiDocument.class);
+        this.context.setDoc(this.mockDocument);
 
-        mockClonedDocument = mock(XWikiDocument.class);
-        when(mockDocument.clone()).thenReturn(mockClonedDocument);
+        this.mockClonedDocument = mock(XWikiDocument.class);
+        when(this.mockDocument.clone()).thenReturn(this.mockClonedDocument);
 
-        mockForm = mock(EditForm.class);
-        context.setForm(mockForm);
+        this.mockForm = mock(EditForm.class);
+        this.context.setForm(this.mockForm);
         when(this.entityNameValidationConfiguration.useValidation()).thenReturn(false);
 
-        context.setUserReference(USER_REFERENCE);
+        this.context.setUserReference(USER_REFERENCE);
     }
 
     @Test
@@ -146,7 +161,7 @@ void newDocumentInvalidName() throws Exception
 
         assertTrue(saveAction.save(this.context));
         assertEquals("entitynamevalidation.create.invalidname", context.get("message"));
-        assertArrayEquals(new Object[] { "Foo.Bar" }, (Object[]) context.get("messageParameters"));
+        assertArrayEquals(new Object[] {"Foo.Bar"}, (Object[]) context.get("messageParameters"));
     }
 
     @Test
@@ -159,7 +174,6 @@ void validSave() throws Exception
         assertFalse(saveAction.save(this.context));
         assertEquals(new Version("1.2"), this.context.get("SaveAction.savedObjectVersion"));
 
-        verify(mockClonedDocument).readFromTemplate("", this.context);
         verify(mockClonedDocument).setAuthor("XWiki.FooBar");
         verify(mockClonedDocument).setMetaDataDirty(true);
         verify(this.xWiki).checkSavingDocument(USER_REFERENCE, mockClonedDocument, "My Changes", false, this.context);
@@ -181,8 +195,8 @@ void validSaveNewTranslation() throws Exception
         when(mockRequest.getParameter("isNew")).thenReturn("true");
         assertFalse(saveAction.save(this.context));
         assertEquals(new Version("1.1"), this.context.get("SaveAction.savedObjectVersion"));
-        verify(this.xWiki).checkSavingDocument(eq(USER_REFERENCE), any(XWikiDocument.class), eq(""),
-            eq(false), eq(this.context));
+        verify(this.xWiki).checkSavingDocument(eq(USER_REFERENCE), any(XWikiDocument.class), eq(""), eq(false),
+            eq(this.context));
         verify(this.xWiki).saveDocument(any(XWikiDocument.class), eq(""), eq(false), eq(this.context));
     }
 
@@ -210,8 +224,8 @@ void validSaveOldTranslation() throws Exception
     }
 
     /**
-     * This tests aims at checking the usecase when uploading an image in the WYSIWYG editor before the first save
-     * and saving afterwards.
+     * This tests aims at checking the usecase when uploading an image in the WYSIWYG editor before the first save and
+     * saving afterwards.
      */
     @Test
     void validSaveRequestImageUploadAndConflictCheck() throws Exception
@@ -237,12 +251,38 @@ void validSaveRequestImageUploadAndConflictCheck() throws Exception
         assertFalse(saveAction.save(this.context));
         assertEquals(new Version("1.2"), this.context.get("SaveAction.savedObjectVersion"));
 
-        verify(mockClonedDocument).readFromTemplate("", this.context);
         verify(mockClonedDocument).setAuthor("XWiki.FooBar");
         verify(mockClonedDocument).setMetaDataDirty(true);
         verify(this.xWiki).checkSavingDocument(USER_REFERENCE, mockClonedDocument, "My Changes", false, this.context);
         verify(this.xWiki).saveDocument(mockClonedDocument, "My Changes", false, this.context);
         verify(mockClonedDocument).removeLock(this.context);
+    }
+
+    @Test
+    void saveFromTemplate() throws Exception
+    {
+        when(this.mockForm.getTemplate()).thenReturn("TemplateSpace.TemplateDocument");
+        DocumentReference templateReference =
+            new DocumentReference(context.getWikiId(), "TemplateSpace", "TemplateDocument");
+
+        when(this.autorization.hasAccess(Right.VIEW, templateReference)).thenReturn(false);
+
+        assertFalse(this.saveAction.save(this.context));
+
+        verify(this.mockClonedDocument, never()).readFromTemplate(templateReference, this.context);
+
+        when(this.autorization.hasAccess(Right.VIEW, templateReference)).thenReturn(true);
+        RefactoringScriptService refactoring = mock(RefactoringScriptService.class);
+        RequestFactory requestFactory = mock(RequestFactory.class);
+        when(refactoring.getRequestFactory()).thenReturn(requestFactory);
+        CreateRequest request = mock(CreateRequest.class);
+        when(requestFactory.createCreateRequest(any())).thenReturn(request);
+        Job job = mock(Job.class);
+        when(refactoring.create(request)).thenReturn(job);
+        this.componentManager.registerComponent(ScriptService.class, "refactoring", refactoring);
+
+        assertFalse(this.saveAction.save(this.context));
 
+        verify(this.mockClonedDocument).readFromTemplate(templateReference, this.context);
     }
 }

programming_language: Java