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