CVE-2022-23617 (Java, published 2022-02-09T21:15Z)
Description: value: 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 v3 base score: 6.5)
Weakness: CWE-862 \u2014 Missing Authorization
The product does not perform an authorization check when an actor attempts to access a resource or perform an action.
Repository: https://github.com/xwiki/xwiki-platform
Files changed:
xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/web/AdminAction.java
xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/web/CreateAction.java
xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/web/EditAction.java
xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/web/InlineAction.java
xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/web/SaveAction.java
xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/web/XWikiAction.java
xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/web/CreateActionTest.java
xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/web/SaveActionTest.java
Commit message: XWIKI-18430: Page content is revealed to users that don't have rights if used as a template for the creation of another page


Vulnerable code:
                tdoc2.readFromTemplate(peform, context);
        DocumentReferenceResolver<String> resolver = getCurrentMixedDocumentReferenceResolver();
        DocumentReference templateReference = resolver.resolve(template);
        newDocument.readFromTemplate(templateReference, context);
            DocumentReference parentReference = resolver.resolve(parent);
        editedDocument.readFromTemplate(editForm, context);
                doc2.readFromTemplate(peform, context);
                cdoc2.readFromTemplate(peform, context);
            tdoc.readFromTemplate(form.getTemplate(), context);
        if (StringUtils.isBlank(editForm.getTemplate())) {
        DocumentReferenceResolver<String> resolver =
            Utils.getComponent(DocumentReferenceResolver.TYPE_STRING, "currentmixed");
        EntityReference templateReference = resolver.resolve(editForm.getTemplate());
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import com.xpn.xwiki.test.MockitoOldcoreRule;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
public class CreateActionTest
    @Rule
    public MockitoOldcoreRule oldcore = new MockitoOldcoreRule();
    @Before
    public void setUp() throws Exception
        context = oldcore.getXWikiContext();
        Utils.setComponentManager(oldcore.getMocker());
            oldcore.getMocker().registerMockComponent((Type) QueryManager.class, "secure");
        mockTemplateProvidersQuery = mock(Query.class);
        when(mockSecureQueryManager.createQuery(any(), any())).thenReturn(mockTemplateProvidersQuery);
        when(mockTemplateProvidersQuery.execute()).thenReturn(Collections.emptyList());
        when(oldcore.getMockContextualAuthorizationManager().hasAccess(any(Right.class), any(EntityReference.class)))
            .thenReturn(true);
            oldcore.getMocker().registerMockComponent(DocumentReference.TYPE_PROVIDER);
        mockURLFactory = mock(XWikiURLFactory.class);
        context.setURLFactory(mockURLFactory);
        action = new CreateAction();
        mockRequest = mock(XWikiRequest.class);
        context.setRequest(mockRequest);
        mockResponse = mock(XWikiResponse.class);
        context.setResponse(mockResponse);

        when(mockRequest.get("type")).thenReturn("plain");
    public void newDocumentFromURL() throws Exception
    public void newDocumentButNonTerminalFromURL() throws Exception
    public void newDocumentFromURLWhenNoType() throws Exception
    public void newDocumentWebHomeTopLevelFromURL() throws Exception
    public void newDocumentWebHomeFromURL() throws Exception
    public void newDocumentWebHomeButTerminalFromURL() throws Exception
    public void newDocumentWebHomeTopLevelSpaceButTerminalFromURL() throws Exception
        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(),
            any(), any(XWikiContext.class));
    public void existingDocumentFromUINoName() throws Exception
        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(),
            any(), any(XWikiContext.class));
    public void existingDocumentFromUI() throws Exception
    public void existingDocumentFromUICheckEscaping() throws Exception
    public void existingDocumentTerminalFromUI() throws Exception
    public void existingDocumentTerminalFromUICheckEscaping() throws Exception
    public void existingDocumentTerminalFromUIButAlreadyExisting() throws Exception
        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(),
            any(), any(XWikiContext.class));
    public void notExistingDocumentFromUIButNameTooLong() throws Exception
        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(),
            any(), any(XWikiContext.class));
    public void notExistingDocumentFromUIButSpaceTooLong() throws Exception
        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(),
            any(), any(XWikiContext.class));
    public void existingDocumentFromUITopLevelDocument() throws Exception
    public void existingDocumentFromUIDeprecated() throws Exception
    public void existingDocumentFromUIDeprecatedCheckEscaping() throws Exception
    public void existingDocumentNonTerminalFromUIDeprecated() throws Exception
    public void existingDocumentNonTerminalFromUIDeprecatedIgnoringPage() throws Exception
    public void existingDocumentNonTerminalFromUIDeprecatedCheckEscaping() throws Exception
    public void existingDocumentFromUITemplateProviderExistingButNoneSelected() throws Exception
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST);
        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(),
            any(), any(XWikiContext.class));
    public void existingDocumentFromUITemplateProviderSpecified() throws Exception
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST);
    public void existingDocumentFromUITemplateProviderSpecifiedRestrictionExists() throws Exception
    public void existingDocumentFromUITemplateProviderSpecifiedRestrictionExistsOnParentSpace() throws Exception
    public void existingDocumentFromUITemplateProviderSpecifiedButNotAllowed() throws Exception
        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(),
            any(), any(XWikiContext.class));
    public void newDocumentFromURLTemplateProviderSpecifiedButNotAllowed() throws Exception
        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(),
            any(), any(XWikiContext.class));
    public void newDocumentWebHomeFromURLTemplateProviderSpecifiedButNotAllowed() throws Exception
        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(),
            any(), any(XWikiContext.class));
    public void newDocumentWebHomeFromURLTemplateProviderSpecifiedTerminal() throws Exception
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST, true);
    public void newDocumentWebHomeFromURLTemplateProviderSpecifiedTerminalOverriddenFromUIToNonTerminal()
        throws Exception
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST, true);
    public void newDocumentFromURLTemplateProviderSpecifiedNonTerminal() throws Exception
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST,
    public void newDocumentFromURLTemplateProviderSpecifiedNonTerminalButOverriddenFromUITerminal() throws Exception
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST,
    public void existingDocumentFromUITemplateSpecified() throws Exception
    public void existingDocumentFromUITemplateProviderSpecifiedTerminal() throws Exception
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST, true);
    public void existingDocumentFromUITemplateProviderSpecifiedTerminalOverridenFromUIToNonTerminal() throws Exception
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST, true);
    public void existingDocumentFromUITemplateProviderSpecifiedNonTerminal() throws Exception
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST,
    public void existingDocumentFromUITemplateProviderSpecifiedNonTerminalOverridenFromUIToTerminal() throws Exception
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST,
    public void newDocumentWebHomeFromURLTemplateProviderSpecifiedButOldPageType() throws Exception
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST, null,
    public void newDocumentWebHomeFromURLTemplateProviderSpecifiedButOldPageTypeButOverriddenFromUIToNonTerminal()
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST, null,
    public void existingDocumentFromUITemplateProviderSpecifiedButOldSpaceType() throws Exception
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST, null,
    public void existingDocumentFromUITemplateProviderSpecifiedButOldSpaceTypeButOverridenFromUIToTerminal()
        throws Exception
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.EMPTY_LIST, null,
    public void newDocumentWebHomeFromURLTemplateProviderSpecifiedWithSaveAndEdit() throws Exception
        when(mockRequest.getParameter("spaceReference")).thenReturn("X");
        when(mockRequest.getParameter("name")).thenReturn("Y");
        when(mockRequest.getParameter("title")).thenReturn("Yippee");
        when(mockRequest.getParameter("templateprovider")).thenReturn(templateProviderFullName);
import org.apache.commons.lang.time.DateUtils;
public class SaveActionTest
        this.saveAction = new SaveAction();

        context = oldcore.getXWikiContext();
        xWiki = mock(XWiki.class);
        context.setWiki(this.xWiki);
        mockRequest = mock(XWikiRequest.class);
        context.setRequest(mockRequest);
        mockResponse = mock(XWikiResponse.class);
        context.setResponse(mockResponse);
        mockDocument = mock(XWikiDocument.class);
        context.setDoc(mockDocument);
        mockClonedDocument = mock(XWikiDocument.class);
        when(mockDocument.clone()).thenReturn(mockClonedDocument);
        mockForm = mock(EditForm.class);
        context.setForm(mockForm);
        context.setUserReference(USER_REFERENCE);
        assertArrayEquals(new Object[] { "Foo.Bar" }, (Object[]) context.get("messageParameters"));
        verify(mockClonedDocument).readFromTemplate("", this.context);
        verify(this.xWiki).checkSavingDocument(eq(USER_REFERENCE), any(XWikiDocument.class), eq(""),
            eq(false), eq(this.context));
     * This tests aims at checking the usecase when uploading an image in the WYSIWYG editor before the first save
     * and saving afterwards.
        verify(mockClonedDocument).readFromTemplate("", this.context);

Fixed code:
                readFromTemplate(tdoc2, peform.getTemplate(), context);
        readFromTemplate(newDocument, template, context);
            DocumentReference parentReference = this.currentmixedReferenceResolver.resolve(parent);
        readFromTemplate(editedDocument, editForm.getTemplate(), context);
                readFromTemplate(doc2, peform.getTemplate(), context);
                readFromTemplate(cdoc2, peform.getTemplate(), context);
            readFromTemplate(tdoc, form.getTemplate(), context);
        DocumentReference templateReference = resolveTemplate(editForm.getTemplate());

        if (templateReference == null) {
import javax.inject.Named;
import org.xwiki.security.authorization.ContextualAuthorizationManager;
import org.xwiki.security.authorization.Right;
    @Inject
    protected ContextualAuthorizationManager autorization;

    @Inject
    @Named("currentmixed")
    protected DocumentReferenceResolver<String> currentmixedReferenceResolver;


    /**
     * 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;
    }
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.xwiki.test.junit5.mockito.InjectMockComponents;
import com.xpn.xwiki.test.MockitoOldcore;
import com.xpn.xwiki.test.junit5.mockito.InjectMockitoOldcore;
import com.xpn.xwiki.test.junit5.mockito.OldcoreTest;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
@OldcoreTest
class CreateActionTest
    @InjectMockitoOldcore
    MockitoOldcore oldcore;
    @InjectMockComponents
    @BeforeEach
    public void beforeEach() throws Exception
        this.context = this.oldcore.getXWikiContext();
        Utils.setComponentManager(this.oldcore.getMocker());
            this.oldcore.getMocker().registerMockComponent((Type) QueryManager.class, "secure");
        this.mockTemplateProvidersQuery = mock(Query.class);
        when(mockSecureQueryManager.createQuery(any(), any())).thenReturn(this.mockTemplateProvidersQuery);
        when(this.mockTemplateProvidersQuery.execute()).thenReturn(Collections.emptyList());
        when(this.oldcore.getMockContextualAuthorizationManager().hasAccess(any(Right.class),
            any(EntityReference.class))).thenReturn(true);
            this.oldcore.getMocker().registerMockComponent(DocumentReference.TYPE_PROVIDER);
        this.mockURLFactory = mock(XWikiURLFactory.class);
        this.context.setURLFactory(this.mockURLFactory);
        this.mockRequest = mock(XWikiRequest.class);
        this.context.setRequest(this.mockRequest);
        this.mockResponse = mock(XWikiResponse.class);
        this.context.setResponse(this.mockResponse);
        when(this.mockRequest.get("type")).thenReturn("plain");
    void newDocumentFromURL() throws Exception
    void newDocumentButNonTerminalFromURL() throws Exception
    void newDocumentFromURLWhenNoType() throws Exception
    void newDocumentWebHomeTopLevelFromURL() throws Exception
    void newDocumentWebHomeFromURL() throws Exception
    void newDocumentWebHomeButTerminalFromURL() throws Exception
    void newDocumentWebHomeTopLevelSpaceButTerminalFromURL() throws Exception
        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(), any(), any(XWikiContext.class));
    void existingDocumentFromUINoName() throws Exception
        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(), any(), any(XWikiContext.class));
    void existingDocumentFromUI() throws Exception
    void existingDocumentFromUICheckEscaping() throws Exception
    void existingDocumentTerminalFromUI() throws Exception
    void existingDocumentTerminalFromUICheckEscaping() throws Exception
    void existingDocumentTerminalFromUIButAlreadyExisting() throws Exception
        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(), any(), any(XWikiContext.class));
    void notExistingDocumentFromUIButNameTooLong() throws Exception
        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(), any(), any(XWikiContext.class));
    void notExistingDocumentFromUIButSpaceTooLong() throws Exception
        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(), any(), any(XWikiContext.class));
    void existingDocumentFromUITopLevelDocument() throws Exception
    void existingDocumentFromUIDeprecated() throws Exception
    void existingDocumentFromUIDeprecatedCheckEscaping() throws Exception
    void existingDocumentNonTerminalFromUIDeprecated() throws Exception
    void existingDocumentNonTerminalFromUIDeprecatedIgnoringPage() throws Exception
    void existingDocumentNonTerminalFromUIDeprecatedCheckEscaping() throws Exception
    void existingDocumentFromUITemplateProviderExistingButNoneSelected() throws Exception
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList());
        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(), any(), any(XWikiContext.class));
    void existingDocumentFromUITemplateProviderSpecified() throws Exception
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList());
    void existingDocumentFromUITemplateProviderSpecifiedRestrictionExists() throws Exception
    void existingDocumentFromUITemplateProviderSpecifiedRestrictionExistsOnParentSpace() throws Exception
    void existingDocumentFromUITemplateProviderSpecifiedButNotAllowed() throws Exception
        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(), any(), any(XWikiContext.class));
    void newDocumentFromURLTemplateProviderSpecifiedButNotAllowed() throws Exception
        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(), any(), any(XWikiContext.class));
    void newDocumentWebHomeFromURLTemplateProviderSpecifiedButNotAllowed() throws Exception
        verify(mockURLFactory, never()).createURL(any(), any(), any(), any(), any(), any(), any(XWikiContext.class));
    void newDocumentWebHomeFromURLTemplateProviderSpecifiedTerminal() throws Exception
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList(),
            true);
    void newDocumentWebHomeFromURLTemplateProviderSpecifiedTerminalOverriddenFromUIToNonTerminal() throws Exception
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList(),
            true);
    void newDocumentFromURLTemplateProviderSpecifiedNonTerminal() throws Exception
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList(),
    void newDocumentFromURLTemplateProviderSpecifiedNonTerminalButOverriddenFromUITerminal() throws Exception
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList(),
    void existingDocumentFromUITemplateSpecified() throws Exception
    void existingDocumentFromUITemplateProviderSpecifiedTerminal() throws Exception
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList(),
            true);
    void existingDocumentFromUITemplateProviderSpecifiedTerminalOverridenFromUIToNonTerminal() throws Exception
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList(),
            true);
    void existingDocumentFromUITemplateProviderSpecifiedNonTerminal() throws Exception
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList(),
    void existingDocumentFromUITemplateProviderSpecifiedNonTerminalOverridenFromUIToTerminal() throws Exception
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList(),
    void newDocumentWebHomeFromURLTemplateProviderSpecifiedButOldPageType() throws Exception
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList(), null,
    void newDocumentWebHomeFromURLTemplateProviderSpecifiedButOldPageTypeButOverriddenFromUIToNonTerminal()
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList(), null,
    void existingDocumentFromUITemplateProviderSpecifiedButOldSpaceType() throws Exception
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList(), null,
    void existingDocumentFromUITemplateProviderSpecifiedButOldSpaceTypeButOverridenFromUIToTerminal() throws Exception
            new DocumentReference("xwiki", Arrays.asList("XWiki"), "MyTemplateProvider"), Collections.emptyList(), null,
    void newDocumentWebHomeFromURLTemplateProviderSpecifiedWithSaveAndEdit() throws Exception
        when(this.mockRequest.getParameter("spaceReference")).thenReturn("X");
        when(this.mockRequest.getParameter("name")).thenReturn("Y");
        when(this.mockRequest.getParameter("title")).thenReturn("Yippee");
        when(this.mockRequest.getParameter("templateprovider")).thenReturn(templateProviderFullName);
import org.xwiki.job.Job;
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.junit5.mockito.InjectComponentManager;
import org.xwiki.test.junit5.mockito.InjectMockComponents;
import org.xwiki.test.mockito.MockitoComponentManager;
import static org.mockito.Mockito.never;
class SaveActionTest
    @InjectComponentManager
    private MockitoComponentManager componentManager;

    @MockComponent
    private ContextualAuthorizationManager autorization;

    @InjectMockComponents
        this.context = this.oldcore.getXWikiContext();
        this.xWiki = mock(XWiki.class);
        this.context.setWiki(this.xWiki);
        this.mockRequest = mock(XWikiRequest.class);
        this.context.setRequest(this.mockRequest);
        this.mockResponse = mock(XWikiResponse.class);
        this.context.setResponse(this.mockResponse);
        this.mockDocument = mock(XWikiDocument.class);
        this.context.setDoc(this.mockDocument);
        this.mockClonedDocument = mock(XWikiDocument.class);
        when(this.mockDocument.clone()).thenReturn(this.mockClonedDocument);
        this.mockForm = mock(EditForm.class);
        this.context.setForm(this.mockForm);
        this.context.setUserReference(USER_REFERENCE);
        assertArrayEquals(new Object[] {"Foo.Bar"}, (Object[]) context.get("messageParameters"));
        verify(this.xWiki).checkSavingDocument(eq(USER_REFERENCE), any(XWikiDocument.class), eq(""), eq(false),
            eq(this.context));
     * This tests aims at checking the usecase when uploading an image in the WYSIWYG editor before the first save and
     * saving afterwards.
    }

    @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);