001/* 002 * The contents of this file are subject to the license and copyright 003 * detailed in the LICENSE and NOTICE files at the root of the source 004 * tree. 005 */ 006package org.fcrepo.auth.webac; 007 008import static org.apache.jena.graph.NodeFactory.createURI; 009import static org.apache.jena.rdf.model.ModelFactory.createDefaultModel; 010import static org.apache.jena.riot.Lang.TTL; 011import static org.fcrepo.auth.webac.URIConstants.FOAF_AGENT_VALUE; 012import static org.fcrepo.auth.webac.URIConstants.VCARD_GROUP; 013import static org.fcrepo.auth.webac.URIConstants.WEBAC_MODE_READ_VALUE; 014import static org.fcrepo.auth.webac.URIConstants.WEBAC_MODE_WRITE_VALUE; 015import static org.fcrepo.kernel.api.FedoraTypes.FEDORA_ID_PREFIX; 016import static org.fcrepo.kernel.api.RdfLexicon.BASIC_CONTAINER; 017import static org.fcrepo.kernel.api.RdfLexicon.FEDORA_RESOURCE; 018import static org.junit.Assert.assertEquals; 019import static org.junit.Assert.assertNull; 020import static org.junit.Assert.assertTrue; 021import static org.mockito.Mockito.when; 022import static org.springframework.test.util.ReflectionTestUtils.setField; 023 024import static java.util.Collections.singletonList; 025 026import java.net.URI; 027import java.nio.file.Paths; 028import java.util.ArrayList; 029import java.util.Collection; 030import java.util.List; 031import java.util.Map; 032import java.util.Optional; 033 034import com.github.benmanes.caffeine.cache.Cache; 035import com.github.benmanes.caffeine.cache.Caffeine; 036import org.apache.jena.graph.Triple; 037import org.apache.jena.rdf.model.Model; 038import org.apache.jena.riot.Lang; 039import org.apache.jena.riot.RDFDataMgr; 040import org.fcrepo.config.AuthPropsConfig; 041import org.fcrepo.kernel.api.RdfStream; 042import org.fcrepo.kernel.api.Transaction; 043import org.fcrepo.kernel.api.auth.ACLHandle; 044import org.fcrepo.kernel.api.exception.PathNotFoundException; 045import org.fcrepo.kernel.api.exception.RepositoryException; 046import org.fcrepo.kernel.api.identifiers.FedoraId; 047import org.fcrepo.kernel.api.models.FedoraResource; 048import org.fcrepo.kernel.api.models.ResourceFactory; 049import org.fcrepo.kernel.api.rdf.DefaultRdfStream; 050import org.junit.Before; 051import org.junit.Rule; 052import org.junit.Test; 053import org.junit.contrib.java.lang.system.RestoreSystemProperties; 054import org.junit.runner.RunWith; 055import org.mockito.Mock; 056import org.mockito.junit.MockitoJUnitRunner; 057 058/** 059 * @author acoburn 060 * @since 9/3/15 061 */ 062@RunWith(MockitoJUnitRunner.Silent.class) 063public class WebACRolesProviderTest { 064 065 private WebACRolesProvider roleProvider; 066 067 private static final String FEDORA_PREFIX = "info:fedora"; 068 private static final String FEDORA_URI_PREFIX = "file:///rest"; 069 private static final URI FEDORA_RESOURCE_URI = URI.create(FEDORA_RESOURCE.getURI()); 070 071 @Mock 072 private Transaction mockTransaction; 073 074 @Mock 075 private ResourceFactory mockResourceFactory; 076 077 @Mock 078 private FedoraResource mockResource, mockParentResource; 079 080 @Mock 081 private FedoraResource mockAclResource; 082 083 @Mock 084 private FedoraResource mockAgentClassResource; 085 086 @Rule 087 public final RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties(); 088 089 private AuthPropsConfig propsConfig; 090 091 private Cache<String, Optional<ACLHandle>> authHandleCache; 092 093 @Before 094 public void setUp() throws RepositoryException { 095 authHandleCache = Caffeine.newBuilder().build(); 096 propsConfig = new AuthPropsConfig(); 097 roleProvider = new WebACRolesProvider(); 098 setField(roleProvider, "resourceFactory", mockResourceFactory); 099 setField(roleProvider, "authPropsConfig", propsConfig); 100 setField(roleProvider, "authHandleCache", authHandleCache); 101 102 when(mockResource.getDescribedResource()).thenReturn(mockResource); 103 when(mockResource.getDescription()).thenReturn(mockResource); 104 105 when(mockResource.getOriginalResource()).thenReturn(mockResource); 106 when(mockResource.getInteractionModel()).thenReturn(BASIC_CONTAINER.getURI()); 107 } 108 109 private void assertOnlyDefaultAgentInRoles(final Map<String, Collection<String>> roles) { 110 assertEquals(1, roles.size()); 111 assertTrue(roles.keySet().contains(FOAF_AGENT_VALUE)); 112 } 113 114 @Test 115 public void noAclTest() throws RepositoryException { 116 final String accessTo = "/dark/archive/sunshine"; 117 118 when(mockResource.getAcl()).thenReturn(null); 119 when(mockParentResource.getAcl()).thenReturn(null); 120 121 when(mockResource.getId()).thenReturn(accessTo); 122 when(mockResource.getContainer()).thenReturn(mockParentResource); 123 when(mockResource.getTriples()) 124 .thenReturn(new DefaultRdfStream(createURI("subject"))); 125 when(mockResource.getOriginalResource()).thenReturn(mockResource); 126 127 when(mockParentResource.getOriginalResource()).thenReturn(mockParentResource); 128 when(mockParentResource.getId()).thenReturn(null); 129 130 final Map<String, Collection<String>> roles = roleProvider.getRoles(mockResource, mockTransaction); 131 132 assertOnlyDefaultAgentInRoles(roles); 133 } 134 135 @Test 136 public void acl01ParentTest() throws RepositoryException { 137 final String agent = "user01"; 138 final String parentPath = "/webacl_box1"; 139 final String accessTo = parentPath + "/foo"; 140 final String acl = "/acls/01/acl.ttl"; 141 142 when(mockResource.getAcl()).thenReturn(null); 143 when(mockParentResource.getAcl()).thenReturn(mockAclResource); 144 145 when(mockResource.getId()).thenReturn(addPrefix(accessTo)); 146 when(mockResource.getContainer()).thenReturn(mockParentResource); 147 when(mockResource.getOriginalResource()).thenReturn(mockResource); 148 149 when(mockParentResource.getId()).thenReturn(addPrefix(parentPath)); 150 when(mockParentResource.getAcl()).thenReturn(mockAclResource); 151 when(mockAclResource.isAcl()).thenReturn(true); 152 when(mockAclResource.getId()).thenReturn(addPrefix(parentPath) + "/fcr:acl"); 153 154 when(mockAclResource.getTriples()) 155 .thenReturn(getRdfStreamFromResource(acl, TTL)); 156 157 final Map<String, Collection<String>> roles = roleProvider.getRoles(mockResource, mockTransaction); 158 159 assertEquals("There should be exactly one agent in the role map", 1, roles.size()); 160 assertEquals("The agent should have exactly two modes", 2, roles.get(agent).size()); 161 assertTrue("The agent should be able to read", roles.get(agent).contains(WEBAC_MODE_READ_VALUE)); 162 assertTrue("The agent should be able to write", roles.get(agent).contains(WEBAC_MODE_WRITE_VALUE)); 163 } 164 165 @Test 166 public void acl21NoDefaultACLStatementTest() throws RepositoryException { 167 final String agent = "user21"; 168 final String parentPath = "/resource_acl_no_inheritance"; 169 final String accessTo = parentPath + "/foo"; 170 final String acl = "/acls/21/acl.ttl"; 171 172 when(mockResource.getAcl()).thenReturn(null); 173 when(mockParentResource.getAcl()).thenReturn(mockAclResource); 174 when(mockAclResource.hasProperty("acl:default")).thenReturn(false); 175 176 when(mockResource.getId()).thenReturn(addPrefix(accessTo)); 177 when(mockResource.getContainer()).thenReturn(mockParentResource); 178 when(mockResource.getOriginalResource()).thenReturn(mockResource); 179 when(mockResource.getAcl()).thenReturn(mockAclResource); 180 181 when(mockParentResource.getId()).thenReturn(addPrefix(parentPath)); 182 when(mockAclResource.getId()).thenReturn(addPrefix(acl)); 183 when(mockParentResource.getAcl()).thenReturn(null); 184 185 186 when(mockAclResource.getTriples()) 187 .thenReturn(getRdfStreamFromResource(acl, TTL)); 188 189 propsConfig.setRootAuthAclPath(Paths.get("./target/test-classes/test-root-authorization2.ttl")); 190 191 // The default root ACL should be used for authorization instead of the parent ACL 192 final String rootAgent = "user06a"; 193 final Map<String, Collection<String>> roles = roleProvider.getRoles(mockResource, mockTransaction); 194 assertEquals("Contains no agents in the role map!", 1, roles.size()); 195 assertNull("Contains agent " + agent + " from ACL in parent node!", roles.get(agent)); 196 assertEquals("Should have agent " + rootAgent + " from the root ACL!", 1, roles.get(rootAgent).size()); 197 assertTrue("Should have read mode for agent " + rootAgent + " from the root ACL!", 198 roles.get(rootAgent).contains(WEBAC_MODE_READ_VALUE)); 199 } 200 201 @Test 202 public void acl01Test1() throws RepositoryException, PathNotFoundException { 203 final String agent = "user01"; 204 final String accessTo = "/webacl_box1"; 205 final String acl = "/acls/01/acl.ttl"; 206 207 when(mockResource.getAcl()).thenReturn(mockAclResource); 208 when(mockResourceFactory.getResource(mockTransaction, FedoraId.create(acl))) 209 .thenReturn(mockAclResource); 210 when(mockAclResource.getId()).thenReturn(addPrefix(acl)); 211 when(mockResource.getId()).thenReturn(addPrefix(accessTo)); 212 when(mockResource.getOriginalResource()).thenReturn(mockResource); 213 when(mockAclResource.getTriples()) 214 .thenReturn(getRdfStreamFromResource(acl, TTL)); 215 when(mockAclResource.isAcl()).thenReturn(true); 216 when(mockAclResource.getId()).thenReturn(addPrefix(accessTo) + "/fcr:acl"); 217 218 219 final Map<String, Collection<String>> roles = roleProvider.getRoles(mockResource, mockTransaction); 220 221 assertEquals("There should be exactly one agent in the role map", 1, roles.size()); 222 assertEquals("The agent should have exactly two modes", 2, roles.get(agent).size()); 223 assertTrue("The agent should be able to read", roles.get(agent).contains(WEBAC_MODE_READ_VALUE)); 224 assertTrue("The agent should be able to write", roles.get(agent).contains(WEBAC_MODE_WRITE_VALUE)); 225 } 226 227 @Test 228 public void acl01Test2() throws RepositoryException, PathNotFoundException { 229 final String accessTo = "/webacl_box2"; 230 final String acl = "/acls/01/acl.ttl"; 231 232 when(mockResource.getAcl()).thenReturn(mockAclResource); 233 when(mockResourceFactory.getResource(mockTransaction, FedoraId.create(acl))).thenReturn( 234 mockAclResource); 235 when(mockAclResource.getId()).thenReturn(addPrefix(acl)); 236 when(mockResource.getId()).thenReturn(addPrefix(accessTo)); 237 when(mockResource.getOriginalResource()).thenReturn(mockResource); 238 when(mockAclResource.getTriples()) 239 .thenReturn(getRdfStreamFromResource(acl, TTL)); 240 241 final Map<String, Collection<String>> roles = roleProvider.getRoles(mockResource, mockTransaction); 242 243 assertOnlyDefaultAgentInRoles(roles); 244 } 245 246 @Test 247 public void acl02Test() throws RepositoryException { 248 final String agent = "Editors"; 249 final String accessTo = "/box/bag/collection"; 250 final String acl = "/acls/02/acl.ttl"; 251 252 when(mockResource.getAcl()).thenReturn(mockAclResource); 253 when(mockAclResource.getId()).thenReturn(addPrefix(acl)); 254 when(mockResource.getId()).thenReturn(addPrefix(accessTo)); 255 when(mockAclResource.getTriples()) 256 .thenReturn(getRdfStreamFromResource(acl, TTL)); 257 when(mockAclResource.isAcl()).thenReturn(true); 258 when(mockAclResource.getId()).thenReturn(addPrefix(accessTo) + "/fcr:acl"); 259 260 when(mockResource.getOriginalResource()).thenReturn(mockResource); 261 262 263 final Map<String, Collection<String>> roles = roleProvider.getRoles(mockResource, mockTransaction); 264 265 assertEquals("There should be exactly one agent in the role map", 1, roles.size()); 266 assertEquals("The agent should have exactly two modes", 2, roles.get(agent).size()); 267 assertTrue("The agent should be able to read", roles.get(agent).contains(WEBAC_MODE_READ_VALUE)); 268 assertTrue("The agent should be able to write", roles.get(agent).contains(WEBAC_MODE_WRITE_VALUE)); 269 } 270 271 @Test 272 public void acl03Test1() throws RepositoryException, PathNotFoundException { 273 final String agent = "http://xmlns.com/foaf/0.1/Agent"; 274 final String accessTo = "/dark/archive/sunshine"; 275 final String acl = "/acls/03/acl.ttl"; 276 277 when(mockResource.getAcl()).thenReturn(mockAclResource); 278 when(mockResourceFactory.getResource(mockTransaction, FedoraId.create(acl))).thenReturn( 279 mockAclResource); 280 when(mockAclResource.getId()).thenReturn(addPrefix(acl)); 281 when(mockResource.getId()).thenReturn(addPrefix(accessTo)); 282 when(mockResource.getOriginalResource()).thenReturn(mockResource); 283 when(mockAclResource.getTriples()) 284 .thenReturn(getRdfStreamFromResource(acl, TTL)); 285 when(mockAclResource.isAcl()).thenReturn(true); 286 when(mockAclResource.getId()).thenReturn(addPrefix(accessTo) + "/fcr:acl"); 287 288 final Map<String, Collection<String>> roles = roleProvider.getRoles(mockResource, mockTransaction); 289 290 assertEquals("There should be exactly one agent in the roles map", 1, roles.size()); 291 assertEquals("The agent should have exactly one mode", 1, roles.get(agent).size()); 292 assertTrue("The agent should be able to read", roles.get(agent).contains(WEBAC_MODE_READ_VALUE)); 293 } 294 295 @Test 296 public void acl03Test2() throws RepositoryException, PathNotFoundException { 297 final String agent = "Restricted"; 298 final String accessTo = "/dark/archive"; 299 final String acl = "/acls/03/acl.ttl"; 300 301 when(mockResource.getAcl()).thenReturn(mockAclResource); 302 when(mockAclResource.isAcl()).thenReturn(true); 303 when(mockResourceFactory.getResource(mockTransaction, FedoraId.create(acl))).thenReturn( 304 mockAclResource); 305 when(mockAclResource.getId()).thenReturn(addPrefix(acl)); 306 when(mockResource.getId()).thenReturn(addPrefix(accessTo)); 307 when(mockResource.getOriginalResource()).thenReturn(mockResource); 308 when(mockAclResource.getTriples()) 309 .thenReturn(getRdfStreamFromResource(acl, TTL)); 310 311 final Map<String, Collection<String>> roles = roleProvider.getRoles(mockResource, mockTransaction); 312 313 assertEquals("There should be exactly one agent", 1, roles.size()); 314 assertEquals("The agent should have one mode", 1, roles.get(agent).size()); 315 assertTrue("The agent should be able to read", roles.get(agent).contains(WEBAC_MODE_READ_VALUE)); 316 } 317 318 @Test 319 public void foafAgentTest() throws RepositoryException, PathNotFoundException { 320 final String agent = "http://xmlns.com/foaf/0.1/Agent"; 321 final String accessTo = "/foaf-agent"; 322 final String acl = "/acls/03/foaf-agent.ttl"; 323 324 when(mockResource.getAcl()).thenReturn(mockAclResource); 325 when(mockResourceFactory.getResource(mockTransaction, FedoraId.create(acl))) 326 .thenReturn(mockAclResource); 327 when(mockAclResource.getId()).thenReturn(addPrefix(acl)); 328 when(mockAclResource.isAcl()).thenReturn(true); 329 when(mockResource.getId()).thenReturn(addPrefix(accessTo)); 330 when(mockResource.getOriginalResource()).thenReturn(mockResource); 331 when(mockAclResource.getTriples()) 332 .thenReturn(getRdfStreamFromResource(acl, TTL)); 333 334 final Map<String, Collection<String>> roles = roleProvider.getRoles(mockResource, mockTransaction); 335 336 assertEquals("There should be only one valid role", 1, roles.size()); 337 assertEquals("The foaf:Agent should have exactly one valid mode", 1, 338 roles.get(agent).size()); 339 assertTrue("The foaf:Agent should be able to write", 340 roles.get(agent).contains(WEBAC_MODE_READ_VALUE)); 341 } 342 343 @Test 344 public void authenticatedAgentTest() throws RepositoryException, PathNotFoundException { 345 final String aclAuthenticatedAgent = "http://www.w3.org/ns/auth/acl#AuthenticatedAgent"; 346 final String accessTo = "/authenticated-agent"; 347 final String acl = "/acls/03/authenticated-agent.ttl"; 348 349 when(mockResource.getAcl()).thenReturn(mockAclResource); 350 when(mockResourceFactory.getResource(mockTransaction, FedoraId.create(acl))).thenReturn( 351 mockAclResource); 352 when(mockAclResource.getId()).thenReturn(addPrefix(acl)); 353 when(mockAclResource.isAcl()).thenReturn(true); 354 when(mockResource.getId()).thenReturn(addPrefix(accessTo)); 355 when(mockResource.getOriginalResource()).thenReturn(mockResource); 356 when(mockAclResource.getTriples()).thenReturn(getRdfStreamFromResource(acl, TTL)); 357 358 final Map<String, Collection<String>> roles = roleProvider.getRoles(mockResource, mockTransaction); 359 360 assertEquals("There should be only one valid role", 1, roles.size()); 361 assertEquals("The acl:AuthenticatedAgent should have exactly one valid mode", 1, 362 roles.get(aclAuthenticatedAgent).size()); 363 assertTrue("The acl:AuthenticatedAgent should be able to write", 364 roles.get(aclAuthenticatedAgent).contains(WEBAC_MODE_READ_VALUE)); 365 } 366 367 @Test 368 public void acl04Test() throws RepositoryException, PathNotFoundException { 369 final String agent1 = "http://xmlns.com/foaf/0.1/Agent"; 370 final String agent2 = "Editors"; 371 final String accessTo = "/public_collection"; 372 final String acl = "/acls/04/acl.ttl"; 373 374 when(mockResource.getAcl()).thenReturn(mockAclResource); 375 when(mockResourceFactory.getResource(mockTransaction, FedoraId.create(acl))).thenReturn( 376 mockAclResource); 377 when(mockAclResource.getId()).thenReturn(addPrefix(acl)); 378 when(mockAclResource.isAcl()).thenReturn(true); 379 when(mockResource.getId()).thenReturn(addPrefix(accessTo)); 380 when(mockResource.getOriginalResource()).thenReturn(mockResource); 381 when(mockAclResource.getTriples()).thenReturn(getRdfStreamFromResource(acl, TTL)); 382 383 final Map<String, Collection<String>> roles = roleProvider.getRoles(mockResource, mockTransaction); 384 385 assertEquals("There should be exactly two agents", 2, roles.size()); 386 assertEquals("The agent should have one mode", 1, roles.get(agent1).size()); 387 assertTrue("The agent should be able to read", roles.get(agent1).contains(WEBAC_MODE_READ_VALUE)); 388 assertEquals("The agent should have two modes", 2, roles.get(agent2).size()); 389 assertTrue("The agent should be able to read", roles.get(agent2).contains(WEBAC_MODE_READ_VALUE)); 390 assertTrue("The agent should be able to write", roles.get(agent2).contains(WEBAC_MODE_READ_VALUE)); 391 } 392 393 @Test 394 public void acl05Test() throws RepositoryException, PathNotFoundException { 395 final String agent1 = "http://xmlns.com/foaf/0.1/Agent"; 396 final String agent2 = "Admins"; 397 final String accessTo = "/mixedCollection"; 398 final String acl = "/acls/05/acl.ttl"; 399 400 when(mockResource.getAcl()).thenReturn(mockAclResource); 401 when(mockResourceFactory.getResource(mockTransaction, FedoraId.create(addPrefix(acl)))).thenReturn( 402 mockAclResource 403 ); 404 when(mockResource.getTypes()).thenReturn(singletonList(URI.create("http://example.com/terms#publicImage"))); 405 when(mockAclResource.isAcl()).thenReturn(true); 406 when(mockAclResource.getId()).thenReturn(addPrefix(acl)); 407 when(mockResource.getId()).thenReturn(addPrefix(accessTo)); 408 when(mockResource.getOriginalResource()).thenReturn(mockResource); 409 when(mockAclResource.getTriples()).thenReturn(getRdfStreamFromResource(acl, TTL)); 410 411 final Map<String, Collection<String>> roles = roleProvider.getRoles(mockResource, mockTransaction); 412 413 assertEquals("There should be exactly two agents", 2, roles.size()); 414 assertEquals("The agent should have one mode", 1, roles.get(agent1).size()); 415 assertTrue("The agent should be able to read", roles.get(agent1).contains(WEBAC_MODE_READ_VALUE)); 416 assertEquals("The agent should have one mode", 1, roles.get(agent2).size()); 417 assertTrue("The agent should be able to read", roles.get(agent2).contains(WEBAC_MODE_READ_VALUE)); 418 } 419 420 @Test 421 public void acl05Test2() throws RepositoryException, PathNotFoundException { 422 final String agent1 = "http://xmlns.com/foaf/0.1/Agent"; 423 final String accessTo = "/someOtherCollection"; 424 final String acl = "/acls/05/acl.ttl"; 425 426 when(mockResourceFactory.getResource(mockTransaction, FedoraId.create(addPrefix(acl)))) 427 .thenReturn(mockAclResource); 428 when(mockResource.getAcl()).thenReturn(mockAclResource); 429 when(mockResource.getTypes()).thenReturn(singletonList(URI.create("http://example.com/terms#publicImage"))); 430 when(mockResource.getId()).thenReturn(addPrefix(accessTo)); 431 when(mockResource.getOriginalResource()).thenReturn(mockResource); 432 when(mockAclResource.getId()).thenReturn(addPrefix(acl)); 433 when(mockAclResource.isAcl()).thenReturn(true); 434 when(mockAclResource.getTriples()).thenReturn(getRdfStreamFromResource(acl, TTL)); 435 436 final Map<String, Collection<String>> roles = roleProvider.getRoles(mockResource, mockTransaction); 437 438 assertEquals("There should be exactly one agent", 1, roles.size()); 439 assertEquals("The agent should have one mode", 1, roles.get(agent1).size()); 440 assertTrue("The agent should be able to read", roles.get(agent1).contains(WEBAC_MODE_READ_VALUE)); 441 } 442 443 /* (non-Javadoc) 444 * Test that an in-repository resource used as a target for acl:agentGroup has 445 * the rdf:type of vcard:Group. This test mocks a vcard:Group resource and should 446 * therefore retrieve two agents. 447 */ 448 @Test 449 public void acl09Test1() throws RepositoryException, PathNotFoundException { 450 final String agent1 = "person1"; 451 final String accessTo = "/anotherCollection"; 452 453 final String groupResource = "/group/foo"; 454 final String aclDir = "/acls/09"; 455 final String acl = aclDir + "/acl.ttl"; 456 final String group = aclDir + "/group.ttl"; 457 458 when(mockResourceFactory.getResource(mockTransaction, FedoraId.create(addPrefix(acl)))) 459 .thenReturn(mockAclResource); 460 when(mockResourceFactory.getResource(mockTransaction, FedoraId.create(addPrefix(groupResource)))) 461 .thenReturn(mockAgentClassResource); 462 when(mockResource.getAcl()).thenReturn(mockAclResource); 463 when(mockResource.getId()).thenReturn(addPrefix(accessTo)); 464 when(mockResource.getOriginalResource()).thenReturn(mockResource); 465 when(mockAclResource.getTriples()).thenReturn(getRdfStreamFromResource(acl, TTL)); 466 when(mockAclResource.isAcl()).thenReturn(true); 467 when(mockAclResource.getId()).thenReturn(addPrefix(accessTo) + "/fcr:acl"); 468 469 when(mockAgentClassResource.getTypes()).thenReturn(singletonList(VCARD_GROUP)); 470 when(mockAgentClassResource.getId()).thenReturn(addPrefix(groupResource)); 471 when(mockAgentClassResource.getTriples()).thenReturn(getRdfStreamFromResource(group, TTL)); 472 473 474 final Map<String, Collection<String>> roles = roleProvider.getRoles(mockResource, mockTransaction); 475 476 assertEquals("There should be exactly two agents", 2, roles.size()); 477 assertEquals("The agent should have two modes", 2, roles.get(agent1).size()); 478 assertTrue("The agent should be able to read", roles.get(agent1).contains(WEBAC_MODE_READ_VALUE)); 479 assertTrue("The agent should be able to write", roles.get(agent1).contains(WEBAC_MODE_WRITE_VALUE)); 480 } 481 482 /* (non-Javadoc) 483 * Test that an in-repository resource used as a target for acl:agentClass has 484 * the rdf:type of foaf:Group. This test mocks a resource that is not of the type 485 * foaf:Group and therefore should retrieve zero agents. 486 */ 487 @Test 488 public void acl09Test2() throws RepositoryException, PathNotFoundException { 489 final String accessTo = "/anotherCollection"; 490 491 final String groupResource = "/group/foo"; 492 final String acl = "/acls/09/acl.ttl"; 493 final String group = "/acls/09/group.ttl"; 494 495 when(mockResourceFactory.getResource(mockTransaction, FedoraId.create(addPrefix(acl)))).thenReturn( 496 mockAclResource); 497 when(mockResourceFactory.getResource(mockTransaction, 498 FedoraId.create(addPrefix(groupResource)))).thenReturn(mockAgentClassResource); 499 when(mockResource.getAcl()).thenReturn(mockAclResource); 500 when(mockResource.getId()).thenReturn(addPrefix(accessTo)); 501 when(mockResource.getOriginalResource()).thenReturn(mockResource); 502 when(mockAclResource.getId()).thenReturn(addPrefix(acl)); 503 when(mockAclResource.getTriples()).thenReturn(getRdfStreamFromResource(acl, TTL)); 504 505 when(mockAgentClassResource.getTypes()).thenReturn(new ArrayList<>()); 506 when(mockAgentClassResource.getId()).thenReturn(addPrefix(groupResource)); 507 when(mockAgentClassResource.getTriples()) 508 .thenReturn(getRdfStreamFromResource(group, TTL)); 509 510 final Map<String, Collection<String>> roles = roleProvider.getRoles(mockResource, mockTransaction); 511 512 assertOnlyDefaultAgentInRoles(roles); 513 } 514 515 @Test 516 public void acl17Test1() throws RepositoryException, PathNotFoundException { 517 final String foafAgent = "http://xmlns.com/foaf/0.1/Agent"; 518 final String accessTo = "/dark/archive/sunshine"; 519 final String acl = "/acls/17/acl.ttl"; 520 521 when(mockResource.getAcl()).thenReturn(mockAclResource); 522 when(mockResourceFactory.getResource(mockTransaction, FedoraId.create(addPrefix(acl)))) 523 .thenReturn(mockAclResource); 524 when(mockAclResource.getId()).thenReturn(addPrefix(acl)); 525 when(mockAclResource.isAcl()).thenReturn(true); 526 when(mockResource.getId()).thenReturn(addPrefix(accessTo)); 527 when(mockResource.getOriginalResource()).thenReturn(mockResource); 528 when(mockAclResource.getTriples()) 529 .thenReturn(getRdfStreamFromResource(acl, TTL)); 530 531 final Map<String, Collection<String>> roles = roleProvider.getRoles(mockResource, mockTransaction); 532 533 assertEquals("There should be only one valid role", 1, roles.size()); 534 assertEquals("The foafAgent should have exactly one valid mode", 1, roles.get(foafAgent).size()); 535 assertTrue("The foafAgent should be able to write", roles.get(foafAgent).contains(WEBAC_MODE_WRITE_VALUE)); 536 } 537 538 @Test 539 public void noAclTest1() { 540 final String agent1 = "http://xmlns.com/foaf/0.1/Agent"; 541 542 when(mockResource.getAcl()).thenReturn(null); 543 544 when(mockResource.getId()).thenReturn(FEDORA_ID_PREFIX); 545 when(mockResource.getTypes()).thenReturn( 546 singletonList(FEDORA_RESOURCE_URI)); 547 when(mockResource.getOriginalResource()).thenReturn(mockResource); 548 final Map<String, Collection<String>> roles = roleProvider.getRoles(mockResource, mockTransaction); 549 550 assertEquals("There should be exactly one agent", 1, roles.size()); 551 assertEquals("The agent should have one mode", 1, roles.get(agent1).size()); 552 } 553 554 @Test(expected = RuntimeException.class) 555 public void noAclTestMalformedRdf2() { 556 557 when(mockResource.getAcl()).thenReturn(null); 558 559 when(mockResource.getId()).thenReturn(FEDORA_ID_PREFIX); 560 when(mockResource.getTypes()).thenReturn( 561 singletonList(FEDORA_RESOURCE_URI)); 562 when(mockResource.getOriginalResource()).thenReturn(mockResource); 563 564 propsConfig.setRootAuthAclPath(Paths.get("./target/test-classes/logback-test.xml")); 565 roleProvider.getRoles(mockResource, mockTransaction); 566 } 567 568 @Test 569 public void noAclTestOkRdf3() { 570 final String agent1 = "testAdminUser"; 571 572 when(mockResource.getAcl()).thenReturn(null); 573 when(mockResource.getId()).thenReturn(FEDORA_ID_PREFIX); 574 when(mockResource.getTypes()).thenReturn( 575 singletonList(FEDORA_RESOURCE_URI)); 576 577 propsConfig.setRootAuthAclPath(Paths.get("./target/test-classes/test-root-authorization.ttl")); 578 final Map<String, Collection<String>> roles = roleProvider.getRoles(mockResource, mockTransaction); 579 580 assertEquals("There should be exactly one agent", 1, roles.size()); 581 assertEquals("The agent should have one mode", 1, roles.get(agent1).size()); 582 assertTrue("The agent should be able to read", roles.get(agent1).contains(WEBAC_MODE_READ_VALUE)); 583 } 584 585 private static RdfStream getRdfStreamFromResource(final String resourcePath, final Lang lang) { 586 final Model model = createDefaultModel(); 587 588 RDFDataMgr.read(model, WebACRolesProviderTest.class.getResourceAsStream(resourcePath), lang); 589 590 final List<Triple> triples = new ArrayList<>(); 591 model.listStatements().forEachRemaining(x -> { 592 final Triple t = x.asTriple(); 593 if (t.getObject().isURI() && t.getObject().getURI().startsWith(FEDORA_URI_PREFIX)) { 594 triples.add(new Triple(t.getSubject(), t.getPredicate(), 595 createURI(FEDORA_PREFIX + t.getObject().getURI().substring(FEDORA_URI_PREFIX.length())))); 596 } else { 597 triples.add(t); 598 } 599 }); 600 601 return new DefaultRdfStream(createURI("subject"), triples.stream()); 602 } 603 604 private String addPrefix(final String id) { 605 final String cleanId = id.replaceFirst("^/", ""); 606 if (!cleanId.startsWith(FEDORA_ID_PREFIX)) { 607 return FEDORA_ID_PREFIX + "/" + cleanId; 608 } 609 return cleanId; 610 } 611 612}