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.stream.Stream.of;
021import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
022import static javax.servlet.http.HttpServletResponse.SC_OK;
023import static org.apache.jena.riot.WebContent.contentTypeSPARQLUpdate;
024import static org.fcrepo.auth.common.ServletContainerAuthFilter.FEDORA_ADMIN_ROLE;
025import static org.fcrepo.auth.common.ServletContainerAuthFilter.FEDORA_USER_ROLE;
026import static org.fcrepo.auth.webac.URIConstants.WEBAC_MODE_APPEND;
027import static org.fcrepo.auth.webac.URIConstants.WEBAC_MODE_CONTROL;
028import static org.fcrepo.auth.webac.URIConstants.WEBAC_MODE_READ;
029import static org.fcrepo.auth.webac.URIConstants.WEBAC_MODE_WRITE;
030import static org.fcrepo.http.commons.session.TransactionConstants.ATOMIC_ID_HEADER;
031import static org.fcrepo.kernel.api.RdfLexicon.BASIC_CONTAINER;
032import static org.fcrepo.kernel.api.RdfLexicon.EMBED_CONTAINED;
033import static org.fcrepo.kernel.api.RdfLexicon.NON_RDF_SOURCE;
034import static org.fcrepo.kernel.api.RdfLexicon.REPOSITORY_NAMESPACE;
035import static org.junit.Assert.assertEquals;
036import static org.mockito.ArgumentMatchers.any;
037import static org.mockito.ArgumentMatchers.eq;
038import static org.mockito.Mockito.when;
039import static org.springframework.test.util.ReflectionTestUtils.setField;
040
041import org.fcrepo.config.FedoraPropsConfig;
042import org.fcrepo.kernel.api.TransactionManager;
043import org.fcrepo.kernel.api.exception.PathNotFoundException;
044import org.fcrepo.kernel.api.identifiers.FedoraId;
045import org.fcrepo.kernel.api.models.ResourceFactory;
046
047import java.net.URI;
048import java.util.ArrayList;
049import java.util.Arrays;
050import java.util.List;
051
052import org.apache.shiro.SecurityUtils;
053import org.apache.shiro.mgt.SecurityManager;
054import org.apache.shiro.subject.Subject;
055import org.apache.shiro.subject.support.SubjectThreadState;
056import org.fcrepo.kernel.api.Transaction;
057import org.fcrepo.kernel.api.models.Container;
058import org.fcrepo.kernel.api.models.Binary;
059import org.fcrepo.kernel.api.models.FedoraResource;
060import org.junit.After;
061import org.junit.Before;
062import org.junit.Ignore;
063import org.junit.Test;
064import org.junit.runner.RunWith;
065import org.mockito.InjectMocks;
066import org.mockito.Mock;
067import org.mockito.Mockito;
068import org.mockito.junit.MockitoJUnitRunner;
069import org.springframework.mock.web.MockFilterChain;
070import org.springframework.mock.web.MockHttpServletRequest;
071import org.springframework.mock.web.MockHttpServletResponse;
072
073/**
074 * @author peichman
075 */
076@RunWith(MockitoJUnitRunner.Silent.class)
077public class WebACFilterTest {
078
079    private static final String baseURL = "http://localhost";
080
081    private static final String transactionId = "abc-def";
082
083    private static final String transactionUri = baseURL + "/fcr:tx/" + transactionId;
084
085    private static final String testPath = "/testUri";
086
087    private static final String testChildPath = testPath + "/child";
088
089    private static final String testAclPath = testPath + "/fcr:acl";
090
091    private static final URI testURI = URI.create(baseURL + testPath);
092
093    private static final URI testAclURI = URI.create(baseURL + testAclPath);
094
095    private static final URI testChildURI = URI.create(baseURL + testChildPath);
096
097    private static final FedoraId testId = FedoraId.create(testPath);
098
099    private static final FedoraId testChildId = FedoraId.create(testChildPath);
100
101    @Mock
102    private SecurityManager mockSecurityManager;
103
104    @Mock
105    private TransactionManager mockTransactionManager;
106
107    @Mock
108    private ResourceFactory mockResourceFactory;
109
110    @Mock
111    private Transaction mockTransaction;
112
113    private FedoraResource mockContainer;
114
115    private FedoraResource mockChildContainer;
116
117    private FedoraResource mockBinary;
118
119    private FedoraResource mockRoot;
120
121    @InjectMocks
122    private final WebACFilter webacFilter = new WebACFilter();
123
124    private static final WebACPermission readPermission = new WebACPermission(WEBAC_MODE_READ, testURI);
125
126    private static final WebACPermission appendPermission = new WebACPermission(WEBAC_MODE_APPEND, testURI);
127
128    private static final WebACPermission writePermission = new WebACPermission(WEBAC_MODE_WRITE, testURI);
129
130    private static final WebACPermission controlPermission = new WebACPermission(WEBAC_MODE_CONTROL, testURI);
131
132    private static final WebACPermission readAclPermission = new WebACPermission(WEBAC_MODE_READ, testAclURI);
133    private static final WebACPermission appendAclPermission = new WebACPermission(WEBAC_MODE_APPEND, testAclURI);
134    private static final WebACPermission writeAclPermission = new WebACPermission(WEBAC_MODE_WRITE, testAclURI);
135    private static final WebACPermission controlAclPermission = new WebACPermission(WEBAC_MODE_CONTROL, testAclURI);
136
137    // We are dealing with internal IDs.
138    private static final WebACPermission readChildPermission = new WebACPermission(WEBAC_MODE_READ,
139            URI.create(testChildId.getFullId()));
140    private static final WebACPermission appendChildPermission = new WebACPermission(WEBAC_MODE_APPEND, testChildURI);
141    private static final WebACPermission writeChildPermission = new WebACPermission(WEBAC_MODE_WRITE, testChildURI);
142    private static final WebACPermission controlChildPermission = new WebACPermission(WEBAC_MODE_CONTROL, testChildURI);
143
144    private MockHttpServletRequest request;
145
146    private MockHttpServletResponse response;
147
148    private MockFilterChain filterChain;
149
150    private SubjectThreadState threadState;
151
152    private Subject mockSubject;
153
154    private FedoraPropsConfig propsConfig;
155
156    @Before
157    public void setupRequest() throws Exception {
158        propsConfig = new FedoraPropsConfig();
159        SecurityUtils.setSecurityManager(mockSecurityManager);
160
161        mockSubject = Mockito.mock(Subject.class);
162        threadState = new SubjectThreadState(mockSubject);
163        threadState.bind();
164
165        request = new MockHttpServletRequest();
166        response = new MockHttpServletResponse();
167        filterChain = new MockFilterChain();
168
169        // set default request URI and path info
170        // for the purposes of this test, there is no context path
171        // so the request URI and path info are the same
172        request.setPathInfo(testPath);
173        request.setRequestURI(testPath);
174        request.setContentType(null);
175        request.addHeader(ATOMIC_ID_HEADER, transactionUri);
176
177        setField(webacFilter, "transactionManager", mockTransactionManager);
178        setField(webacFilter, "fedoraPropsConfig", propsConfig);
179
180        mockContainer = Mockito.mock(Container.class);
181        mockChildContainer = Mockito.mock(Container.class);
182        mockBinary = Mockito.mock(Binary.class);
183        mockRoot = Mockito.mock(Container.class);
184
185        when(mockTransactionManager.get(transactionId)).thenReturn(mockTransaction);
186
187        when(mockResourceFactory.getResource(mockTransaction, testChildId))
188                .thenReturn(null);
189
190        when(mockResourceFactory.getResource(mockTransaction, FedoraId.getRepositoryRootId()))
191                .thenReturn(mockRoot);
192        when(mockContainer.getContainer()).thenReturn(mockRoot);
193        when(mockChildContainer.getContainer()).thenReturn(mockContainer);
194
195        when(mockContainer.getTypes()).thenReturn(Arrays.asList(URI.create(BASIC_CONTAINER.toString())));
196        when(mockChildContainer.getTypes()).thenReturn(Arrays.asList(URI.create(BASIC_CONTAINER.toString())));
197        when(mockBinary.getTypes()).thenReturn(Arrays.asList(URI.create(NON_RDF_SOURCE.toString())));
198
199        final List<URI> rootTypes = new ArrayList<>();
200        of("RepositoryRoot", "Resource", "Container").forEach(x -> rootTypes.add(URI.create(REPOSITORY_NAMESPACE +
201                x)));
202        when(mockRoot.getTypes()).thenReturn(rootTypes);
203
204        // Setup Container by default
205        setupContainerResource();
206    }
207
208    private void setupContainerResource() throws Exception {
209        when(mockResourceFactory.getResource(mockTransaction, testId))
210                .thenReturn(mockContainer);
211        when(mockContainer.getFedoraId()). thenReturn(testId);
212        when(mockResourceFactory.getResource(mockTransaction, testChildId))
213                .thenReturn(mockChildContainer);
214        when(mockChildContainer.getFedoraId()).thenReturn(testChildId);
215    }
216
217    private void setupBinaryResource() throws Exception {
218        when(mockResourceFactory.getResource(mockTransaction, testId))
219                .thenReturn(mockBinary);
220        when(mockBinary.getFedoraId()).thenReturn(testId);
221    }
222
223    private void setupAdminUser() {
224        // admin user
225        when(mockSubject.isAuthenticated()).thenReturn(true);
226        when(mockSubject.hasRole(FEDORA_ADMIN_ROLE)).thenReturn(true);
227    }
228
229    private void setupAuthUserNoPerms() {
230        // authenticated user without permissions
231        when(mockSubject.isAuthenticated()).thenReturn(true);
232        when(mockSubject.hasRole(FEDORA_ADMIN_ROLE)).thenReturn(false);
233        when(mockSubject.hasRole(FEDORA_USER_ROLE)).thenReturn(true);
234        when(mockSubject.isPermitted(readPermission)).thenReturn(false);
235        when(mockSubject.isPermitted(appendPermission)).thenReturn(false);
236        when(mockSubject.isPermitted(writePermission)).thenReturn(false);
237        when(mockSubject.isPermitted(controlPermission)).thenReturn(false);
238
239    }
240
241    private void setupAuthUserReadOnly() {
242        // authenticated user with only read permissions
243        when(mockSubject.isAuthenticated()).thenReturn(true);
244        when(mockSubject.hasRole(FEDORA_ADMIN_ROLE)).thenReturn(false);
245        when(mockSubject.hasRole(FEDORA_USER_ROLE)).thenReturn(true);
246        when(mockSubject.isPermitted(readPermission)).thenReturn(true);
247        when(mockSubject.isPermitted(appendPermission)).thenReturn(false);
248        when(mockSubject.isPermitted(writePermission)).thenReturn(false);
249        when(mockSubject.isPermitted(controlPermission)).thenReturn(false);
250
251    }
252
253    private void setupAuthUserAppendOnly() {
254        // authenticated user with only read permissions
255        when(mockSubject.isAuthenticated()).thenReturn(true);
256        when(mockSubject.hasRole(FEDORA_ADMIN_ROLE)).thenReturn(false);
257        when(mockSubject.hasRole(FEDORA_USER_ROLE)).thenReturn(true);
258        when(mockSubject.isPermitted(readPermission)).thenReturn(false);
259        when(mockSubject.isPermitted(appendPermission)).thenReturn(true);
260        when(mockSubject.isPermitted(appendChildPermission)).thenReturn(true);
261        when(mockSubject.isPermitted(writePermission)).thenReturn(false);
262        when(mockSubject.isPermitted(controlPermission)).thenReturn(false);
263
264    }
265
266    private void setupAuthUserReadAppend() {
267        // authenticated user with only read permissions
268        when(mockSubject.isAuthenticated()).thenReturn(true);
269        when(mockSubject.hasRole(FEDORA_ADMIN_ROLE)).thenReturn(false);
270        when(mockSubject.hasRole(FEDORA_USER_ROLE)).thenReturn(true);
271        when(mockSubject.isPermitted(readPermission)).thenReturn(true);
272        when(mockSubject.isPermitted(appendPermission)).thenReturn(true);
273        when(mockSubject.isPermitted(appendChildPermission)).thenReturn(true);
274        when(mockSubject.isPermitted(writePermission)).thenReturn(false);
275        when(mockSubject.isPermitted(controlPermission)).thenReturn(false);
276    }
277
278    private void setupAuthUserReadWrite() {
279        // authenticated user with read and write permissions
280        when(mockSubject.isAuthenticated()).thenReturn(true);
281        when(mockSubject.hasRole(FEDORA_ADMIN_ROLE)).thenReturn(false);
282        when(mockSubject.hasRole(FEDORA_USER_ROLE)).thenReturn(true);
283        when(mockSubject.isPermitted(readPermission)).thenReturn(true);
284        when(mockSubject.isPermitted(appendPermission)).thenReturn(false);
285        when(mockSubject.isPermitted(writePermission)).thenReturn(true);
286        when(mockSubject.isPermitted(controlPermission)).thenReturn(false);
287    }
288
289    private void setupAuthUserAclControl() {
290        // authenticated user with read and write permissions
291        when(mockSubject.isAuthenticated()).thenReturn(true);
292        when(mockSubject.hasRole(FEDORA_ADMIN_ROLE)).thenReturn(false);
293        when(mockSubject.hasRole(FEDORA_USER_ROLE)).thenReturn(true);
294        when(mockSubject.isPermitted(readAclPermission)).thenReturn(false);
295        when(mockSubject.isPermitted(appendAclPermission)).thenReturn(false);
296        when(mockSubject.isPermitted(writeAclPermission)).thenReturn(false);
297        when(mockSubject.isPermitted(controlAclPermission)).thenReturn(true);
298    }
299
300    private void setupAuthUserNoAclControl() {
301        // authenticated user with read and write permissions
302        when(mockSubject.isAuthenticated()).thenReturn(true);
303        when(mockSubject.hasRole(FEDORA_ADMIN_ROLE)).thenReturn(false);
304        when(mockSubject.hasRole(FEDORA_USER_ROLE)).thenReturn(true);
305        when(mockSubject.isPermitted(readAclPermission)).thenReturn(true);
306        when(mockSubject.isPermitted(appendAclPermission)).thenReturn(true);
307        when(mockSubject.isPermitted(writeAclPermission)).thenReturn(true);
308        when(mockSubject.isPermitted(controlAclPermission)).thenReturn(false);
309    }
310
311    private void setupAuthUserReadAppendWrite() {
312        // authenticated user with read and write permissions
313        when(mockSubject.isAuthenticated()).thenReturn(true);
314        when(mockSubject.hasRole(FEDORA_ADMIN_ROLE)).thenReturn(false);
315        when(mockSubject.hasRole(FEDORA_USER_ROLE)).thenReturn(true);
316        when(mockSubject.isPermitted(readPermission)).thenReturn(true);
317        when(mockSubject.isPermitted(appendPermission)).thenReturn(true);
318        when(mockSubject.isPermitted(appendChildPermission)).thenReturn(true);
319        when(mockSubject.isPermitted(writePermission)).thenReturn(true);
320        when(mockSubject.isPermitted(controlPermission)).thenReturn(true);
321
322    }
323
324    private void setupAuthUserReadParentAndChildren(final boolean accessToChild) {
325        // authenticated user has read to a container and it's contained resources.
326        when(mockSubject.isAuthenticated()).thenReturn(true);
327        when(mockSubject.hasRole(FEDORA_ADMIN_ROLE)).thenReturn(false);
328        when(mockSubject.hasRole(FEDORA_USER_ROLE)).thenReturn(true);
329        when(mockSubject.isPermitted(readPermission)).thenReturn(true);
330        when(mockSubject.isPermitted(appendPermission)).thenReturn(false);
331        when(mockSubject.isPermitted(writePermission)).thenReturn(false);
332        when(mockSubject.isPermitted(controlPermission)).thenReturn(false);
333        when(mockSubject.isPermitted(readChildPermission)).thenReturn(accessToChild);
334        when(mockSubject.isPermitted(appendChildPermission)).thenReturn(false);
335        when(mockSubject.isPermitted(writeChildPermission)).thenReturn(false);
336        when(mockSubject.isPermitted(controlChildPermission)).thenReturn(false);
337        when(mockResourceFactory.getChildren(any(), eq(testId))).thenReturn(List.of(mockChildContainer).stream());
338    }
339
340    private void setupEmbeddedResourceHeader() {
341        request.addHeader("Prefer", "return=representation; include=\"" + EMBED_CONTAINED + "\"");
342    }
343
344    @Test
345    public void testAdminUserHead() throws Exception {
346        setupAdminUser();
347        // HEAD => 200
348        request.setMethod("HEAD");
349        webacFilter.doFilter(request, response, filterChain);
350        assertEquals(SC_OK, response.getStatus());
351    }
352
353    @Test
354    public void testAdminUserOptions() throws Exception {
355        setupAdminUser();
356        // GET => 200
357        request.setMethod("OPTIONS");
358        webacFilter.doFilter(request, response, filterChain);
359        assertEquals(SC_OK, response.getStatus());
360    }
361
362    @Test
363    public void testAdminUserGet() throws Exception {
364        setupAdminUser();
365        // GET => 200
366        request.setMethod("GET");
367        webacFilter.doFilter(request, response, filterChain);
368        assertEquals(SC_OK, response.getStatus());
369    }
370
371    @Test
372    public void testAdminUserPost() throws Exception {
373        setupAdminUser();
374        // GET => 200
375        request.setMethod("POST");
376        webacFilter.doFilter(request, response, filterChain);
377        assertEquals(SC_OK, response.getStatus());
378    }
379
380    @Test
381    public void testAdminUserPut() throws Exception {
382        setupAdminUser();
383        // GET => 200
384        request.setMethod("PUT");
385        webacFilter.doFilter(request, response, filterChain);
386        assertEquals(SC_OK, response.getStatus());
387    }
388
389    @Test
390    public void testAdminUserPatch() throws Exception {
391        setupAdminUser();
392        // GET => 200
393        request.setMethod("PATCH");
394        webacFilter.doFilter(request, response, filterChain);
395        assertEquals(SC_OK, response.getStatus());
396    }
397
398    @Test
399    public void testAdminUserDelete() throws Exception {
400        setupAdminUser();
401        // GET => 200
402        request.setMethod("DELETE");
403        webacFilter.doFilter(request, response, filterChain);
404        assertEquals(SC_OK, response.getStatus());
405    }
406
407    @Test
408    public void testAuthUserNoPermsHead() throws Exception {
409        setupAuthUserNoPerms();
410        // HEAD => 403
411        request.setMethod("HEAD");
412        webacFilter.doFilter(request, response, filterChain);
413        assertEquals(SC_FORBIDDEN, response.getStatus());
414    }
415
416    @Test
417    public void testAuthUserNoPermsOptions() throws Exception {
418        setupAuthUserNoPerms();
419        // GET => 403
420        request.setMethod("OPTIONS");
421        webacFilter.doFilter(request, response, filterChain);
422        assertEquals(SC_FORBIDDEN, response.getStatus());
423    }
424
425    @Test
426    public void testAuthUserNoPermsGet() throws Exception {
427        setupAuthUserNoPerms();
428        // GET => 403
429        request.setMethod("GET");
430        webacFilter.doFilter(request, response, filterChain);
431        assertEquals(SC_FORBIDDEN, response.getStatus());
432    }
433
434    @Test
435    public void testAuthUserNoPermsPost() throws Exception {
436        setupAuthUserNoPerms();
437        // POST => 403
438        request.setMethod("POST");
439        webacFilter.doFilter(request, response, filterChain);
440        assertEquals(SC_FORBIDDEN, response.getStatus());
441    }
442
443    @Test
444    public void testAuthUserNoPermsPut() throws Exception {
445        setupAuthUserNoPerms();
446        // PUT => 403
447        request.setMethod("PUT");
448        webacFilter.doFilter(request, response, filterChain);
449        assertEquals(SC_FORBIDDEN, response.getStatus());
450    }
451
452    @Test
453    public void testAuthUserNoPermsPatch() throws Exception {
454        setupAuthUserNoPerms();
455        // PATCH => 403
456        request.setMethod("PATCH");
457        webacFilter.doFilter(request, response, filterChain);
458        assertEquals(SC_FORBIDDEN, response.getStatus());
459    }
460
461    @Test
462    public void testAuthUserNoPermsDelete() throws Exception {
463        setupAuthUserNoPerms();
464        // DELETE => 403
465        request.setMethod("DELETE");
466        webacFilter.doFilter(request, response, filterChain);
467        assertEquals(SC_FORBIDDEN, response.getStatus());
468    }
469
470    @Test
471    public void testAuthUserReadOnlyHead() throws Exception {
472        setupAuthUserReadOnly();
473        // HEAD => 200
474        request.setMethod("HEAD");
475        webacFilter.doFilter(request, response, filterChain);
476        assertEquals(SC_OK, response.getStatus());
477    }
478
479    @Test
480    public void testAuthUserReadOnlyOptions() throws Exception {
481        setupAuthUserReadOnly();
482        // GET => 200
483        request.setMethod("OPTIONS");
484        webacFilter.doFilter(request, response, filterChain);
485        assertEquals(SC_OK, response.getStatus());
486    }
487
488    @Test
489    public void testAuthUserReadOnlyGet() throws Exception {
490        setupAuthUserReadOnly();
491        // GET => 200
492        request.setMethod("GET");
493        webacFilter.doFilter(request, response, filterChain);
494        assertEquals(SC_OK, response.getStatus());
495    }
496
497    @Test
498    public void testAuthUserReadOnlyPost() throws Exception {
499        setupAuthUserReadOnly();
500        // POST => 403
501        request.setMethod("POST");
502        webacFilter.doFilter(request, response, filterChain);
503        assertEquals(SC_FORBIDDEN, response.getStatus());
504    }
505
506    @Test
507    public void testAuthUserReadOnlyPut() throws Exception {
508        setupAuthUserReadOnly();
509        // PUT => 403
510        request.setMethod("PUT");
511        request.setRequestURI(testPath);
512        webacFilter.doFilter(request, response, filterChain);
513        assertEquals(SC_FORBIDDEN, response.getStatus());
514    }
515
516    @Test
517    public void testAuthUserReadOnlyPatch() throws Exception {
518        setupAuthUserReadOnly();
519        // PATCH => 403
520        request.setMethod("PATCH");
521        webacFilter.doFilter(request, response, filterChain);
522        assertEquals(SC_FORBIDDEN, response.getStatus());
523    }
524
525    @Test
526    public void testAuthUserReadOnlyDelete() throws Exception {
527        setupAuthUserReadOnly();
528        // DELETE => 403
529        request.setMethod("DELETE");
530        webacFilter.doFilter(request, response, filterChain);
531        assertEquals(SC_FORBIDDEN, response.getStatus());
532    }
533
534    @Test
535    public void testAuthUserReadAppendPatchNonSparqlContent() throws Exception {
536        setupAuthUserReadAppend();
537        // PATCH (Non Sparql Content) => 403
538        request.setRequestURI(testPath);
539        request.setMethod("PATCH");
540        webacFilter.doFilter(request, response, filterChain);
541        assertEquals(SC_FORBIDDEN, response.getStatus());
542    }
543
544    @Test
545    public void testAuthUserReadAppendPatchSparqlNoContent() throws Exception {
546        setupAuthUserReadAppend();
547        // PATCH (Sparql No Content) => 200 (204)
548        request.setContentType(contentTypeSPARQLUpdate);
549        request.setRequestURI(testPath);
550        request.setMethod("PATCH");
551        webacFilter.doFilter(request, response, filterChain);
552        assertEquals(SC_OK, response.getStatus());
553    }
554
555    @Ignore // TODO FIX THIS TEST
556    @Test
557    public void testAuthUserReadAppendPatchSparqlInvalidContent() throws Exception {
558        setupAuthUserReadAppend();
559        // PATCH (Sparql Invalid Content) => 403
560        request.setContentType(contentTypeSPARQLUpdate);
561        request.setContent("SOME TEXT".getBytes());
562        request.setRequestURI(testPath);
563        request.setMethod("PATCH");
564        webacFilter.doFilter(request, response, filterChain);
565        assertEquals(SC_FORBIDDEN, response.getStatus());
566    }
567
568    @Ignore // TODO FIX THIS TEST
569    @Test
570    public void testAuthUserReadAppendPatchSparqlInsert() throws Exception {
571        setupAuthUserReadAppend();
572        // PATCH (Sparql INSERT) => 200 (204)
573        final String updateString =
574                "INSERT { <> <http://purl.org/dc/elements/1.1/title> \"new title\" } WHERE { }";
575        request.setContentType(contentTypeSPARQLUpdate);
576        request.setContent(updateString.getBytes());
577        request.setRequestURI(testPath);
578        request.setMethod("PATCH");
579        webacFilter.doFilter(request, response, filterChain);
580        assertEquals(SC_OK, response.getStatus());
581    }
582
583    @Ignore // TODO FIX THIS TEST
584    @Test
585    public void testAuthUserReadAppendPatchSparqlDelete() throws Exception {
586        setupAuthUserReadAppend();
587        // PATCH (Sparql DELETE) => 403
588        final String updateString =
589                "DELETE { <> <http://purl.org/dc/elements/1.1/title> \"new title\" } WHERE { }";
590        request.setContentType(contentTypeSPARQLUpdate);
591        request.setContent(updateString.getBytes());
592        request.setRequestURI(testPath);
593        request.setMethod("PATCH");
594        webacFilter.doFilter(request, response, filterChain);
595        assertEquals(SC_FORBIDDEN, response.getStatus());
596    }
597
598    @Ignore // TODO FIX THIS TEST
599    @Test
600    public void testAuthUserAppendPostContainer() throws Exception {
601        setupAuthUserAppendOnly();
602        // POST => 200
603        request.setRequestURI(testPath);
604        request.setMethod("POST");
605        webacFilter.doFilter(request, response, filterChain);
606        assertEquals(SC_OK, response.getStatus());
607    }
608
609    @Test
610    public void testAuthUserAppendPostBinary() throws Exception {
611        setupAuthUserAppendOnly();
612        setupBinaryResource();
613        // POST => 403
614        request.setRequestURI(testPath);
615        request.setMethod("POST");
616        webacFilter.doFilter(request, response, filterChain);
617        assertEquals(SC_FORBIDDEN, response.getStatus());
618    }
619
620    @Ignore // TODO FIX THIS TEST
621    @Test
622    public void testAuthUserAppendDelete() throws Exception {
623        setupAuthUserAppendOnly();
624        // POST => 403
625        request.setRequestURI(testPath);
626        request.setMethod("DELETE");
627        webacFilter.doFilter(request, response, filterChain);
628        assertEquals(SC_FORBIDDEN, response.getStatus());
629    }
630
631    @Ignore // TODO FIX THIS TEST
632    @Test
633    public void testAuthUserReadAppendPostContainer() throws Exception {
634        setupAuthUserReadAppend();
635        // POST => 200
636        request.setRequestURI(testPath);
637        request.setMethod("POST");
638        webacFilter.doFilter(request, response, filterChain);
639        assertEquals(SC_OK, response.getStatus());
640    }
641
642    @Test
643    public void testAuthUserReadAppendPostBinary() throws Exception {
644        setupAuthUserReadAppend();
645        setupBinaryResource();
646        // POST => 403
647        request.setRequestURI(testPath);
648        request.setMethod("POST");
649        webacFilter.doFilter(request, response, filterChain);
650        assertEquals(SC_FORBIDDEN, response.getStatus());
651    }
652
653    @Ignore // TODO FIX THIS TEST
654    @Test
655    public void testAuthUserReadAppendDelete() throws Exception {
656        setupAuthUserReadAppend();
657        // DELETE => 403
658        request.setRequestURI(testPath);
659        request.setMethod("DELETE");
660        webacFilter.doFilter(request, response, filterChain);
661        assertEquals(SC_FORBIDDEN, response.getStatus());
662    }
663
664    @Test
665    public void testAuthUserReadAppendWritePostContainer() throws Exception {
666        setupAuthUserReadAppendWrite();
667        // POST => 200
668        request.setRequestURI(testPath);
669        request.setMethod("POST");
670        webacFilter.doFilter(request, response, filterChain);
671        assertEquals(SC_OK, response.getStatus());
672    }
673
674    @Test
675    public void testAuthUserReadAppendWritePostBinary() throws Exception {
676        setupAuthUserReadAppendWrite();
677        setupBinaryResource();
678        // POST => 200
679        request.setRequestURI(testPath);
680        request.setMethod("POST");
681        webacFilter.doFilter(request, response, filterChain);
682        assertEquals(SC_OK, response.getStatus());
683    }
684
685    @Test
686    public void testAuthUserReadWriteHead() throws Exception {
687        setupAuthUserReadWrite();
688        // HEAD => 200
689        request.setMethod("HEAD");
690        webacFilter.doFilter(request, response, filterChain);
691        assertEquals(SC_OK, response.getStatus());
692    }
693
694    @Test
695    public void testAuthUserReadWriteOptions() throws Exception {
696        setupAuthUserReadWrite();
697        // GET => 200
698        request.setMethod("OPTIONS");
699        webacFilter.doFilter(request, response, filterChain);
700        assertEquals(SC_OK, response.getStatus());
701    }
702
703    @Test
704    public void testAuthUserReadWriteGet() throws Exception {
705        setupAuthUserReadWrite();
706        // GET => 200
707        request.setMethod("GET");
708        webacFilter.doFilter(request, response, filterChain);
709        assertEquals(SC_OK, response.getStatus());
710    }
711
712    @Test
713    public void testAuthUserReadWritePost() throws Exception {
714        setupAuthUserReadWrite();
715        // POST => 200
716        request.setMethod("POST");
717        webacFilter.doFilter(request, response, filterChain);
718        assertEquals(SC_OK, response.getStatus());
719    }
720
721    @Test
722    public void testAuthUserReadWritePut() throws Exception {
723        setupAuthUserReadWrite();
724        // PUT => 200
725        request.setMethod("PUT");
726        request.setRequestURI(testPath);
727        webacFilter.doFilter(request, response, filterChain);
728        assertEquals(SC_OK, response.getStatus());
729    }
730
731    @Ignore // TODO FIX THIS TEST
732    @Test
733    public void testAuthUserReadWritePatch() throws Exception {
734        setupAuthUserReadWrite();
735        // PATCH => 200
736        request.setMethod("PATCH");
737        webacFilter.doFilter(request, response, filterChain);
738        assertEquals(SC_OK, response.getStatus());
739    }
740
741    @Ignore // TODO FIX THIS TEST
742    @Test
743    public void testAuthUserReadWriteDelete() throws Exception {
744        setupAuthUserReadWrite();
745        // DELETE => 200
746        request.setMethod("DELETE");
747        webacFilter.doFilter(request, response, filterChain);
748        assertEquals(SC_OK, response.getStatus());
749    }
750
751    @Ignore // TODO FIX THIS TEST
752    @Test
753    public void testAuthUserReadAppendWriteDelete() throws Exception {
754        setupAuthUserReadAppendWrite();
755        // DELETE => 200
756        request.setRequestURI(testPath);
757        request.setMethod("DELETE");
758        webacFilter.doFilter(request, response, filterChain);
759        assertEquals(SC_OK, response.getStatus());
760    }
761
762    @Test
763    public void testAuthUserAppendPutNewChild() throws Exception {
764        setupAuthUserAppendOnly();
765        // PUT => 200
766        when(mockResourceFactory.getResource((Transaction)any(), eq(testChildId)))
767                .thenThrow(PathNotFoundException.class);
768        request.setRequestURI(testChildPath);
769        request.setPathInfo(testChildPath);
770        request.setMethod("PUT");
771        webacFilter.doFilter(request, response, filterChain);
772        assertEquals(SC_OK, response.getStatus());
773    }
774
775    @Test
776    public void testAclControlPutToAcl() throws Exception {
777        setupAuthUserAclControl();
778        request.setRequestURI(testAclPath);
779        request.setMethod("PUT");
780        webacFilter.doFilter(request, response, filterChain);
781        assertEquals(SC_OK, response.getStatus());
782    }
783
784    @Test
785    public void testNoAclControlPutToAcl() throws Exception {
786        setupAuthUserNoAclControl();
787        request.setRequestURI(testAclPath);
788        request.setMethod("PUT");
789        webacFilter.doFilter(request, response, filterChain);
790        assertEquals(SC_FORBIDDEN, response.getStatus());
791    }
792
793    @Test
794    public void testAclControlGetToAcl() throws Exception {
795        setupAuthUserAclControl();
796        request.setRequestURI(testAclPath);
797        request.setMethod("GET");
798        webacFilter.doFilter(request, response, filterChain);
799        assertEquals(SC_OK, response.getStatus());
800    }
801
802    @Test
803    public void testNoAclControlGetToAcl() throws Exception {
804        setupAuthUserNoAclControl();
805        request.setRequestURI(testAclPath);
806        request.setMethod("GET");
807        webacFilter.doFilter(request, response, filterChain);
808        assertEquals(SC_FORBIDDEN, response.getStatus());
809    }
810
811    @Test
812    public void testAclControlHeadToAcl() throws Exception {
813        setupAuthUserAclControl();
814        request.setRequestURI(testAclPath);
815        request.setMethod("HEAD");
816        webacFilter.doFilter(request, response, filterChain);
817        assertEquals(SC_OK, response.getStatus());
818    }
819
820    @Test
821    public void testNoAclControlHeadToAcl() throws Exception {
822        setupAuthUserNoAclControl();
823        request.setRequestURI(testAclPath);
824        request.setMethod("HEAD");
825        webacFilter.doFilter(request, response, filterChain);
826        assertEquals(SC_FORBIDDEN, response.getStatus());
827    }
828
829    @Test
830    public void testAclControlPatchToAcl() throws Exception {
831        setupAuthUserAclControl();
832        request.setRequestURI(testAclPath);
833        request.setMethod("PATCH");
834        webacFilter.doFilter(request, response, filterChain);
835        assertEquals(SC_OK, response.getStatus());
836    }
837
838    @Test
839    public void testNoAclControlPatchToAcl() throws Exception {
840        setupAuthUserNoAclControl();
841        request.setRequestURI(testAclPath);
842        request.setMethod("PATCH");
843        webacFilter.doFilter(request, response, filterChain);
844        assertEquals(SC_FORBIDDEN, response.getStatus());
845    }
846
847    @Test
848    public void testAclControlDelete() throws Exception {
849        setupAuthUserAclControl();
850        request.setRequestURI(testAclPath);
851        request.setMethod("DELETE");
852        webacFilter.doFilter(request, response, filterChain);
853        assertEquals(SC_OK, response.getStatus());
854    }
855
856    @Test
857    public void testNoAclControlDelete() throws Exception {
858        setupAuthUserNoAclControl();
859        request.setRequestURI(testAclPath);
860        request.setMethod("DELETE");
861        webacFilter.doFilter(request, response, filterChain);
862        assertEquals(SC_FORBIDDEN, response.getStatus());
863    }
864
865    @Test
866    public void testAclReadEmbeddedOk() throws Exception {
867        setupAuthUserReadParentAndChildren(true);
868        setupEmbeddedResourceHeader();
869        request.setRequestURI(testPath);
870        request.setMethod("GET");
871        webacFilter.doFilter(request, response, filterChain);
872        assertEquals(SC_OK, response.getStatus());
873    }
874
875    @Test
876    public void testAclReadEmbeddedDenied() throws Exception {
877        setupAuthUserReadParentAndChildren(false);
878        setupEmbeddedResourceHeader();
879        request.setRequestURI(testPath);
880        request.setMethod("GET");
881        webacFilter.doFilter(request, response, filterChain);
882        assertEquals(SC_FORBIDDEN, response.getStatus());
883    }
884
885    @After
886    public void clearSubject() {
887        // unbind the subject to the thread
888        threadState.restore();
889    }
890}