Skip to content
Snippets Groups Projects
Commit 6b39befd authored by Michael Hamann's avatar Michael Hamann
Browse files

XWIKI-21607: XWiki.PDFClass is not triggering required rights warnings

* Add an analyzer for XWiki.PDFClass
* Add a component test
parent 203de695
No related merge requests found
/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.xwiki.platform.security.requiredrights.internal.analyzer;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.xwiki.component.annotation.Component;
import org.xwiki.platform.security.requiredrights.RequiredRight;
import org.xwiki.platform.security.requiredrights.RequiredRightAnalysisResult;
import org.xwiki.platform.security.requiredrights.RequiredRightAnalyzer;
import org.xwiki.platform.security.requiredrights.RequiredRightsException;
import org.xwiki.platform.security.requiredrights.internal.provider.BlockSupplierProvider;
import org.xwiki.velocity.internal.util.VelocityDetector;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.objects.BaseObject;
import com.xpn.xwiki.objects.BaseProperty;
/**
* Analyzer for the {@code XWiki.PDFClass} objects.
*
* @version $Id$
* @since 15.10.5
* @since 16.0.0RC1
*/
@Component
@Singleton
@Named("XWiki.PDFClass")
public class PDFClassObjectRequiredRightsAnalyzer implements RequiredRightAnalyzer<BaseObject>
{
@Inject
private VelocityDetector velocityDetector;
@Inject
@Named("translation")
private BlockSupplierProvider<String> translationMessageSupplierProvider;
@Inject
@Named("stringCode")
private BlockSupplierProvider<String> stringCodeBlockSupplierProvider;
@Override
public List<RequiredRightAnalysisResult> analyze(BaseObject object) throws RequiredRightsException
{
List<RequiredRightAnalysisResult> results = new ArrayList<>();
for (String propertyName : object.getPropertyList()) {
try {
// Analyze every property as all properties that are used in PDFClass are evaluated as Velocity.
BaseProperty<?> field = (BaseProperty<?>) object.get(propertyName);
String value = (String) field.getValue();
if (this.velocityDetector.containsVelocityScript(value)) {
results.add(new RequiredRightAnalysisResult(field.getReference(),
this.translationMessageSupplierProvider.get("security.requiredrights.object.pdfClass",
propertyName),
this.stringCodeBlockSupplierProvider.get(value),
RequiredRight.SCRIPT_AND_MAYBE_PROGRAM));
}
} catch (XWikiException e) {
throw new RequiredRightsException(String.format("Failed to get the property [%s] to analyze",
propertyName), e);
}
}
return results;
}
}
......@@ -96,6 +96,8 @@ security.requiredrights.object.error=An error occurred during the analysis of th
Please manually check which rights it requires. Root cause of the error: [{0}].
security.requiredrights.object.configurableClassHeading=The heading of the configurable contains "#" or "$" which \
might be executed as Velocity code if the document's author has script or programming rights.
security.requiredrights.object.pdfClass=The export customization [{0}] contains Velocity code which requires script \
rights and might use programming rights.
####################
# For the edit confirmation checker.
......
......@@ -4,6 +4,7 @@ org.xwiki.platform.security.requiredrights.internal.analyzer.DefaultMacroBlockRe
org.xwiki.platform.security.requiredrights.internal.analyzer.DefaultMacroRequiredRightReporter
org.xwiki.platform.security.requiredrights.internal.analyzer.DefaultObjectRequiredRightAnalyzer
org.xwiki.platform.security.requiredrights.internal.analyzer.XDOMRequiredRightAnalyzer
org.xwiki.platform.security.requiredrights.internal.analyzer.PDFClassObjectRequiredRightsAnalyzer
org.xwiki.platform.security.requiredrights.internal.analyzer.RequiredRightObjectRequiredRightAnalyzer
org.xwiki.platform.security.requiredrights.internal.analyzer.ScriptMacroAnalyzer
org.xwiki.platform.security.requiredrights.internal.analyzer.SkinExtensionObjectRequiredRightAnalyzer
......
/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.xwiki.platform.security.requiredrights.internal.analyzer;
import java.util.List;
import java.util.Set;
import javax.inject.Named;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.xwiki.model.reference.EntityReference;
import org.xwiki.platform.security.requiredrights.RequiredRight;
import org.xwiki.platform.security.requiredrights.RequiredRightAnalysisResult;
import org.xwiki.platform.security.requiredrights.internal.provider.BlockSupplierProvider;
import org.xwiki.test.annotation.ComponentList;
import org.xwiki.test.junit5.mockito.ComponentTest;
import org.xwiki.test.junit5.mockito.InjectMockComponents;
import org.xwiki.test.junit5.mockito.MockComponent;
import org.xwiki.velocity.internal.util.VelocityDetector;
import com.xpn.xwiki.objects.BaseObject;
import com.xpn.xwiki.objects.BaseProperty;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
* Component tests for {@link PDFClassObjectRequiredRightsAnalyzer}.
*
* @version $Id$
*/
@ComponentTest
@ComponentList({ VelocityDetector.class })
class PDFClassObjectRequiredRightsAnalyzerTest
{
@MockComponent
@Named("translation")
private BlockSupplierProvider<String> translationMessageSupplierProvider;
@MockComponent
@Named("stringCode")
private BlockSupplierProvider<String> stringCodeBlockSupplierProvider;
@InjectMockComponents
private PDFClassObjectRequiredRightsAnalyzer analyzer;
@ParameterizedTest
@CsvSource({ "$hello, true", "hello, false" })
void analyze(String value, boolean isVelocity) throws Exception
{
BaseObject object = mock(BaseObject.class);
String propertyName = "style";
when(object.getPropertyList()).thenReturn(Set.of(propertyName));
BaseProperty<EntityReference> styleProperty = mock();
EntityReference stylePropertyReference = mock(EntityReference.class);
when(styleProperty.getReference()).thenReturn(stylePropertyReference);
when(styleProperty.getValue()).thenReturn(value);
when(object.get(propertyName)).thenReturn(styleProperty);
List<RequiredRightAnalysisResult> result = this.analyzer.analyze(object);
if (isVelocity) {
assertEquals(1, result.size());
assertEquals(RequiredRight.SCRIPT_AND_MAYBE_PROGRAM, result.get(0).getRequiredRights());
assertEquals(stylePropertyReference, result.get(0).getEntityReference());
verify(this.stringCodeBlockSupplierProvider).get(value);
verify(this.translationMessageSupplierProvider)
.get("security.requiredrights.object.pdfClass", propertyName);
} else {
assertEquals(0, result.size());
}
}
}
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