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