Skip to content
Snippets Groups Projects
Commit 77dab7d7 authored by Thomas Mortagne's avatar Thomas Mortagne
Browse files

XWIKI-20653: Setting restricted=true in the context macro should force executing the content

parent 2bcfaa71
No related branches found
No related tags found
No related merge requests found
......@@ -184,7 +184,7 @@
#set ($uix = $uixs.get($index))
#set ($tip = $uix.getParameters().get('tip'))
#if ($tip)
{{context restricted="true" transformationContext="transformations" source="script:tip"/}}
{{context restricted="true" source="script:tip"/}}
#else
{{uiextension id="$services.rendering.escape($uix.id, 'xwiki/2.1')"/}}
#end
......
......@@ -138,7 +138,7 @@ public List<Block> execute(ContextMacroParameters parameters, String macroConten
}
List<Block> blocks;
if (parameters.getTransformationContext() == TransformationContextMode.DOCUMENT
if (parameters.isRestricted() || parameters.getTransformationContext() == TransformationContextMode.DOCUMENT
|| parameters.getTransformationContext() == TransformationContextMode.TRANSFORMATIONS) {
// Execute the content in the context of the target document
blocks = executeContext(xdom, parameters, context);
......@@ -155,12 +155,17 @@ public List<Block> execute(ContextMacroParameters parameters, String macroConten
private List<Block> executeContext(XDOM xdom, ContextMacroParameters parameters, MacroTransformationContext context)
throws MacroExecutionException
{
DocumentReference currentAuthor = this.documentAccessBridge.getCurrentAuthorReference();
DocumentReference referencedDocReference =
this.macroReferenceResolver.resolve(parameters.getDocument(), context.getCurrentMacroBlock());
DocumentReference referencedDocReference;
if (parameters.getDocument() != null) {
referencedDocReference =
this.macroReferenceResolver.resolve(parameters.getDocument(), context.getCurrentMacroBlock());
DocumentReference currentAuthor = this.documentAccessBridge.getCurrentAuthorReference();
// Make sure the author is allowed to use the target document
checkAccess(currentAuthor, referencedDocReference);
// Make sure the author is allowed to use the target document
checkAccess(currentAuthor, referencedDocReference);
} else {
referencedDocReference = null;
}
// Reuse the very generic async rendering framework (even if we don't do async and caching) since it's
// taking
......@@ -173,31 +178,35 @@ private List<Block> executeContext(XDOM xdom, ContextMacroParameters parameters,
configuration.setResricted(true);
}
Map<String, Object> backupObjects = new HashMap<>();
Map<String, Object> backupObjects = null;
try {
// Switch the context document
this.documentAccessBridge.pushDocumentInContext(backupObjects, referencedDocReference);
// Apply the transformations but with a Transformation Context having the XDOM of the passed
// document so that macros execute on the passed document's XDOM (e.g. the TOC macro will generate
// the toc for the passed document instead of the current document).
DocumentModelBridge referencedDoc =
this.documentAccessBridge.getTranslatedDocumentInstance(referencedDocReference);
XDOM referencedXDOM = referencedDoc.getXDOM();
if (parameters.getTransformationContext() == TransformationContextMode.TRANSFORMATIONS) {
// Get the XDOM from the referenced doc but with Transformations applied so that all macro are
// executed and contribute XDOM elements.
// IMPORTANT: This can be dangerous since it means executing macros, and thus also script macros
// defined in the referenced document. To be used with caution.
TransformationContext referencedTxContext =
new TransformationContext(referencedXDOM, referencedDoc.getSyntax());
this.transformationManager.performTransformations(referencedXDOM, referencedTxContext);
if (referencedDocReference != null) {
backupObjects = new HashMap<>();
// Switch the context document
this.documentAccessBridge.pushDocumentInContext(backupObjects, referencedDocReference);
// Apply the transformations but with a Transformation Context having the XDOM of the passed
// document so that macros execute on the passed document's XDOM (e.g. the TOC macro will generate
// the toc for the passed document instead of the current document).
DocumentModelBridge referencedDoc =
this.documentAccessBridge.getTranslatedDocumentInstance(referencedDocReference);
XDOM referencedXDOM = referencedDoc.getXDOM();
if (parameters.getTransformationContext() == TransformationContextMode.TRANSFORMATIONS) {
// Get the XDOM from the referenced doc but with Transformations applied so that all macro are
// executed and contribute XDOM elements.
// IMPORTANT: This can be dangerous since it means executing macros, and thus also script macros
// defined in the referenced document. To be used with caution.
TransformationContext referencedTxContext =
new TransformationContext(referencedXDOM, referencedDoc.getSyntax());
this.transformationManager.performTransformations(referencedXDOM, referencedTxContext);
}
// Configure the Transformation Context XDOM depending on the mode asked.
configuration.setXDOM(referencedXDOM);
}
// Configure the Transformation Context XDOM depending on the mode asked.
configuration.setXDOM(referencedXDOM);
// Execute the content
Block result = this.executor.execute(configuration);
......@@ -205,8 +214,10 @@ private List<Block> executeContext(XDOM xdom, ContextMacroParameters parameters,
} catch (Exception e) {
throw new MacroExecutionException("Failed start the execution of the macro", e);
} finally {
// Restore the context document
this.documentAccessBridge.popDocumentFromContext(backupObjects);
if (backupObjects != null) {
// Restore the context document
this.documentAccessBridge.popDocumentFromContext(backupObjects);
}
}
}
}
......@@ -214,22 +214,22 @@ void executeInCURRENTContext() throws Exception
@Test
void executeInDOCUMENTContext() throws Exception
{
execute(false, false);
execute(false, TransformationContextMode.DOCUMENT, false);
}
@Test
void executeInDOCUMENTContextInRestrictedMode() throws Exception
{
execute(true, false);
execute(true, TransformationContextMode.DOCUMENT, false);
}
@Test
void executeInDOCUMENTContextWithRestricted() throws Exception
void executeWithRestricted() throws Exception
{
execute(false, true);
execute(false, null, true);
}
private void execute(boolean restrictedContext, boolean restricted) throws Exception
private void execute(boolean restrictedContext, TransformationContextMode mode, boolean restricted) throws Exception
{
MacroBlock macroBlock = new MacroBlock("context", Collections.<String, String>emptyMap(), false);
MetaData metadata = new MetaData();
......@@ -241,23 +241,31 @@ private void execute(boolean restrictedContext, boolean restricted) throws Excep
macroContext.setXDOM(pageXDOM);
macroContext.getTransformationContext().setRestricted(restrictedContext);
DocumentModelBridge dmb = mock(DocumentModelBridge.class);
when(this.dab.getTranslatedDocumentInstance(TARGET_REFERENCE)).thenReturn(dmb);
XDOM targetXDOM = new XDOM(Arrays.asList(new WordBlock("word")), metadata);
when(dmb.getXDOM()).thenReturn(targetXDOM);
MetaData parserMetadata = new MetaData();
parserMetadata.addMetaData(MetaData.SOURCE, "target");
parserMetadata.addMetaData(MetaData.BASE, "target");
XDOM targetXDOM;
MetaData parserMetadata;
ContextMacroParameters parameters = new ContextMacroParameters();
if (mode != null) {
DocumentModelBridge dmb = mock(DocumentModelBridge.class);
when(this.dab.getTranslatedDocumentInstance(TARGET_REFERENCE)).thenReturn(dmb);
targetXDOM = new XDOM(Arrays.asList(new WordBlock("word")), metadata);
when(dmb.getXDOM()).thenReturn(targetXDOM);
parameters.setDocument("target");
parameters.setTransformationContext(mode);
parserMetadata = new MetaData();
parserMetadata.addMetaData(MetaData.SOURCE, "target");
parserMetadata.addMetaData(MetaData.BASE, "target");
} else {
targetXDOM = null;
parserMetadata = null;
}
parameters.setRestricted(restricted);
XDOM contentXDOM = new XDOM(Arrays.asList(new WordBlock("test")), parserMetadata);
when(this.parser.parse(eq(""), same(null), same(macroContext), eq(false), eq(parserMetadata), eq(false)))
.thenReturn(contentXDOM);
ContextMacroParameters parameters = new ContextMacroParameters();
parameters.setDocument("target");
parameters.setTransformationContext(TransformationContextMode.DOCUMENT);
parameters.setRestricted(restricted);
when(this.executor.execute(any())).thenReturn(new WordBlock("result"));
......@@ -270,7 +278,9 @@ private void execute(boolean restrictedContext, boolean restricted) throws Excep
BlockAsyncRendererConfiguration configuration = configurationCaptor.getValue();
assertEquals(AUTHOR, configuration.getSecureAuthorReference());
assertEquals(SOURCE_REFERENCE, configuration.getSecureDocumentReference());
assertSame(targetXDOM, configuration.getXDOM());
if (targetXDOM != null) {
assertSame(targetXDOM, configuration.getXDOM());
}
assertEquals(restrictedContext ? true : restricted, configuration.isResricted());
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment