Skip to content

Commit 70293ca

Browse files
committed
JCL-361: Make it easier to modify Access Control resources
1 parent f29ee8c commit 70293ca

File tree

3 files changed

+88
-55
lines changed

3 files changed

+88
-55
lines changed

access-grant/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424
<artifactId>inrupt-client-api</artifactId>
2525
<version>${project.version}</version>
2626
</dependency>
27+
<dependency>
28+
<groupId>com.inrupt.client</groupId>
29+
<artifactId>inrupt-client-vocabulary</artifactId>
30+
<version>${project.version}</version>
31+
</dependency>
2732
<dependency>
2833
<groupId>commons-io</groupId>
2934
<artifactId>commons-io</artifactId>
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright 2023 Inrupt Inc.
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal in
6+
* the Software without restriction, including without limitation the rights to use,
7+
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
8+
* Software, and to permit persons to whom the Software is furnished to do so,
9+
* subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
15+
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
16+
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
17+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
18+
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
19+
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20+
*/
21+
package com.inrupt.client.accessgrant;
22+
23+
import com.inrupt.client.spi.RDFFactory;
24+
import com.inrupt.client.util.URIBuilder;
25+
import com.inrupt.client.vocabulary.ACP;
26+
27+
import java.net.URI;
28+
import java.util.HashSet;
29+
import java.util.Set;
30+
import java.util.UUID;
31+
32+
import org.apache.commons.rdf.api.IRI;
33+
import org.apache.commons.rdf.api.RDF;
34+
import org.apache.commons.rdf.api.Triple;
35+
36+
/**
37+
* Utility methods for use with the Access Grant module.
38+
**/
39+
public final class AccessGrantUtils {
40+
41+
private static final RDF rdf = RDFFactory.getInstance();
42+
private static final IRI SOLID_ACCESS_GRANT = rdf.createIRI("http://www.w3.org/ns/solid/vc#SolidAccessGrant");
43+
44+
private static IRI asIRI(final URI uri) {
45+
return rdf.createIRI(uri.toString());
46+
}
47+
48+
public static Set<Triple> accessControlPolicyTriples(final URI acl, final URI... modes) {
49+
final Set<Triple> triples = new HashSet<>();
50+
51+
// Matcher
52+
final IRI matcher = asIRI(URIBuilder.newBuilder(acl).fragment(UUID.randomUUID().toString()).build());
53+
triples.add(rdf.createTriple(matcher, asIRI(ACP.vc), SOLID_ACCESS_GRANT));
54+
55+
// Policy
56+
final IRI policy = asIRI(URIBuilder.newBuilder(acl).fragment(UUID.randomUUID().toString()).build());
57+
triples.add(rdf.createTriple(policy, asIRI(ACP.allOf), matcher));
58+
for (final URI mode : modes ) {
59+
triples.add(rdf.createTriple(policy, asIRI(ACP.allow), asIRI(mode)));
60+
}
61+
62+
// Access Control
63+
final IRI accessControl = asIRI(URIBuilder.newBuilder(acl).fragment(UUID.randomUUID().toString()).build());
64+
triples.add(rdf.createTriple(accessControl, asIRI(ACP.apply), policy));
65+
66+
triples.add(rdf.createTriple(asIRI(acl), asIRI(ACP.accessControl), accessControl));
67+
triples.add(rdf.createTriple(asIRI(acl), asIRI(ACP.memberAccessControl), accessControl));
68+
return triples;
69+
}
70+
71+
private AccessGrantUtils() {
72+
// Prevent instantiation
73+
}
74+
}

integration/base/src/main/java/com/inrupt/client/integration/base/AccessGrantScenarios.java

Lines changed: 9 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@
2525
import static org.junit.jupiter.api.Assertions.assertThrows;
2626
import static org.junit.jupiter.api.Assertions.assertTrue;
2727

28-
import com.inrupt.client.Headers;
2928
import com.inrupt.client.Request;
3029
import com.inrupt.client.Response;
3130
import com.inrupt.client.accessgrant.AccessGrant;
3231
import com.inrupt.client.accessgrant.AccessGrantClient;
3332
import com.inrupt.client.accessgrant.AccessGrantSession;
33+
import com.inrupt.client.accessgrant.AccessGrantUtils;
3434
import com.inrupt.client.accessgrant.AccessRequest;
3535
import com.inrupt.client.auth.Credential;
3636
import com.inrupt.client.auth.Session;
@@ -40,7 +40,6 @@
4040
import com.inrupt.client.spi.RDFFactory;
4141
import com.inrupt.client.util.URIBuilder;
4242
import com.inrupt.client.vocabulary.ACL;
43-
import com.inrupt.client.vocabulary.ACP;
4443
import com.inrupt.client.webid.WebIdProfile;
4544

4645
import java.io.ByteArrayInputStream;
@@ -620,60 +619,15 @@ void accessGrantCreateNonRdfTest(final Session session) throws IOException {
620619

621620
private static void prepareACPofResource(final SolidSyncClient authClient, final URI resourceURI) {
622621

623-
final IRI acpAllOf = rdf.createIRI(ACP.allOf.toString());
624-
final IRI acpVc = rdf.createIRI(ACP.vc.toString());
625-
final IRI acpAllow = rdf.createIRI(ACP.allow.toString());
626-
final IRI acpApply = rdf.createIRI(ACP.apply.toString());
627-
final IRI acpAccessControl = rdf.createIRI(ACP.accessControl.toString());
628-
final IRI aclRead = rdf.createIRI(ACL.Read.toString());
629-
final IRI aclWrite = rdf.createIRI(ACL.Write.toString());
630-
631622
// find the acl Link in the header of the resource
632-
final Request req = Request.newBuilder(resourceURI)
633-
.HEAD()
634-
.build();
635-
final Response<Void> res = authClient.send(req, Response.BodyHandlers.discarding());
636-
final Headers.Link acrLink = res.headers().allValues("Link").stream()
637-
.flatMap(l -> Headers.Link.parse(l).stream())
638-
.filter(link -> link.getParameter("rel").contains("acl"))
639-
.findAny()
640-
.orElse(null);
641-
642-
// add the triples needed for access grant
643-
if (acrLink != null) {
644-
final URI resourceACRurl = acrLink.getUri();
645-
final IRI resourceACRiri = rdf.createIRI(resourceACRurl.toString());
646-
647-
//read the existing triples and add them to the dataset
648-
try (final SolidRDFSource resource = authClient.read(resourceACRurl, SolidRDFSource.class)) {
649-
650-
//creating a new matcher
651-
final URI newMatcherURI = URIBuilder.newBuilder(resourceACRurl).fragment("newMatcher").build();
652-
final IRI newMatcher = rdf.createIRI(newMatcherURI.toString());
653-
final IRI solidAccessGrant = rdf.createIRI("http://www.w3.org/ns/solid/vc#SolidAccessGrant");
654-
655-
resource.add(rdf.createQuad(resourceACRiri, newMatcher, acpVc, solidAccessGrant));
656-
657-
//create a new policy
658-
final URI newPolicyURI = URIBuilder.newBuilder(resourceACRurl).fragment("newPolicy").build();
659-
final IRI newPolicy = rdf.createIRI(newPolicyURI.toString());
660-
661-
resource.add(rdf.createQuad(resourceACRiri, newPolicy, acpAllOf, newMatcher));
662-
resource.add(rdf.createQuad(resourceACRiri, newPolicy, acpAllow, aclRead));
663-
resource.add(rdf.createQuad(resourceACRiri, newPolicy, acpAllow, aclWrite));
664-
665-
//creating a new access control
666-
final URI newAccessControlURI =
667-
URIBuilder.newBuilder(resourceACRurl).fragment("newAccessControl").build();
668-
final IRI newAccessControl = rdf.createIRI(newAccessControlURI.toString());
669-
670-
resource.add(rdf.createQuad(resourceACRiri, newAccessControl, acpApply, newPolicy));
671-
672-
//adding the new access control to the ACP
673-
resource.add(rdf.createQuad(resourceACRiri, resourceACRiri, acpAccessControl, newAccessControl));
674-
675-
authClient.update(resource);
676-
}
623+
try (final SolidRDFSource resource = authClient.read(resourceURI, SolidRDFSource.class)) {
624+
resource.getMetadata().getAcl().ifPresent(acl -> {
625+
try (final SolidRDFSource acr = authClient.read(acl, SolidRDFSource.class)) {
626+
AccessGrantUtils.accessControlPolicyTriples(acl, ACL.Read, ACL.Write)
627+
.forEach(acr.getGraph()::add);
628+
authClient.update(acr);
629+
}
630+
});
677631
}
678632
}
679633

0 commit comments

Comments
 (0)