Skip to content

Commit 286d1d6

Browse files
authored
JCL-377: distinguish between creator and recipient (#534)
* Split query tests between creator and recipient: It was initially only possible to query on the recipient. When the distinction between recipient and creator was introduced, some of the tests were not updated. * Replace "agent" by a more specific "recipient": This aligns the terminology with the attributes of the obtained credentials.
1 parent 0895fe7 commit 286d1d6

3 files changed

Lines changed: 49 additions & 38 deletions

File tree

access-grant/src/main/java/com/inrupt/client/accessgrant/AccessGrantClient.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -177,19 +177,20 @@ public AccessGrantClient session(final Session session) {
177177
/**
178178
* Issue an access request.
179179
*
180-
* @param agent the agent to whom the access request is made; i.e., the agent controlling access to the resources
180+
* @param recipient the agent to whom the access request is made;
181+
* i.e., the agent controlling access to the resources
181182
* @param resources the resources to which this credential applies
182183
* @param modes the access modes for this credential
183184
* @param purposes the purposes of this credential
184185
* @param expiration the expiration time of this credential
185186
* @return the next stage of completion containing the resulting access request
186187
*/
187-
public CompletionStage<AccessRequest> requestAccess(final URI agent, final Set<URI> resources,
188+
public CompletionStage<AccessRequest> requestAccess(final URI recipient, final Set<URI> resources,
188189
final Set<String> modes, final Set<URI> purposes, final Instant expiration) {
189190
Objects.requireNonNull(resources, "Resources may not be null!");
190191
Objects.requireNonNull(modes, "Access modes may not be null!");
191192
return v1Metadata().thenCompose(metadata -> {
192-
final Map<String, Object> data = buildAccessRequestv1(agent, resources, modes, expiration, purposes);
193+
final Map<String, Object> data = buildAccessRequestv1(recipient, resources, modes, expiration, purposes);
193194

194195
final Request req = Request.newBuilder(metadata.issueEndpoint)
195196
.header(CONTENT_TYPE, APPLICATION_JSON)
@@ -280,7 +281,7 @@ public CompletionStage<AccessDenial> denyAccess(final AccessRequest request) {
280281
* Issue an access grant or request.
281282
*
282283
* @param type the credential type
283-
* @param agent the receiving agent for this credential
284+
* @param recipient the receiving agent for this credential
284285
* @param resources the resources to which this credential applies
285286
* @param modes the access modes for this credential
286287
* @param purposes the purposes of this credential
@@ -289,7 +290,7 @@ public CompletionStage<AccessDenial> denyAccess(final AccessRequest request) {
289290
* @deprecated as of Beta3, please use the {@link #requestAccess} or {@link #grantAccess} methods
290291
*/
291292
@Deprecated
292-
public CompletionStage<AccessGrant> issue(final URI type, final URI agent, final Set<URI> resources,
293+
public CompletionStage<AccessGrant> issue(final URI type, final URI recipient, final Set<URI> resources,
293294
final Set<String> modes, final Set<String> purposes, final Instant expiration) {
294295
Objects.requireNonNull(type, "Access Grant type may not be null!");
295296
Objects.requireNonNull(resources, "Resources may not be null!");
@@ -305,9 +306,9 @@ public CompletionStage<AccessGrant> issue(final URI type, final URI agent, final
305306
return v1Metadata().thenCompose(metadata -> {
306307
final Map<String, Object> data;
307308
if (FQ_ACCESS_GRANT.equals(type)) {
308-
data = buildAccessGrantv1(agent, resources, modes, expiration, uriPurposes);
309+
data = buildAccessGrantv1(recipient, resources, modes, expiration, uriPurposes);
309310
} else if (FQ_ACCESS_REQUEST.equals(type)) {
310-
data = buildAccessRequestv1(agent, resources, modes, expiration, uriPurposes);
311+
data = buildAccessRequestv1(recipient, resources, modes, expiration, uriPurposes);
311312
} else {
312313
throw new AccessGrantException("Unsupported grant type: " + type);
313314
}

access-grant/src/test/java/com/inrupt/client/accessgrant/AccessGrantClientTest.java

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -274,10 +274,10 @@ void testFetchNotFound() {
274274

275275
assertInstanceOf(AccessGrantException.class, err1.getCause());
276276

277-
final URI agent = URI.create("https://id.test/agent");
277+
final URI recipient = URI.create("https://id.test/agent");
278278

279279
final CompletionException err2 = assertThrows(CompletionException.class,
280-
agClient.issue(ACCESS_GRANT, agent, Collections.emptySet(), Collections.emptySet(),
280+
agClient.issue(ACCESS_GRANT, recipient, Collections.emptySet(), Collections.emptySet(),
281281
Collections.emptySet(), Instant.now()).toCompletableFuture()::join);
282282
assertInstanceOf(AccessGrantException.class, err2.getCause());
283283
}
@@ -292,18 +292,18 @@ void testIssueGrantDeprecated() {
292292
final String token = generateIdToken(claims);
293293
final AccessGrantClient client = agClient.session(OpenIdSession.ofIdToken(token));
294294

295-
final URI agent = URI.create("https://id.test/agent");
295+
final URI recipient = URI.create("https://id.test/agent");
296296
final Instant expiration = Instant.parse("2022-08-27T12:00:00Z");
297297
final Set<String> modes = new HashSet<>(Arrays.asList("Read", "Append"));
298298
final Set<String> purposes = Collections.singleton("https://purpose.test/Purpose1");
299299

300300
final Set<URI> resources = Collections.singleton(URI.create("https://storage.test/data/"));
301-
final AccessGrant grant = client.issue(ACCESS_GRANT, agent, resources, modes, purposes, expiration)
301+
final AccessGrant grant = client.issue(ACCESS_GRANT, recipient, resources, modes, purposes, expiration)
302302
.toCompletableFuture().join();
303303

304304
assertTrue(grant.getTypes().contains("SolidAccessGrant"));
305-
assertEquals(Optional.of(agent), grant.getGrantee());
306-
assertEquals(Optional.of(agent), grant.getRecipient());
305+
assertEquals(Optional.of(recipient), grant.getGrantee());
306+
assertEquals(Optional.of(recipient), grant.getRecipient());
307307
assertEquals(modes, grant.getModes());
308308
assertEquals(expiration, grant.getExpiration());
309309
assertEquals(baseUri, grant.getIssuer());
@@ -322,17 +322,17 @@ void testIssueRequest() {
322322
final String token = generateIdToken(claims);
323323
final AccessGrantClient client = agClient.session(OpenIdSession.ofIdToken(token));
324324

325-
final URI agent = URI.create("https://id.test/agent");
325+
final URI recipient = URI.create("https://id.test/agent");
326326
final Instant expiration = Instant.parse("2022-08-27T12:00:00Z");
327327
final Set<String> modes = new HashSet<>(Arrays.asList("Read", "Append"));
328328
final Set<URI> purposes = Collections.singleton(URI.create("https://purpose.test/Purpose1"));
329329

330330
final Set<URI> resources = Collections.singleton(URI.create("https://storage.test/data/"));
331-
final AccessRequest request = client.requestAccess(agent, resources, modes, purposes, expiration)
331+
final AccessRequest request = client.requestAccess(recipient, resources, modes, purposes, expiration)
332332
.toCompletableFuture().join();
333333

334334
assertTrue(request.getTypes().contains("SolidAccessRequest"));
335-
assertEquals(Optional.of(agent), request.getRecipient());
335+
assertEquals(Optional.of(recipient), request.getRecipient());
336336
assertEquals(modes, request.getModes());
337337
assertEquals(expiration, request.getExpiration());
338338
assertEquals(baseUri, request.getIssuer());
@@ -342,14 +342,14 @@ void testIssueRequest() {
342342

343343
@Test
344344
void testRequestAccessNoAuth() {
345-
final URI agent = URI.create("https://id.test/agent");
345+
final URI recipient = URI.create("https://id.test/agent");
346346
final Instant expiration = Instant.parse("2022-08-27T12:00:00Z");
347347
final Set<String> modes = new HashSet<>(Arrays.asList("Read", "Append"));
348348
final Set<URI> purposes = Collections.singleton(URI.create("https://purpose.test/Purpose1"));
349349

350350
final Set<URI> resources = Collections.singleton(URI.create("https://storage.test/data/"));
351351

352-
final CompletableFuture<AccessRequest> future = agClient.requestAccess(agent, resources, modes, purposes,
352+
final CompletableFuture<AccessRequest> future = agClient.requestAccess(recipient, resources, modes, purposes,
353353
expiration).toCompletableFuture();
354354
final CompletionException err = assertThrows(CompletionException.class, future::join);
355355
assertInstanceOf(AccessGrantException.class, err.getCause());
@@ -365,19 +365,19 @@ void testGrantAccess() {
365365
final String token = generateIdToken(claims);
366366
final AccessGrantClient client = agClient.session(OpenIdSession.ofIdToken(token));
367367

368-
final URI agent = URI.create("https://id.test/agent");
368+
final URI recipient = URI.create("https://id.test/agent");
369369
final Instant expiration = Instant.parse("2022-08-27T12:00:00Z");
370370
final Set<String> modes = new HashSet<>(Arrays.asList("Read", "Append"));
371371
final Set<URI> purposes = Collections.singleton(URI.create("https://purpose.test/Purpose1"));
372372

373373
final Set<URI> resources = Collections.singleton(URI.create("https://storage.test/data/"));
374-
final AccessRequest request = client.requestAccess(agent, resources, modes, purposes, expiration)
374+
final AccessRequest request = client.requestAccess(recipient, resources, modes, purposes, expiration)
375375
.toCompletableFuture().join();
376376

377377
final AccessGrant grant = client.grantAccess(request).toCompletableFuture().join();
378378

379379
assertTrue(grant.getTypes().contains("SolidAccessGrant"));
380-
assertEquals(Optional.of(agent), grant.getRecipient());
380+
assertEquals(Optional.of(recipient), grant.getRecipient());
381381
assertEquals(modes, grant.getModes());
382382
assertEquals(expiration, grant.getExpiration());
383383
assertEquals(baseUri, grant.getIssuer());
@@ -395,19 +395,19 @@ void testDenyAccess() {
395395
final String token = generateIdToken(claims);
396396
final AccessGrantClient client = agClient.session(OpenIdSession.ofIdToken(token));
397397

398-
final URI agent = URI.create("https://id.test/agent");
398+
final URI recipient = URI.create("https://id.test/agent");
399399
final Instant expiration = Instant.parse("2022-09-12T12:00:00Z");
400400
final Set<String> modes = new HashSet<>(Arrays.asList("Read", "Append"));
401401
final Set<URI> purposes = Collections.singleton(URI.create("https://purpose.test/Purpose1"));
402402

403403
final Set<URI> resources = Collections.singleton(URI.create("https://storage.test/data/"));
404-
final AccessRequest request = client.requestAccess(agent, resources, modes, purposes, expiration)
404+
final AccessRequest request = client.requestAccess(recipient, resources, modes, purposes, expiration)
405405
.toCompletableFuture().join();
406406

407407
final AccessDenial denial = client.denyAccess(request).toCompletableFuture().join();
408408

409409
assertTrue(denial.getTypes().contains("SolidAccessDenial"));
410-
assertEquals(Optional.of(agent), denial.getRecipient());
410+
assertEquals(Optional.of(recipient), denial.getRecipient());
411411
assertEquals(modes, denial.getModes());
412412
assertEquals(expiration, denial.getExpiration());
413413
assertEquals(baseUri, denial.getIssuer());
@@ -430,13 +430,13 @@ void testGrantAccessNoAuth() {
430430
final String token = generateIdToken(claims);
431431
final AccessGrantClient client = agClient.session(OpenIdSession.ofIdToken(token));
432432

433-
final URI agent = URI.create("https://id.test/agent");
433+
final URI recipient = URI.create("https://id.test/agent");
434434
final Instant expiration = Instant.parse("2022-08-27T12:00:00Z");
435435
final Set<String> modes = new HashSet<>(Arrays.asList("Read", "Append"));
436436
final Set<URI> purposes = Collections.singleton(URI.create("https://purpose.test/Purpose1"));
437437

438438
final Set<URI> resources = Collections.singleton(URI.create("https://storage.test/data/"));
439-
final AccessRequest request = client.requestAccess(agent, resources, modes, purposes, expiration)
439+
final AccessRequest request = client.requestAccess(recipient, resources, modes, purposes, expiration)
440440
.toCompletableFuture().join();
441441

442442
final CompletableFuture<AccessGrant> future = agClient.grantAccess(request).toCompletableFuture();
@@ -446,14 +446,14 @@ void testGrantAccessNoAuth() {
446446

447447
@Test
448448
void testIssueNoAuth() {
449-
final URI agent = URI.create("https://id.test/agent");
449+
final URI recipient = URI.create("https://id.test/agent");
450450
final Instant expiration = Instant.parse("2022-08-27T12:00:00Z");
451451
final Set<String> modes = new HashSet<>(Arrays.asList("Read", "Append"));
452452
final Set<String> purposes = Collections.singleton("https://purpose.test/Purpose1");
453453

454454
final Set<URI> resources = Collections.singleton(URI.create("https://storage.test/data/"));
455455

456-
final CompletableFuture<AccessGrant> future = agClient.issue(ACCESS_GRANT, agent, resources, modes,
456+
final CompletableFuture<AccessGrant> future = agClient.issue(ACCESS_GRANT, recipient, resources, modes,
457457
purposes, expiration).toCompletableFuture();
458458
final CompletionException err = assertThrows(CompletionException.class, future::join);
459459
assertInstanceOf(AccessGrantException.class, err.getCause());
@@ -469,14 +469,14 @@ void testIssueOther() {
469469
final String token = generateIdToken(claims);
470470
final AccessGrantClient client = agClient.session(OpenIdSession.ofIdToken(token));
471471

472-
final URI agent = URI.create("https://id.test/agent");
472+
final URI recipient = URI.create("https://id.test/agent");
473473
final Instant expiration = Instant.parse("2022-08-27T12:00:00Z");
474474
final Set<String> modes = new HashSet<>(Arrays.asList("Read", "Append"));
475475
final Set<String> purposes = Collections.singleton("https://purpose.test/Purpose1");
476476

477477
final Set<URI> resources = Collections.singleton(URI.create("https://storage.test/data/"));
478478
final URI type = URI.create("https://vc.test/Type");
479-
final CompletableFuture<AccessGrant> future = client.issue(type, agent, resources,
479+
final CompletableFuture<AccessGrant> future = client.issue(type, recipient, resources,
480480
modes, purposes, expiration).toCompletableFuture();
481481
final CompletionException err = assertThrows(CompletionException.class, future::join);
482482
assertInstanceOf(AccessGrantException.class, err.getCause());
@@ -532,7 +532,7 @@ void testQueryGrantBuilder() {
532532
}
533533

534534
@Test
535-
void testQueryGrantAgent() {
535+
void testQueryGrantRecipient() {
536536
final Map<String, Object> claims = new HashMap<>();
537537
claims.put("webid", WEBID);
538538
claims.put("sub", SUB);
@@ -547,18 +547,18 @@ void testQueryGrantAgent() {
547547
}
548548

549549
@Test
550-
void testQueryGrantAgentBuilder() {
550+
void testQueryGrantCreator() {
551551
final Map<String, Object> claims = new HashMap<>();
552552
claims.put("webid", WEBID);
553553
claims.put("sub", SUB);
554554
claims.put("iss", ISS);
555555
claims.put("azp", AZP);
556556
final String token = generateIdToken(claims);
557557
final AccessGrantClient client = agClient.session(OpenIdSession.ofIdToken(token));
558-
559-
final AccessCredentialQuery<AccessGrant> query = AccessCredentialQuery.newBuilder()
560-
.recipient(URI.create("https://id.test/user")).mode("Read").build(AccessGrant.class);
561-
final List<AccessGrant> grants = client.query(query).toCompletableFuture().join();
558+
// A query is always done with the agent making the query as the creator.
559+
final List<AccessGrant> grants = client.query(
560+
null, URI.create("https://id.test/user"), null, null, "Read", AccessGrant.class
561+
).toCompletableFuture().join();
562562
assertEquals(1, grants.size());
563563
}
564564

@@ -605,7 +605,7 @@ void testQueryGrantModesPurposesNoMatchBuilder() {
605605
}
606606

607607
@Test
608-
void testQueryRequestAgent() {
608+
void testQueryRequestRecipient() {
609609
final Map<String, Object> claims = new HashMap<>();
610610
claims.put("webid", WEBID);
611611
claims.put("sub", SUB);
@@ -620,7 +620,7 @@ void testQueryRequestAgent() {
620620
}
621621

622622
@Test
623-
void testQueryRequestAgentBuilder() {
623+
void testQueryRequestRecipientBuilder() {
624624
final Map<String, Object> claims = new HashMap<>();
625625
claims.put("webid", WEBID);
626626
claims.put("sub", SUB);
@@ -716,6 +716,7 @@ void testQueryInvalidType() {
716716
client.query(uri, null, null, null, "Read", AccessCredential.class));
717717
}
718718

719+
719720
@Test
720721
void testQueryInvalidAuth() {
721722
final CompletionException err = assertThrows(CompletionException.class,

access-grant/src/test/java/com/inrupt/client/accessgrant/MockAccessGrantServer.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,15 @@ private void setupMocks() {
338338
.withHeader("Content-Type", "application/json")
339339
.withBody(getResource("/query_response5.json", wireMockServer.baseUrl()))));
340340

341+
wireMockServer.stubFor(post(urlEqualTo("/derive"))
342+
.atPriority(2)
343+
.withHeader("Authorization", containing("Bearer eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9."))
344+
.withRequestBody(containing("\"id\":\"https://id.test/user\""))
345+
.willReturn(aResponse()
346+
.withStatus(200)
347+
.withHeader("Content-Type", "application/json")
348+
.withBody(getResource("/query_response4.json", wireMockServer.baseUrl()))));
349+
341350
wireMockServer.stubFor(post(urlEqualTo("/derive"))
342351
.atPriority(2)
343352
.withHeader("Authorization", containing("Bearer eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9."))

0 commit comments

Comments
 (0)