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