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