1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.rendering.macro.groovy

File SecurityTest.java

 

Code metrics

2
35
14
1
195
119
16
0.46
2.5
14
1.14

Classes

Class Line # Actions
SecurityTest 50 35 0% 16 3
0.941176594.1%
 

Contributing tests

This file is covered by 9 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.rendering.macro.groovy;
21   
22    import java.util.ArrayList;
23    import java.util.Collections;
24    import java.util.List;
25   
26    import org.apache.commons.lang3.StringUtils;
27    import org.jmock.Expectations;
28    import org.junit.Assert;
29    import org.junit.Before;
30    import org.junit.Test;
31    import org.xwiki.bridge.DocumentAccessBridge;
32    import org.xwiki.configuration.ConfigurationSource;
33    import org.xwiki.model.reference.AttachmentReferenceResolver;
34    import org.xwiki.rendering.block.MacroBlock;
35    import org.xwiki.rendering.macro.Macro;
36    import org.xwiki.rendering.macro.MacroExecutionException;
37    import org.xwiki.rendering.macro.script.JSR223ScriptMacroParameters;
38    import org.xwiki.rendering.syntax.Syntax;
39    import org.xwiki.rendering.transformation.MacroTransformationContext;
40    import org.xwiki.security.authorization.ContextualAuthorizationManager;
41    import org.xwiki.security.authorization.Right;
42    import org.xwiki.test.jmock.AbstractComponentTestCase;
43   
44    /**
45    * Integration test to verify the security configuration of the Groovy Macro.
46    *
47    * @version $Id: 6548ec224b9a61b1eb5b930704ec0c19c9dc3896 $
48    * @since 4.1M1
49    */
 
50    public class SecurityTest extends AbstractComponentTestCase
51    {
52    private ContextualAuthorizationManager cam;
53   
54    private ConfigurationSource configurationSource;
55   
 
56  9 toggle @Before
57    public void setUpMocks() throws Exception
58    {
59    // Mock Model dependencies.
60  9 registerMockComponent(DocumentAccessBridge.class);
61   
62    // Mock the authorization manager.
63  9 this.cam = registerMockComponent(ContextualAuthorizationManager.class);
64  9 registerMockComponent(AttachmentReferenceResolver.TYPE_STRING, "current");
65   
66    // Mock Configuration Source so that we can configure security parameters
67  9 this.configurationSource = registerMockComponent(ConfigurationSource.class);
68    }
69   
70    // Using a customizer
71   
 
72  1 toggle @Test
73    public void testExecutionWhenSecureCustomizerWithScriptRightsAndNoProgrammingRights() throws Exception
74    {
75    // Conclusion: Can run with a customizer and SR to avoid PR.
76  1 testExecution(true, false, true, false);
77    }
78   
 
79  1 toggle @Test(expected = MacroExecutionException.class)
80    public void testExecutionWhenSecureCustomizerWithNoScriptRightsAndNoProgrammingRights() throws Exception
81    {
82    // Conclusion: When running with a customizer and no PR, SR is needed.
83  1 testExecution(true, false, false, false);
84    }
85   
 
86  1 toggle @Test
87    public void testExecutionWhenSecureCustomizerWithNoScriptRightsAndProgrammingRights() throws Exception
88    {
89    // Conclusion: When running with a customizer and PR, SR are implied by the PR.
90  1 testExecution(true, false, false, true);
91    }
92   
 
93  1 toggle @Test(expected = MacroExecutionException.class)
94    public void testExecutionWhenSecureCustomizerAndRestricted() throws Exception
95    {
96    // Conclusion: When running with a customizer and SR to avoid PR, transformations have to not be restricted.
97  1 testExecution(true, true, true, false);
98    }
99   
 
100  1 toggle @Test(expected = MacroExecutionException.class)
101    public void testExecutionWhenSecureCustomizerAndRestrictedWithScriptRightsAndProgrammingRights() throws Exception
102    {
103    // Conclusion: When running with a customizer, event with PR (and inherited SR), transformations have to not be
104    // restricted.
105  1 testExecution(true, true, false, true);
106    }
107   
108    // Not using a customizer
109   
 
110  1 toggle @Test
111    public void testExecutionWhenNoSecureCustomizerAndNoRights() throws Exception
112    {
113    // Conclusion: When running with no customizer and no PR, execution fails.
114  1 try {
115  1 testExecution(false, false, false, false);
116  0 Assert.fail("Should have thrown an exception here!");
117    } catch (MacroExecutionException expected) {
118  1 Assert.assertTrue(StringUtils.startsWith(expected.getMessage(),
119    "The execution of the [groovy] script macro is not allowed."));
120    }
121    }
122   
 
123  1 toggle @Test(expected = MacroExecutionException.class)
124    public void testExecutionWhenNoSecureCustomizerAndScriptRights() throws Exception
125    {
126    // Conclusion: When running with no customizer, SR is not enough. You need PR.
127  1 testExecution(false, false, true, false);
128    }
129   
 
130  1 toggle @Test
131    public void testExecutionWhenNoSecureCustomizerAndProgrammingRights() throws Exception
132    {
133    // Conclusion: When running with no customizer, PR is needed.
134  1 testExecution(false, false, false, true);
135    }
136   
 
137  1 toggle @Test
138    public void testExecutionWhenNoSecureCustomizerAndExecutionRestrictedAndProgrammingRights() throws Exception
139    {
140    // Conclusion: When running with no customizer, transformation restrictions do not matter, only PR does.
141  1 testExecution(false, true, false, true);
142    }
143   
144    /*
145    * Utility methods.
146    */
147   
 
148  9 toggle private void testExecution(final boolean hasCustomizer, final boolean isRestricted, final boolean hasSR,
149    final boolean hasPR) throws Exception
150    {
151  9 getMockery().checking(new Expectations()
152    {
 
153  9 toggle {
154    // Programming Rights
155  9 allowing(cam).hasAccess(Right.PROGRAM);
156  9 will(returnValue(hasPR));
157   
158    // Script Rights
159  9 allowing(cam).hasAccess(Right.SCRIPT);
160  9 will(returnValue(hasSR || hasPR));
161   
162    // Secure AST Customizer
163  9 List<String> customizers = new ArrayList<>();
164  9 if (hasCustomizer) {
165  5 customizers.add("secure");
166    }
167  9 allowing(configurationSource).getProperty("groovy.compilationCustomizers", Collections.emptyList());
168  9 will(returnValue(customizers));
169   
170    }
171    });
172   
173    // Note: We execute something that works with the Groovy Security customizer...
174  9 executeGroovyMacro("new Integer(0)", isRestricted);
175    }
176   
 
177  0 toggle private void executeGroovyMacro(String script) throws Exception
178    {
179  0 executeGroovyMacro(script, false);
180    }
181   
 
182  9 toggle private void executeGroovyMacro(String script, boolean restricted) throws Exception
183    {
184  9 Macro macro = getComponentManager().getInstance(Macro.class, "groovy");
185  9 JSR223ScriptMacroParameters parameters = new JSR223ScriptMacroParameters();
186   
187  9 MacroTransformationContext context = new MacroTransformationContext();
188  9 context.getTransformationContext().setRestricted(restricted);
189  9 context.setSyntax(Syntax.XWIKI_2_1);
190    // The script macro checks the current block (which is a macro block) to see what engine to use.
191  9 context.setCurrentMacroBlock(new MacroBlock("groovy", Collections.<String, String>emptyMap(), false));
192   
193  9 macro.execute(parameters, script, context);
194    }
195    }