Skip to content

Commit 68fd974

Browse files
authored
Merge branch 'main' into JCL-394-access-request-builder
2 parents 67eac40 + 1c7f1a2 commit 68fd974

File tree

8 files changed

+228
-368
lines changed

8 files changed

+228
-368
lines changed

integration/README.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ All the possible value are listed next:
3030
* `inrupt.test.client-secret` // mandatory
3131
* `inrupt.test.auth-method` // default is `client_secret_basic`
3232
* `inrupt.test.webid`
33-
* `inrupt.test.public-resource-path` // default is no dedicated container, everything gets created on the storage root
34-
* `inrupt.test.private-resource-path` // default is a container named `private`
3533
* `inrupt.test.access-grant.provider`
3634
* `inrupt.test.requester.webid`
3735
* `inrupt.test.requester.client-id` // mandatory
@@ -45,7 +43,6 @@ Optional fields are:
4543
* `inrupt.test.webid` is needed only if we want to run the integration tests on a live service. Otherwise, this property needs to be left out because it will be populated by the Mocked services with a mock username called `someuser`.
4644
* `inrupt.test.requester.webid` is only needed in the access grants test scenarios and can be also left empty because the Mocked services will create a username called `requester`.
4745
* `inrupt.test.auth-method` refers to the [client authentication](https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication) method and has a default value of `client_secret_basic`. This value is used when this property is not provided.
48-
* `inrupt.test.public-resource-path` & `inrupt.test.private-resource-path` are properties used to fine grain the containers we use for testing.
4946

5047
## The embedded Mock Solid Server
5148

@@ -58,7 +55,7 @@ The Mock Solid Server is actually a collection of services which try to mock, as
5855
* provide a token on its token endpoint (found under `oauth/oauth20/token`);
5956
* provide a jwks on its jwks endpoint (found under `oauth/jwks`).
6057

61-
* `MockSolidServer` - mocks the storage service of a Pod provider. It mocks the behavior of private and public resources by looking if the resource path contains the `inrupt.test.private-resource-path`. And it mocks, according to Solid Protocol methods like GET, PUT, POST and PATCH.
58+
* `MockSolidServer` - mocks the storage service of a Pod provider. It mocks the behavior of private and public resources by looking if the resource path contains the `State.PRIVATE_RESOURCE_PATH` which is set to `private`. And it mocks, according to Solid Protocol methods like GET, PUT, POST, HEAD and PATCH.
6259

6360
* `MockUMAAuthorizationServer` - mocks the authorization service, in our case a UMA service. UMA authorization is the default, hard-coded, in the Mocked services. This can be seen in any request on a private resource in the MockSolidServer. When not authorized, the Solid Server will respond with a WWW-Authenticate header which contains a UMA ticket.
6461

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

Lines changed: 57 additions & 94 deletions
Large diffs are not rendered by default.

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

Lines changed: 20 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,12 @@
2222

2323
import static org.junit.jupiter.api.Assertions.*;
2424

25-
import com.inrupt.client.Headers;
26-
import com.inrupt.client.Request;
27-
import com.inrupt.client.Response;
2825
import com.inrupt.client.auth.Credential;
2926
import com.inrupt.client.auth.Session;
3027
import com.inrupt.client.openid.OpenIdException;
3128
import com.inrupt.client.openid.OpenIdSession;
3229
import com.inrupt.client.solid.*;
3330
import com.inrupt.client.util.URIBuilder;
34-
import com.inrupt.client.vocabulary.LDP;
3531
import com.inrupt.client.webid.WebIdProfile;
3632

3733
import java.net.URI;
@@ -68,10 +64,8 @@ public class AuthenticationScenarios {
6864
private static final String MOCK_USERNAME = "someuser";
6965

7066
private static String testResourceName = "resource.ttl";
71-
private static URI publicTestContainerURI;
7267
private static URI publicResourceURI;
7368
private static URI publicContainerURI;
74-
private static URI privateTestContainerURI;
7569
protected static URI privateResourceURI;
7670
private static URI privateContainerURI;
7771
private static final Config config = ConfigProvider.getConfig();
@@ -81,13 +75,7 @@ public class AuthenticationScenarios {
8175
private static final String AUTH_METHOD = config
8276
.getOptionalValue("inrupt.test.auth-method", String.class)
8377
.orElse("client_secret_basic");
84-
private static final String PRIVATE_RESOURCE_PATH = config
85-
.getOptionalValue("inrupt.test.private-resource-path", String.class)
86-
.orElse("private");
87-
private static final String PUBLIC_RESOURCE_PATH = config
88-
.getOptionalValue("inrupt.test.public-resource-path", String.class)
89-
.orElse("");
90-
private static SolidSyncClient authClient;
78+
private static SolidSyncClient localAuthClient;
9179

9280
@BeforeAll
9381
static void setup() {
@@ -106,8 +94,6 @@ static void setup() {
10694
MOCK_USERNAME);
10795
webIdService.start();
10896

109-
State.PRIVATE_RESOURCE_PATH = PRIVATE_RESOURCE_PATH;
110-
11197
webidUrl = config
11298
.getOptionalValue("inrupt.test.webid", String.class)
11399
.orElse(URIBuilder.newBuilder(URI.create(webIdService.getMockServerUrl()))
@@ -125,66 +111,41 @@ static void setup() {
125111
podUrl += Utils.FOLDER_SEPARATOR;
126112
}
127113

128-
createAuthenticatedClient();
129-
if (PUBLIC_RESOURCE_PATH.isEmpty()) {
130-
publicTestContainerURI = URIBuilder.newBuilder(URI.create(podUrl))
131-
.path("test-" + UUID.randomUUID())
132-
.build();
133-
134-
} else {
135-
publicTestContainerURI = URIBuilder.newBuilder(URI.create(podUrl))
136-
.path(PUBLIC_RESOURCE_PATH)
137-
.path("test-" + UUID.randomUUID())
138-
.build();
139-
140-
publicContainerURI = URIBuilder.newBuilder(URI.create(podUrl))
141-
.path(PUBLIC_RESOURCE_PATH + "/").build();
114+
final Session session = OpenIdSession.ofClientCredentials(
115+
URI.create(issuer), //Client credentials
116+
CLIENT_ID,
117+
CLIENT_SECRET,
118+
AUTH_METHOD);
142119

143-
createContainer(publicContainerURI);
144-
prepareACR(publicContainerURI);
145-
}
120+
localAuthClient = SolidSyncClient.getClient().session(session);
146121

147-
publicResourceURI = URIBuilder.newBuilder(publicTestContainerURI)
122+
publicContainerURI = URIBuilder.newBuilder(URI.create(podUrl))
123+
.path("public-auth-test-" + UUID.randomUUID() + "/")
124+
.build();
125+
publicResourceURI = URIBuilder.newBuilder(publicContainerURI)
148126
.path(testResourceName)
149127
.build();
150128

151-
privateTestContainerURI = URIBuilder.newBuilder(URI.create(podUrl))
152-
.path(State.PRIVATE_RESOURCE_PATH)
153-
.path("test-" + UUID.randomUUID())
129+
Utils.createPublicContainer(localAuthClient, publicContainerURI);
130+
131+
privateContainerURI = URIBuilder.newBuilder(URI.create(podUrl))
132+
.path(State.PRIVATE_RESOURCE_PATH + "-auth-test-" + UUID.randomUUID() + "/")
154133
.build();
155134

156-
privateResourceURI = URIBuilder.newBuilder(privateTestContainerURI)
135+
privateResourceURI = URIBuilder.newBuilder(privateContainerURI)
157136
.path(testResourceName)
158137
.build();
159138

160-
privateContainerURI = URIBuilder.newBuilder(URI.create(podUrl))
161-
.path(PRIVATE_RESOURCE_PATH + "/").build();
139+
Utils.createContainer(localAuthClient, privateContainerURI);
162140

163141
LOGGER.info("Integration Test Issuer: [{}]", issuer);
164142
LOGGER.info("Integration Test Pod Host: [{}]", URI.create(podUrl).getHost());
165143
}
166144
@AfterAll
167145
static void teardown() {
168146
//cleanup pod
169-
final var reqDeletePrivateResource = Request.newBuilder(privateTestContainerURI).DELETE().build();
170-
authClient.send(reqDeletePrivateResource, Response.BodyHandlers.discarding());
171-
172-
final var reqDeletePrivateParent = Request.newBuilder(privateTestContainerURI.resolve("..")).DELETE().build();
173-
authClient.send(reqDeletePrivateParent, Response.BodyHandlers.discarding());
174-
175-
final var reqDeletePrivateContainer = Request.newBuilder(privateContainerURI).DELETE().build();
176-
authClient.send(reqDeletePrivateContainer, Response.BodyHandlers.discarding());
177-
178-
final var reqDeletePublic = Request.newBuilder(publicTestContainerURI).DELETE().build();
179-
authClient.send(reqDeletePublic, Response.BodyHandlers.discarding());
180-
181-
final var reqDeletePublicParent = Request.newBuilder(publicTestContainerURI.resolve("..")).DELETE().build();
182-
authClient.send(reqDeletePublicParent, Response.BodyHandlers.discarding());
183-
184-
if (publicContainerURI != null) {
185-
final var reqDeletePublicContainer = Request.newBuilder(publicContainerURI).DELETE().build();
186-
authClient.send(reqDeletePublicContainer, Response.BodyHandlers.discarding());
187-
}
147+
Utils.deleteContentsRecursively(localAuthClient, publicContainerURI);
148+
Utils.deleteContentsRecursively(localAuthClient, privateContainerURI);
188149

189150
mockHttpServer.stop();
190151
identityProviderServer.stop();
@@ -297,8 +258,7 @@ void multiSessionTest(final Session session) {
297258
assertDoesNotThrow(() -> authClient1.create(testResource));
298259

299260
//create another private resource with another client
300-
final URI privateResourceURL2 = URIBuilder.newBuilder(URI.create(podUrl))
301-
.path(State.PRIVATE_RESOURCE_PATH)
261+
final URI privateResourceURL2 = URIBuilder.newBuilder(privateContainerURI)
302262
.path("resource2.ttl")
303263
.build();
304264
try (final SolidRDFSource testResource2 = new SolidRDFSource(privateResourceURL2, null, null)) {
@@ -335,42 +295,4 @@ private static Stream<Arguments> provideSessions() throws SolidClientException {
335295
Arguments.of(OpenIdSession.ofIdToken(token), //OpenId token
336296
Arguments.of(session)));
337297
}
338-
339-
private static void createAuthenticatedClient() {
340-
final Session session = OpenIdSession.ofClientCredentials(
341-
URI.create(issuer), //Client credentials
342-
CLIENT_ID,
343-
CLIENT_SECRET,
344-
AUTH_METHOD);
345-
346-
authClient = SolidSyncClient.getClient().session(session);
347-
}
348-
349-
private static void createContainer(final URI publicContainerURI) {
350-
final var requestCreate = Request.newBuilder(publicContainerURI)
351-
.header(Utils.CONTENT_TYPE, Utils.TEXT_TURTLE)
352-
.header("Link", Headers.Link.of(LDP.RDFSource, "type").toString())
353-
.PUT(Request.BodyPublishers.noBody())
354-
.build();
355-
final var resCreate =
356-
authClient.send(requestCreate, Response.BodyHandlers.discarding());
357-
assertTrue(Utils.isSuccessful(resCreate.statusCode()));
358-
}
359-
360-
private static void prepareACR(final URI publicContainerURI) {
361-
try (SolidResource resource = authClient.read(publicContainerURI, SolidRDFSource.class)) {
362-
if (resource != null) {
363-
// find the acl Link in the header of the resource
364-
resource.getMetadata().getAcl().ifPresent(acl -> {
365-
try (final SolidRDFSource acr = authClient.read(acl, SolidRDFSource.class)) {
366-
Utils.publicAgentPolicyTriples(acl)
367-
.forEach(acr.getGraph()::add);
368-
authClient.update(acr);
369-
}
370-
});
371-
}
372-
} catch (Exception e) {
373-
throw new RuntimeException(e);
374-
}
375-
}
376298
}

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

Lines changed: 17 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -70,24 +70,15 @@ public class CoreModulesResource {
7070
private static MockOpenIDProvider identityProviderServer;
7171
private static MockUMAAuthorizationServer authServer;
7272
private static MockWebIdService webIdService;
73-
7473
private static final Config config = ConfigProvider.getConfig();
75-
7674
private static final SolidSyncClient client = SolidSyncClient.getClient().session(Session.anonymous());
7775
private static String podUrl;
78-
private static String issuer;
7976
private static final String MOCK_USERNAME = "someuser";
8077
private static final String TYPE = "type";
8178
private static final String LINK = "Link";
82-
private static final String PUBLIC_RESOURCE_PATH = config
83-
.getOptionalValue("inrupt.test.public-resource-path", String.class)
84-
.orElse("");
85-
86-
private static String testContainer = "resource/";
87-
private static URI testContainerURI;
8879
private static URI publicContainerURI;
8980

90-
private static SolidSyncClient authClient;
81+
private static SolidSyncClient localAuthClient;
9182
private static final String AUTH_METHOD = config
9283
.getOptionalValue("inrupt.test.auth-method", String.class)
9384
.orElse("client_secret_basic");
@@ -123,44 +114,33 @@ static void setup() {
123114
final var issuers = responseRdf.body()
124115
.listObjectsOfProperty(createProperty(Solid.oidcIssuer.toString()))
125116
.toList();
126-
issuer = issuers.get(0).toString();
117+
final String issuer = issuers.get(0).toString();
127118
final var storages = responseRdf.body()
128119
.listObjectsOfProperty(createProperty(PIM.storage.toString()))
129120
.toList();
130121
if (!storages.isEmpty()) {
131122
podUrl = storages.get(0).toString();
132123
}
133-
if (PUBLIC_RESOURCE_PATH.isEmpty()) {
134-
testContainerURI = URIBuilder.newBuilder(URI.create(podUrl))
135-
.path("test-" + UUID.randomUUID())
136-
.path(testContainer).build();
137-
} else {
138-
testContainerURI = URIBuilder.newBuilder(URI.create(podUrl))
139-
.path(PUBLIC_RESOURCE_PATH)
140-
.path("test-" + UUID.randomUUID())
141-
.path(testContainer)
124+
final Session session = OpenIdSession.ofClientCredentials(
125+
URI.create(issuer), //Client credentials
126+
CLIENT_ID,
127+
CLIENT_SECRET,
128+
AUTH_METHOD);
129+
localAuthClient = SolidSyncClient.getClient().session(session);
130+
131+
publicContainerURI = URIBuilder.newBuilder(URI.create(podUrl))
132+
.path("public-core-test-" + UUID.randomUUID() + "/")
142133
.build();
143134

144-
publicContainerURI = URIBuilder.newBuilder(URI.create(podUrl))
145-
.path(PUBLIC_RESOURCE_PATH + "/").build();
146-
createAuthenticatedClient();
147-
createContainer(publicContainerURI);
148-
prepareACR(publicContainerURI);
149-
}
135+
Utils.createPublicContainer(localAuthClient, publicContainerURI);
150136

151137
LOGGER.info("Integration Test Pod Host: [{}]", URI.create(podUrl).getHost());
152138
}
153139

154140
@AfterAll
155141
static void teardown() {
156142
//cleanup pod
157-
client.send(Request.newBuilder(testContainerURI).DELETE().build(), Response.BodyHandlers.discarding());
158-
client.send(Request.newBuilder(testContainerURI.resolve("..")).DELETE().build(),
159-
Response.BodyHandlers.discarding());
160-
if (publicContainerURI != null) {
161-
authClient.send(Request.newBuilder(publicContainerURI).DELETE().build(),
162-
Response.BodyHandlers.discarding());
163-
}
143+
Utils.deleteContentsRecursively(localAuthClient, publicContainerURI);
164144

165145
mockHttpServer.stop();
166146
identityProviderServer.stop();
@@ -174,7 +154,7 @@ static void teardown() {
174154
void crudRdfTest() {
175155
LOGGER.info("Integration Test - CRUD on RDF resource");
176156

177-
final String newResourceName = testContainerURI + "e2e-test-subject";
157+
final String newResourceName = publicContainerURI + "e2e-test-subject-core1";
178158
final String newPredicateName = "https://example.example/predicate";
179159

180160
//create
@@ -186,7 +166,6 @@ void crudRdfTest() {
186166
.build();
187167
final var resCreateIfNotExist =
188168
client.send(requestCreateIfNotExist, Response.BodyHandlers.discarding());
189-
assertTrue(Utils.isSuccessful(resCreateIfNotExist.statusCode()));
190169

191170
//if the resource already exists -> we get all its statements and filter out the ones we are interested in
192171
List<Statement> statementsToDelete = new ArrayList<>();
@@ -278,7 +257,7 @@ void crudRdfTest() {
278257
void containerCreateDeleteTest() {
279258
LOGGER.info("Integration Test - create and remove Containers");
280259

281-
final String containerName = testContainerURI + "newContainer/";
260+
final String containerName = publicContainerURI + "newContainer-" + UUID.randomUUID() + "/";
282261
final String container2Name = "newContainer2";
283262

284263
//create a Container
@@ -329,7 +308,7 @@ void nonRdfTest() {
329308
LOGGER.info("Integration Test - create, delete, and differentiate between RDF and non-RDF Resources");
330309

331310
final String fileName = "myFile.txt";
332-
final String fileURL = testContainerURI + fileName;
311+
final String fileURL = publicContainerURI + fileName;
333312

334313
//create non RDF resource
335314
final Request reqCreate =
@@ -362,7 +341,7 @@ void blankNodesTest() {
362341
LOGGER.info("Integration Test - update statements containing Blank Nodes " +
363342
"in different instances of the same model");
364343

365-
final String newResourceName = testContainerURI + "e2e-test-subject";
344+
final String newResourceName = publicContainerURI + "e2e-test-subject-core2";
366345
final String predicate = "https://example.example/predicate";
367346
final String predicateForBlank = "https://example.example/predicateForBlank";
368347

@@ -470,42 +449,5 @@ private String deleteInsertSparqlQuery(final List<Statement> quadsToDelete,
470449
return sparql;
471450
}
472451

473-
private static void createAuthenticatedClient() {
474-
final Session session = OpenIdSession.ofClientCredentials(
475-
URI.create(issuer), //Client credentials
476-
CLIENT_ID,
477-
CLIENT_SECRET,
478-
AUTH_METHOD);
479-
480-
authClient = SolidSyncClient.getClient().session(session);
481-
}
482-
483-
private static void createContainer(final URI publicContainerURI) {
484-
final var requestCreate = Request.newBuilder(publicContainerURI)
485-
.header(Utils.CONTENT_TYPE, Utils.TEXT_TURTLE)
486-
.header(LINK, Headers.Link.of(LDP.RDFSource, TYPE).toString())
487-
.PUT(Request.BodyPublishers.noBody())
488-
.build();
489-
final var resCreate =
490-
authClient.send(requestCreate, Response.BodyHandlers.discarding());
491-
assertTrue(Utils.isSuccessful(resCreate.statusCode()));
492-
}
493-
494-
private static void prepareACR(final URI publicContainerURI) {
495-
try (SolidResource resource = authClient.read(publicContainerURI, SolidRDFSource.class)) {
496-
if (resource != null) {
497-
// find the acl Link in the header of the resource
498-
resource.getMetadata().getAcl().ifPresent(acl -> {
499-
try (final SolidRDFSource acr = authClient.read(acl, SolidRDFSource.class)) {
500-
Utils.publicAgentPolicyTriples(acl)
501-
.forEach(acr.getGraph()::add);
502-
authClient.update(acr);
503-
}
504-
});
505-
}
506-
} catch (Exception e) {
507-
throw new RuntimeException(e);
508-
}
509-
}
510452
}
511453

0 commit comments

Comments
 (0)