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