|
42 | 42 | import java.util.UUID; |
43 | 43 | import java.util.concurrent.CompletableFuture; |
44 | 44 | import java.util.concurrent.CompletionException; |
| 45 | +import java.util.stream.Collectors; |
45 | 46 |
|
46 | 47 | import org.apache.commons.io.IOUtils; |
47 | 48 | import org.jose4j.jwk.PublicJsonWebKey; |
@@ -174,7 +175,6 @@ void testFetch5() { |
174 | 175 | assertInstanceOf(AccessGrantException.class, err1.getCause()); |
175 | 176 | } |
176 | 177 |
|
177 | | - |
178 | 178 | @Test |
179 | 179 | void testFetch6() { |
180 | 180 | final Map<String, Object> claims = new HashMap<>(); |
@@ -215,6 +215,27 @@ void testNotAccessGrant() { |
215 | 215 | client.fetch(uri, AccessGrant.class).toCompletableFuture()::join); |
216 | 216 | } |
217 | 217 |
|
| 218 | + @Test |
| 219 | + void testFetchTemplate() { |
| 220 | + final Map<String, Object> claims = new HashMap<>(); |
| 221 | + claims.put("webid", WEBID); |
| 222 | + claims.put("sub", SUB); |
| 223 | + claims.put("iss", ISS); |
| 224 | + claims.put("azp", AZP); |
| 225 | + final String token = generateIdToken(claims); |
| 226 | + final URI uri = URIBuilder.newBuilder(baseUri).path("access-request-6").build(); |
| 227 | + final AccessGrantClient client = agClient.session(OpenIdSession.ofIdToken(token)); |
| 228 | + final AccessRequest request = client.fetch(uri, AccessRequest.class).toCompletableFuture().join(); |
| 229 | + |
| 230 | + assertEquals(uri, request.getIdentifier()); |
| 231 | + assertEquals(baseUri, request.getIssuer()); |
| 232 | + |
| 233 | + // Revoke |
| 234 | + final CompletableFuture<Void> future = client.revoke(request).toCompletableFuture(); |
| 235 | + final CompletionException err1 = assertThrows(CompletionException.class, future::join); |
| 236 | + assertInstanceOf(AccessGrantException.class, err1.getCause()); |
| 237 | + } |
| 238 | + |
218 | 239 | @Test |
219 | 240 | void testFetchInvalid() { |
220 | 241 | final URI uri = URIBuilder.newBuilder(baseUri).path(".well-known/vc-configuration").build(); |
@@ -286,6 +307,33 @@ void testIssueRequestBuilder() { |
286 | 307 | assertEquals(resources, request.getResources()); |
287 | 308 | } |
288 | 309 |
|
| 310 | + @Test |
| 311 | + void testGrantFromTemplate() { |
| 312 | + final Map<String, Object> claims = new HashMap<>(); |
| 313 | + claims.put("webid", WEBID); |
| 314 | + claims.put("sub", SUB); |
| 315 | + claims.put("iss", ISS); |
| 316 | + claims.put("azp", AZP); |
| 317 | + final String token = generateIdToken(claims); |
| 318 | + final URI uri = URIBuilder.newBuilder(baseUri).path("access-request-6").build(); |
| 319 | + final AccessGrantClient client = agClient.session(OpenIdSession.ofIdToken(token)); |
| 320 | + final AccessRequest request = client.fetch(uri, AccessRequest.class).toCompletableFuture().join(); |
| 321 | + |
| 322 | + final AccessGrant grant = client.grantAccess(request).toCompletableFuture().join(); |
| 323 | + |
| 324 | + final Instant expiration = Instant.parse("2022-08-27T12:00:00Z"); |
| 325 | + final Set<String> modes = Set.of("Read", "Append"); |
| 326 | + final Set<URI> purposes = Collections.singleton(URI.create("https://purpose.test/Purpose1")); |
| 327 | + |
| 328 | + assertTrue(grant.getTypes().contains("SolidAccessGrant")); |
| 329 | + assertEquals(Optional.of(URI.create("https://id.test/agent")), grant.getRecipient()); |
| 330 | + assertEquals(modes, grant.getModes()); |
| 331 | + assertEquals(expiration, grant.getExpiration()); |
| 332 | + assertEquals(baseUri, grant.getIssuer()); |
| 333 | + assertEquals(purposes, grant.getPurposes()); |
| 334 | + assertNotNull(grant.getAccessRequest()); |
| 335 | + } |
| 336 | + |
289 | 337 | @Test |
290 | 338 | void testRequestAccessNoAuth() { |
291 | 339 | final URI recipient = URI.create("https://id.test/agent"); |
@@ -335,6 +383,53 @@ void testGrantAccess(final boolean verifyRequest) { |
335 | 383 | assertNotNull(grant.getAccessRequest()); |
336 | 384 | } |
337 | 385 |
|
| 386 | + @ParameterizedTest |
| 387 | + @ValueSource(booleans = {true, false}) |
| 388 | + void testGrantTemplatedAccess(final boolean verifyRequest) { |
| 389 | + final Map<String, Object> claims = new HashMap<>(); |
| 390 | + claims.put("webid", WEBID); |
| 391 | + claims.put("sub", SUB); |
| 392 | + claims.put("iss", ISS); |
| 393 | + claims.put("azp", AZP); |
| 394 | + final String token = generateIdToken(claims); |
| 395 | + final AccessGrantClient client = agClient.session(OpenIdSession.ofIdToken(token)); |
| 396 | + |
| 397 | + final URI recipient = URI.create("https://id.test/agent"); |
| 398 | + final Instant expiration = Instant.parse("2022-08-27T12:00:00Z"); |
| 399 | + final Set<String> modes = Set.of("Read", "Append"); |
| 400 | + final Set<URI> purposes = Collections.singleton(URI.create("https://purpose.test/Purpose1")); |
| 401 | + final Set<URI> resources = Collections.singleton(URI.create("https://storage.test/data/")); |
| 402 | + |
| 403 | + final var req = AccessRequest.RequestParameters.newBuilder() |
| 404 | + .recipient(recipient) |
| 405 | + .templates(Collections.singleton("http://{storage}/path")) |
| 406 | + .templates(null) |
| 407 | + .template(AccessRequest.template("data")) |
| 408 | + .modes(modes) |
| 409 | + .purposes(purposes) |
| 410 | + .expiration(expiration) |
| 411 | + .build(); |
| 412 | + |
| 413 | + final AccessRequest request = client.requestAccess(req) |
| 414 | + .toCompletableFuture().join(); |
| 415 | + |
| 416 | + final AccessGrant grant = client.grantAccess(request, templates -> |
| 417 | + templates.stream() |
| 418 | + .map(t -> t.replace("{domain}", "storage.test").replace("{+path}/", "")) |
| 419 | + .map(URI::create) |
| 420 | + .collect(Collectors.toSet()), verifyRequest) |
| 421 | + .toCompletableFuture().join(); |
| 422 | + |
| 423 | + assertTrue(grant.getTypes().contains("SolidAccessGrant")); |
| 424 | + assertEquals(Optional.of(recipient), grant.getRecipient()); |
| 425 | + assertEquals(modes, grant.getModes()); |
| 426 | + assertEquals(expiration, grant.getExpiration()); |
| 427 | + assertEquals(baseUri, grant.getIssuer()); |
| 428 | + assertEquals(purposes, grant.getPurposes()); |
| 429 | + assertEquals(resources, grant.getResources()); |
| 430 | + assertNotNull(grant.getAccessRequest()); |
| 431 | + } |
| 432 | + |
338 | 433 | @ParameterizedTest |
339 | 434 | @ValueSource(booleans = {true, false}) |
340 | 435 | void testDenyAccess(final boolean verifyRequest) { |
@@ -371,6 +466,58 @@ void testDenyAccess(final boolean verifyRequest) { |
371 | 466 | assertInstanceOf(AccessGrantException.class, err.getCause()); |
372 | 467 | } |
373 | 468 |
|
| 469 | + @Test |
| 470 | + void testNoTemplatesResources() { |
| 471 | + final Map<String, Object> claims = new HashMap<>(); |
| 472 | + claims.put("webid", WEBID); |
| 473 | + claims.put("sub", SUB); |
| 474 | + claims.put("iss", ISS); |
| 475 | + claims.put("azp", AZP); |
| 476 | + final String token = generateIdToken(claims); |
| 477 | + final AccessGrantClient client = agClient.session(OpenIdSession.ofIdToken(token)); |
| 478 | + |
| 479 | + final URI recipient = URI.create("https://id.test/agent"); |
| 480 | + final Instant expiration = Instant.parse("2022-08-27T12:00:00Z"); |
| 481 | + final Set<String> modes = Set.of("Read", "Append"); |
| 482 | + final Set<URI> purposes = Collections.singleton(URI.create("https://purpose.test/Purpose1")); |
| 483 | + |
| 484 | + final var req = AccessRequest.RequestParameters.newBuilder() |
| 485 | + .recipient(recipient) |
| 486 | + .modes(modes) |
| 487 | + .purposes(purposes) |
| 488 | + .expiration(expiration) |
| 489 | + .build(); |
| 490 | + |
| 491 | + assertDoesNotThrow(client.requestAccess(req).toCompletableFuture()::join); |
| 492 | + } |
| 493 | + |
| 494 | + @Test |
| 495 | + void testBothTemplatesResources() { |
| 496 | + final Map<String, Object> claims = new HashMap<>(); |
| 497 | + claims.put("webid", WEBID); |
| 498 | + claims.put("sub", SUB); |
| 499 | + claims.put("iss", ISS); |
| 500 | + claims.put("azp", AZP); |
| 501 | + final String token = generateIdToken(claims); |
| 502 | + final AccessGrantClient client = agClient.session(OpenIdSession.ofIdToken(token)); |
| 503 | + |
| 504 | + final URI recipient = URI.create("https://id.test/agent"); |
| 505 | + final Instant expiration = Instant.parse("2022-08-27T12:00:00Z"); |
| 506 | + final Set<String> modes = Set.of("Read", "Append"); |
| 507 | + final Set<URI> purposes = Collections.singleton(URI.create("https://purpose.test/Purpose1")); |
| 508 | + |
| 509 | + final var req = AccessRequest.RequestParameters.newBuilder() |
| 510 | + .recipient(recipient) |
| 511 | + .modes(modes) |
| 512 | + .purposes(purposes) |
| 513 | + .expiration(expiration) |
| 514 | + .template(AccessRequest.template("data")) |
| 515 | + .resource(URI.create("https://storage.test/path/data/")) |
| 516 | + .build(); |
| 517 | + |
| 518 | + assertDoesNotThrow(client.requestAccess(req).toCompletableFuture()::join); |
| 519 | + } |
| 520 | + |
374 | 521 | @Test |
375 | 522 | void testGrantAccessNoAuth() { |
376 | 523 | final Map<String, Object> claims = new HashMap<>(); |
|
0 commit comments