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