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.integration.http.api;
019
020import static javax.ws.rs.core.HttpHeaders.ACCEPT;
021import static javax.ws.rs.core.HttpHeaders.CONTENT_TYPE;
022import static javax.ws.rs.core.HttpHeaders.LINK;
023import static javax.ws.rs.core.Link.fromUri;
024import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
025import static javax.ws.rs.core.Response.Status.CONFLICT;
026import static javax.ws.rs.core.Response.Status.CREATED;
027import static javax.ws.rs.core.Response.Status.NOT_FOUND;
028import static javax.ws.rs.core.Response.Status.NO_CONTENT;
029import static javax.ws.rs.core.Response.Status.OK;
030import static org.apache.jena.graph.Node.ANY;
031import static org.apache.jena.graph.NodeFactory.createLiteral;
032import static org.apache.jena.graph.NodeFactory.createURI;
033import static org.apache.jena.vocabulary.RDF.type;
034import static org.fcrepo.kernel.api.FedoraTypes.FCR_ACL;
035import static org.fcrepo.kernel.api.RdfLexicon.CONSTRAINED_BY;
036import static org.fcrepo.kernel.api.RdfLexicon.RDF_SOURCE;
037import static org.fcrepo.kernel.api.RdfLexicon.WEBAC_NAMESPACE_VALUE;
038import static org.junit.Assert.assertEquals;
039import static org.junit.Assert.assertFalse;
040import static org.junit.Assert.assertTrue;
041
042import java.io.IOException;
043import java.net.URI;
044import java.nio.file.Paths;
045
046import javax.ws.rs.core.Link;
047
048import org.apache.http.client.methods.CloseableHttpResponse;
049import org.apache.http.client.methods.HttpDelete;
050import org.apache.http.client.methods.HttpGet;
051import org.apache.http.client.methods.HttpPatch;
052import org.apache.http.client.methods.HttpPut;
053import org.apache.http.entity.StringEntity;
054import org.apache.jena.graph.Node;
055import org.apache.jena.sparql.core.DatasetGraph;
056import org.fcrepo.http.commons.test.util.CloseableDataset;
057import org.junit.Before;
058import org.junit.Test;
059import org.springframework.test.context.TestExecutionListeners;
060
061/**
062 * @author lsitu
063 * @author 4/20/2018
064 */
065@TestExecutionListeners(
066        listeners = { TestIsolationExecutionListener.class },
067        mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS)
068public class FedoraAclIT extends AbstractResourceIT {
069
070    private String subjectUri;
071    private String id;
072
073    @Before
074    public void init() {
075        id = getRandomUniqueId();
076        subjectUri = serverAddress + id;
077        authPropsConfig.setRootAuthAclPath(null);
078    }
079
080    @Test
081    public void testCreateAclWithoutBody() throws Exception {
082        createObjectAndClose(id);
083
084        final HttpPut put = new HttpPut(subjectUri + "/" + FCR_ACL);
085        final String aclLocation;
086        try (final CloseableHttpResponse response = execute(put)) {
087            assertEquals(CREATED.getStatusCode(), getStatus(response));
088            aclLocation = response.getFirstHeader("Location").getValue();
089            // verify the acl container is translated to fcr:acl
090            assertEquals(subjectUri + "/" + FCR_ACL, aclLocation);
091        }
092    }
093
094    @Test
095    public void testCreateAclOnAclResource() throws Exception {
096        createObjectAndClose(id);
097
098        final String aclLocation = createACL();
099
100        final HttpPut put1 = new HttpPut(aclLocation + "/" + FCR_ACL);
101        assertEquals(BAD_REQUEST.getStatusCode(), getStatus(put1));
102    }
103
104    private String createACL() throws IOException {
105        final HttpPut put = new HttpPut(subjectUri + "/" + FCR_ACL);
106
107        try (final CloseableHttpResponse response = execute(put)) {
108            assertEquals(CREATED.getStatusCode(), getStatus(response));
109            return response.getFirstHeader("Location").getValue();
110        }
111    }
112
113    @Test
114    public void testCreateAclOnBinary() throws Exception {
115        createDatastream(id, "x", "some content");
116
117        final HttpPut put = new HttpPut(subjectUri + "/x/" + FCR_ACL);
118        final String aclLocation;
119        try (final CloseableHttpResponse response = execute(put)) {
120            assertEquals(CREATED.getStatusCode(), getStatus(response));
121            aclLocation = response.getFirstHeader("Location").getValue();
122            // verify the acl container for binary is translated to fcr:acl
123            assertEquals(subjectUri + "/x/" + FCR_ACL, aclLocation);
124        }
125
126        try (final CloseableDataset dataset = getDataset(new HttpGet(aclLocation))) {
127            final DatasetGraph graph = dataset.asDatasetGraph();
128            assertTrue(graph.contains(ANY,
129                                      createURI(aclLocation),
130                                      type.asNode(),
131                                      RDF_SOURCE.asNode()));
132        }
133    }
134
135    @Test
136    public void testPatchAcl() throws Exception {
137        createObjectAndClose(id);
138        final String aclURI = createACL();
139        final HttpPatch patch = new HttpPatch(aclURI);
140        patch.addHeader(CONTENT_TYPE, "application/sparql-update");
141        patch.setEntity(new StringEntity("PREFIX acl: <http://www.w3.org/ns/auth/acl#> " +
142                                         "INSERT { <#writeAccess> acl:mode acl:Write . } WHERE { }"));
143        assertEquals(NO_CONTENT.getStatusCode(), getStatus(patch));
144
145        //verify the patch worked
146        try (final CloseableDataset dataset = getDataset(new HttpGet(aclURI))) {
147            final DatasetGraph graph = dataset.asDatasetGraph();
148            assertTrue(graph.contains(ANY,
149                                      createURI(aclURI + "#writeAccess"),
150                                      createURI("http://www.w3.org/ns/auth/acl#mode"),
151                                      createURI("http://www.w3.org/ns/auth/acl#Write")));
152        }
153
154    }
155
156    @Test
157    public void testPatchAclDelete() throws Exception {
158        final String aclURI = subjectUri + "/" + FCR_ACL;
159        createObjectAndClose(id);
160        final HttpPut putAcl = putObjMethod(id + "/" + FCR_ACL);
161        putAcl.setHeader(CONTENT_TYPE, "text/turtle");
162        putAcl.setEntity(new StringEntity("@prefix acl: <http://www.w3.org/ns/auth/acl#> . " +
163                "<#authorization> a acl:Authorization ; acl:agent \"user3\" ; acl:mode acl:Read ; " +
164                "acl:accessTo <" + subjectUri + "> ; acl:default <" + subjectUri + "> ."));
165        assertEquals(CREATED.getStatusCode(), getStatus(putAcl));
166
167        final Node subjectNode = createURI(subjectUri);
168        final Node authNode = createURI(aclURI + "#authorization");
169        final Node modeNode = createURI("http://www.w3.org/ns/auth/acl#mode");
170        final Node writeNode = createURI("http://www.w3.org/ns/auth/acl#Read");
171        final Node accessToNode = createURI("http://www.w3.org/ns/auth/acl#accessTo");
172        final Node defaultNode = createURI("http://www.w3.org/ns/auth/acl#default");
173        // Verify initial state
174        try (final CloseableDataset dataset = getDataset(new HttpGet(aclURI))) {
175            final DatasetGraph graph = dataset.asDatasetGraph();
176            assertTrue(graph.contains(ANY,
177                    authNode,
178                    modeNode,
179                    writeNode));
180            assertTrue(graph.contains(ANY,
181                    authNode,
182                    accessToNode,
183                    subjectNode));
184            assertTrue(graph.contains(ANY,
185                    authNode,
186                    defaultNode,
187                    subjectNode));
188        }
189
190        final HttpPatch patch = new HttpPatch(aclURI);
191        patch.addHeader(CONTENT_TYPE, "application/sparql-update");
192        patch.setEntity(new StringEntity("PREFIX acl: <http://www.w3.org/ns/auth/acl#> " +
193                "DELETE { <#authorization> acl:default <" + subjectUri + "> . } WHERE { }"));
194        assertEquals(NO_CONTENT.getStatusCode(), getStatus(patch));
195
196        // verify the patch worked
197        try (final CloseableDataset dataset = getDataset(new HttpGet(aclURI))) {
198            final DatasetGraph graph = dataset.asDatasetGraph();
199            assertTrue(graph.contains(ANY,
200                    authNode,
201                    modeNode,
202                    writeNode));
203            assertTrue(graph.contains(ANY,
204                    authNode,
205                    accessToNode,
206                    subjectNode));
207            assertFalse(graph.contains(ANY,
208                    authNode,
209                    defaultNode,
210                    subjectNode));
211        }
212    }
213
214    @Test
215    public void testCreateAndRetrieveAcl() throws Exception {
216        createObjectAndClose(id);
217
218        final HttpPut put = new HttpPut(subjectUri + "/" + FCR_ACL);
219        final String aclLocation;
220        try (final CloseableHttpResponse response = execute(put)) {
221            assertEquals(CREATED.getStatusCode(), getStatus(response));
222            aclLocation = response.getFirstHeader("Location").getValue();
223            // verify the acl container is translated to fcr:acl
224            assertEquals(subjectUri + "/" + FCR_ACL, aclLocation);
225        }
226
227        final HttpGet get = new HttpGet(aclLocation);
228        assertEquals(OK.getStatusCode(), getStatus(get));
229
230    }
231
232    @Test
233    public void testPutACLBadRdf() throws IOException {
234        createObjectAndClose(id);
235
236        final HttpPut put = new HttpPut(subjectUri + "/" + FCR_ACL);
237        put.setHeader(CONTENT_TYPE, "text/turtle");
238        put.setEntity(new StringEntity("<> a junk:Object ;"));
239        assertEquals(BAD_REQUEST.getStatusCode(), getStatus(put));
240    }
241
242    @Test
243    public void testDeleteAcl() throws Exception {
244        createObjectAndClose(id);
245
246        final HttpPut put = new HttpPut(subjectUri + "/" + FCR_ACL);
247        final String aclLocation;
248        try (final CloseableHttpResponse response = execute(put)) {
249            assertEquals(CREATED.getStatusCode(), getStatus(response));
250            aclLocation = response.getFirstHeader("Location").getValue();
251            // verify the acl container is translated to fcr:acl
252            assertEquals(subjectUri + "/" + FCR_ACL, aclLocation);
253        }
254
255        final HttpGet get = new HttpGet(aclLocation);
256        assertEquals(OK.getStatusCode(), getStatus(get));
257
258        final HttpDelete delete = new HttpDelete(aclLocation);
259        assertEquals(NO_CONTENT.getStatusCode(), getStatus(delete));
260
261        final HttpGet getNotFound = new HttpGet(aclLocation);
262        assertEquals(NOT_FOUND.getStatusCode(), getStatus(getNotFound));
263
264    }
265
266    @Test
267    public void testGetNonExistentAcl() {
268        createObjectAndClose(id);
269        final HttpGet getNotFound = new HttpGet(subjectUri + "/" + FCR_ACL);
270        assertEquals(NOT_FOUND.getStatusCode(), getStatus(getNotFound));
271
272    }
273
274    @Test
275    public void testGetDefaultRootAcl() throws Exception {
276        final String rootAclUri = serverAddress + FCR_ACL;
277        final String rootFedoraUri = serverAddress;
278        final String authzUri = rootFedoraUri + FCR_ACL + "#authz";
279        try (final CloseableDataset dataset = getDataset(new HttpGet(rootAclUri))) {
280            final DatasetGraph graph = dataset.asDatasetGraph();
281            assertTrue(graph.contains(ANY,
282                    createURI(authzUri),
283                    createURI("http://www.w3.org/2000/01/rdf-schema#label"),
284                    createLiteral("Root Authorization")));
285
286            assertTrue(graph.contains(ANY,
287                    createURI(authzUri),
288                    createURI(WEBAC_NAMESPACE_VALUE + "default"),
289                    createURI(rootFedoraUri)));
290
291            assertTrue(graph.contains(ANY,
292                    createURI(authzUri),
293                    createURI(WEBAC_NAMESPACE_VALUE + "accessTo"),
294                    createURI(rootFedoraUri)));
295
296            assertTrue(graph.contains(ANY,
297                    createURI(authzUri),
298                    createURI(WEBAC_NAMESPACE_VALUE + "mode"),
299                    createURI(WEBAC_NAMESPACE_VALUE + "Read")));
300        }
301    }
302
303    @Test
304    public void testDeleteDefaultRootAcl() {
305        final String rootAclUri = serverAddress + FCR_ACL;
306        assertEquals("DELETE should fail for default generated root ACL.",
307                CONFLICT.getStatusCode(), getStatus(new HttpDelete(rootAclUri)));
308    }
309
310    @Test
311    public void testPatchDefaultRootAcl() {
312        final String rootAclUri = serverAddress + FCR_ACL;
313        assertEquals("PATCH should fail for default generated root ACL.",
314                CONFLICT.getStatusCode(), getStatus(new HttpPatch(rootAclUri)));
315    }
316
317    @Test
318    public void testGetUserDefinedDefaultRootAcl() throws Exception {
319        authPropsConfig.setRootAuthAclPath(Paths.get("./target/test-classes/test-root-authorization.ttl"));
320        final String rootAclUri = serverAddress + FCR_ACL;
321        try (final CloseableDataset dataset = getDataset(new HttpGet(rootAclUri))) {
322            final DatasetGraph graph = dataset.asDatasetGraph();
323            assertTrue(graph.contains(ANY,
324                                      createURI(rootAclUri),
325                                      createURI("http://www.w3.org/2000/01/rdf-schema#label"),
326                                      createLiteral("(Test) Root ACL")));
327
328            assertTrue(graph.contains(ANY,
329                                      createURI(rootAclUri),
330                                      createURI(WEBAC_NAMESPACE_VALUE + "default"),
331                                      createURI(serverAddress)));
332            }
333    }
334
335    @Test
336    public void testAddModifyDeleteUserDefinedDefaultRootAcl() throws Exception {
337        final String rootAclUri = serverAddress + FCR_ACL;
338        final HttpPut put = new HttpPut(rootAclUri);
339        final String aclBody = "@prefix acl: <http://www.w3.org/ns/auth/acl#> .\n" +
340                               "@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n" +
341                               "@prefix ldp: <http://www.w3.org/ns/ldp#> .\n" +
342                               "\n" +
343                               "<#readAccess> a acl:Authorization ;\n" +
344                               "    acl:mode acl:Read .";
345
346        put.setEntity(new StringEntity(aclBody));
347        put.setHeader("Content-Type", "text/turtle");
348
349        // Test PUT
350        assertEquals("PUT a new ACL should succeed.",
351                CREATED.getStatusCode(), getStatus(put));
352
353        // Test PATCH
354        final HttpPatch patch = new HttpPatch(rootAclUri);
355        patch.addHeader(CONTENT_TYPE, "application/sparql-update");
356        patch.setEntity(new StringEntity("PREFIX acl: <http://www.w3.org/ns/auth/acl#> " +
357                                            "INSERT { <#readAccess> acl:mode acl:Write . } WHERE { }"));
358        assertEquals("PATCH should succeed for default generated root ACL.",
359                NO_CONTENT.getStatusCode(), getStatus(patch));
360
361        // Test DELETE
362        assertEquals("DELETE should succeed for user-defined default root ACL.",
363                NO_CONTENT.getStatusCode(), getStatus(new HttpDelete(rootAclUri)));
364    }
365
366    @Test
367    public void testCreateAclWithBody() throws Exception {
368        createObjectAndClose(id);
369
370        final HttpPut put = new HttpPut(subjectUri + "/" + FCR_ACL);
371        final String aclBody = "@prefix acl: <http://www.w3.org/ns/auth/acl#> .\n" +
372                               "@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n" +
373                               "@prefix ldp: <http://www.w3.org/ns/ldp#> .\n" +
374                               "\n" +
375                               "<#readAccess> a acl:Authorization ;\n" +
376                               "    acl:mode acl:Read .";
377
378        put.setEntity(new StringEntity(aclBody));
379        put.setHeader("Content-Type", "text/turtle");
380
381        final String aclLocation;
382        try (final CloseableHttpResponse response = execute(put)) {
383            assertEquals(CREATED.getStatusCode(), getStatus(response));
384            aclLocation = response.getFirstHeader("Location").getValue();
385            // verify the acl container is translated to fcr:acl
386            assertEquals(subjectUri + "/" + FCR_ACL, aclLocation);
387
388        }
389
390        //verify the put worked
391        try (final CloseableDataset dataset = getDataset(new HttpGet(aclLocation))) {
392            final DatasetGraph graph = dataset.asDatasetGraph();
393            assertTrue(graph.contains(ANY,
394                                      createURI(aclLocation + "#readAccess"),
395                                      createURI("http://www.w3.org/ns/auth/acl#mode"),
396                                      createURI("http://www.w3.org/ns/auth/acl#Read")));
397        }
398
399    }
400
401    @Test
402    public void testCreateAclWithoutAccessToSetsDefaultTarget() throws Exception {
403        createObjectAndClose(id);
404
405        final HttpPut put = new HttpPut(subjectUri + "/" + FCR_ACL);
406        final String aclBody = "@prefix acl: <http://www.w3.org/ns/auth/acl#> .\n" +
407                               "@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n" +
408                               "@prefix ldp: <http://www.w3.org/ns/ldp#> .\n" +
409                               "\n" +
410                               "<#readAccess> a acl:Authorization ;\n" +
411                               "    acl:mode acl:Read .";
412
413        put.setEntity(new StringEntity(aclBody));
414        put.setHeader("Content-Type", "text/turtle");
415
416        final String aclLocation;
417        try (final CloseableHttpResponse response = execute(put)) {
418            assertEquals(CREATED.getStatusCode(), getStatus(response));
419            aclLocation = response.getFirstHeader("Location").getValue();
420            // verify the acl container is translated to fcr:acl
421            assertEquals(subjectUri + "/" + FCR_ACL, aclLocation);
422        }
423
424        // verify that the accessTo is set to subjectUri when no accessTo or accessToClass
425        try (final CloseableDataset dataset = getDataset(new HttpGet(aclLocation))) {
426            final DatasetGraph graph = dataset.asDatasetGraph();
427            assertTrue(graph.contains(ANY,
428                                      createURI(aclLocation + "#readAccess"),
429                                      createURI("http://www.w3.org/ns/auth/acl#accessTo"),
430                                      createURI(subjectUri)));
431        }
432
433    }
434
435    @Test
436    public void testCreateAclWithAccessTo() throws Exception {
437        createObjectAndClose(id);
438
439        final HttpPut put = new HttpPut(subjectUri + "/" + FCR_ACL);
440        final String aclBody = "@prefix acl: <http://www.w3.org/ns/auth/acl#> .\n" +
441                               "@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n" +
442                               "@prefix ldp: <http://www.w3.org/ns/ldp#> .\n" +
443                               "\n" +
444                               "<#readAccess> a acl:Authorization ;\n" +
445                               "    acl:mode acl:Read ;\n" +
446                               "    acl:accessTo <http://example.com/> .";
447        System.out.println("ACLBODY");
448        System.out.println(aclBody);
449
450        put.setEntity(new StringEntity(aclBody));
451        put.setHeader("Content-Type", "text/turtle");
452
453        final String aclLocation;
454        try (final CloseableHttpResponse response = execute(put)) {
455            assertEquals(CREATED.getStatusCode(), getStatus(response));
456            aclLocation = response.getFirstHeader("Location").getValue();
457            // verify the acl container is translated to fcr:acl
458            assertEquals(subjectUri + "/" + FCR_ACL, aclLocation);
459        }
460
461        // verify that the accessTo is set to the sepcified accessTo Target
462        try (final CloseableDataset dataset = getDataset(new HttpGet(aclLocation))) {
463            final DatasetGraph graph = dataset.asDatasetGraph();
464            assertTrue(graph.contains(ANY,
465                                      createURI(aclLocation + "#readAccess"),
466                                      createURI("http://www.w3.org/ns/auth/acl#accessTo"),
467                                      createURI("http://example.com/")));
468        }
469
470        // verify that the accessTo is not set to subjectUri (default)
471        try (final CloseableDataset dataset = getDataset(new HttpGet(aclLocation))) {
472            final DatasetGraph graph = dataset.asDatasetGraph();
473            assertFalse(graph.contains(ANY,
474                                      createURI(aclLocation + "#readAccess"),
475                                      createURI("http://www.w3.org/ns/auth/acl#accessTo"),
476                                      createURI(subjectUri)));
477        }
478    }
479
480    @Test
481    public void testCreateAclWithAccessToClass() throws Exception {
482        createObjectAndClose(id);
483
484        final HttpPut put = new HttpPut(subjectUri + "/" + FCR_ACL);
485        final String aclBody = "@prefix acl: <http://www.w3.org/ns/auth/acl#> .\n" +
486                               "@prefix webac: <http://fedora.info/definitions/v4/webac#> .\n" +
487                               "@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n" +
488                               "@prefix ldp: <http://www.w3.org/ns/ldp#> .\n" +
489                               "\n" +
490                               "<#readAccess> a acl:Authorization ;\n" +
491                               "    acl:mode acl:Read ;\n" +
492                               "    acl:accessToClass webac:Acl .";
493
494        put.setEntity(new StringEntity(aclBody));
495        put.setHeader("Content-Type", "text/turtle");
496
497        final String aclLocation;
498        try (final CloseableHttpResponse response = execute(put)) {
499            assertEquals(CREATED.getStatusCode(), getStatus(response));
500            aclLocation = response.getFirstHeader("Location").getValue();
501            // verify the acl container is translated to fcr:acl
502            assertEquals(subjectUri + "/" + FCR_ACL, aclLocation);
503
504        }
505
506        // verify that the accessToClass is set to the specified accessToClass
507        try (final CloseableDataset dataset = getDataset(new HttpGet(aclLocation))) {
508            final DatasetGraph graph = dataset.asDatasetGraph();
509            assertTrue(graph.contains(ANY,
510                                      createURI(aclLocation + "#readAccess"),
511                                      createURI("http://www.w3.org/ns/auth/acl#accessToClass"),
512                                      createURI("http://fedora.info/definitions/v4/webac#Acl")));
513        }
514
515        // verify that the accessTo is not set to subjectUri (default)
516        try (final CloseableDataset dataset = getDataset(new HttpGet(aclLocation))) {
517            final DatasetGraph graph = dataset.asDatasetGraph();
518            assertFalse(graph.contains(ANY,
519                                      createURI(aclLocation + "#readAccess"),
520                                      createURI("http://www.w3.org/ns/auth/acl#accessTo"),
521                                      createURI(subjectUri)));
522        }
523    }
524
525    @Test
526    public void testCreateAclWithBothAccessToandAccessToClassIsNotAllowed() throws Exception {
527        createObjectAndClose(id);
528
529        final HttpPut put = new HttpPut(subjectUri + "/" + FCR_ACL);
530        final String aclBody = "@prefix acl: <http://www.w3.org/ns/auth/acl#> .\n" +
531                               "@prefix webac: <http://fedora.info/definitions/v4/webac#> .\n" +
532                               "@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n" +
533                               "@prefix ldp: <http://www.w3.org/ns/ldp#> .\n" +
534                               "\n" +
535                               "<#readAccess> a acl:Authorization ;\n" +
536                               "    acl:mode acl:Read ;\n" +
537                               "    acl:accessTo <http://example.com/> ;\n" +
538                               "    acl:accessToClass webac:Acl .";
539        final Link ex = fromUri(URI.create(serverAddress +
540                                    "static/constraints/ACLAuthorizationConstraintViolationException.rdf"))
541                               .rel(CONSTRAINED_BY.getURI()).build();
542
543        put.setEntity(new StringEntity(aclBody));
544        put.setHeader("Content-Type", "text/turtle");
545
546        try (final CloseableHttpResponse response = execute(put)) {
547            assertEquals(BAD_REQUEST.getStatusCode(), getStatus(response));
548            assertEquals(ex.toString(), response.getFirstHeader(LINK).getValue());
549        }
550    }
551
552    @Test
553    public void testGetDefaultAcl() throws Exception {
554        final Node aclMode = createURI(WEBAC_NAMESPACE_VALUE + "mode");
555        final Node aclRead = createURI(WEBAC_NAMESPACE_VALUE + "Read");
556        final Node aclWrite = createURI(WEBAC_NAMESPACE_VALUE + "Write");
557
558        final Node defaultAclSubject = createURI(serverAddress + FCR_ACL + "#authz");
559
560        final var getTurtle = getObjMethod(FCR_ACL);
561        getTurtle.addHeader(ACCEPT, "text/turtle");
562        try (final var response = execute(getTurtle)) {
563            assertEquals(OK.getStatusCode(), getStatus(response));
564            final var graph = getDataset(response).asDatasetGraph();
565            assertTrue(graph.contains(ANY, defaultAclSubject, aclMode, aclRead));
566            assertFalse(graph.contains(ANY, defaultAclSubject, aclMode, aclWrite));
567        }
568
569        final var getHtml = getObjMethod(FCR_ACL);
570        getHtml.addHeader(ACCEPT, "text/html");
571        assertEquals(OK.getStatusCode(), getStatus(getHtml));
572    }
573}