1 /*Copyright (C) 2014 Red Hat, Inc. 2 3 This file is part of IcedTea. 4 5 IcedTea is free software; you can redistribute it and/or 6 modify it under the terms of the GNU General Public License as published by 7 the Free Software Foundation, version 2. 8 9 IcedTea is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with IcedTea; see the file COPYING. If not, write to 16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 17 02110-1301 USA. 18 19 Linking this library statically or dynamically with other modules is 20 making a combined work based on this library. Thus, the terms and 21 conditions of the GNU General Public License cover the whole 22 combination. 23 24 As a special exception, the copyright holders of this library give you 25 permission to link this library with independent modules to produce an 26 executable, regardless of the license terms of these independent 27 modules, and to copy and distribute the resulting executable under 28 terms of your choice, provided that you also meet, for each linked 29 independent module, the terms and conditions of the license of that 30 module. An independent module is a module which is not derived from 31 or based on this library. If you modify this library, you may extend 32 this exception to your version of the library, but you are not 33 obligated to do so. If you do not wish to do so, delete this 34 exception statement from your version. 35 */ 36 37 package net.sourceforge.jnlp.security.policyeditor; 38 39 import net.sourceforge.jnlp.util.FileUtils; 40 import org.junit.Before; 41 import org.junit.Test; 42 43 import java.io.File; 44 import java.util.Arrays; 45 import java.util.Collection; 46 import java.util.Collections; 47 import java.util.HashSet; 48 import java.util.Map; 49 import java.util.Set; 50 51 import static org.junit.Assert.*; 52 import static org.junit.Assert.assertEquals; 53 54 public class PolicyEditorControllerTest { 55 56 private String tempFilePath; 57 private PolicyEditorController controller; 58 59 @Before setNewTempfile()60 public void setNewTempfile() throws Exception { 61 tempFilePath = File.createTempFile("policyeditor", null).getCanonicalPath(); 62 controller = new PolicyEditorController(); 63 controller.setFile(new File(tempFilePath)); 64 } 65 66 @Test testChangesMadeInitiallyFalse()67 public void testChangesMadeInitiallyFalse() throws Exception { 68 // #setFile() counts as a change made 69 assertTrue("Controller should report changes made initially", controller.changesMade()); 70 } 71 72 @Test testChangesMade()73 public void testChangesMade() throws Exception { 74 controller.setChangesMade(false); 75 assertFalse("Controller should have changes made marked false after being explicitly set", controller.changesMade()); 76 } 77 78 @Test testFileHasChanged()79 public void testFileHasChanged() throws Exception { 80 assertFalse("File should not have been changed initially", controller.fileHasChanged()); 81 } 82 83 @Test testFileHasChangedWithChange()84 public void testFileHasChangedWithChange() throws Exception { 85 assertFalse("Controller should report file has changed initially", controller.fileHasChanged()); 86 final String codebase = "http://example.com"; 87 final PolicyEditorPermissions editorPermissions = PolicyEditorPermissions.CLIPBOARD; 88 final Collection<PolicyEditorPermissions> permissions = Collections.singleton(editorPermissions); 89 final CustomPermission customPermission = new CustomPermission(PermissionType.FILE_PERMISSION, PermissionTarget.USER_HOME, PermissionActions.FILE_ALL); 90 final Collection<CustomPermission> customPermissions = Collections.singleton(customPermission); 91 final PolicyEntry policyEntry = new PolicyEntry(codebase, permissions, customPermissions); 92 FileUtils.saveFile(policyEntry.toString(), new File(tempFilePath)); 93 controller.openAndParsePolicyFile(); 94 final Collection<PolicyEditorPermissions> editorPermissions2 = Collections.singleton(PolicyEditorPermissions.ALL_AWT); 95 final PolicyEntry policyEntry2 = new PolicyEntry(codebase, editorPermissions2, customPermissions); 96 FileUtils.saveFile(policyEntry2.toString(), new File(tempFilePath)); 97 assertTrue("File should be marked changed after being externally modified", controller.fileHasChanged()); 98 } 99 100 @Test testInitialCodebase()101 public void testInitialCodebase() throws Exception { 102 final Collection<String> initialCodebases = controller.getCodebases(); 103 assertEquals("Controller should have no codebases to begin with", 0, initialCodebases.size()); 104 } 105 106 @Test testAddCodebase()107 public void testAddCodebase() throws Exception { 108 final String urlString = "http://example.com"; 109 controller.addCodebase(urlString); 110 final Collection<String> codebases = controller.getCodebases(); 111 assertTrue("Controller should have http://example.com", codebases.contains(urlString)); 112 assertEquals("Controller should only have two codebases", 1, codebases.size()); 113 } 114 115 @Test testAddMultipleCodebases()116 public void testAddMultipleCodebases() throws Exception { 117 final Set<String> toAdd = new HashSet<String>(); 118 toAdd.add("http://example.com"); 119 toAdd.add("http://icedtea.classpath.org"); 120 for (final String cb : toAdd) { 121 controller.addCodebase(cb); 122 } 123 final Collection<String> codebases = controller.getCodebases(); 124 for (final String codebase : toAdd) { 125 assertTrue("Controller should have " + codebase, codebases.contains(codebase)); 126 } 127 } 128 129 @Test testRemoveCodebase()130 public void testRemoveCodebase() throws Exception { 131 final String urlString = "http://example.com"; 132 controller.addCodebase(urlString); 133 final Collection<String> codebases = controller.getCodebases(); 134 assertTrue("Controller should have http://example.com", codebases.contains(urlString)); 135 assertEquals("Controller should only have one codebase", 1, codebases.size()); 136 controller.removeCodebase(urlString); 137 final Collection<String> afterRemove = controller.getCodebases(); 138 assertFalse("Controller should not have http://example.com. Contained: " + afterRemove, afterRemove.contains(urlString)); 139 assertEquals("Controller should have no codebases", 0, afterRemove.size()); 140 } 141 142 @Test testCopyPasteCodebase()143 public void testCopyPasteCodebase() throws Exception { 144 final String copyUrl = "http://example.com"; 145 final String pasteUrl = "http://example.com/example"; 146 final PolicyEditorPermissions clipBoard = PolicyEditorPermissions.CLIPBOARD; 147 controller.addCodebase(copyUrl); 148 controller.setPermission(copyUrl, clipBoard, Boolean.TRUE); 149 final Collection<String> beforePasteCodebases = controller.getCodebases(); 150 assertTrue("Controller should contain original codebase: " + copyUrl, beforePasteCodebases.contains(copyUrl)); 151 assertTrue(copyUrl + " should have " + clipBoard, controller.getPermissions(copyUrl).get(clipBoard)); 152 controller.copyCodebaseToClipboard(copyUrl); 153 final PolicyEntry clipboardEntry = PolicyEditorController.getPolicyEntryFromClipboard(); 154 controller.addPolicyEntry(new PolicyEntry(pasteUrl, clipboardEntry.getPermissions(), clipboardEntry.getCustomPermissions())); 155 final Collection<String> afterPasteCodebases = controller.getCodebases(); 156 assertTrue("Controller should still contain original codebase: " + copyUrl, afterPasteCodebases.contains(copyUrl)); 157 assertTrue("Controller should also contain pasted codebase:" + pasteUrl, afterPasteCodebases.contains(pasteUrl)); 158 assertTrue(copyUrl + " should have " + clipBoard, controller.getPermissions(copyUrl).get(clipBoard)); 159 assertTrue(pasteUrl + " should have " + clipBoard, controller.getPermissions(pasteUrl).get(clipBoard)); 160 } 161 162 @Test testAddPolicyEntry()163 public void testAddPolicyEntry() throws Exception { 164 final String codebase = "http://example.com"; 165 final PolicyEditorPermissions editorPermissions = PolicyEditorPermissions.CLIPBOARD; 166 final Collection<PolicyEditorPermissions> permissions = Collections.singleton(editorPermissions); 167 final CustomPermission customPermission = new CustomPermission(PermissionType.FILE_PERMISSION, PermissionTarget.USER_HOME, PermissionActions.FILE_ALL); 168 final Collection<CustomPermission> customPermissions = Collections.singleton(customPermission); 169 final PolicyEntry policyEntry = new PolicyEntry(codebase, permissions, customPermissions); 170 controller.addPolicyEntry(policyEntry); 171 final Collection<String> codebases = controller.getCodebases(); 172 assertTrue("Controller should have " + codebase, codebases.contains(codebase)); 173 assertEquals("Controller should only have one codebase", 1, codebases.size()); 174 assertTrue("Controller should have granted " + editorPermissions, controller.getPermission(codebase, editorPermissions)); 175 assertTrue("Controller should have granted " + customPermission, controller.getCustomPermissions(codebase).contains(customPermission)); 176 } 177 178 @Test testAddCustomPermissionNoActions()179 public void testAddCustomPermissionNoActions() throws Exception { 180 final String codebase = "http://example.com"; 181 final CustomPermission customPermission = new CustomPermission("java.lang.RuntimePermission", "createClassLoader"); 182 controller.addCustomPermission(codebase, customPermission); 183 assertTrue("Controller custom permissions should include " + customPermission + " but did not", controller.getCustomPermissions(codebase).contains(customPermission)); 184 } 185 186 @Test testAddCustomPermissionEmptyActions()187 public void testAddCustomPermissionEmptyActions() throws Exception { 188 final String codebase = "http://example.com"; 189 final CustomPermission customPermission = new CustomPermission("java.lang.RuntimePermission", "createClassLoader", ""); 190 controller.addCustomPermission(codebase, customPermission); 191 assertTrue("Controller custom permissions should include " + customPermission + " but did not", controller.getCustomPermissions(codebase).contains(customPermission)); 192 } 193 194 @Test testClearCustomPermissionsNoActions()195 public void testClearCustomPermissionsNoActions() throws Exception { 196 final String codebase = "http://example.com"; 197 final CustomPermission customPermission = new CustomPermission("java.lang.RuntimePermission", "createClassLoader"); 198 controller.addCustomPermission(codebase, customPermission); 199 assertTrue("Controller custom permissions should include " + customPermission + " but did not", controller.getCustomPermissions(codebase).contains(customPermission)); 200 controller.clearCustomCodebase(codebase); 201 assertEquals(0, controller.getCustomPermissions(codebase).size()); 202 } 203 204 @Test testClearCustomPermissionsEmptyActions()205 public void testClearCustomPermissionsEmptyActions() throws Exception { 206 final String codebase = "http://example.com"; 207 final CustomPermission customPermission = new CustomPermission("java.lang.RuntimePermission", "createClassLoader", ""); 208 controller.addCustomPermission(codebase, customPermission); 209 assertTrue("Controller custom permissions should include " + customPermission + " but did not", controller.getCustomPermissions(codebase).contains(customPermission)); 210 controller.clearCustomCodebase(codebase); 211 assertEquals(0, controller.getCustomPermissions(codebase).size()); 212 } 213 214 @Test testReturnedCodebasesIsCopy()215 public void testReturnedCodebasesIsCopy() throws Exception { 216 final Collection<String> original = controller.getCodebases(); 217 original.add("some invalid value"); 218 original.remove(""); 219 final Collection<String> second = controller.getCodebases(); 220 assertEquals("Controller should have no codebases", 0, second.size()); 221 } 222 223 @Test testReturnedPermissionsMapIsCopy()224 public void testReturnedPermissionsMapIsCopy() throws Exception { 225 final Map<PolicyEditorPermissions, Boolean> original = controller.getPermissions(""); 226 for (final PolicyEditorPermissions perm : PolicyEditorPermissions.values()) { 227 original.put(perm, true); 228 } 229 final Map<PolicyEditorPermissions, Boolean> second = controller.getPermissions(""); 230 for (final Map.Entry<PolicyEditorPermissions, Boolean> entry : second.entrySet()) { 231 assertFalse("Permission " + entry.getKey() + " should be false", entry.getValue()); 232 } 233 } 234 235 @Test testReturnedCustomPermissionsSetIsCopy()236 public void testReturnedCustomPermissionsSetIsCopy() throws Exception { 237 final Collection<CustomPermission> original = controller.getCustomPermissions(""); 238 assertTrue("There should not be any custom permissions to start", original.isEmpty()); 239 original.add(new CustomPermission("java.io.FilePermission", "*", "write")); 240 final Collection<CustomPermission> second = controller.getCustomPermissions(""); 241 assertTrue("The custom permission should not have been present", second.isEmpty()); 242 } 243 244 @Test testDefaultPermissionsAllFalse()245 public void testDefaultPermissionsAllFalse() throws Exception { 246 final Map<PolicyEditorPermissions, Boolean> defaultMap = controller.getPermissions(""); 247 controller.addCodebase("http://example.com"); 248 final Map<PolicyEditorPermissions, Boolean> addedMap = controller.getPermissions("http://example.com"); 249 for (final Map.Entry<PolicyEditorPermissions, Boolean> entry : defaultMap.entrySet()) { 250 assertFalse("Permission " + entry.getKey() + " should be false", entry.getValue()); 251 } 252 for (final Map.Entry<PolicyEditorPermissions, Boolean> entry : addedMap.entrySet()) { 253 assertFalse("Permission " + entry.getKey() + " should be false", entry.getValue()); 254 } 255 } 256 257 @Test testAllPermissionsRepresented()258 public void testAllPermissionsRepresented() throws Exception { 259 final Map<PolicyEditorPermissions, Boolean> defaultMap = controller.getPermissions(""); 260 controller.addCodebase("http://example.com"); 261 final Map<PolicyEditorPermissions, Boolean> addedMap = controller.getPermissions("http://example.com"); 262 assertTrue("Default codebase permissions keyset should be the same size as enum values set", 263 defaultMap.keySet().size() == PolicyEditorPermissions.values().length); 264 assertTrue("Added codebase permissions keyset should be the same size as enum values set", 265 addedMap.keySet().size() == PolicyEditorPermissions.values().length); 266 for (final PolicyEditorPermissions perm : PolicyEditorPermissions.values()) { 267 assertTrue("Permission " + perm + " should be in the editor's codebase keyset", defaultMap.keySet().contains(perm)); 268 } 269 for (final PolicyEditorPermissions perm : PolicyEditorPermissions.values()) { 270 assertTrue("Permission " + perm + " should be in the editor's codebase keyset", addedMap.keySet().contains(perm)); 271 } 272 } 273 274 @Test testSetGetPermission()275 public void testSetGetPermission() throws Exception { 276 final String codebase = "http://example.com"; 277 controller.addCodebase(codebase); 278 final PolicyEditorPermissions permission = PolicyEditorPermissions.CLIPBOARD; 279 assertFalse("Clipboard permission should not be initially granted", controller.getPermission(codebase, permission)); 280 controller.setPermission(codebase, permission, true); 281 assertTrue("Clipboard permission should be granted after being set", controller.getPermission(codebase, permission)); 282 } 283 284 @Test testClearPermission()285 public void testClearPermission() throws Exception { 286 final String codebase = "http://example.com"; 287 controller.addCodebase(codebase); 288 final PolicyEditorPermissions permission = PolicyEditorPermissions.CLIPBOARD; 289 assertFalse("Clipboard permission should not be initially granted", controller.getPermission(codebase, permission)); 290 controller.setPermission(codebase, permission, true); 291 assertTrue("Clipboard permission should be granted after being set", controller.getPermission(codebase, permission)); 292 controller.clearPermissions(); 293 for (final String cb : controller.getCodebases()) { 294 for (final Map.Entry<PolicyEditorPermissions, Boolean> entry : controller.getPermissions(cb).entrySet()) { 295 assertFalse("Permission " + entry.getKey() + " should be false for codebase " + cb, entry.getValue()); 296 } 297 } 298 assertEquals(0, controller.getCodebases().size()); 299 } 300 301 @Test testCodebaseTrailingSlashesDoNotMatch()302 public void testCodebaseTrailingSlashesDoNotMatch() throws Exception { 303 final Collection<String> toAdd = Arrays.asList("http://redhat.com", "http://redhat.com/"); 304 for (final String cb : toAdd) { 305 controller.addCodebase(cb); 306 } 307 final Collection<String> codebases = controller.getCodebases(); 308 for (final String codebase : toAdd) { 309 assertTrue("Controller should have " + codebase, codebases.contains(codebase)); 310 } 311 } 312 313 @Test testOpenAndParsePolicyFile()314 public void testOpenAndParsePolicyFile() throws Exception { 315 final String codebase = "http://example.com"; 316 final PolicyEditorPermissions editorPermissions = PolicyEditorPermissions.CLIPBOARD; 317 final Collection<PolicyEditorPermissions> permissions = Collections.singleton(editorPermissions); 318 final CustomPermission customPermission = new CustomPermission("com.example.CustomPermission", PermissionTarget.USER_HOME.target, PermissionActions.FILE_ALL.rawString()); 319 final Collection<CustomPermission> customPermissions = new HashSet<>(Collections.singleton(customPermission)); 320 final PolicyEntry policyEntry = new PolicyEntry(codebase, permissions, customPermissions); 321 FileUtils.saveFile(policyEntry.toString(), new File(tempFilePath)); 322 controller.openAndParsePolicyFile(); 323 assertEquals("Controller should have one codebase", 1, controller.getCodebases().size()); 324 assertTrue("Controller should have codebase " + codebase, controller.getCodebases().contains(codebase)); 325 assertTrue("Controller should grant " + editorPermissions, controller.getPermission(codebase, editorPermissions)); 326 assertEquals("Custom permission sets were not equal", customPermissions, controller.getCustomPermissions(codebase)); 327 } 328 329 @Test testSavePolicyFile()330 public void testSavePolicyFile() throws Exception { 331 final String codebase = "http://example.com"; 332 final PolicyEditorPermissions editorPermissions = PolicyEditorPermissions.CLIPBOARD; 333 final Collection<PolicyEditorPermissions> permissions = Collections.singleton(editorPermissions); 334 final CustomPermission customPermission = new CustomPermission(PermissionType.FILE_PERMISSION, PermissionTarget.USER_HOME, PermissionActions.FILE_ALL); 335 final Collection<CustomPermission> customPermissions = Collections.singleton(customPermission); 336 final PolicyEntry policyEntry = new PolicyEntry(codebase, permissions, customPermissions); 337 controller.addPolicyEntry(policyEntry); 338 controller.savePolicyFile(); 339 final String fileContent = FileUtils.loadFileAsString(new File(tempFilePath)); 340 assertTrue("Saved file should contain policy entry as string", fileContent.contains(policyEntry.toString())); 341 } 342 } 343