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