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