From 0647e4ff8a2ff249d3f7c0b3a65a69b97b4d1664 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Mur=C3=A9?= Date: Tue, 5 Aug 2025 12:11:20 +0200 Subject: [PATCH] adjust the toolkit to the new location --- go.mod | 1 + go.sum | 2 + pkg/container/containertest/Base64StdPadding | 2 +- .../containertest/Base64StdPaddingGzipped | 2 +- pkg/container/containertest/Base64URL | 2 +- pkg/container/containertest/Base64URLGzipped | 2 +- pkg/container/containertest/Bytes | Bin 4180 -> 4220 bytes pkg/container/containertest/BytesGzipped | Bin 2336 -> 2345 bytes pkg/container/reader.go | 23 ++- pkg/container/writer.go | 4 +- token/delegation/delegation_test.go | 2 +- .../delegationtest/generator/generator.go | 2 +- .../delegationtest/generator/main.go | 2 +- token/delegation/examples_test.go | 2 +- token/delegation/schema_test.go | 2 +- token/internal/didtest/crypto.go | 139 ------------- token/invocation/invocation_test.go | 2 +- toolkit/_example/Readme.md | 2 +- .../_protocol-issuer/request-resolver.go | 6 +- .../_example/_protocol-issuer/requester.go | 9 +- toolkit/_example/alice-client-issuer/alice.go | 19 +- toolkit/_example/bob-client/bob.go | 22 +- toolkit/_example/service-issuer/issuer.go | 13 +- toolkit/_example/service/service.go | 6 +- toolkit/_example/shared_values.go | 22 +- toolkit/client/client.go | 13 +- toolkit/client/client_test.go | 7 +- toolkit/client/clientissuer.go | 9 +- toolkit/client/pool.go | 3 +- toolkit/client/proof.go | 9 +- toolkit/client/proof_test.go | 3 +- toolkit/client/requester.go | 3 +- toolkit/client/requester_infura.go | 99 --------- toolkit/issuer/http_wrapper.go | 23 ++- toolkit/issuer/root_issuer.go | 20 +- toolkit/server/bearer/bearer_test.go | 2 + toolkit/server/exectx/middlewares.go | 6 +- toolkit/server/exectx/middlewares_test.go | 3 +- toolkit/server/exectx/ucanctx.go | 60 ++---- toolkit/server/exectx/ucanctx_test.go | 55 +---- toolkit/server/extargs/Readme.md | 21 +- .../server/extargs/{infura.go => custom.go} | 36 ++-- .../{infura_test.go => custom_test.go} | 27 +-- toolkit/server/extargs/http.go | 5 +- toolkit/server/extargs/http_test.go | 10 +- toolkit/server/extargs/jsonrpc.go | 171 ---------------- toolkit/server/extargs/jsonrpc_test.go | 188 ------------------ 47 files changed, 233 insertions(+), 828 deletions(-) delete mode 100644 token/internal/didtest/crypto.go delete mode 100644 toolkit/client/requester_infura.go rename toolkit/server/extargs/{infura.go => custom.go} (57%) rename toolkit/server/extargs/{infura_test.go => custom_test.go} (76%) delete mode 100644 toolkit/server/extargs/jsonrpc.go delete mode 100644 toolkit/server/extargs/jsonrpc_test.go diff --git a/go.mod b/go.mod index c8c2ab1..619f8e5 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ toolchain go1.24.5 require ( github.com/MetaMask/go-did-it v1.0.0-pre1 + github.com/avast/retry-go/v4 v4.6.1 github.com/ipfs/go-cid v0.5.0 github.com/ipld/go-ipld-prime v0.21.0 github.com/multiformats/go-multibase v0.2.0 diff --git a/go.sum b/go.sum index 5f9198d..71d4ac2 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/MetaMask/go-did-it v1.0.0-pre1 h1:NTGAC7z52TwFegEF7c+csUr/6Al1nAo6ValAAxOsjto= github.com/MetaMask/go-did-it v1.0.0-pre1/go.mod h1:7m9syDnXFTg5GmUEcydpO4Rs3eYT4McFH7vCw5fp3A4= +github.com/avast/retry-go/v4 v4.6.1 h1:VkOLRubHdisGrHnTu89g08aQEWEgRU7LVEop3GbIcMk= +github.com/avast/retry-go/v4 v4.6.1/go.mod h1:V6oF8njAwxJ5gRo1Q7Cxab24xs5NCWZBeaHHBklR8mA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/pkg/container/containertest/Base64StdPadding b/pkg/container/containertest/Base64StdPadding index 58936c0..e912350 100644 --- a/pkg/container/containertest/Base64StdPadding +++ b/pkg/container/containertest/Base64StdPadding @@ -1 +1 @@ -BoWZjdG4tdjGKWQGeglhAa8vQAimsd6982rgPP0e1ccInV/4cjWzjR71iyXGc2qVOGyEEZMT+e/Zfaw1WzVS5Ybgtpjw5/845jAPNbJv1DqJhaEQ07QFxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1rdnF0eDhkWFZ3NzZkTnc2U0FZUXJ3cFEzQlI4S3NwZ2FUN0Rwd3F3OW1zbXhjY21kaC9mb28vYmFyY2V4cBpnfrIdY2lzc3g4ZGlkOmtleTp6Nk1rcDZmMng2TW1xY1BDVWJhRVBxM0VqYjc4cjI3TFVKTEJWYUxjZ2hZaFR6TXJjcG9sgYNjYWxsYy5bXYNhPmYudmFsdWUCY3N1Yng4ZGlkOmtleTp6Nk1rcDZmMng2TW1xY1BDVWJhRVBxM0VqYjc4cjI3TFVKTEJWYUxjZ2hZaFR6TXJkbWV0YaNoNTIxZDIzZDBqMzMwNTJkZjgzOGg3NDVlZWFlZGpkYzg2NDM2M2QxaDgzZjY5OGYzajNhMDA3ZWY4Mjllbm9uY2VMwB+HSucZ5j+7FG/wWQGeglhAFgW0vCDmL/dzrIIT5oVRXsA1b/Fk5AiKhFlAVXRSXFoKuCixvn17vePm8anPkPewtZS7QiekJYwt9a0Aoe/CBaJhaEQ07QFxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1rcGNrS01FM3c3UWlvdWV3WkpLUFI0cDF5ak4yUDRjOXF3aDc1NVFqeTNyMURjY21kaC9mb28vYmFyY2V4cBpnfrIdY2lzc3g4ZGlkOmtleTp6Nk1ramlzQmZ3RE5SSHlYZmljd1k1M2MxaVpHdnBqaWVlclBuc1JxSEN2emhvOXpjcG9sgYNjYWxsYy5bXYNhPmYudmFsdWUCY3N1Yng4ZGlkOmtleTp6Nk1ramlzQmZ3RE5SSHlYZmljd1k1M2MxaVpHdnBqaWVlclBuc1JxSEN2emhvOXpkbWV0YaNoMTllZGI5NWFqN2ZkNThkYjc5M2gyY2FhY2NiYmo0NWJkNmQ1ODY2aDg4ZmY0N2E3amU2YjgzNjZlNGRlbm9uY2VMCrOVvOHN5HLH2khEWQGeglhAf4mTe11QRPxtukpFKL6IaKRxrZPSytRgfOHYXGHLrImx0j0qbdPkQLaQeajQAG2vYnrjqG74v+lRhHIFTLsRCKJhaEQ07QFxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1rcWREc2FqdDhUQXBkeGtNbmRHQXoxa1FNY0w4bWtxYXNWR1ZoZm5MRnRIeFRjY21kaC9mb28vYmFyY2V4cBpnfrIdY2lzc3g4ZGlkOmtleTp6Nk1raDlicHdRWjNycFZ0dlZXOFhtRUJEc01ucUJBZG00Q2MzczFWeTE3VUhDR1NjcG9sgYNjYWxsYy5bXYNhPmYudmFsdWUCY3N1Yng4ZGlkOmtleTp6Nk1raDlicHdRWjNycFZ0dlZXOFhtRUJEc01ucUJBZG00Q2MzczFWeTE3VUhDR1NkbWV0YaNoMDhjYTQ0MmNqMTBiNmU5Y2JjY2hjNTZmMjUwM2o1ZTJlNmU0ZDNiaGU3ODNhNTcxajY2OWVmZTI2Y2Nlbm9uY2VMm+hnFEzvWMyIwPWpWQGeglhAg2jLUqHQRlsIoBt7jaif9n1AFiuODDXx0lxtIhZLK52E9AjdPl+MRYaE4HrYXLUZdsACOovH6YrS8onV0E2ZA6JhaEQ07QFxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1rb1dIQXN2d2ZRWnZDamdCYWhlSjRMWVlXYWJ2MTVjcmpSVGJEWWpGM2ZHbWVjY21kaC9mb28vYmFyY2V4cBpnfrIdY2lzc3g4ZGlkOmtleTp6Nk1rcXFhcVdMZEVRWTVBUkV1c2U0UUduWUtDVTY5OHFleU5Lc0ZTZzRKdkVzWUxjcG9sgYNjYWxsYy5bXYNhPmYudmFsdWUCY3N1Yng4ZGlkOmtleTp6Nk1rcXFhcVdMZEVRWTVBUkV1c2U0UUduWUtDVTY5OHFleU5Lc0ZTZzRKdkVzWUxkbWV0YaNoMmE5NmNjNmVqNGNlM2ZjMTdjZGg3ZmMzZTdkM2piMjkwZTMyNDE3aGUwMDFmYzdmajJjOTAwNWY0NmRlbm9uY2VMC3IjW2PprOmuLut7WQGeglhAviUPHHfU+n8H1vyKyatGMS2YvJUvSvBxjC9hQSw7wIVbYAUJIgRr54V6vAifE2O4CvldXb16Qkqh1w9LnhX+A6JhaEQ07QFxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1ra0o3TTNzUXdOR0hFdEZOZGd4UFV5V1lXdGRWdXhLVXFiWndGdTU0TkVkOThjY21kaC9mb28vYmFyY2V4cBpnfrIdY2lzc3g4ZGlkOmtleTp6Nk1rdkZVcGhKcGpaVFZHYzRqdjVjWnJWampuV2JQWUM1UHhvVWduenhuVVZzMUJjcG9sgYNjYWxsYy5bXYNhPmYudmFsdWUCY3N1Yng4ZGlkOmtleTp6Nk1rdkZVcGhKcGpaVFZHYzRqdjVjWnJWampuV2JQWUM1UHhvVWduenhuVVZzMUJkbWV0YaNoMGYzOTk5M2VqNWMwOGI2NzEwNWgzNmFmNTMzNmpiNGU0MWRlZTFmaGMyOWVjZWM1ajdlMGZjMzE4OWZlbm9uY2VMwsoostxej7C8KxTfWQGeglhAABlu2b+acxlXwvhl3Cvr1t6wTRgDZyhwui2K//dXhixO+IBslbAM9a4W7wssVcpaA1M/U91DwRH6JjG8lfwnA6JhaEQ07QFxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1rbW9iNGlDczdXRHdRNU1KNDNOZERzaEplbXF4ZjF4RHBrWnJ0NFFYdUNTaURjY21kaC9mb28vYmFyY2V4cBpnfrIdY2lzc3g4ZGlkOmtleTp6Nk1rcG1BY0dLdWtLQ281czlzQzhpUGVaajkyMWc3YzRWeVM3WEFNcjR2ZGZSN1BjcG9sgYNjYWxsYy5bXYNhPmYudmFsdWUCY3N1Yng4ZGlkOmtleTp6Nk1rcG1BY0dLdWtLQ281czlzQzhpUGVaajkyMWc3YzRWeVM3WEFNcjR2ZGZSN1BkbWV0YaNoMjk3MTk1OTRqM2ZkYjI4MDA3Ymg4M2I4ZTQ2OGpiMDlhMDY3OWQxaGEwNjQzYmI4amE1ZWQ4NjcwYmRlbm9uY2VMBevInlpWjVqplZC8WQGeglhAVuW7Dme4SHo/P7+mB67OfD6DK6NBnZy1cyBAsbk76HL42MjYzPp8fi8+JkoZDs4g24iXi9vixQhfpPG8GfrUAKJhaEQ07QFxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1rcmJUbWRXaDZ2TUg2eDZFNlI3UnNpUEpIdFloM3hlSzdtTnFpSzJoekVxZ0VjY21kaC9mb28vYmFyY2V4cBpnfrIdY2lzc3g4ZGlkOmtleTp6Nk1ralZtNUdqblhLU2I4d0s3VDF2dmU4eHRuWlJvaUVYUjJGSGdQYVF5M2lEeWhjcG9sgYNjYWxsYy5bXYNhPmYudmFsdWUCY3N1Yng4ZGlkOmtleTp6Nk1ralZtNUdqblhLU2I4d0s3VDF2dmU4eHRuWlJvaUVYUjJGSGdQYVF5M2lEeWhkbWV0YaNoODU4MzY2ODhqNGZlNzI1Mzg2ZWg4NjNiMTIxOWo2MmY2Nzg1YWFmaGE5Y2M0MTEyajExMjgwZTM5NTBlbm9uY2VMUPFgyqtzEkRPXukGWQGeglhAIHB/6ndHOw4ruRy33I9yJej9A/ec3mGJsIEmNr33/rErTXlcNx+YH269sRCO9xOoRXFugTFDkAr92gjoUAeEAKJhaEQ07QFxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1rb3U4ZkRxc0xjcXVNaWRlRzZGdlpteFJOdG9EOVU0S2dIWjgycVBxOHJLR25jY21kaC9mb28vYmFyY2V4cBpnfrIdY2lzc3g4ZGlkOmtleTp6Nk1rc0RrenVVMncyeFZocVFGTjJVdHhyWkE1QWlIdWpHeGdEWHBueXdoNGV0TGRjcG9sgYNjYWxsYy5bXYNhPmYudmFsdWUCY3N1Yng4ZGlkOmtleTp6Nk1rc0RrenVVMncyeFZocVFGTjJVdHhyWkE1QWlIdWpHeGdEWHBueXdoNGV0TGRkbWV0YaNoNzIwMzUzNGRqYTMwMDY2Nzk4Y2g5ZDM1ZmUwOWoxZTg0Mzc3MTU0aGE4ZWY4YjM3ajIzMDM5YTljMTdlbm9uY2VMVLWsemG3WIh8/QshWQGeglhAR0zlf5Hc4m8hEwf664w9Cim5PHJftx0Y/rno06f9lTth3JuvY8znsXvl7Ym+ShIjTk9H9uJcjpVaNABfkr2YCKJhaEQ07QFxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1rcUU3SkptM3pkdXoxV2hFenpRcFZQa01SODdRaG5jRlpDNmpnMlZOV2JvVHNjY21kaC9mb28vYmFyY2V4cBpnfrIdY2lzc3g4ZGlkOmtleTp6Nk1rbTN1ZWF5cXo5akJXa2NRcWI2RDJpbkc1cVk4OTNOVWtnTWdXWmtudU1vcVJjcG9sgYNjYWxsYy5bXYNhPmYudmFsdWUCY3N1Yng4ZGlkOmtleTp6Nk1rbTN1ZWF5cXo5akJXa2NRcWI2RDJpbkc1cVk4OTNOVWtnTWdXWmtudU1vcVJkbWV0YaNoNmUyNzYwOThqZDQwOGRhYmJjZmhiMmE5ZGVhZGo2MWFjZmNlOWMwaGVhNWRjY2QwamVjYWUyMDVkMmNlbm9uY2VMcrvruHcj5dHWBhjMWQGeglhARe/SIBfmxJzT9pT650Vr3xmTvOhB2vOO3SsxEk5emAbTD0msHSWiwROgpbcsVOczBAMpR3MDlv+KDWzU5vKyBaJhaEQ07QFxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1rZkhTbW12TEppM1R5QmF3emczbmlFWUxOQzZnREd1NW9xcnhueFo5U3FkYk5jY21kaC9mb28vYmFyY2V4cBpnfrIdY2lzc3g4ZGlkOmtleTp6Nk1rblhhaXl1cUdXdTFrWTh2Rm1tZ2lMRjR1YnB4bW8zZlg3RlNpdlhBcmFac1djcG9sgYNjYWxsYy5bXYNhPmYudmFsdWUCY3N1Yng4ZGlkOmtleTp6Nk1rblhhaXl1cUdXdTFrWTh2Rm1tZ2lMRjR1YnB4bW8zZlg3RlNpdlhBcmFac1dkbWV0YaNoODg2NGQ5MmNqNTZhNjZhYjY5NWg4OGI3NjAwOGpmMjQwM2FkYTExaGZiY2Q1NDQ5amE4ZGVhNzhiMmZlbm9uY2VM2bLoKvbEKP43Vixd \ No newline at end of file +BoWZjdG4tdjGKWQGiglhABYakVJ3qMsyohPE5jEbaJ/o7OgvQT9dI/drXscOq+F6V8twJV6xRIXVYzWsoga7BYsf2XwTf+b+PEEQGRkOSAaJhaEg0Ae0B7QETcXN1Y2FuL2RsZ0AxLjAuMC1yYy4xqGNhdWR4OGRpZDprZXk6ejZNa3JYd0hzYmtXSjg0ZkVpOUt3QjJSQzRwUFN0WG1QbkJXd2RQR3V0Tk56eXhBY2NtZGgvZm9vL2JhcmNleHAaaJIvt2Npc3N4OGRpZDprZXk6ejZNa3ZWTlNMWlI1ZlFRMlpkeDhGZGRtcXoxTEx0dzFtMzVKc1VhVjdiSmszblpwY3BvbIGDY2FsbGMuW12DYT5mLnZhbHVlAmNzdWJ4OGRpZDprZXk6ejZNa3ZWTlNMWlI1ZlFRMlpkeDhGZGRtcXoxTEx0dzFtMzVKc1VhVjdiSmszblpwZG1ldGGjaDEzYjcyOWRiamJiYjZmZGNkOTJoMWY5M2U1YTBqZTA4MTk0MDdlOGg3M2Y4MWIzMWowNzQ1ZTQ0MzI3ZW5vbmNlTBGodc59dCiOB1O9lVkBooJYQPMo/EMhJhThi8Ab9zxcWlsBdJJf/WQnp7biGcrSOr/F5YrvumbUj31pd7s8mggD6BLSmi/Ch6wqQztRGD3Atw2iYWhINAHtAe0BE3FzdWNhbi9kbGdAMS4wLjAtcmMuMahjYXVkeDhkaWQ6a2V5Ono2TWtmcmVKb2o4cGtqamE1OHJUTTVEc3k0OGd3MWhaU0hmY1pXSHREcTI4WVp0QmNjbWRoL2Zvby9iYXJjZXhwGmiSL7djaXNzeDhkaWQ6a2V5Ono2TWtwZ1k1b3pUUWVMRnIxUENtV0UyU1lDWjZmNUZhckZERUF4Y1JmSEZQcFpycmNwb2yBg2NhbGxjLltdg2E+Zi52YWx1ZQJjc3VieDhkaWQ6a2V5Ono2TWtwZ1k1b3pUUWVMRnIxUENtV0UyU1lDWjZmNUZhckZERUF4Y1JmSEZQcFpycmRtZXRho2g5NTkyYTVkNWo1OGM5ZTYyN2E3aGNlYjhhMDVmamRlZjI1ZGNiN2JoZGZjOWE4OGVqNmVhZjQ1YTllNGVub25jZUzWFKuHIJ8sGrSYiD5ZAaKCWEDh97Nhb9gfjBT5wMlUe/VKpKXtO5C/P9/DOngvpVrc2fjxLmU+izfdFIMfsZc4fqFWXRGa7mM/vqFKsK7tAxoPomFoSDQB7QHtARNxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1rd1JmN2VDczRBWkc1RGhuNXJmcEZvNzhRTEhpbnNCc01TeFZ1eHpOeUM5aW5jY21kaC9mb28vYmFyY2V4cBpoki+3Y2lzc3g4ZGlkOmtleTp6Nk1raVo1c1lrMjF3VFVkZjc0NGNZRDFMSlgyS1Z1UlNxc29mN05TcEJISjVSVm1jcG9sgYNjYWxsYy5bXYNhPmYudmFsdWUCY3N1Yng4ZGlkOmtleTp6Nk1raVo1c1lrMjF3VFVkZjc0NGNZRDFMSlgyS1Z1UlNxc29mN05TcEJISjVSVm1kbWV0YaNoMDU2ZWE4NzlqMzY0MmIyZDE3MWgzNDI4ZmExY2pjNTE1ODlhNTFiaDc4ODQ2MDI2ajhiNGVlMzhmZTRlbm9uY2VMlJH6zxWeWLgrPFL8WQGiglhAodgbslQnxQ6LbUhJ2ZVE6YXZmJzsXpptz45Px8HX67seRXLboSiTpJGX7CWn2l/C3Bkvpc9wWr4os4UmAP8WCaJhaEg0Ae0B7QETcXN1Y2FuL2RsZ0AxLjAuMC1yYy4xqGNhdWR4OGRpZDprZXk6ejZNa3Jpbng5WHNwVEdaMjlhSHBQdWkxUXhwUTFNRko3b2lnSERVbWdINWN4MUtZY2NtZGgvZm9vL2JhcmNleHAaaJIvt2Npc3N4OGRpZDprZXk6ejZNa2pRa3hFbUNVSHdVTEV0R1VZOTFLMUdlY2NScHJVdkI0QndXVUQ4Z0hGcVpUY3BvbIGDY2FsbGMuW12DYT5mLnZhbHVlAmNzdWJ4OGRpZDprZXk6ejZNa2pRa3hFbUNVSHdVTEV0R1VZOTFLMUdlY2NScHJVdkI0QndXVUQ4Z0hGcVpUZG1ldGGjaDcxOTBjZmE5ajM4NmU0OGFiZmJoN2U1OTdjZTlqZDFiYmI2ZjYxNGg5ZTljYTc4OWpjZWM5Zjk5NTgxZW5vbmNlTL6XetkzghuY2J6Y51kBooJYQHoWRs/WJJro50YyRnRzlhpvn1JL6uD2z6bHo5F4Ke9ui0WIr6kSxQKcwbT1/6EkrFAL4n/FlxXG73ba31zgwwSiYWhINAHtAe0BE3FzdWNhbi9kbGdAMS4wLjAtcmMuMahjYXVkeDhkaWQ6a2V5Ono2TWt3ZW9hbVp1VFBrVVFRUlhhaXIyb0hKem1QYzVFYnh6UkExeXZ2RjU2SFJ3YmNjbWRoL2Zvby9iYXJjZXhwGmiSL7djaXNzeDhkaWQ6a2V5Ono2TWttYWRLaFJqR2FOV2MzQzczbzUxb0E0QzY5U01jaHBBUFJYU1A2V2NYelFwWGNwb2yBg2NhbGxjLltdg2E+Zi52YWx1ZQJjc3VieDhkaWQ6a2V5Ono2TWttYWRLaFJqR2FOV2MzQzczbzUxb0E0QzY5U01jaHBBUFJYU1A2V2NYelFwWGRtZXRho2gxYzgxYmJjMGo4OWEyNjJhYjNlaDU4ZTVjZjc5ajk0NmZkZDcwOTNoNjUyYTFiOWRqNDQwZDg0YzNiY2Vub25jZUxV6CeWkqLbqyInfX1ZAaKCWECPCG7QlXAncItxluVoom9ExdZB36bJgVcC8atGlNkZztgwgi2qRn/PAPJ+izizRxPvXo2HeVl8oFMx+eVU9I0IomFoSDQB7QHtARNxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1ramFDdzNqNTRFcGN0SGFVdjNqeGVTQkRhd2RNTW5EYXNLcERLMVozQmtNYmRjY21kaC9mb28vYmFyY2V4cBpoki+3Y2lzc3g4ZGlkOmtleTp6Nk1rbUVBZVZYdVNncWhybzNZMUNETEtjN0pDbUhMNmM1eHFlM0ZIVkdhZU52UjljcG9sgYNjYWxsYy5bXYNhPmYudmFsdWUCY3N1Yng4ZGlkOmtleTp6Nk1rbUVBZVZYdVNncWhybzNZMUNETEtjN0pDbUhMNmM1eHFlM0ZIVkdhZU52UjlkbWV0YaNoN2U3NjA3NWNqZWYyNDEzMGMyM2g4ZGI3YTA0YWpmMDUwMDRiOGZiaGQwMTJkNTNiamMwYTk0ZTU2OGZlbm9uY2VM0A2enQKwnAQODN09WQGiglhAH7cY+u6guPL+h4Gl1MD99HMYxzauamvTl9BDhm+gf1qI5wyyJZz9s1jDn9DIV0kc+X4zOukFEc2mxgi3B3DmDqJhaEg0Ae0B7QETcXN1Y2FuL2RsZ0AxLjAuMC1yYy4xqGNhdWR4OGRpZDprZXk6ejZNa3FhNmNoU2ZMM2NHYWNFamVxalNnY3pLZmlYNmRWM0xRbWMzQ1JWVnhDVmg4Y2NtZGgvZm9vL2JhcmNleHAaaJIvt2Npc3N4OGRpZDprZXk6ejZNa3VKQWQ4b3BQUkxWNzJXZXp0UFFIcnhkZENwcTM3UDFQeDFRNXlhVEdhdjl2Y3BvbIGDY2FsbGMuW12DYT5mLnZhbHVlAmNzdWJ4OGRpZDprZXk6ejZNa3VKQWQ4b3BQUkxWNzJXZXp0UFFIcnhkZENwcTM3UDFQeDFRNXlhVEdhdjl2ZG1ldGGjaDA2ODc4MmY3amRhMGJjNGUzN2RoNGEyY2U0YzFqNTJkNGQzMmVmN2hhZGU5MGE1OGphOTk1ODdhZTliZW5vbmNlTB8pysCUZIh8y43VnFkBooJYQLaRhdQ03p5fKqnz8nRjb9h+uFvrVK4Ke7JlGuhnEL8LUQzjbDckjicDfkZX//duNEV3qKyTHiSGvU1FQo9nyAiiYWhINAHtAe0BE3FzdWNhbi9kbGdAMS4wLjAtcmMuMahjYXVkeDhkaWQ6a2V5Ono2TWtxcWlienI5amYxTjkxQVY1eUVLYzRjSzRaMWlVMkpXRzdndWJLdWhoZTR6a2NjbWRoL2Zvby9iYXJjZXhwGmiSL7djaXNzeDhkaWQ6a2V5Ono2TWtqeFIyVGFBUWNqRERXTjl5dloyY3BFYUVrbncydmkxNENLTmhBSzQ0TGZ1Y2Nwb2yBg2NhbGxjLltdg2E+Zi52YWx1ZQJjc3VieDhkaWQ6a2V5Ono2TWtqeFIyVGFBUWNqRERXTjl5dloyY3BFYUVrbncydmkxNENLTmhBSzQ0TGZ1Y2RtZXRho2gyMDkyZjYwYmpiMzcwZjMwNzI3aDQ3OGI0Y2M1ajk4YjdkYjAxMzJoNmQ0YmFhZjVqYmVkNGUxYjJmM2Vub25jZUx+tmRsecAtdwXDqY1ZAaKCWEB3o5gA741QVQnxqMkgt7DwS/4WgoReEKdUCz4RpaM5LDeJNg4vi8rOUTaU4VhpowgDxn+lBGraJUbp2Y5L/q8PomFoSDQB7QHtARNxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1rdHhRUjg5b0F4VG1kdjNTOFFhbVk2aXdGYlp6SDZ1QnlFQWZLOGNpY0RkU3JjY21kaC9mb28vYmFyY2V4cBpoki+3Y2lzc3g4ZGlkOmtleTp6Nk1raTgyc2dFa1ZrYnNjZEJ5ZDY4WVoyQ2ViSmh4QXlzSnpDZHluOTFhRHROdjhjcG9sgYNjYWxsYy5bXYNhPmYudmFsdWUCY3N1Yng4ZGlkOmtleTp6Nk1raTgyc2dFa1ZrYnNjZEJ5ZDY4WVoyQ2ViSmh4QXlzSnpDZHluOTFhRHROdjhkbWV0YaNoMmI1MTllNzNqM2E3MTc5NmQ3MWg5YWE3NjQwMGoxM2FiZGYwNWQ2aDlmZmU1ZTliajY5YmU3NjI5ZDFlbm9uY2VMyL0L8CRxcMsMq5hbWQGiglhA3YnA0f5qejI6yGKfabYt1rojIQkTKSdLfMLSwhl9LR+aHXivxgKWzy/W3wbHOjG5JdEb7sl/yH0G4SFcpTSOCaJhaEg0Ae0B7QETcXN1Y2FuL2RsZ0AxLjAuMC1yYy4xqGNhdWR4OGRpZDprZXk6ejZNa3VqVTVCTFhQZkt6OVlVUmNZY1IzNVN1eFV1UmNEajZOZmtpV1c0dEhReUJQY2NtZGgvZm9vL2JhcmNleHAaaJIvt2Npc3N4OGRpZDprZXk6ejZNa3MydVJxUEV5akdBM3Z4eEVEZmNHSzdpZ2tWN1JwSGltNTVqamlKazYzcTJzY3BvbIGDY2FsbGMuW12DYT5mLnZhbHVlAmNzdWJ4OGRpZDprZXk6ejZNa3MydVJxUEV5akdBM3Z4eEVEZmNHSzdpZ2tWN1JwSGltNTVqamlKazYzcTJzZG1ldGGjaGNlOTk3ZWVjamFkZDA2NzBhMTdoZDczMjA4YTFqZDhmNTllZjc3N2hkYTg3MDQwMWpiNzVhNTRlNTYzZW5vbmNlTBZguMsZADREIeYq5g== \ No newline at end of file diff --git a/pkg/container/containertest/Base64StdPaddingGzipped b/pkg/container/containertest/Base64StdPaddingGzipped index d619ebd..1fdd6b3 100644 --- a/pkg/container/containertest/Base64StdPaddingGzipped +++ b/pkg/container/containertest/Base64StdPaddingGzipped @@ -1 +1 @@ -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 \ No newline at end of file +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 \ No newline at end of file diff --git a/pkg/container/containertest/Base64URL b/pkg/container/containertest/Base64URL index 9fe7b78..2113e30 100644 --- a/pkg/container/containertest/Base64URL +++ b/pkg/container/containertest/Base64URL @@ -1 +1 @@ -CoWZjdG4tdjGKWQGeglhACpXpdxwBGhOBgP0i_jkbddYEXF1SIqsFv3_hqgTujlJB1hiKUArH2AIsVSKtpGH-g1tI691qlTZrWoWbReObC6JhaEQ07QFxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1raEFHdzlXbk1yMlpoRHlBalpVVFJ0UEZURmh6WXN4SjF2R211NXVEdDJFcFRjY21kaC9mb28vYmFyY2V4cBpnfrIdY2lzc3g4ZGlkOmtleTp6Nk1rc1FtZVcxb3RUeWNQeWRnQ1hxakxRS2JaRUZSMlF5cXJwYWZUZjVhNWFiYVdjcG9sgYNjYWxsYy5bXYNhPmYudmFsdWUCY3N1Yng4ZGlkOmtleTp6Nk1rc1FtZVcxb3RUeWNQeWRnQ1hxakxRS2JaRUZSMlF5cXJwYWZUZjVhNWFiYVdkbWV0YaNoYzdjOWYzM2VqYTYxMzQ2ZTVhMGhmNzNhNDJjOWplZDU4YWQ0ZTg1aGZlZjI5NTlmajBjY2NmN2I5NjFlbm9uY2VM4c8LJwfjIdKZbUd-WQGeglhAGRizpuAMSDUiVK3a7JS_Wr-Z1lqn9eASP5He4iZi2lsXcqgKOozEHOBddL302HETEZyWvZJpjsr7pRDl8nvcA6JhaEQ07QFxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1raHo4bWtKOTZOQjN5Y1VnNHcyeWVQbzd3cnJwYlVYZkZVNEhyQ2tEaEg0aEJjY21kaC9mb28vYmFyY2V4cBpnfrIdY2lzc3g4ZGlkOmtleTp6Nk1raEZ3SmhiNENaQVBScHlXWmMxNXA5NU04NDE3RW1RbUdIU3liMlRwOW95QVpjcG9sgYNjYWxsYy5bXYNhPmYudmFsdWUCY3N1Yng4ZGlkOmtleTp6Nk1raEZ3SmhiNENaQVBScHlXWmMxNXA5NU04NDE3RW1RbUdIU3liMlRwOW95QVpkbWV0YaNoMTYwMTM4YzZqMmJkYWYzNzcxYWg4M2Y4MTdkM2pjM2IwYjdmNjQ5aDkwZGMxODA5amMxMDZiOTJmYWZlbm9uY2VM0GJFExCefuuIz3DAWQGeglhAKgFiPWomi3iuL4RcE_XMscG8JjAUBCTsCu9_aQY6U6sA_E2GnlI37ASYcnqgM0Kk4BLjta2nHgKh6T26CtY-AaJhaEQ07QFxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1rdkc0aXJlN3J6YmtTYXR1MVl4c0J1R3FLczlrTmdHWnRUWFFCNkhXRm1iUlRjY21kaC9mb28vYmFyY2V4cBpnfrIdY2lzc3g4ZGlkOmtleTp6Nk1rdnlwMWdWNlM3TFhMbUNOUEhRblR4VnBjeFJTNlhuZkdIaExycHVldk4xZ1VjcG9sgYNjYWxsYy5bXYNhPmYudmFsdWUCY3N1Yng4ZGlkOmtleTp6Nk1rdnlwMWdWNlM3TFhMbUNOUEhRblR4VnBjeFJTNlhuZkdIaExycHVldk4xZ1VkbWV0YaNoYWE2NmY4NDdqOGQyZTIzNTM3ZWhjMzExYjNkNWozOTZlYTJjZTE5aGQ2NmM3YmVkajg3MGQ1YjNhNmRlbm9uY2VMw0wBN_QOVu5WH3ZUWQGeglhA4uBojvXBeoEJ4qnDmtHrtZArqBOj1jRMQrXOxy75JD2xpBhhxW_c90ofhjexFy5m-TM1a9pciFfVdgUwc8a7AqJhaEQ07QFxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1razVKRXNDUW1tWGZoMU5XazJVSjJBZ01zYmRxNDhmU1JoaXdiTmJmN0ZVbVFjY21kaC9mb28vYmFyY2V4cBpnfrIdY2lzc3g4ZGlkOmtleTp6Nk1ra0VXanFxRkVwZUJlakJBREpneTNRdmZBU01KSkZjc0FIZmRqNkpkSlJKSnZjcG9sgYNjYWxsYy5bXYNhPmYudmFsdWUCY3N1Yng4ZGlkOmtleTp6Nk1ra0VXanFxRkVwZUJlakJBREpneTNRdmZBU01KSkZjc0FIZmRqNkpkSlJKSnZkbWV0YaNoZGVjOTBjOWFqYjZiNGU2NTRlY2hlMGYyN2VmNGo2YTJhZWZjM2U5aGY1NjNjNjEwajNhM2EyNzA4MDJlbm9uY2VMdQysOoQ6Wn3YZJ9KWQGeglhA58PG4OcNtwHt9nXjgcTBebRvhQhVTG6tYyJvTNeFaJj9V-JD3jiT4ZgLJKFenedmwNA0Et31Jfu6MNqkiYUcCaJhaEQ07QFxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1ramQ5THQ0WXRKNFU4TjRRc29hUVRveEFqekxlMkZnbVZXUkhycTltQUFmTHVjY21kaC9mb28vYmFyY2V4cBpnfrIdY2lzc3g4ZGlkOmtleTp6Nk1rbkJITFl3N0tpbzVwb2NhclVoTW9BWmEzb25nZXpjcmJpcHRLRkxGU1REM1RjcG9sgYNjYWxsYy5bXYNhPmYudmFsdWUCY3N1Yng4ZGlkOmtleTp6Nk1rbkJITFl3N0tpbzVwb2NhclVoTW9BWmEzb25nZXpjcmJpcHRLRkxGU1REM1RkbWV0YaNoNDNmNmZjNjlqOWUxMGNhM2I5NGg2YjNjMjYxY2pjMzBkZDlmYTI2aGNkMDAwYzU1ajA2YjZjMDNiM2Zlbm9uY2VMbwisskfMLx4-gstgWQGeglhAIgN-nA7mA4g2FKr6_CR3kCPzcegoqgIDWk1qCotQWLo0ntG2WoSfnJvPWj9o1HLtxTAKAWzexFwiBTamow2EA6JhaEQ07QFxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1rdm5lcWd0ZG52cHVmdHQ0emJHSEZxMnRMSjRkc1dWN2N2NHhrbjlGajlXUjZjY21kaC9mb28vYmFyY2V4cBpnfrIdY2lzc3g4ZGlkOmtleTp6Nk1rcmhpc3JqVkFWOVROQ3dkejY4NURpdHY2eWRaSjIzWkh0cUFjM0E4SHJvUUhjcG9sgYNjYWxsYy5bXYNhPmYudmFsdWUCY3N1Yng4ZGlkOmtleTp6Nk1rcmhpc3JqVkFWOVROQ3dkejY4NURpdHY2eWRaSjIzWkh0cUFjM0E4SHJvUUhkbWV0YaNoMGM3OGVmMmFqMjI1ZDgxYTg3ZGgxMzIyZWU5MmozZTJjZjNmOWZjaDQ1YjM1MWYzamExYTMzOTU1YzZlbm9uY2VMGkPaJ3crRATPQ7jrWQGeglhAFK5Ex__PUA3vkGgS6JKYwyGf03AvjNKLW7S8aDnC4lRCh0VjOdMQ1xHHsV6fsqBDcPC6dwqpFTHOO9YbMPBNCaJhaEQ07QFxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1rZkZSRndzVVNNc1hzWVRvWGtWZ01mQnBwbTdxRkpqc2g4Z2FSZjY2Q1FvMmhjY21kaC9mb28vYmFyY2V4cBpnfrIdY2lzc3g4ZGlkOmtleTp6Nk1rdE5UdUhUakI2bWhhMkNKZFFRQ2FyUFE5cGN5a3RQcE5DVmg0TVhMVlNQNlFjcG9sgYNjYWxsYy5bXYNhPmYudmFsdWUCY3N1Yng4ZGlkOmtleTp6Nk1rdE5UdUhUakI2bWhhMkNKZFFRQ2FyUFE5cGN5a3RQcE5DVmg0TVhMVlNQNlFkbWV0YaNoMWU2Zjc4YzVqOWRhOThkYWVjNmg4YjRjYTg1OGo4MjNmY2Y3MjliaGYyN2I1YzA1ajU4NjkyMDEyMWVlbm9uY2VMrIMpUz2MjCvzE0tMWQGeglhAy9s8amUFAKS7soQbA4oFzhU4cVRJ73LhUFicmTM3q5dd3vVfy-xeq7yhc-8orqEvsdiXPRVbfZdFtjmEbjRSCqJhaEQ07QFxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1raVoxMUxWUm9keU0yRmI2VjlUbmF5M3g4bVhVa3p0R0c3TlVxZHFrOHRYYkFjY21kaC9mb28vYmFyY2V4cBpnfrIdY2lzc3g4ZGlkOmtleTp6Nk1rcFVKc3J5b2V1Mnp6WVNBdng3Z1VRcG0yc2JyRmVFSnFNVERIYVVnSjhrd3djcG9sgYNjYWxsYy5bXYNhPmYudmFsdWUCY3N1Yng4ZGlkOmtleTp6Nk1rcFVKc3J5b2V1Mnp6WVNBdng3Z1VRcG0yc2JyRmVFSnFNVERIYVVnSjhrd3dkbWV0YaNoMjdiYjAzZGVqOTY2NzgxZTQwOGg0NDFjMGIzMGo0NDhmNzEwZmU0aDc0MmM0NDQ5ajdiZjVjMjhiMjJlbm9uY2VM7ctTlMIv0HNvXrsUWQGeglhAUgkAhE9RqmEC6Yx5EUrhcq61qNc3tJ1x1bfAuPO01gxVkD9v4PebljD1PVtYE8uFgQtMFA0u0oI4mHTBHcx8CKJhaEQ07QFxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1rdmZNNVdxZ1JlWThWN3FLRHdWaWs3NHRLVmhjNktOeEoxcHQ2MTNGMktySnpjY21kaC9mb28vYmFyY2V4cBpnfrIdY2lzc3g4ZGlkOmtleTp6Nk1rdTV6WmhUajdENTF0azNGRTRNYUtCVm9paU1rRnpGNHdNOFl4SFhybmpUdlZjcG9sgYNjYWxsYy5bXYNhPmYudmFsdWUCY3N1Yng4ZGlkOmtleTp6Nk1rdTV6WmhUajdENTF0azNGRTRNYUtCVm9paU1rRnpGNHdNOFl4SFhybmpUdlZkbWV0YaNoNWViOWY3YmJqOGFjYTI4MDhjOGhhZTFmMTA4MWo0ODllM2U1OTk4aGFmOTUwZTU0ajM1ZTMzZDNkMTVlbm9uY2VMn16caMQ_aieJes1jWQGeglhA3zJcxENVVf7UDXPewhqsoEHO6Y2fAjOkpjAjdpz244-w2GUand8PTxp1E7ET8FqFx9gD74WjPbzamIoaWsCzAqJhaEQ07QFxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1ra252UjFjb2hRNzdNaU1mZ3JWelpvdVlGaHk1RTh2YUNXckFvdk1zNXJvZkxjY21kaC9mb28vYmFyY2V4cBpnfrIdY2lzc3g4ZGlkOmtleTp6Nk1rbmFhZmdwaUU0OHo3WjQ5N1F6NkVXQzI2ZlluRlI4NXJjYm5kV3Q4UFZoVk1jcG9sgYNjYWxsYy5bXYNhPmYudmFsdWUCY3N1Yng4ZGlkOmtleTp6Nk1rbmFhZmdwaUU0OHo3WjQ5N1F6NkVXQzI2ZlluRlI4NXJjYm5kV3Q4UFZoVk1kbWV0YaNoMmViYjFjMmZqYmE5ZGE1OGFkM2g2Yzk3OWU1YWoxNzM3YjBmN2Q4aDkxNGM3NDE5ajZjMGE4ODhkNzBlbm9uY2VMgiJAdle-huUpDQ2L \ No newline at end of file +CoWZjdG4tdjGKWQGiglhAXK6LJ-9JgdpCjLi54ixA5OFBFp7vBU02xIDUImpOqQivENmMUTPlVBMItJicruJkQW9TFYGIgdU834Sc-cX0DqJhaEg0Ae0B7QETcXN1Y2FuL2RsZ0AxLjAuMC1yYy4xqGNhdWR4OGRpZDprZXk6ejZNa216WnZIQVhqWEN0QlJ2TFZhbWpBcmdOTUtXclpiQlozeXhlRmVSeTVic3p5Y2NtZGgvZm9vL2JhcmNleHAaaJIvt2Npc3N4OGRpZDprZXk6ejZNa3Q2NndmdXF5Zzd3RDdiS1VCQnhtbmlLOEFjY2dGYkpIZFo4U3hReHVGcG5uY3BvbIGDY2FsbGMuW12DYT5mLnZhbHVlAmNzdWJ4OGRpZDprZXk6ejZNa3Q2NndmdXF5Zzd3RDdiS1VCQnhtbmlLOEFjY2dGYkpIZFo4U3hReHVGcG5uZG1ldGGjaDBhY2E0NmVmajU4NDMyMWIxZWJoMWEzMjY0ZTFqMTIxMDg0OWM0MGgzYzAzZGJlZmphODI4ZTRmNjYwZW5vbmNlTKalaRQbcv4bIk1TTFkBooJYQEiwfwLY7-QP5CMQZZxZ43YFfownZz6nZ-jIiWSV40KCxlgrbFwI4SMqbZqGI-Liw6kzbpZDbYxM2gfz9euI7QqiYWhINAHtAe0BE3FzdWNhbi9kbGdAMS4wLjAtcmMuMahjYXVkeDhkaWQ6a2V5Ono2TWttZ0d1azhFQjF3NUU2Nm9WQWlYd0MxZE1UTTRNcnFRTGdjMlhkTFRpMzdFZmNjbWRoL2Zvby9iYXJjZXhwGmiSL7djaXNzeDhkaWQ6a2V5Ono2TWttSFJMaTh6Y0NXTTZTanVSOVE3eWlGc3d1QnRqZHlYTmd0TUZ0dFhodjkyZmNwb2yBg2NhbGxjLltdg2E-Zi52YWx1ZQJjc3VieDhkaWQ6a2V5Ono2TWttSFJMaTh6Y0NXTTZTanVSOVE3eWlGc3d1QnRqZHlYTmd0TUZ0dFhodjkyZmRtZXRho2gxNjk2MTc3OWpiMTVjMjNkODM3aDkxMTRkODhiajkxZWYwZjBhMGFoYzNhZGJhZmNqZWI1MGIxODk2MGVub25jZUw1LGc2wZfkb6IbLW9ZAaKCWEAWLLHLuchRVuT6He5PokIoGcpkDmCD8WSdTYFxIT-owTrprc-XR2bVF_KmVr_dnA7KDIUhyEv4c6WoO_euiAsMomFoSDQB7QHtARNxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1ra0ZyZkE5b2tQclFueHhrN2JMTUFWZUw0RkNwUHZwZDhvWWhVMW5OdDR2d2ZjY21kaC9mb28vYmFyY2V4cBpoki-3Y2lzc3g4ZGlkOmtleTp6Nk1rblk3eG1zaDQ3R3UxNkVKNDV5amF3YXdGQVZmYWVSN2hDVXFGYXpOUkJBU1ljcG9sgYNjYWxsYy5bXYNhPmYudmFsdWUCY3N1Yng4ZGlkOmtleTp6Nk1rblk3eG1zaDQ3R3UxNkVKNDV5amF3YXdGQVZmYWVSN2hDVXFGYXpOUkJBU1lkbWV0YaNoOWRiNTk5M2NqYWYwMTg0NjkyOWhiNDY0YjI3OGo1NGY1YjI3ZTIxaGYzNDNmYmEyajA5YWVhZGJjYmRlbm9uY2VMFp4p-yZ4Ogcmi0vIWQGiglhA1zTngEaE-B2DWSRtYnTIVBw8B_hvjK-Xo1HJZJBmTor-ebgmRED4VSEO6ALSnJV94w0UVE5xtYIaFXMTWD0ABaJhaEg0Ae0B7QETcXN1Y2FuL2RsZ0AxLjAuMC1yYy4xqGNhdWR4OGRpZDprZXk6ejZNa3NTTnQ5WVZUYnBheEZFNFJXUWsyQUpUYjFZNDZKTmNaY2ZvRHF3b0dUQnMyY2NtZGgvZm9vL2JhcmNleHAaaJIvt2Npc3N4OGRpZDprZXk6ejZNa3dNd3VjQjQ1MXZ0MWVxMTJzRERWeUx5WnR2RHM3TmoxMVlNQ0pLUVF3UEx3Y3BvbIGDY2FsbGMuW12DYT5mLnZhbHVlAmNzdWJ4OGRpZDprZXk6ejZNa3dNd3VjQjQ1MXZ0MWVxMTJzRERWeUx5WnR2RHM3TmoxMVlNQ0pLUVF3UEx3ZG1ldGGjaDg4MmJmZTdlajg2NjVjZjRhZDNoYWE4Zjg0ZWJqNjEyZDA1YTBkY2hkZmMxM2ExOWpmY2NkNGFmNjM5ZW5vbmNlTAJEDRnTi6GKtY7R6lkBooJYQL4aUlU_8vy0StepejrIgZyVdJaBitXDohffD2K31q8h47gTEIFGTpiRXLPVFNClpcfq8vqz7tY4s4aFkfaf3gKiYWhINAHtAe0BE3FzdWNhbi9kbGdAMS4wLjAtcmMuMahjYXVkeDhkaWQ6a2V5Ono2TWtuSmNrRVE0NzJzaW1lZDI5M3VFVDRmTVNLa1hIekpNR0FGNndodzJiUlVxcWNjbWRoL2Zvby9iYXJjZXhwGmiSL7djaXNzeDhkaWQ6a2V5Ono2TWtyTkFmNWlKc3BLbzNYQW5NZUFyN3ZtR1VvaXU0Sk1YcVI4Qk5RdnAza0dpRGNwb2yBg2NhbGxjLltdg2E-Zi52YWx1ZQJjc3VieDhkaWQ6a2V5Ono2TWtyTkFmNWlKc3BLbzNYQW5NZUFyN3ZtR1VvaXU0Sk1YcVI4Qk5RdnAza0dpRGRtZXRho2gzMTkxYzk5MWpjMmFjMGZiNGQ3aDNjMTVjODE2ajFiNWJkNzUwZmRoM2ZhN2Y3ZmJqY2NkN2EwM2E0YmVub25jZUxWk3ydedhXvgUkFh9ZAaKCWECJZ55_QKiJk3hKybyAvAEkiE51lyY2mNdGOfG7RTtkiQZt0l9O_-D-41Fq7qe-zeLcZOOb96n615aLCmwFqHIDomFoSDQB7QHtARNxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1rbXpZWUxIM2IzY1FUV3RSQ2JTdGRLSEhDNHBTRlM0bW15R3h0R3ZiVm5Qa3hjY21kaC9mb28vYmFyY2V4cBpoki-3Y2lzc3g4ZGlkOmtleTp6Nk1rdnJHREprakJ1RTF4UnVqYngzTTRwQ21oRm5RYUVxaVBzZndaNzZiOTVrNXVjcG9sgYNjYWxsYy5bXYNhPmYudmFsdWUCY3N1Yng4ZGlkOmtleTp6Nk1rdnJHREprakJ1RTF4UnVqYngzTTRwQ21oRm5RYUVxaVBzZndaNzZiOTVrNXVkbWV0YaNoOTM2YmFiOWZqMDcxNDUwMzRiZGhhMzg1ZGI3OGpjYWQ0NWFmYjVhaGI4ZWRlNzU5ajlmNzU3NGYzMzNlbm9uY2VMKkjI37EdjtTTE2K0WQGiglhA5BhIT_LE47HO7eR1I5F0o4SsBb8DulP9ADLQLAbINm3-w8u_tsuO1F8JIwBNgra3k2djQgsHN7wFf4eikBd0DqJhaEg0Ae0B7QETcXN1Y2FuL2RsZ0AxLjAuMC1yYy4xqGNhdWR4OGRpZDprZXk6ejZNa3ZGdkFRM2ZuZTVLeWE3MVM5R0RyYnRxM0pFVTQ0eEt3OENXZ29wUTVmRzl5Y2NtZGgvZm9vL2JhcmNleHAaaJIvt2Npc3N4OGRpZDprZXk6ejZNa25ZcE5mZllhUHg1OVhhb1JVSnFyb2N3WThuTFRUdllpdnRoWTZiWXdKVmtHY3BvbIGDY2FsbGMuW12DYT5mLnZhbHVlAmNzdWJ4OGRpZDprZXk6ejZNa25ZcE5mZllhUHg1OVhhb1JVSnFyb2N3WThuTFRUdllpdnRoWTZiWXdKVmtHZG1ldGGjaDZjODdjM2RkamQzNmUzMjFlMGVoYjQzZjdlZGJqOTkyZmY2YmI1YmhmMzI1ZmJlYWpiYThmZGMxZjEzZW5vbmNlTIkknZW6tK1-EdreVFkBooJYQKyH4lVF6wSWRtLC5rNeMG93E9szx0tQ752O0A33oY7AWiyCmooVQ2QcwvNO4eYAhZ6O07UnT9cjRMJEJhh8VQiiYWhINAHtAe0BE3FzdWNhbi9kbGdAMS4wLjAtcmMuMahjYXVkeDhkaWQ6a2V5Ono2TWtxS3oxeVo3WHk2UndUZDlQZ2VuN29DWGh2SHRTM29wTlNCUTV4aHRUd0h6ZmNjbWRoL2Zvby9iYXJjZXhwGmiSL7djaXNzeDhkaWQ6a2V5Ono2TWtzTFlUMk53V0hTZ3pYTFZ2d291cGM0OTZ3Ym1mc0dac0NtWWdtdThlZlJoa2Nwb2yBg2NhbGxjLltdg2E-Zi52YWx1ZQJjc3VieDhkaWQ6a2V5Ono2TWtzTFlUMk53V0hTZ3pYTFZ2d291cGM0OTZ3Ym1mc0dac0NtWWdtdThlZlJoa2RtZXRho2gxMmZjNjdkNmpiYmQ3ZDZiMzlmaDdmY2IyZGQxajIzOTUyMmRkY2NoYjU3NzA3YTVqY2M5ZjE2MDU0ZWVub25jZUwyFq7E45CwN9A_5e9ZAaKCWEBkB2rGLezpJf2uyxS71bzCTucR4-WM-Jl13g_jLXAoiBBn7J6y6Ueak050Nm_2St91WQpXkCq8IQIwUqvCtCoComFoSDQB7QHtARNxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1rcHhBWkN6Z0xWa0Y2Zkx2RzdDSmdIRlUzSG50aHZnWE41d2Y5M3FiZnNTV1ZjY21kaC9mb28vYmFyY2V4cBpoki-3Y2lzc3g4ZGlkOmtleTp6Nk1rbXk2aUxjWEpOdlYycEpyWU03WE52VTZRbVFFVFVZbVZ1dUhvd1VkWTlkSFJjcG9sgYNjYWxsYy5bXYNhPmYudmFsdWUCY3N1Yng4ZGlkOmtleTp6Nk1rbXk2aUxjWEpOdlYycEpyWU03WE52VTZRbVFFVFVZbVZ1dUhvd1VkWTlkSFJkbWV0YaNoMmY2ZjcyZWRqYmE3YzMzMmZmZWhkNDUyYjFkMWo1ZGM5MDgxMDhkaGQ2NDIyNzQxajg1ZGQ1ODExMmJlbm9uY2VMk3PNrYZB3Hz0inGWWQGiglhAF2lX0RhdPOAhwR0O_peTUIZJLRoWYrzNSGTMO9aATJJ8gUvQvwY6K2WDBifwzFo6Wn_FfVNYdwDj9LmvpcTlAKJhaEg0Ae0B7QETcXN1Y2FuL2RsZ0AxLjAuMC1yYy4xqGNhdWR4OGRpZDprZXk6ejZNa3NIdWtwZXBBM2Z3cmVlbm9KaGU5MWdaaWtHWG95VjZ4NFZHbTEzYXQxazJFY2NtZGgvZm9vL2JhcmNleHAaaJIvt2Npc3N4OGRpZDprZXk6ejZNa2dveTFRYnBUcm1oOGhadXRBVVB0cU14cW9rWXZOb0RDUUh1MkNCdUU4MnNKY3BvbIGDY2FsbGMuW12DYT5mLnZhbHVlAmNzdWJ4OGRpZDprZXk6ejZNa2dveTFRYnBUcm1oOGhadXRBVVB0cU14cW9rWXZOb0RDUUh1MkNCdUU4MnNKZG1ldGGjaDAyM2YxYjEyajAyNDkzZjhjYWFoMmM1ZjQ1ZGJqNzllY2M1MGM1MGg5MDFmNWI5OWpiN2JlODk4YjI4ZW5vbmNlTDz3ETxDC8vlSUNQBA \ No newline at end of file diff --git a/pkg/container/containertest/Base64URLGzipped b/pkg/container/containertest/Base64URLGzipped index 4c43905..72a392c 100644 --- a/pkg/container/containertest/Base64URLGzipped +++ b/pkg/container/containertest/Base64URLGzipped @@ -1 +1 @@ -PH4sIAAAAAAAA_5zWa5cUxR3HcVcRiejmuCII3siKwgnubnd1dVW1eIS5rzM9w8zs3HZETFd19_T07PTcZ2cH1KMgoB41YgIo3nM0G1GCRhCRiILIEaIhIEo0Bi9c9ewaFfEazYMd8iCPdvIGvk8-p_71e1RnZaujyt_e2_LQLYk5Fbb1QefFR9-_5LzWO59-9PfWoWV_nN_f177z06eH31j13Je8-Wpk35bTccKjtV_22MRfnz9DufuSg8Ntn02KzZtw83sLxj-mGE441FIoVZhidal9qTl8J9fJdRRZJz_IlIpaI2pavTKjDVxZR_5MQXa4aFIFgr-gMCrrOTWUqWNajNZERzin0GLRz7IxsTcfAgnGsqrRpedyXVQpMq2Wn5K68dmLWLpU-p9msRbQ-usuHEsGorZK0BbwxWzxvCdrhDK2vL23UMCRTM0RlStVxPK5vpsXMaWvj3Vee90i5Wq9s6r0VbRTWalC__-smtXKyu8MERNOwJSZkCACeAFgzkC6xGkYAhOLqkJEiBXJkJAuCUBUTMIA4KEgAEWzchbT5DXHfxwc7LiqNnPmRwdHgBa8NO6jDQ9uvW6wa7DHYetfP3DxO4s7JhybLa1YcerUV-Yae7aDww_P2_zjvH9euWqOOW3yjBWtO2__bKzLvfnR_enEpmaBMtFuy4qEsgrlqRMpPm86mql6apjI4V63V_bFgl5WT-USpQhDowVK2amiFmM8tEUsiRJcCeowHM9AvVQreLGE83LMkcBBI99dAE0ANZNtAGFewJjwkilBJPG8TphoKEQhmihKpsgBXuIVhXEGRRQpRGAmhzkRqIpOaQNo4afuoTWTj60cfjw5fQQoxy98ZPGmF3YsWLJo8voJ587Y9-X38geyLBq_nHXZIy9fPun5m1pebqVzv7J-NuaM08XEzYl3v3kmtfuCr2Yc-VAa3vtxS7NAnpKSKsBEzVaMphWdFB0kgNSEgHpwiPe7a0qaxYtVG_SVq_7RAhkey-asYmfUZ1XKMbGSr-Vo1UZ60rZyNV6Uy8l8MY_iES1ic0abAGom2wCCEqcLVFRNpEKBaghAaCBJUYgKOVNVGMQCUyXRQBqFTJWwKQkIIoZFQW8AvZV64bRDez_6flYbbmu8oDa_euu2yJB9w1vX3uO-YrZvobj2yK07V7-1YebjrRcgbsvS4fiyJ9_gpx4KvT5n_A7PTz-cqF_asuuaoTFnn2N-bbU2CaSHi0bJlrEi3kyh6NFrgqOu59VKOJ2t9Xj4sllT4wXqJdFQfzI2aiBvIGSG_Zls2IsDSdKblRV3QlQz2X7Z2evudVBk16QIM1yiCZsBaiLbAOIEnROQppu8AjgKiKqIhgQVwDQCTCKJkqCIBIqGpoicCilvcoxDWJewcPLE3TD0fHzb0y_BrtRd2gjQN3fd--36ju_CYzuV8adcsOeA95UvVv-09N1t05_bN7DllouWTN-18r4nTm-9Y8uZ2L02fj1XLizHlzyfrZ-x65Pt503b0uyJs0oDhpWuSh4vwFpJjlcDciKRCbtQTzmvxkWrKIWCUQm51FomO1ogKyMLyXSPx0xHxKrixwFT7a9XgzUUTuedXgDi8XKmgGJmJOwMNQHUTLYBhERGkE6YCTXEYYAYxxuE5xGnCbopAkWjAtCgbhCMKAUQmQqkvA4wJaQBpNyhPfDyK9Ijs-yOv40ArTv_hoMtSbB12NjtzD1Ef35ow47k_D3frn41f-2LX6YmdTxzzba3t180_7XFV5m-fz304tj2Td-t7Nx_oblszv7ctI2Hmz1xhayl1myOkhEOxUt2S_S4shFvMI7dIbseyPa4AlalJ8q6g2KhGBktUJGVfQEaSsXtsK7EnXnC6zIP84ZHrYUyGR9vcxXj9lwuaIvG7E0ANZM9-QcBHkNCNFMFEKhYFTRiSBoUOV0RTE3DKmWMCJKhijzgeJWakgoIwyLUuAZQSlq-Y177mBOSHt49AjRF-PBAe9d1H3ffcvyZczrHLAhP9X3jC5y797YFa-mNxYl_evDqo4fu_8NZh3d88un1R1f_5cfBf8_76p3tv_psyooll_k-nj2mWaC6b8BCmVrCytYjIFZKF1wytmUFKdijVuoCLIdrBV8dk3AxbIwWqJRAkpyRMnkY9ReLcipX8PR3u6RcrheykFINGCCc7-lJ25LMpjUB1Ez25IljDHFYpCYUiUYR4yVkUMKYIEiSiTDBSFcRgAajPAOU6ibjmShBToOwAXRf-6V31zceuXHdjHV9I0D7Jn7wgXzr4TVX_-PYw_mpLatO69_qW7R1Q-m8o9OcsGP2rM_f3lM_3n0_-aL18zWHV-eHzkik9r4_LriMt16a98Tm889sdiTASDqRwFLW3evj6_mU6i96cqInGEY4Ea0F1brlsPUXJSlCrcpogfRCzGll1YKRsqXrWEuVajq21wK5buKv5FxOV7wQy4Wz5Wwg3NRIaCbbABKopoi6BkymSSrTRCpSQ8UqEEQBmkTTBQp0VcSGBgAvYaiZCgQMUiz89wXdVtm7cNtjqvLmb5ZtHAHq2vfX9Uem2q-ZXTzw3oub0ruemj52f29hwuWeZ2_6_qylidcO5d9p3310-_wptTV3Dv1WXZzbuLsNDU2-dzDy7Sf84MxxTQKZAxWi5wO0Agci0WTOnStHklUpbPaHSi7JcsV9UbvH6_IHzHTVNeqRwLtlj6rV_T3ZehxGex2KLA3EXX4XhNmaGZdj-VjCRgy37HA4mhkJTWQbQBImhOkcbyIeQA1oiOcNBVBEdBWYlOc0IgBAREPnBYoABSavUAI0RhFuAM22T_nzs8NTTyz94YFVI0Bze_9-4utz3dvfW5B7fXL7uJWvr-1rO-uG5evusY_jlk-ynvzheOfE5IFIt4ieunAfO3bK-CWuX2w-0HbQP_fDi-8Y2NPsitNYLCfr2YLGEhrwg7LNoL3ZWKLSAzwDxNvNV_OA1L0oFVdToz5xuURswBupyoo7Ggua8Vg8kIjV5TLvcyCUDJsV7PXKuglTehn5mwBqJnvyBSEd6qpKTV5HCEOeU4mBCJSwpImmIkBd4BRGoUEUHUlMQ6amQVVVJB2CBpBwxRsH-9-cvnYnOfvd_wQAAP__hMJ751MQAAA \ No newline at end of file +PH4sIAAAAAAAA_5zW65MU1f3HcS7-hB8igpfIgqUxCqLC0tfTfUADMzs7M87ObubaOzMEsM-lp6eb6Zmee49GvEKwVBQRgygIUVHLCwoqoJAAikCQaJRICCqFGPCCcXVFoaBMJbukKs929h94P3nV-ZzvSg2XrEkV9u7kwFW3J6bv7bj7tflfrjm4e8_grc7Dke4jPx6c_Mm87olH_O9Of35_59-X7z2xe056dKx7156F074aOXzCcemCRe-Y4T3n3v7SNV-fdd4qVfcLA48NPDbwArtYxqo1mcxJT2ebmWZmUgE3s09jtUxqMsmQKSZ1ptRBu5lF0WK75ZbawpVO25NW2rLtfgG5XFZKtlwBr1GPVfyKU9YjZS_BOEv0yVouNxmpBUxr-TH6osmv4Uyx-L9NM5PUWqLtmqTohbQnkWp1i5JlxiOWLxAFAdaJeU13Z0gwWsN2AOdzc267A6tz5uDmGTPvUH-pNVfUOWU6CBfLqP9ZkqUl9fc6w3KqRmTVUDWGB1BiiKoDCBhJptRABAuCxrJY0zHPQBZjbLCY8hKCVBOplbMwDXbdsO9O4ZT5m20fTPywBymh3HfTBjDl5MzlT65xpm15kC4-f_2hlTtKyQUbrj78wBPfjn1e3T9i7OmuEfmt25d4z_q2K_0H36lRiw_9NbK0Szy0d3A_kPKuFk6qOYqVTSCj2uGNknxdT0BN0Etlqklxr8QaSqzF468oQl-R0oo7rztKQaK5crqzmMq7vOV4uh4jFZ2zPIrfFL0hS_ZYOFikDSA1ku1FAqJEZIRUA2gMy0OeY4EOKGVlHmCDIgZKKhYhp2NKGQR5YvBYZAWVp4j0Io1b4N905xU_e_SJj1-4pAfpbefa207fnMit_9XP39xxw7D3Fk0bH7vs09W_3uwcG3Vk5Nxv14yYP2Zj7lLPQ01Nnw0bsmXTssuZprL6-dX3zB3U9NH9q8_tB1KhgwUG8gA54HH5OcMyW1vqjmLnO11GNB0Ph6ut8WI1zAbdSMv2FclKhWK2riCS9trFvDvmd3tC0bpo8SAeC5QExZfiO3LeIOuKePkGkBrJnkEiWJYlnjEg1nhERSKouowIUgEvGUTGRBN5Ims6QiyVZVUwNIp4GUNOxr1I199x4OH_y6103Q-3DOhBuhYw1x1Y9eHYjejREfahp2Z9SNaqo83Xb0yff-mFr3_srFg7at3FV2aEy28atv2p8zbc-313YOQ3y65gm1Z9MHzdipHm0H4gFYmaLrQGWjpFLp4ICmagamWKHI560tlAsoa1uNcotoQKWj7fGuvz3Ck1v5hJgvZQJGYIKTlcFrypWocVLHPuEC_oWa2e0M3OVsen-BuZuwayZ-YOckQARDJ4TLAsChqUdVHVOBkA1pA5GVKGkaiqA04CDISiIcoUMhRjCHuRmjJraxO7f_ji-PiTE3pf0g83F4Zc-hF4-7uTV4XPG7xw986TC__2_qlnjrf9OLDrrKfeXioPGvtN0-NHRv8OHh7_5fzP1V3Lt40Zar-z-c3Vtx5O54b0AykTCrGsVS1iKmkdapQ1q6lqKWkV2gD1J3MIY09SlHw5O6yHgn1FqnoTLU66YobsbASoKq46rmoka2c8LomNkHBFYH2VVldNa-GTQgNIjWR7kTiVAIYRsYEFTcMCgpDqogw4TFXGwKqmYaACRtMJ4ClmEDAQFaHAYAbSXqRXxt9z8fIVxXOXjpjI9SDtXIkK6MJ3T6xbv-WuN7azi9K8UGl5a1t056x9G6fgxJJ5g03lSBk_O2juXV0Lnh2kVHfIwcqrKw-9dboId5X-eU5__iRPLhyxMsF03C9ZnWYKtRfZajIbUDjb68k7XFG2UL5adKesKOwrku42qkgrRaK2lI1jYJaMelnpaLf9RhW0sfmUrjk-FymaAcHBDSA1ku1FYjVeBBpGBqUCpjIUKdI5TuAwwqqhiQAAyvAQ6BoDBCgiwSCizMsSQhzfi_SP-2K_-PGE9saxTzMze5Dy-z0P7Di679olRys3fzdIXbZgbpvy0Krm5oXnnP_1w9yzj0yF8_64bCjzW2H22feEv48NLk6_8UD32fWPNvlf_CS18OUB_UDSE1WcaNUKSsqx_SjA-zNeLYI4T0cybfM4pbMg4AknnbbOetjqK1K-blcKUt4DWcNrVBzBIiJ2fGE7W8gCKZbI4WhBy4KkP9MWhA0gNZL9LxJLVMQhA_KEkTAjEkbnBZFILMQGQRLPi5gSpAOqEShqqoFFWZA4jCHoRRLeO9XcMqtwy7p35cd6kIY99snirRBtnvqcHN9benz4hCuG3LJt9bafZki7thTP_mHpi5PGXfbY6N1Nm68Z992tLD51S-q5DR98dsnhAbNSNzwZvOr_-4FUTdpy0XIjlg0nZSHkqaneUBVUCylgZEtmwQ3LhZrhR3WtkrX7PHegSpISVKtKuCYFyu11s5pK6FHbR112BNtsIZUOt1fSHVIuLzYydw1kz8ydoGqUF4nBizIHZYFyog5ZLHCU0QwEOZGROVEiusr824blDCgBSSIMgGdO8ClPP7KYPJnsQIeKG3uQrnz5teFvvD98hrrOc3nrmK3rn9s_-09PjBzaddOwxDl3Hz1xfEx810uPhvYcbL3sL9dNWjnuxamjXnCFEheAP29i5nXf3tGf6y7r6qwrJZfHlLyGLCvuWCf05Qp6JGDYBaNWqnvS5bKN_VRBVaWvSDnJBG4lHBEAl05yIccVIHZabmmLBttdobSjaKY3FRY9alvY42oAqZFsL5KKCAaEQkMlokgpyzKijhlRpaIoGZClCLCU1ahOIGQhFWSDQwLLqkhlzrwkvOH-ScEtSw68Omr87B6kpYWRa185WbvuC8u8aMC0i1pXbHeO72P9982fsHhh2xbf8WGe0y5Zq-wAk3YenZ05evG93MzVAx78aXJlxr1r2hce7A9Srqh6jIIVjNU7INENUg7Tqmz7tFBb2pfy-oq6zxuOOO0kWo27-3yC58tCwi900DxOtpk-k2txFCfuCGKllnOscqVk-W0N1dmoFcw3coI3kO1FElVWYhiiGhzgCS-xPES6zFKVAZxgyIAXJZWjAOsygppAEG_8Z-wIQZzai7Ri5eyp3V8981nL9fET_woAAP__svLMp3sQAAA \ No newline at end of file diff --git a/pkg/container/containertest/Bytes b/pkg/container/containertest/Bytes index 32c6d7ebf0c58d879d4e70b572404ed0ab735277..c256776f93a3602ec7b4d509fa1642c07b36ed05 100644 GIT binary patch literal 4220 zcmbW)X^<4<83%A62(lI+8m(j%5Rf3^?)LTefdrY^x$HTdnVnlScE5f1&h$)A_gpa| ztcqGH2n8sL36MkxDvAe$HL=i=!>B8ViV)GnBP)s&i4aXnO;_#sA>Vek`dfF`|3m-k zdES37+9*M*&{09}&5qu*EVJm9Q6InZ^5DF}np>xQ`1Ovb2G;$F?6jW0V9%?2ZoT7b z#y4+p?BQ`*^tUHgz5e!#FO*D}>X_zVzUSs+zq#-BfzOS(OFzBw*N42L z*3BH)8W?-+!8?>k|MKG{2X_`1Sd-w4&G7#IjpvU9N%Xt(g3G5&29KB=!R9bwx0%m_SyaGcf2}2fPH%FK6CTp%Au*h zdnUNdT>tSChn_q-eewa~q9;#u^t2U^)&6;ZKRwX+V9W@RO7&VbkuTOlK~rNAi3Veb zT?Q64eI8%6Vo^yxT_O?*56)I{#&D6Wio(Vt&Ln5#vYXUxE#oC?i6U)9(OB7F(m{+e zdC{YI^4*CRkXngtBB7k4#7mrpiG+kBJT5_nz$ivQI7X955kUw@;)Eg*B;+8&XgH8i z0^%&DVMd+S7TCMB0pHRDTrN_pCG@7Z!v!+&w zi9G6NK_TidxLm1h3rMZRHjyw?IbBoRy!6+m&4GcdH~xH*?IOpL-462s#p zrU8i%P}F%%Xd)e^*RF^h$hNhO_H+#)xtW(HZIHjees^m7ON%%5U;6#?yXCR%r{=CQ z77ir7`P$lfuIJ$uQ=XnU`@+KyJa}eJ_4Ldm>*m~iVDICrkM4N}dvD?hki@#oxXHSR z8oFP}H)uuz{z4cKs?2h-5zUl{YJ6E65by!)5C+*g?s zbF;Ul&b+n%qT=AF!MQJ#MycL+_r11#eb=#>-xdGcaqZ+;`#d`@yq&GyIbj4ya!#nw zL8}^NycHV91DFz5^;p%zyP0^&lc1rNHWU1o$&0X$4le(JXc=##rUP`9~!%0^^yMH{`%sGD;0th09BZ|Obr~o+0 zxd%m3bf5%9;+^5bP)uVaXO&2#ye`)enh|U)?M$8TPS*G&HnxIXis#^$vM}&AN}%Q!Z-5P zdrn?HX#_~6SiHyJf-a+;%f>`C70-1;Z?zsN`vbLf9n0%cGpOW4M95a1E<3ymF2y3n znquo}I!C%1Caq?~bT(3}1*&dCNo#yQ2Y|vQ)7~IeYyqj2*dLH2K$8SbYK+Knh#>M5 zstAxqNSXo~PVpE55QIk*iGrd4NM{8i6bdls3ExDTcx2bW`TJisuh{qcgdrrLpZ9bT zKRsz%;KW^j)t~Cyb#jUR%9M}y3NLGuXWrocI)L;&0KTexkU#Po9}rq zv1P-H?c)c%m-UYXN%O^U!_G+@jj}=`N5K(AU0t_cX%_->;CNT(4G?8{J^uGD`@g~|g_3&%WN%FiE zl_!s(rp;Y*$^LzzMbYZy;)Xb$Nj$dsZ@v55KAW*(-jly*iydCP{79y9^AiJ`itMV< zxw$m*2mISdkK!Y#;7X$>rRm*iLyPd$hKgk?xH}~GunA8%62WUhX!`SpnW-eP3OQUP zjm6U>N2ha{oNeJ;CeDLm8WI6BYpFdHP$(A<%9>qICSA1_kXngtB4McWj|wqf6QKYI z5p({Q6cTZc9}M6cDmWsHv)l!RmM8`TfYeBVbLt?#_#f8YnNnfax#eBgUwqp5$NvC) CDkO6N literal 4180 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 G5C8y~7K5t* diff --git a/pkg/container/reader.go b/pkg/container/reader.go index c96bf58..82c368d 100644 --- a/pkg/container/reader.go +++ b/pkg/container/reader.go @@ -142,12 +142,29 @@ func (ctn Reader) GetDelegation(cid cid.Cid) (*delegation.Token, error) { return nil, delegation.ErrDelegationNotFound } +// GetDelegationBundle is the same as GetToken but only return a delegation.Bundle, with the right type. +// If not found, delegation.ErrDelegationNotFound is returned. +func (ctn Reader) GetDelegationBundle(cid cid.Cid) (*delegation.Bundle, error) { + bndl, ok := ctn[cid] + if !ok { + return nil, delegation.ErrDelegationNotFound + } + if tkn, ok := bndl.token.(*delegation.Token); ok { + return &delegation.Bundle{ + Cid: cid, + Decoded: tkn, + Sealed: bndl.sealed, + }, nil + } + return nil, delegation.ErrDelegationNotFound +} + // GetAllDelegations returns all the delegation.Token in the container. -func (ctn Reader) GetAllDelegations() iter.Seq[delegation.Bundle] { - return func(yield func(delegation.Bundle) bool) { +func (ctn Reader) GetAllDelegations() iter.Seq[*delegation.Bundle] { + return func(yield func(*delegation.Bundle) bool) { for c, bndl := range ctn { if t, ok := bndl.token.(*delegation.Token); ok { - if !yield(delegation.Bundle{ + if !yield(&delegation.Bundle{ Cid: c, Decoded: t, Sealed: bndl.sealed, diff --git a/pkg/container/writer.go b/pkg/container/writer.go index a8ca0ff..1ae73ec 100644 --- a/pkg/container/writer.go +++ b/pkg/container/writer.go @@ -73,12 +73,12 @@ func (ctn Writer) ToBase64URLWriter(w io.Writer) error { return ctn.toWriter(headerBase64URL, w) } -// ToBase64URL encode the container into pre-gzipped base64 string, with URL-safe encoding and no padding. +// ToBase64URLGzipped encode the container into pre-gzipped base64 string, with URL-safe encoding and no padding. func (ctn Writer) ToBase64URLGzipped() (string, error) { return ctn.toString(headerBase64URLGzip) } -// ToBase64URLWriter is the same as ToBase64URL, but with an io.Writer. +// ToBase64URLGzipWriter is the same as ToBase64URL, but with an io.Writer. func (ctn Writer) ToBase64URLGzipWriter(w io.Writer) error { return ctn.toWriter(headerBase64URLGzip, w) } diff --git a/token/delegation/delegation_test.go b/token/delegation/delegation_test.go index 09dd312..5fde690 100644 --- a/token/delegation/delegation_test.go +++ b/token/delegation/delegation_test.go @@ -6,12 +6,12 @@ import ( "testing" "time" + "github.com/MetaMask/go-did-it/didtest" "github.com/stretchr/testify/require" "github.com/ucan-wg/go-ucan/pkg/command" "github.com/ucan-wg/go-ucan/pkg/policy" "github.com/ucan-wg/go-ucan/token/delegation" - "github.com/ucan-wg/go-ucan/token/internal/didtest" ) //go:embed testdata/new.dagjson diff --git a/token/delegation/delegationtest/generator/generator.go b/token/delegation/delegationtest/generator/generator.go index 4f26639..b9bcb83 100644 --- a/token/delegation/delegationtest/generator/generator.go +++ b/token/delegation/delegationtest/generator/generator.go @@ -12,6 +12,7 @@ import ( "github.com/MetaMask/go-did-it" didkeyctl "github.com/MetaMask/go-did-it/controller/did-key" "github.com/MetaMask/go-did-it/crypto" + "github.com/MetaMask/go-did-it/didtest" "github.com/ipfs/go-cid" "github.com/ucan-wg/go-ucan/pkg/command" @@ -19,7 +20,6 @@ import ( "github.com/ucan-wg/go-ucan/pkg/policy/policytest" "github.com/ucan-wg/go-ucan/token/delegation" "github.com/ucan-wg/go-ucan/token/delegation/delegationtest" - "github.com/ucan-wg/go-ucan/token/internal/didtest" ) const ( diff --git a/token/delegation/delegationtest/generator/main.go b/token/delegation/delegationtest/generator/main.go index e5d5fca..09618f4 100644 --- a/token/delegation/delegationtest/generator/main.go +++ b/token/delegation/delegationtest/generator/main.go @@ -1,7 +1,7 @@ package main import ( - "github.com/ucan-wg/go-ucan/token/internal/didtest" + "github.com/MetaMask/go-did-it/didtest" ) func main() { diff --git a/token/delegation/examples_test.go b/token/delegation/examples_test.go index 7537498..fdf2b2a 100644 --- a/token/delegation/examples_test.go +++ b/token/delegation/examples_test.go @@ -8,6 +8,7 @@ import ( "fmt" "time" + "github.com/MetaMask/go-did-it/didtest" "github.com/ipfs/go-cid" "github.com/ipld/go-ipld-prime" "github.com/ipld/go-ipld-prime/codec/dagcbor" @@ -17,7 +18,6 @@ import ( "github.com/ucan-wg/go-ucan/pkg/policy" "github.com/ucan-wg/go-ucan/pkg/policy/literal" "github.com/ucan-wg/go-ucan/token/delegation" - "github.com/ucan-wg/go-ucan/token/internal/didtest" "github.com/ucan-wg/go-ucan/token/internal/envelope" ) diff --git a/token/delegation/schema_test.go b/token/delegation/schema_test.go index 33f6a01..7127755 100644 --- a/token/delegation/schema_test.go +++ b/token/delegation/schema_test.go @@ -5,12 +5,12 @@ import ( _ "embed" "testing" + "github.com/MetaMask/go-did-it/didtest" "github.com/ipld/go-ipld-prime" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/ucan-wg/go-ucan/token/delegation" - "github.com/ucan-wg/go-ucan/token/internal/didtest" "github.com/ucan-wg/go-ucan/token/internal/envelope" ) diff --git a/token/internal/didtest/crypto.go b/token/internal/didtest/crypto.go deleted file mode 100644 index 9836d4d..0000000 --- a/token/internal/didtest/crypto.go +++ /dev/null @@ -1,139 +0,0 @@ -// Package didtest provides Personas that can be used for testing. Each -// Persona has a name, crypto.PrivKey and associated crypto.PubKey and -// did.DID. -package didtest - -import ( - "encoding/base64" - "fmt" - - "github.com/MetaMask/go-did-it" - didkeyctl "github.com/MetaMask/go-did-it/controller/did-key" - "github.com/MetaMask/go-did-it/crypto" - "github.com/MetaMask/go-did-it/crypto/ed25519" -) - -const ( - // all are ed25519 as base64 - alicePrivKeyB64 = "zth/9cTSUVwlLzfEWwLCcOkaEmjrRGPOI6mOJksWAYZ3Toe7ymxAzDeiseyxbmEpJ81qYM3dZ8XrXqgonnTTEw==" - bobPrivKeyB64 = "+p1REV3MkUnLhUMbFe9RcSsmo33TT/FO85yaV+c6fiYJCBsdiwfMwodlkzSAG3sHQIuZj8qnJ678oJucYy7WEg==" - carolPrivKeyB64 = "aSu3vTwE7z3pXaTaAhVLeizuqnZUJZQHTCSLMLxyZh5LDoZQn80uoQgMEdsbOhR+zIqrjBn5WviGurDkKYVfug==" - danPrivKeyB64 = "s1zM1av6og3o0UMNbEs/RyezS7Nk/jbSYL2Z+xPEw9Cho/KuEAa75Sf4yJHclLwpKXNucbrZ2scE8Iy8K05KWQ==" - erinPrivKeyB64 = "+qHpaAR3iivWMEl+pkXmq+uJeHtqFiY++XOXtZ9Tu/WPABCO+eRFrTCLJykJEzAPGFmkJF8HQ7DMwOH7Ry3Aqw==" - frankPrivKeyB64 = "4k/1N0+Fq73DxmNbGis9PY2KgKxWmtDWhmi1E6sBLuGd7DS0TWjCn1Xa3lXkY49mFszMjhWC+V6DCBf7R68u4Q==" -) - -// Persona is a generic participant used for cryptographic testing. -type Persona int - -// The provided Personas were selected from the first few generic -// participants listed in this [table]. -// -// [table]: https://en.wikipedia.org/wiki/Alice_and_Bob#Cryptographic_systems -const ( - PersonaAlice Persona = iota + 1 - PersonaBob - PersonaCarol - PersonaDan - PersonaErin - PersonaFrank -) - -var privKeys map[Persona]crypto.PrivateKeySigningBytes - -func init() { - privKeys = make(map[Persona]crypto.PrivateKeySigningBytes, 6) - for persona, pB64 := range privKeyB64() { - privBytes, err := base64.StdEncoding.DecodeString(pB64) - if err != nil { - return - } - - privKey, err := ed25519.PrivateKeyFromBytes(privBytes) - if err != nil { - return - } - - privKeys[persona] = privKey - } -} - -// DID returns a did.DID based on the Persona's Ed25519 public key. -func (p Persona) DID() did.DID { - return didkeyctl.FromPrivateKey(p.PrivKey()) -} - -// Name returns the username of the Persona. -func (p Persona) Name() string { - name, ok := map[Persona]string{ - PersonaAlice: "Alice", - PersonaBob: "Bob", - PersonaCarol: "Carol", - PersonaDan: "Dan", - PersonaErin: "Erin", - PersonaFrank: "Frank", - }[p] - if !ok { - panic(fmt.Sprintf("Unknown persona: %v", p)) - } - - return name -} - -// PrivKey returns the Ed25519 private key for the Persona. -func (p Persona) PrivKey() crypto.PrivateKeySigningBytes { - res, ok := privKeys[p] - if !ok { - panic(fmt.Sprintf("Unknown persona: %v", p)) - } - return res -} - -func (p Persona) PrivKeyConfig() string { - res, ok := privKeyB64()[p] - if !ok { - panic(fmt.Sprintf("Unknown persona: %v", p)) - } - return res -} - -// PubKey returns the Ed25519 public key for the Persona. -func (p Persona) PubKey() crypto.PublicKey { - return p.PrivKey().Public() -} - -func privKeyB64() map[Persona]string { - return map[Persona]string{ - PersonaAlice: alicePrivKeyB64, - PersonaBob: bobPrivKeyB64, - PersonaCarol: carolPrivKeyB64, - PersonaDan: danPrivKeyB64, - PersonaErin: erinPrivKeyB64, - PersonaFrank: frankPrivKeyB64, - } -} - -// Personas returns an (alphabetically) ordered list of the defined -// Persona values. -func Personas() []Persona { - return []Persona{ - PersonaAlice, - PersonaBob, - PersonaCarol, - PersonaDan, - PersonaErin, - PersonaFrank, - } -} - -// DidToName retrieve the persona's name from its DID. -func DidToName(d did.DID) string { - return map[did.DID]string{ - PersonaAlice.DID(): "Alice", - PersonaBob.DID(): "Bob", - PersonaCarol.DID(): "Carol", - PersonaDan.DID(): "Dan", - PersonaErin.DID(): "Erin", - PersonaFrank.DID(): "Frank", - }[d] -} diff --git a/token/invocation/invocation_test.go b/token/invocation/invocation_test.go index 6d34a4c..72f798c 100644 --- a/token/invocation/invocation_test.go +++ b/token/invocation/invocation_test.go @@ -4,6 +4,7 @@ import ( _ "embed" "testing" + "github.com/MetaMask/go-did-it/didtest" "github.com/ipfs/go-cid" "github.com/stretchr/testify/require" @@ -11,7 +12,6 @@ import ( "github.com/ucan-wg/go-ucan/pkg/command" "github.com/ucan-wg/go-ucan/pkg/policy/policytest" "github.com/ucan-wg/go-ucan/token/delegation/delegationtest" - "github.com/ucan-wg/go-ucan/token/internal/didtest" "github.com/ucan-wg/go-ucan/token/invocation" ) diff --git a/toolkit/_example/Readme.md b/toolkit/_example/Readme.md index 54bfa45..282dcae 100644 --- a/toolkit/_example/Readme.md +++ b/toolkit/_example/Readme.md @@ -8,7 +8,7 @@ Please note that UCAN in itself doesn't enforce any protocol, topology or transp Your situation may be different from this, and would call for a different setup. -Remember that everything in `go-ucan-toolkit` is essentially helpers, pre-made building blocks. You can use them, change them or make your own. +Remember that everything in `/toolkit` is essentially helpers, pre-made building blocks. You can use them, change them or make your own. ## Scenario 1 diff --git a/toolkit/_example/_protocol-issuer/request-resolver.go b/toolkit/_example/_protocol-issuer/request-resolver.go index ff7497a..47db4fd 100644 --- a/toolkit/_example/_protocol-issuer/request-resolver.go +++ b/toolkit/_example/_protocol-issuer/request-resolver.go @@ -4,10 +4,10 @@ import ( "encoding/json" "net/http" - "github.com/ucan-wg/go-ucan/did" - "github.com/ucan-wg/go-ucan/pkg/command" + "github.com/MetaMask/go-did-it" - "github.com/INFURA/go-ucan-toolkit/issuer" + "github.com/ucan-wg/go-ucan/pkg/command" + "github.com/ucan-wg/go-ucan/toolkit/issuer" ) func RequestResolver(r *http.Request) (*issuer.ResolvedRequest, error) { diff --git a/toolkit/_example/_protocol-issuer/requester.go b/toolkit/_example/_protocol-issuer/requester.go index fa0db0e..a212578 100644 --- a/toolkit/_example/_protocol-issuer/requester.go +++ b/toolkit/_example/_protocol-issuer/requester.go @@ -8,12 +8,13 @@ import ( "log" "net/http" - "github.com/ucan-wg/go-ucan/did" + "github.com/MetaMask/go-did-it" + "github.com/ucan-wg/go-ucan/pkg/command" "github.com/ucan-wg/go-ucan/token/delegation" - "github.com/INFURA/go-ucan-toolkit/client" - "github.com/INFURA/go-ucan-toolkit/issuer" + "github.com/ucan-wg/go-ucan/toolkit/client" + "github.com/ucan-wg/go-ucan/toolkit/issuer" ) var _ client.DelegationRequester = &Requester{} @@ -55,5 +56,5 @@ func (r Requester) RequestDelegation(ctx context.Context, audience did.DID, cmd return nil, err } - return issuer.DecodeResponse(res) + return issuer.DecodeResponse(res, audience, cmd, subject) } diff --git a/toolkit/_example/alice-client-issuer/alice.go b/toolkit/_example/alice-client-issuer/alice.go index a6bee86..9531c02 100644 --- a/toolkit/_example/alice-client-issuer/alice.go +++ b/toolkit/_example/alice-client-issuer/alice.go @@ -13,19 +13,20 @@ import ( "syscall" "time" - "github.com/libp2p/go-libp2p/core/crypto" - "github.com/ucan-wg/go-ucan/did" + "github.com/MetaMask/go-did-it" + "github.com/MetaMask/go-did-it/crypto" + "github.com/ucan-wg/go-ucan/pkg/command" "github.com/ucan-wg/go-ucan/pkg/container" "github.com/ucan-wg/go-ucan/pkg/policy" "github.com/ucan-wg/go-ucan/pkg/policy/literal" "github.com/ucan-wg/go-ucan/token/delegation" - example "github.com/INFURA/go-ucan-toolkit/_example" - protocol "github.com/INFURA/go-ucan-toolkit/_example/_protocol-issuer" - "github.com/INFURA/go-ucan-toolkit/client" - "github.com/INFURA/go-ucan-toolkit/issuer" - "github.com/INFURA/go-ucan-toolkit/server/bearer" + example "github.com/ucan-wg/go-ucan/toolkit/_example" + protocol "github.com/ucan-wg/go-ucan/toolkit/_example/_protocol-issuer" + "github.com/ucan-wg/go-ucan/toolkit/client" + "github.com/ucan-wg/go-ucan/toolkit/issuer" + "github.com/ucan-wg/go-ucan/toolkit/server/bearer" ) func main() { @@ -49,7 +50,7 @@ func main() { } } -func run(ctx context.Context, ownIssuerUrl string, priv crypto.PrivKey, d did.DID, +func run(ctx context.Context, ownIssuerUrl string, priv crypto.PrivateKeySigningBytes, d did.DID, serviceIssuerUrl string, serviceUrl string, serviceDid did.DID) error { log.Printf("Alice DID is %s", d.String()) @@ -67,7 +68,7 @@ func run(ctx context.Context, ownIssuerUrl string, priv crypto.PrivKey, d did.DI return delegation.New(iss, aud, cmd, policies, subject) } - cli, err := client.NewWithIssuer(priv, protocol.NewRequester("http://"+serviceIssuerUrl), issuingLogic) + cli, err := client.NewWithIssuer(priv, d, protocol.NewRequester("http://"+serviceIssuerUrl), issuingLogic) if err != nil { return err } diff --git a/toolkit/_example/bob-client/bob.go b/toolkit/_example/bob-client/bob.go index 99b786d..feb7413 100644 --- a/toolkit/_example/bob-client/bob.go +++ b/toolkit/_example/bob-client/bob.go @@ -12,14 +12,17 @@ import ( "syscall" "time" - "github.com/ucan-wg/go-ucan/did" + "github.com/MetaMask/go-did-it" + didkeyctl "github.com/MetaMask/go-did-it/controller/did-key" + "github.com/MetaMask/go-did-it/crypto/ed25519" + "github.com/ucan-wg/go-ucan/pkg/command" "github.com/ucan-wg/go-ucan/pkg/container" - example "github.com/INFURA/go-ucan-toolkit/_example" - protocol "github.com/INFURA/go-ucan-toolkit/_example/_protocol-issuer" - "github.com/INFURA/go-ucan-toolkit/client" - "github.com/INFURA/go-ucan-toolkit/server/bearer" + example "github.com/ucan-wg/go-ucan/toolkit/_example" + protocol "github.com/ucan-wg/go-ucan/toolkit/_example/_protocol-issuer" + "github.com/ucan-wg/go-ucan/toolkit/client" + "github.com/ucan-wg/go-ucan/toolkit/server/bearer" ) func main() { @@ -43,14 +46,15 @@ func main() { func run(ctx context.Context, aliceUrl string, aliceDid did.DID, serverUrl string, serviceDid did.DID) error { // Let's generate a keypair for our client: - priv, d, err := did.GenerateEd25519() + pub, priv, err := ed25519.GenerateKeyPair() if err != nil { return err } + d := didkeyctl.FromPublicKey(pub) log.Printf("Bob DID is %s", d.String()) - cli, err := client.NewClient(priv, protocol.NewRequester("http://"+aliceUrl)) + cli, err := client.NewClient(priv, d, protocol.NewRequester("http://"+aliceUrl)) if err != nil { return err } @@ -69,13 +73,13 @@ func run(ctx context.Context, aliceUrl string, aliceDid did.DID, serverUrl strin select { case <-ctx.Done(): return nil - case <-time.After(5 * time.Second): + case <-time.After(1 * time.Second): } } } func makeRequest(ctx context.Context, clientDid did.DID, serviceUrl string, aliceDid did.DID, proofs container.Writer) error { - // we construct a URL that include the our DID and Alice DID as path, as requested by the UCAN policy we get issued + // we construct a URL that include our DID and Alice DID as path, as requested by the UCAN policy we get issued u, err := url.JoinPath("http://"+serviceUrl, aliceDid.String(), clientDid.String()) if err != nil { return err diff --git a/toolkit/_example/service-issuer/issuer.go b/toolkit/_example/service-issuer/issuer.go index cac7894..f3e9dcd 100644 --- a/toolkit/_example/service-issuer/issuer.go +++ b/toolkit/_example/service-issuer/issuer.go @@ -11,16 +11,17 @@ import ( "syscall" "time" - "github.com/libp2p/go-libp2p/core/crypto" - "github.com/ucan-wg/go-ucan/did" + "github.com/MetaMask/go-did-it" + "github.com/MetaMask/go-did-it/crypto" + "github.com/ucan-wg/go-ucan/pkg/command" "github.com/ucan-wg/go-ucan/pkg/policy" "github.com/ucan-wg/go-ucan/pkg/policy/literal" "github.com/ucan-wg/go-ucan/token/delegation" - example "github.com/INFURA/go-ucan-toolkit/_example" - protocol "github.com/INFURA/go-ucan-toolkit/_example/_protocol-issuer" - "github.com/INFURA/go-ucan-toolkit/issuer" + example "github.com/ucan-wg/go-ucan/toolkit/_example" + protocol "github.com/ucan-wg/go-ucan/toolkit/_example/_protocol-issuer" + "github.com/ucan-wg/go-ucan/toolkit/issuer" ) func main() { @@ -42,7 +43,7 @@ func main() { } } -func run(ctx context.Context, issuerUrl string, servicePrivKey crypto.PrivKey) error { +func run(ctx context.Context, issuerUrl string, servicePrivKey crypto.PrivateKeySigningBytes) error { issuingLogic := func(iss did.DID, aud did.DID, cmd command.Command) (*delegation.Token, error) { log.Printf("issuing delegation to %v for %v", aud, cmd) diff --git a/toolkit/_example/service/service.go b/toolkit/_example/service/service.go index f09d532..beb1f6c 100644 --- a/toolkit/_example/service/service.go +++ b/toolkit/_example/service/service.go @@ -9,10 +9,10 @@ import ( "os/signal" "syscall" - "github.com/ucan-wg/go-ucan/did" + "github.com/MetaMask/go-did-it" - example "github.com/INFURA/go-ucan-toolkit/_example" - "github.com/INFURA/go-ucan-toolkit/server/exectx" + example "github.com/ucan-wg/go-ucan/toolkit/_example" + "github.com/ucan-wg/go-ucan/toolkit/server/exectx" ) func main() { diff --git a/toolkit/_example/shared_values.go b/toolkit/_example/shared_values.go index befa737..468b00d 100644 --- a/toolkit/_example/shared_values.go +++ b/toolkit/_example/shared_values.go @@ -3,8 +3,10 @@ package example import ( "encoding/base64" - "github.com/libp2p/go-libp2p/core/crypto" - "github.com/ucan-wg/go-ucan/did" + "github.com/MetaMask/go-did-it" + didkeyctl "github.com/MetaMask/go-did-it/controller/did-key" + "github.com/MetaMask/go-did-it/crypto" + "github.com/MetaMask/go-did-it/crypto/ed25519" ) // Endpoints @@ -16,20 +18,20 @@ var AliceIssuerUrl = ":8082" // Service -var ServicePrivKey crypto.PrivKey +var ServicePrivKey crypto.PrivateKeySigningBytes var ServiceDid did.DID // Alice -var AlicePrivKey crypto.PrivKey +var AlicePrivKey crypto.PrivateKeySigningBytes var AliceDid did.DID func init() { - servPrivRaw, _ := base64.StdEncoding.DecodeString("CAESQGs7hPBRBmxH1UmHrdcPrBkecuFUuCWHK0kMJvZYCBqIa35SGxUdXVGuigQDkMpf7xO4C2C2Acl8QTtSrYS7Cnc=") - ServicePrivKey, _ = crypto.UnmarshalPrivateKey(servPrivRaw) - ServiceDid, _ = did.FromPrivKey(ServicePrivKey) + servPrivRaw, _ := base64.StdEncoding.DecodeString("HVcbgoj30c+7zoQzUgpl7Jc7bkXoyvo9bMX5OHaAohpv036EMxuWXGqmEWhFKHPEuRAaIGSURK8pyUYOAseiiQ==") + ServicePrivKey, _ = ed25519.PrivateKeyFromBytes(servPrivRaw) + ServiceDid = didkeyctl.FromPrivateKey(ServicePrivKey) - alicePrivRaw, _ := base64.StdEncoding.DecodeString("CAESQFESA31nDYUhXXwbCNSFvg7M+TOFgyxy0tVX6o+TkJAKqAwDvtGxZeGyUjibGd/op+xOLvzE6BrTIOw62K3yLp8=") - AlicePrivKey, _ = crypto.UnmarshalPrivateKey(alicePrivRaw) - AliceDid, _ = did.FromPrivKey(AlicePrivKey) + alicePrivRaw, _ := base64.StdEncoding.DecodeString("jIIk/4ZBgIzx7fU41AWYRUDjgQmgFTIXxN4WeZAPCjwE04oLfiHgNjwIIZi97a6WwSIL5tFGdkrqDkSmDx95tw==") + AlicePrivKey, _ = ed25519.PrivateKeyFromBytes(alicePrivRaw) + AliceDid = didkeyctl.FromPrivateKey(AlicePrivKey) } diff --git a/toolkit/client/client.go b/toolkit/client/client.go index 470c12b..6236ebe 100644 --- a/toolkit/client/client.go +++ b/toolkit/client/client.go @@ -5,9 +5,10 @@ import ( "fmt" "iter" + "github.com/MetaMask/go-did-it" + "github.com/MetaMask/go-did-it/crypto" "github.com/ipfs/go-cid" - "github.com/libp2p/go-libp2p/core/crypto" - "github.com/ucan-wg/go-ucan/did" + "github.com/ucan-wg/go-ucan/pkg/command" "github.com/ucan-wg/go-ucan/pkg/container" "github.com/ucan-wg/go-ucan/pkg/policy" @@ -17,17 +18,13 @@ import ( type Client struct { did did.DID - privKey crypto.PrivKey + privKey crypto.PrivateKeySigningBytes pool *Pool requester DelegationRequester } -func NewClient(privKey crypto.PrivKey, requester DelegationRequester) (*Client, error) { - d, err := did.FromPrivKey(privKey) - if err != nil { - return nil, err - } +func NewClient(privKey crypto.PrivateKeySigningBytes, d did.DID, requester DelegationRequester) (*Client, error) { return &Client{ did: d, privKey: privKey, diff --git a/toolkit/client/client_test.go b/toolkit/client/client_test.go index 5a310f5..541e1a0 100644 --- a/toolkit/client/client_test.go +++ b/toolkit/client/client_test.go @@ -6,8 +6,9 @@ import ( "iter" "time" - "github.com/ucan-wg/go-ucan/did" - "github.com/ucan-wg/go-ucan/did/didtest" + "github.com/MetaMask/go-did-it" + "github.com/MetaMask/go-did-it/didtest" + "github.com/ucan-wg/go-ucan/pkg/command" "github.com/ucan-wg/go-ucan/pkg/policy" "github.com/ucan-wg/go-ucan/token/delegation" @@ -21,7 +22,7 @@ func ExampleNewClient() { // requester is an adaptor for a real world issuer, we use a mock in that example requester := &requesterMock{persona: servicePersona} - client, err := NewClient(clientPersona.PrivKey(), requester) + client, err := NewClient(clientPersona.PrivKey(), clientPersona.DID(), requester) handleError(err) cont, err := client.PrepareInvoke( diff --git a/toolkit/client/clientissuer.go b/toolkit/client/clientissuer.go index 57afc75..4653fdc 100644 --- a/toolkit/client/clientissuer.go +++ b/toolkit/client/clientissuer.go @@ -5,9 +5,10 @@ import ( "fmt" "iter" + "github.com/MetaMask/go-did-it" + "github.com/MetaMask/go-did-it/crypto" "github.com/ipfs/go-cid" - "github.com/libp2p/go-libp2p/core/crypto" - "github.com/ucan-wg/go-ucan/did" + "github.com/ucan-wg/go-ucan/pkg/command" "github.com/ucan-wg/go-ucan/token/delegation" ) @@ -29,8 +30,8 @@ type WithIssuer struct { logic DlgIssuingLogic } -func NewWithIssuer(privKey crypto.PrivKey, requester DelegationRequester, logic DlgIssuingLogic) (*WithIssuer, error) { - client, err := NewClient(privKey, requester) +func NewWithIssuer(privKey crypto.PrivateKeySigningBytes, d did.DID, requester DelegationRequester, logic DlgIssuingLogic) (*WithIssuer, error) { + client, err := NewClient(privKey, d, requester) if err != nil { return nil, err } diff --git a/toolkit/client/pool.go b/toolkit/client/pool.go index 13603cc..71d9d69 100644 --- a/toolkit/client/pool.go +++ b/toolkit/client/pool.go @@ -6,8 +6,9 @@ import ( "sync" "time" + "github.com/MetaMask/go-did-it" "github.com/ipfs/go-cid" - "github.com/ucan-wg/go-ucan/did" + "github.com/ucan-wg/go-ucan/pkg/command" "github.com/ucan-wg/go-ucan/token/delegation" ) diff --git a/toolkit/client/proof.go b/toolkit/client/proof.go index fa6c701..14d557d 100644 --- a/toolkit/client/proof.go +++ b/toolkit/client/proof.go @@ -4,8 +4,9 @@ import ( "iter" "math" + "github.com/MetaMask/go-did-it" "github.com/ipfs/go-cid" - "github.com/ucan-wg/go-ucan/did" + "github.com/ucan-wg/go-ucan/pkg/command" "github.com/ucan-wg/go-ucan/token/delegation" ) @@ -23,12 +24,12 @@ func FindProof(dlgs func() iter.Seq[*delegation.Bundle], issuer did.DID, cmd com // TODO: maybe that should be part of delegation.Token directly? dlgMatch := func(dlg *delegation.Token, issuer did.DID, cmd command.Command, subject did.DID) bool { // The Subject of each delegation must equal the invocation's Subject (or Audience if defined). - 4f - if dlg.Subject() != subject { + if !dlg.Subject().Equal(subject) { return false } // The first proof must be issued to the Invoker (audience DID). - 4c // The Issuer of each delegation must be the Audience in the next one. - 4d - if dlg.Audience() != issuer { + if !dlg.Audience().Equal(issuer) { return false } // The command of each delegation must "allow" the one before it. - 4g @@ -72,7 +73,7 @@ func FindProof(dlgs func() iter.Seq[*delegation.Bundle], issuer did.DID, cmd com at := cur.bundle // if it's a root delegation, we found a valid proof - if at.Decoded.Issuer() == at.Decoded.Subject() { + if at.Decoded.Issuer().Equal(at.Decoded.Subject()) { if len(bestProof) == 0 || len(cur.path) < len(bestProof) || len(cur.path) == len(bestProof) && cur.size < bestSize { bestProof = append([]cid.Cid{}, cur.path...) // make a copy bestSize = cur.size diff --git a/toolkit/client/proof_test.go b/toolkit/client/proof_test.go index cfca2c2..c729418 100644 --- a/toolkit/client/proof_test.go +++ b/toolkit/client/proof_test.go @@ -4,8 +4,9 @@ import ( "iter" "testing" + "github.com/MetaMask/go-did-it/didtest" "github.com/stretchr/testify/require" - "github.com/ucan-wg/go-ucan/did/didtest" + "github.com/ucan-wg/go-ucan/pkg/command" "github.com/ucan-wg/go-ucan/token/delegation" "github.com/ucan-wg/go-ucan/token/delegation/delegationtest" diff --git a/toolkit/client/requester.go b/toolkit/client/requester.go index 9cb3855..3e683e5 100644 --- a/toolkit/client/requester.go +++ b/toolkit/client/requester.go @@ -5,8 +5,9 @@ import ( "iter" "time" + "github.com/MetaMask/go-did-it" "github.com/avast/retry-go/v4" - "github.com/ucan-wg/go-ucan/did" + "github.com/ucan-wg/go-ucan/pkg/command" "github.com/ucan-wg/go-ucan/token/delegation" ) diff --git a/toolkit/client/requester_infura.go b/toolkit/client/requester_infura.go deleted file mode 100644 index b60f64b..0000000 --- a/toolkit/client/requester_infura.go +++ /dev/null @@ -1,99 +0,0 @@ -package client - -import ( - "bytes" - "context" - "encoding/base64" - "encoding/json" - "fmt" - "io" - "iter" - "net/http" - "net/url" - - "github.com/ucan-wg/go-ucan/did" - "github.com/ucan-wg/go-ucan/pkg/command" - "github.com/ucan-wg/go-ucan/token/delegation" -) - -var _ DelegationRequester = &InfuraRequester{} - -type InfuraRequester struct { - baseURL string -} - -// NewInfuraRequester create a requester client for the Infura UCAN token issuer. -// dev: http://ucan-issuer-api.commercial-dev.eks-dev.infura.org -// prod: http://ucan-issuer-api.commercial-prod.eks.infura.org -func NewInfuraRequester(baseURL string) *InfuraRequester { - return &InfuraRequester{baseURL: baseURL} -} - -func (i InfuraRequester) RequestDelegation(ctx context.Context, audience did.DID, cmd command.Command, subject did.DID) (iter.Seq2[*delegation.Bundle, error], error) { - p, err := url.JoinPath(i.baseURL, "v1/token/generate-with-did") - if err != nil { - return nil, err - } - - payload := struct { - Cmd string `json:"cmd"` - Aud string `json:"aud"` - }{ - Cmd: cmd.String(), - Aud: audience.String(), - } - - body, err := json.Marshal(payload) - if err != nil { - return nil, err - } - - r, err := http.NewRequest(http.MethodPost, p, bytes.NewReader(body)) - if err != nil { - return nil, err - } - - res, err := http.DefaultClient.Do(r.WithContext(ctx)) - if err != nil { - return nil, err - } - if res.StatusCode != http.StatusOK { - msg, err := io.ReadAll(res.Body) - if err != nil { - return nil, fmt.Errorf("request failed with status %d, then failed to read response body: %w", res.StatusCode, err) - } - return nil, fmt.Errorf("request failed with status %d: %s", res.StatusCode, msg) - } - - resp := struct { - Cid string `json:"cid"` - Content string `json:"content"` - }{} - if err := json.NewDecoder(res.Body).Decode(&resp); err != nil { - return nil, err - } - - raw, err := base64.StdEncoding.DecodeString(resp.Content) - if err != nil { - return nil, err - } - - tkn, c, err := delegation.FromSealed(raw) - if err != nil { - return nil, err - } - - // For sanity, we verify that the delegation we got matches the expected subject, - // meaning that we are talking to the expected issuer. - if tkn.Subject() != subject { - return nil, fmt.Errorf("received token has unexpected subject: expected %s, got %s", subject, tkn.Subject()) - } - - return func(yield func(*delegation.Bundle, error) bool) { - yield(&delegation.Bundle{ - Cid: c, - Decoded: tkn, - Sealed: raw, - }, nil) - }, nil -} diff --git a/toolkit/issuer/http_wrapper.go b/toolkit/issuer/http_wrapper.go index a0a095f..e9fa220 100644 --- a/toolkit/issuer/http_wrapper.go +++ b/toolkit/issuer/http_wrapper.go @@ -6,12 +6,12 @@ import ( "iter" "net/http" - "github.com/ucan-wg/go-ucan/did" + "github.com/MetaMask/go-did-it" + "github.com/ucan-wg/go-ucan/pkg/command" "github.com/ucan-wg/go-ucan/pkg/container" "github.com/ucan-wg/go-ucan/token/delegation" - - "github.com/INFURA/go-ucan-toolkit/client" + "github.com/ucan-wg/go-ucan/toolkit/client" ) type RequestResolver func(r *http.Request) (*ResolvedRequest, error) @@ -60,7 +60,7 @@ func HttpWrapper(requester client.DelegationRequester, resolver RequestResolver) }) } -func DecodeResponse(res *http.Response) (iter.Seq2[*delegation.Bundle, error], error) { +func DecodeResponse(res *http.Response, audience did.DID, cmd command.Command, subject did.DID) (iter.Seq2[*delegation.Bundle, error], error) { defer res.Body.Close() if res.StatusCode != http.StatusOK { msg, err := io.ReadAll(res.Body) @@ -73,9 +73,20 @@ func DecodeResponse(res *http.Response) (iter.Seq2[*delegation.Bundle, error], e if err != nil { return nil, err } + + // the container doesn't guarantee the ordering, so we must order the delegation in a chain + proof := client.FindProof(func() iter.Seq[*delegation.Bundle] { + return cont.GetAllDelegations() + }, audience, cmd, subject) + return func(yield func(*delegation.Bundle, error) bool) { - for bundle := range cont.GetAllDelegations() { - if !yield(&bundle, nil) { + for _, c := range proof { + bndl, err := cont.GetDelegationBundle(c) + if err != nil { + yield(nil, err) + return + } + if !yield(bndl, nil) { return } } diff --git a/toolkit/issuer/root_issuer.go b/toolkit/issuer/root_issuer.go index 5723a8c..fe77691 100644 --- a/toolkit/issuer/root_issuer.go +++ b/toolkit/issuer/root_issuer.go @@ -5,12 +5,13 @@ import ( "fmt" "iter" - "github.com/libp2p/go-libp2p/core/crypto" - "github.com/ucan-wg/go-ucan/did" + "github.com/MetaMask/go-did-it" + didkeyctl "github.com/MetaMask/go-did-it/controller/did-key" + "github.com/MetaMask/go-did-it/crypto" + "github.com/ucan-wg/go-ucan/pkg/command" "github.com/ucan-wg/go-ucan/token/delegation" - - "github.com/INFURA/go-ucan-toolkit/client" + "github.com/ucan-wg/go-ucan/toolkit/client" ) // RootIssuingLogic is a function that decides what powers are given to a client. @@ -29,16 +30,13 @@ var _ client.DelegationRequester = &RootIssuer{} // Feel free to replace this component with your own flavor. type RootIssuer struct { did did.DID - privKey crypto.PrivKey + privKey crypto.PrivateKeySigningBytes logic RootIssuingLogic } -func NewRootIssuer(privKey crypto.PrivKey, logic RootIssuingLogic) (*RootIssuer, error) { - d, err := did.FromPrivKey(privKey) - if err != nil { - return nil, err - } +func NewRootIssuer(privKey crypto.PrivateKeySigningBytes, logic RootIssuingLogic) (*RootIssuer, error) { + d := didkeyctl.FromPrivateKey(privKey) return &RootIssuer{ did: d, privKey: privKey, @@ -47,7 +45,7 @@ func NewRootIssuer(privKey crypto.PrivKey, logic RootIssuingLogic) (*RootIssuer, } func (r *RootIssuer) RequestDelegation(ctx context.Context, audience did.DID, cmd command.Command, subject did.DID) (iter.Seq2[*delegation.Bundle, error], error) { - if subject != r.did { + if !subject.Equal(r.did) { return nil, fmt.Errorf("subject DID doesn't match the issuer DID") } diff --git a/toolkit/server/bearer/bearer_test.go b/toolkit/server/bearer/bearer_test.go index 0070159..23c5b03 100644 --- a/toolkit/server/bearer/bearer_test.go +++ b/toolkit/server/bearer/bearer_test.go @@ -4,7 +4,9 @@ import ( "net/http" "testing" + _ "github.com/MetaMask/go-did-it/verifiers/did-key" "github.com/stretchr/testify/require" + "github.com/ucan-wg/go-ucan/pkg/container" "github.com/ucan-wg/go-ucan/pkg/container/containertest" ) diff --git a/toolkit/server/exectx/middlewares.go b/toolkit/server/exectx/middlewares.go index c431905..b46969f 100644 --- a/toolkit/server/exectx/middlewares.go +++ b/toolkit/server/exectx/middlewares.go @@ -4,9 +4,9 @@ import ( "errors" "net/http" - "github.com/ucan-wg/go-ucan/did" + "github.com/MetaMask/go-did-it" - "github.com/INFURA/go-ucan-toolkit/server/bearer" + "github.com/ucan-wg/go-ucan/toolkit/server/bearer" ) // ExtractMW returns an HTTP middleware tasked with: @@ -38,7 +38,7 @@ func ExtractMW(next http.Handler, serviceDID did.DID) http.Handler { return } - if ucanCtx.Invocation().Subject() != serviceDID { + if !ucanCtx.Invocation().Subject().Equal(serviceDID) { http.Error(w, "UCAN delegation doesn't match the service DID", http.StatusUnauthorized) return } diff --git a/toolkit/server/exectx/middlewares_test.go b/toolkit/server/exectx/middlewares_test.go index 00dd652..08c6865 100644 --- a/toolkit/server/exectx/middlewares_test.go +++ b/toolkit/server/exectx/middlewares_test.go @@ -6,9 +6,10 @@ import ( "net/http/httptest" "testing" + "github.com/MetaMask/go-did-it/didtest" "github.com/ipfs/go-cid" "github.com/stretchr/testify/require" - "github.com/ucan-wg/go-ucan/did/didtest" + "github.com/ucan-wg/go-ucan/pkg/container" "github.com/ucan-wg/go-ucan/token/delegation" "github.com/ucan-wg/go-ucan/token/invocation" diff --git a/toolkit/server/exectx/ucanctx.go b/toolkit/server/exectx/ucanctx.go index 04250d3..11d99d0 100644 --- a/toolkit/server/exectx/ucanctx.go +++ b/toolkit/server/exectx/ucanctx.go @@ -6,9 +6,9 @@ import ( "net/http" "slices" - "github.com/INFURA/go-ethlibs/jsonrpc" "github.com/ipfs/go-cid" "github.com/ipld/go-ipld-prime/datamodel" + "github.com/ucan-wg/go-ucan/pkg/args" "github.com/ucan-wg/go-ucan/pkg/command" "github.com/ucan-wg/go-ucan/pkg/container" @@ -16,8 +16,7 @@ import ( "github.com/ucan-wg/go-ucan/pkg/policy" "github.com/ucan-wg/go-ucan/token/delegation" "github.com/ucan-wg/go-ucan/token/invocation" - - "github.com/INFURA/go-ucan-toolkit/server/extargs" + "github.com/ucan-wg/go-ucan/toolkit/server/extargs" ) var _ delegation.Loader = &UcanCtx{} @@ -33,9 +32,8 @@ type UcanCtx struct { meta *meta.Meta // all meta combined, with no overwriting // argument sources - http *extargs.HttpExtArgs - jsonrpc *extargs.JsonRpcExtArgs - infura *extargs.InfuraExtArgs + http *extargs.HttpExtArgs + custom map[string]*extargs.CustomExtArgs } // FromContainer prepare a UcanCtx from a UCAN container, for further evaluation in a server pipeline. @@ -79,7 +77,7 @@ func FromContainer(cont container.Reader) (*UcanCtx, error) { chainTo := inv.Issuer() for _, c := range inv.Proof() { dlg := ctx.dlgs[c] - if dlg.Audience() != chainTo { + if !dlg.Audience().Equal(chainTo) { return nil, fmt.Errorf("proof chain is broken or not ordered correctly") } chainTo = dlg.Issuer() @@ -137,28 +135,19 @@ func (ctn *UcanCtx) VerifyHttp(req *http.Request) error { return ctn.http.Verify() } -// VerifyJsonRpc verify the delegation's policies against arguments constructed from the JsonRpc request. -// These arguments will be set in the `.jsonrpc` argument key, at the root. -// This function can only be called once per context. +// VerifyCustom verify the delegation's policies against arbitrary arguments provider through an IPLD MapAssembler. +// These arguments will be set under the given argument key, at the root. +// This function can only be called once per context and key. // After being used, those constructed arguments will be used in ExecutionAllowed as well. -func (ctn *UcanCtx) VerifyJsonRpc(req *jsonrpc.Request) error { - if ctn.jsonrpc != nil { - panic("only use once per request context") +func (ctn *UcanCtx) VerifyCustom(key string, assembler func(ma datamodel.MapAssembler)) error { + if ctn.custom == nil { + ctn.custom = make(map[string]*extargs.CustomExtArgs) } - ctn.jsonrpc = extargs.NewJsonRpcExtArgs(ctn.policies, ctn.inv.Arguments(), req) - return ctn.jsonrpc.Verify() -} - -// VerifyInfura verify the delegation's policies against arbitrary arguments provider through an IPLD MapAssembler. -// These arguments will be set in the `.inf` argument key, at the root. -// This function can only be called once per context. -// After being used, those constructed arguments will be used in ExecutionAllowed as well. -func (ctn *UcanCtx) VerifyInfura(assembler func(ma datamodel.MapAssembler)) error { - if ctn.infura != nil { - panic("only use once per request context") + if _, ok := ctn.custom[key]; ok { + panic("only use once per request context and key") } - ctn.infura = extargs.NewInfuraExtArgs(ctn.policies, assembler) - return ctn.infura.Verify() + ctn.custom[key] = extargs.NewCustomExtArgs(key, ctn.policies, assembler) + return ctn.custom[key].Verify() } // ExecutionAllowed does the final verification of the invocation. @@ -174,19 +163,14 @@ func (ctn *UcanCtx) ExecutionAllowed() error { } newArgs.Include(httpArgs) } - if ctn.jsonrpc != nil { - jsonRpcArgs, err := ctn.jsonrpc.Args() - if err != nil { - return nil, err + if ctn.custom != nil { + for _, cea := range ctn.custom { + customArgs, err := cea.Args() + if err != nil { + return nil, err + } + newArgs.Include(customArgs) } - newArgs.Include(jsonRpcArgs) - } - if ctn.infura != nil { - infuraArgs, err := ctn.infura.Args() - if err != nil { - return nil, err - } - newArgs.Include(infuraArgs) } return newArgs, nil diff --git a/toolkit/server/exectx/ucanctx_test.go b/toolkit/server/exectx/ucanctx_test.go index 7d72309..7ae8a58 100644 --- a/toolkit/server/exectx/ucanctx_test.go +++ b/toolkit/server/exectx/ucanctx_test.go @@ -1,29 +1,26 @@ package exectx_test import ( - "bytes" "context" - "encoding/json" "net/http" "net/http/httptest" "strings" "testing" "time" - "github.com/INFURA/go-ethlibs/jsonrpc" + "github.com/MetaMask/go-did-it/didtest" "github.com/ipfs/go-cid" "github.com/ipld/go-ipld-prime/datamodel" "github.com/ipld/go-ipld-prime/fluent/qp" "github.com/stretchr/testify/require" - "github.com/ucan-wg/go-ucan/did/didtest" + "github.com/ucan-wg/go-ucan/pkg/command" "github.com/ucan-wg/go-ucan/pkg/container" "github.com/ucan-wg/go-ucan/pkg/policy" "github.com/ucan-wg/go-ucan/pkg/policy/literal" "github.com/ucan-wg/go-ucan/token/delegation" "github.com/ucan-wg/go-ucan/token/invocation" - - "github.com/INFURA/go-ucan-toolkit/server/exectx" + "github.com/ucan-wg/go-ucan/toolkit/server/exectx" ) const ( @@ -45,16 +42,11 @@ func TestUcanCtxFullFlow(t *testing.T) { // some basic HTTP constraints policy.Equal(".http.method", literal.String("GET")), policy.Like(".http.path", "/foo/*"), - // some JsonRpc constraints - policy.Or( - policy.Like(".jsonrpc.method", "eth_*"), - policy.Equal(".jsonrpc.method", literal.String("debug_traceCall")), - ), - // some infura constraints + // some custom constraints // Network - policy.Equal(".inf.ntwk", literal.String(network)), + policy.Equal(".custom.ntwk", literal.String(network)), // Quota - policy.LessThanOrEqual(".inf.quota.ur", literal.Int(1234)), + policy.LessThanOrEqual(".custom.quota.ur", literal.Int(1234)), ) dlg, err := delegation.Root(service.DID(), user.DID(), cmd, pol, @@ -84,12 +76,7 @@ func TestUcanCtxFullFlow(t *testing.T) { // MAKING A REQUEST: we pass the container in the Bearer HTTP header - jrpc := jsonrpc.NewRequest() - jrpc.Method = "eth_call" - jrpc.Params = jsonrpc.MustParams("0x599784", true) - jrpcBytes, err := jrpc.MarshalJSON() - require.NoError(t, err) - req, err := http.NewRequest(http.MethodGet, "/foo/bar", bytes.NewReader(jrpcBytes)) + req, err := http.NewRequest(http.MethodGet, "/foo/bar", nil) require.NoError(t, err) req.Header.Set("Authorization", "Bearer "+string(contBytes)) @@ -132,33 +119,13 @@ func TestUcanCtxFullFlow(t *testing.T) { }) } - // SERVER: JsonRpc checks + // SERVER: custom args checks - jsonrpcMw := func(next http.Handler) http.Handler { + customArgsMw := func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ucanCtx, ok := exectx.FromContext(r.Context()) require.True(t, ok) - - var jrpc jsonrpc.Request - err := json.NewDecoder(r.Body).Decode(&jrpc) - require.NoError(t, err) - - err = ucanCtx.VerifyJsonRpc(&jrpc) - if err != nil { - http.Error(w, err.Error(), http.StatusUnauthorized) - return - } - next.ServeHTTP(w, r) - }) - } - - // SERVER: custom infura checks - - infuraMw := func(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - ucanCtx, ok := exectx.FromContext(r.Context()) - require.True(t, ok) - err := ucanCtx.VerifyInfura(func(ma datamodel.MapAssembler) { + err := ucanCtx.VerifyCustom("custom", func(ma datamodel.MapAssembler) { qp.MapEntry(ma, "ntwk", qp.String(network)) qp.MapEntry(ma, "quota", qp.Map(1, func(ma datamodel.MapAssembler) { qp.MapEntry(ma, "ur", qp.Int(1234)) @@ -183,7 +150,7 @@ func TestUcanCtxFullFlow(t *testing.T) { w.WriteHeader(http.StatusOK) } - sut := authMw(httpMw(jsonrpcMw(infuraMw(http.HandlerFunc(handler))))) + sut := authMw(httpMw(customArgsMw(http.HandlerFunc(handler)))) rec := httptest.NewRecorder() sut.ServeHTTP(rec, req) diff --git a/toolkit/server/extargs/Readme.md b/toolkit/server/extargs/Readme.md index ecaedf7..f44472f 100644 --- a/toolkit/server/extargs/Readme.md +++ b/toolkit/server/extargs/Readme.md @@ -8,31 +8,28 @@ In this package, we cross the chasm of the pure UCAN world into our practical ne ## Example -Below is an example of `args` in Dag-Json format, where the values are recomposed server-side from the HTTP request (header and JSONRPC body): +Below is an example of `args` in Dag-Json format, where the values are recomposed server-side from the HTTP request: ```json { "http": { "scheme": "https", "method": "POST", - "host": "mainnet.infura.io", + "host": "example.com", "path": "" }, - "jsonrpc": { - "jsonrpc": "2.0", - "method": "eth_blockbynumber", - "params": [], - "id": 1 + "custom": { + "foo": "bar" } } ``` Those `args` can be evaluated against a delegation's policy, for example: ```json { - "cmd": "/infura/jsonrpc", + "cmd": "/foo/bar", "pol": [ - ["==", ".http.host", "mainnet.infura.io"], - ["like", ".jsonrpc.method", "eth_*"] + ["==", ".http.host", "example.com"], + ["like", ".custom.foo", "ba*"] ] } ``` @@ -50,7 +47,7 @@ There is a way to get around that, and have the best of both worlds, but **it co ```json { "http": "zQmSnuWmxptJZdLJpKRarxBMS2Ju2oANVrgbr2xWbie9b2D", - "jsonrpc": "zQmP8jTG1m9GSDJLCbeWhVSVgEzCPPwXRdCRuJtQ5Tz9Kc9" + "custom": "zQmP8jTG1m9GSDJLCbeWhVSVgEzCPPwXRdCRuJtQ5Tz9Kc9" } ``` @@ -63,4 +60,4 @@ Therefore, the server-side logic is made to have this hashing optional: - the client can opt out of passing that hash, and won't benefit from the enforced security The particular hash selected is SHA2-256 of the DAG-CBOR encoded argument, expressed in the form of a Multihash in raw bytes. -The arguments being hashed are the complete map of values, including the root key being replaced (for example `jsonrpc` or `http`). \ No newline at end of file +The arguments being hashed are the complete map of values, including the root key being replaced (for example `http` or `custom` here). \ No newline at end of file diff --git a/toolkit/server/extargs/infura.go b/toolkit/server/extargs/custom.go similarity index 57% rename from toolkit/server/extargs/infura.go rename to toolkit/server/extargs/custom.go index ff6c066..51accd1 100644 --- a/toolkit/server/extargs/infura.go +++ b/toolkit/server/extargs/custom.go @@ -8,13 +8,13 @@ import ( "github.com/ipld/go-ipld-prime/datamodel" "github.com/ipld/go-ipld-prime/fluent/qp" "github.com/ipld/go-ipld-prime/node/basicnode" + "github.com/ucan-wg/go-ucan/pkg/args" "github.com/ucan-wg/go-ucan/pkg/policy" ) -const InfuraArgsKey = "inf" - -type InfuraExtArgs struct { +type CustomExtArgs struct { + key string pol policy.Policy originalArgs args.ReadOnly assembler func(ma datamodel.MapAssembler) @@ -24,44 +24,44 @@ type InfuraExtArgs struct { argsIpld ipld.Node } -func NewInfuraExtArgs(pol policy.Policy, assembler func(ma datamodel.MapAssembler)) *InfuraExtArgs { - return &InfuraExtArgs{pol: pol, assembler: assembler} +func NewCustomExtArgs(key string, pol policy.Policy, assembler func(ma datamodel.MapAssembler)) *CustomExtArgs { + return &CustomExtArgs{key: key, pol: pol, assembler: assembler} } -func (ia *InfuraExtArgs) Verify() error { - if err := ia.makeArgs(); err != nil { +func (cea *CustomExtArgs) Verify() error { + if err := cea.makeArgs(); err != nil { return err } - // Note: InfuraExtArgs doesn't support verifying a hash computed client-side like the other + // Note: CustomExtArgs doesn't support verifying a hash computed client-side like the other // external args, as the arguments are by nature dynamic. The client can't generate a meaningful hash. - ok, leaf := ia.pol.PartialMatch(ia.argsIpld) + ok, leaf := cea.pol.PartialMatch(cea.argsIpld) if !ok { return fmt.Errorf("the following UCAN policy is not satisfied: %v", leaf.String()) } return nil } -func (ia *InfuraExtArgs) Args() (*args.Args, error) { - if err := ia.makeArgs(); err != nil { +func (cea *CustomExtArgs) Args() (*args.Args, error) { + if err := cea.makeArgs(); err != nil { return nil, err } - return ia.args, nil + return cea.args, nil } -func (ia *InfuraExtArgs) makeArgs() error { +func (cea *CustomExtArgs) makeArgs() error { var outerErr error - ia.once.Do(func() { + cea.once.Do(func() { var err error - ia.args, err = makeInfuraArgs(ia.assembler) + cea.args, err = makeCustomArgs(cea.key, cea.assembler) if err != nil { outerErr = err return } - ia.argsIpld, err = ia.args.ToIPLD() + cea.argsIpld, err = cea.args.ToIPLD() if err != nil { outerErr = err return @@ -70,14 +70,14 @@ func (ia *InfuraExtArgs) makeArgs() error { return outerErr } -func makeInfuraArgs(assembler func(ma datamodel.MapAssembler)) (*args.Args, error) { +func makeCustomArgs(key string, assembler func(ma datamodel.MapAssembler)) (*args.Args, error) { n, err := qp.BuildMap(basicnode.Prototype.Any, -1, assembler) if err != nil { return nil, err } res := args.New() - err = res.Add(InfuraArgsKey, n) + err = res.Add(key, n) if err != nil { return nil, err } diff --git a/toolkit/server/extargs/infura_test.go b/toolkit/server/extargs/custom_test.go similarity index 76% rename from toolkit/server/extargs/infura_test.go rename to toolkit/server/extargs/custom_test.go index b8de085..86d53cd 100644 --- a/toolkit/server/extargs/infura_test.go +++ b/toolkit/server/extargs/custom_test.go @@ -7,18 +7,19 @@ import ( "github.com/ipld/go-ipld-prime/datamodel" "github.com/ipld/go-ipld-prime/fluent/qp" "github.com/stretchr/testify/require" + "github.com/ucan-wg/go-ucan/pkg/policy" "github.com/ucan-wg/go-ucan/pkg/policy/literal" ) -func ExampleInfuraExtArgs() { - // Note: this is an example for how to build arguments, but you likely want to use InfuraExtArgs +func ExampleCustomExtArgs() { + // Note: this is an example for how to build arguments, but you likely want to use CustomExtArgs // through UcanCtx. pol := policy.Policy{} // policies from the delegations // We will construct the following args: - // { + // "key": { // "ntwk":"eth-mainnet", // "quota":{ // "ur":1234, @@ -29,7 +30,7 @@ func ExampleInfuraExtArgs() { // "up":1234 // } // } - infArgs := NewInfuraExtArgs(pol, func(ma datamodel.MapAssembler) { + customArgs := NewCustomExtArgs("key", pol, func(ma datamodel.MapAssembler) { qp.MapEntry(ma, "ntwk", qp.String("eth-mainnet")) qp.MapEntry(ma, "quota", qp.Map(6, func(ma datamodel.MapAssembler) { qp.MapEntry(ma, "ur", qp.Int(1234)) @@ -41,14 +42,14 @@ func ExampleInfuraExtArgs() { })) }) - err := infArgs.Verify() + err := customArgs.Verify() fmt.Println(err) // Output: // } -func TestInfura(t *testing.T) { +func TestCustom(t *testing.T) { assembler := func(ma datamodel.MapAssembler) { qp.MapEntry(ma, "ntwk", qp.String("eth-mainnet")) qp.MapEntry(ma, "quota", qp.Map(6, func(ma datamodel.MapAssembler) { @@ -74,24 +75,24 @@ func TestInfura(t *testing.T) { { name: "matching args", pol: policy.MustConstruct( - policy.Equal(".inf.ntwk", literal.String("eth-mainnet")), - policy.LessThanOrEqual(".inf.quota.ur", literal.Int(1234)), + policy.Equal(".key.ntwk", literal.String("eth-mainnet")), + policy.LessThanOrEqual(".key.quota.ur", literal.Int(1234)), ), expected: true, }, { name: "wrong network", pol: policy.MustConstruct( - policy.Equal(".inf.ntwk", literal.String("avalanche-fuji")), - policy.LessThanOrEqual(".inf.quota.ur", literal.Int(1234)), + policy.Equal(".key.ntwk", literal.String("avalanche-fuji")), + policy.LessThanOrEqual(".key.quota.ur", literal.Int(1234)), ), expected: false, }, { name: "unrespected quota", pol: policy.MustConstruct( - policy.Equal(".inf.ntwk", literal.String("eth-mainnet")), - policy.LessThanOrEqual(".inf.quota.ur", literal.Int(100)), + policy.Equal(".key.ntwk", literal.String("eth-mainnet")), + policy.LessThanOrEqual(".key.quota.ur", literal.Int(100)), ), expected: false, }, @@ -99,7 +100,7 @@ func TestInfura(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - extArgs := NewInfuraExtArgs(tc.pol, assembler) + extArgs := NewCustomExtArgs("key", tc.pol, assembler) _, err := extArgs.Args() require.NoError(t, err) diff --git a/toolkit/server/extargs/http.go b/toolkit/server/extargs/http.go index e2062f6..7c354cd 100644 --- a/toolkit/server/extargs/http.go +++ b/toolkit/server/extargs/http.go @@ -13,6 +13,7 @@ import ( "github.com/ipld/go-ipld-prime/fluent/qp" "github.com/ipld/go-ipld-prime/node/basicnode" "github.com/multiformats/go-multihash" + "github.com/ucan-wg/go-ucan/pkg/args" "github.com/ucan-wg/go-ucan/pkg/policy" "github.com/ucan-wg/go-ucan/token/invocation" @@ -88,7 +89,7 @@ func (hea *HttpExtArgs) verifyHash() error { mhBytes, err := n.AsBytes() if err != nil { - return fmt.Errorf("http args hash should be a string") + return fmt.Errorf("http args hash should be bytes") } data, err := ipld.Encode(hea.argsIpld, dagcbor.Encode) @@ -112,7 +113,7 @@ func (hea *HttpExtArgs) verifyHash() error { // If that hash is inserted at the HttpArgsKey key in the invocation arguments, // this increases the security as the UCAN token cannot be used with a different // HTTP request. -// For convenience, the hash is returned as a read to use invocation argument. +// For convenience, the hash is returned as a ready-to-use invocation argument. func MakeHttpHash(req *http.Request) (invocation.Option, error) { // Note: the hash is computed on the full IPLD args, including HttpArgsKey computedArgs, err := makeHttpArgs(req) diff --git a/toolkit/server/extargs/http_test.go b/toolkit/server/extargs/http_test.go index ebb20f7..3c1dbd6 100644 --- a/toolkit/server/extargs/http_test.go +++ b/toolkit/server/extargs/http_test.go @@ -5,9 +5,10 @@ import ( "net/http/httptest" "testing" + "github.com/MetaMask/go-did-it/didtest" "github.com/multiformats/go-multihash" "github.com/stretchr/testify/require" - "github.com/ucan-wg/go-ucan/did/didtest" + "github.com/ucan-wg/go-ucan/pkg/args" "github.com/ucan-wg/go-ucan/pkg/command" "github.com/ucan-wg/go-ucan/pkg/policy" @@ -200,3 +201,10 @@ func TestHttpHash(t *testing.T) { }) } } + +func must[T any](t T, err error) T { + if err != nil { + panic(err) + } + return t +} diff --git a/toolkit/server/extargs/jsonrpc.go b/toolkit/server/extargs/jsonrpc.go deleted file mode 100644 index 51e911e..0000000 --- a/toolkit/server/extargs/jsonrpc.go +++ /dev/null @@ -1,171 +0,0 @@ -package extargs - -import ( - "bytes" - "encoding/json" - "fmt" - "sync" - - "github.com/INFURA/go-ethlibs/jsonrpc" - "github.com/ipld/go-ipld-prime" - "github.com/ipld/go-ipld-prime/codec/dagcbor" - "github.com/ipld/go-ipld-prime/datamodel" - "github.com/ipld/go-ipld-prime/fluent/qp" - "github.com/ipld/go-ipld-prime/node/basicnode" - "github.com/multiformats/go-multihash" - "github.com/ucan-wg/go-ucan/pkg/args" - "github.com/ucan-wg/go-ucan/pkg/policy" - "github.com/ucan-wg/go-ucan/pkg/policy/literal" - "github.com/ucan-wg/go-ucan/token/invocation" -) - -// JsonRpcArgsKey is the key in the args, used for: -// - if it exists in the invocation, holds a hash of the args derived from the JsonRpc request -// - in the final args to be evaluated against the policies, holds the args derived from the JsonRpc request -const JsonRpcArgsKey = "jsonrpc" - -type JsonRpcExtArgs struct { - pol policy.Policy - originalArgs args.ReadOnly - req *jsonrpc.Request - - once sync.Once - args *args.Args - argsIpld ipld.Node -} - -func NewJsonRpcExtArgs(pol policy.Policy, originalArgs args.ReadOnly, req *jsonrpc.Request) *JsonRpcExtArgs { - return &JsonRpcExtArgs{pol: pol, originalArgs: originalArgs, req: req} -} - -func (jrea *JsonRpcExtArgs) Verify() error { - if err := jrea.makeArgs(); err != nil { - return err - } - - if err := jrea.verifyHash(); err != nil { - return err - } - - ok, leaf := jrea.pol.PartialMatch(jrea.argsIpld) - if !ok { - return fmt.Errorf("the following UCAN policy is not satisfied: %v", leaf.String()) - } - return nil -} - -func (jrea *JsonRpcExtArgs) Args() (*args.Args, error) { - if err := jrea.makeArgs(); err != nil { - return nil, err - } - return jrea.args, nil -} - -func (jrea *JsonRpcExtArgs) makeArgs() error { - var outerErr error - jrea.once.Do(func() { - var err error - jrea.args, err = makeJsonRpcArgs(jrea.req) - if err != nil { - outerErr = err - return - } - - jrea.argsIpld, err = jrea.args.ToIPLD() - if err != nil { - outerErr = err - return - } - }) - return outerErr -} - -func (jrea *JsonRpcExtArgs) verifyHash() error { - n, err := jrea.originalArgs.GetNode(JsonRpcArgsKey) - if err != nil { - // no hash found, nothing to verify - return nil - } - - mhBytes, err := n.AsBytes() - if err != nil { - return fmt.Errorf("jsonrpc args hash should be a string") - } - - data, err := ipld.Encode(jrea.argsIpld, dagcbor.Encode) - if err != nil { - return fmt.Errorf("can't encode derived args in dag-cbor: %w", err) - } - - sum, err := multihash.Sum(data, multihash.SHA2_256, -1) - if err != nil { - return err - } - - if !bytes.Equal(mhBytes, sum) { - return fmt.Errorf("derived args from jsonrpc request don't match the expected hash") - } - - return nil -} - -// MakeJsonRpcHash compute the hash of the derived arguments from the JsonRPC request. -// If that hash is inserted at the JsonRpcArgsKey key in the invocation arguments, -// this increases the security as the UCAN token cannot be used with a different -// JsonRPC request. -// For convenience, the hash is returned as a read to use invocation argument. -func MakeJsonRpcHash(req *jsonrpc.Request) (invocation.Option, error) { - // Note: the hash is computed on the full IPLD args, including JsonRpcArgsKey - computedArgs, err := makeJsonRpcArgs(req) - if err != nil { - return nil, err - } - - n, err := computedArgs.ToIPLD() - if err != nil { - return nil, err - } - - data, err := ipld.Encode(n, dagcbor.Encode) - if err != nil { - return nil, err - } - - sum, err := multihash.Sum(data, multihash.SHA2_256, -1) - if err != nil { - return nil, err - } - - return invocation.WithArgument(JsonRpcArgsKey, []byte(sum)), nil -} - -func makeJsonRpcArgs(req *jsonrpc.Request) (*args.Args, error) { - deserialized := make([]any, len(req.Params)) - for i, param := range req.Params { - err := json.Unmarshal(param, &deserialized[i]) - if err != nil { - return nil, err - } - } - - params, err := literal.List(deserialized) - if err != nil { - return nil, err - } - - n, err := qp.BuildMap(basicnode.Prototype.Any, 3, func(ma datamodel.MapAssembler) { - qp.MapEntry(ma, "jsonrpc", qp.String(req.JSONRPC)) - qp.MapEntry(ma, "method", qp.String(req.Method)) - qp.MapEntry(ma, "params", qp.Node(params)) - }) - if err != nil { - return nil, err - } - - res := args.New() - err = res.Add(JsonRpcArgsKey, n) - if err != nil { - return nil, err - } - return res, nil -} diff --git a/toolkit/server/extargs/jsonrpc_test.go b/toolkit/server/extargs/jsonrpc_test.go deleted file mode 100644 index ceb715d..0000000 --- a/toolkit/server/extargs/jsonrpc_test.go +++ /dev/null @@ -1,188 +0,0 @@ -package extargs - -import ( - "testing" - - "github.com/INFURA/go-ethlibs/jsonrpc" - "github.com/multiformats/go-multihash" - "github.com/stretchr/testify/require" - "github.com/ucan-wg/go-ucan/did/didtest" - "github.com/ucan-wg/go-ucan/pkg/args" - "github.com/ucan-wg/go-ucan/pkg/command" - "github.com/ucan-wg/go-ucan/pkg/policy" - "github.com/ucan-wg/go-ucan/pkg/policy/literal" - "github.com/ucan-wg/go-ucan/token/invocation" -) - -func TestJsonRpc(t *testing.T) { - tests := []struct { - name string - req *jsonrpc.Request - pol policy.Policy - expected bool - }{ - { - name: "or on method, not matching", - req: jsonrpc.MustRequest(1839673506133526, "eth_getBlockByNumber", - "0x599784", true, - ), - pol: policy.MustConstruct( - policy.Or( - policy.Equal(".jsonrpc.method", literal.String("eth_getCode")), - policy.Equal(".jsonrpc.method", literal.String("eth_getBalance")), - policy.Equal(".jsonrpc.method", literal.String("eth_call")), - policy.Equal(".jsonrpc.method", literal.String("eth_blockNumber")), - ), - ), - expected: false, - }, - { - name: "or on method, matching", - req: jsonrpc.MustRequest(1839673506133526, "eth_call", - map[string]string{"to": "0xBADBADBADBADBADBADBADBADBADBADBADBADBAD1"}, - ), - pol: policy.MustConstruct( - policy.Or( - policy.Equal(".jsonrpc.method", literal.String("eth_getCode")), - policy.Equal(".jsonrpc.method", literal.String("eth_getBalance")), - policy.Equal(".jsonrpc.method", literal.String("eth_call")), - policy.Equal(".jsonrpc.method", literal.String("eth_blockNumber")), - ), - ), - expected: true, - }, - { - name: "complex, optional parameter, matching", - req: jsonrpc.MustRequest(1839673506133526, "debug_traceCall", - true, false, 1234, "callTracer", - ), - pol: policy.MustConstruct( - policy.Equal(".jsonrpc.method", literal.String("debug_traceCall")), - policy.Or( - policy.Equal(".jsonrpc.params[3]?", literal.String("callTracer")), - policy.Equal(".jsonrpc.params[3]?", literal.String("prestateTracer")), - ), - ), - expected: true, - }, - { - name: "complex, optional parameter, missing parameter", - req: jsonrpc.MustRequest(1839673506133526, "debug_traceCall", - true, false, 1234, - ), - pol: policy.MustConstruct( - policy.Equal(".jsonrpc.method", literal.String("debug_traceCall")), - policy.Or( - policy.Equal(".jsonrpc.params[3]?", literal.String("callTracer")), - policy.Equal(".jsonrpc.params[3]?", literal.String("prestateTracer")), - ), - ), - expected: true, - }, - { - name: "complex, parameter not matching", - req: jsonrpc.MustRequest(1839673506133526, "debug_traceCall", - true, false, 1234, "ho_no", - ), - pol: policy.MustConstruct( - policy.Equal(".jsonrpc.method", literal.String("debug_traceCall")), - policy.Or( - policy.Equal(".jsonrpc.params[3]?", literal.String("callTracer")), - policy.Equal(".jsonrpc.params[3]?", literal.String("prestateTracer")), - ), - ), - expected: false, - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - // we don't test the args hash here - emptyArgs := args.New().ReadOnly() - - ctx := NewJsonRpcExtArgs(tc.pol, emptyArgs, tc.req) - - _, err := ctx.Args() - require.NoError(t, err) - - if tc.expected { - require.NoError(t, ctx.Verify()) - } else { - require.Error(t, ctx.Verify()) - } - }) - } -} - -func TestJsonRpcHash(t *testing.T) { - servicePersona := didtest.PersonaAlice - clientPersona := didtest.PersonaBob - - req := jsonrpc.MustRequest(1839673506133526, "debug_traceCall", - true, false, 1234, "ho_no", - ) - pol := policy.MustConstruct( - policy.Equal(".jsonrpc.method", literal.String("debug_traceCall")), - ) - - makeArg := func(data []byte, code uint64) invocation.Option { - mh, err := multihash.Sum(data, code, -1) - require.NoError(t, err) - return invocation.WithArgument(JsonRpcArgsKey, []byte(mh)) - } - - tests := []struct { - name string - argOptions []invocation.Option - expected bool - }{ - { - name: "correct hash", - argOptions: []invocation.Option{must(MakeJsonRpcHash(req))}, - expected: true, - }, - { - name: "non-matching hash", - argOptions: []invocation.Option{makeArg([]byte{1, 2, 3, 4}, multihash.SHA2_256)}, - expected: false, - }, - { - name: "wrong type of hash", - argOptions: []invocation.Option{makeArg([]byte{1, 2, 3, 4}, multihash.BLAKE3)}, - expected: false, - }, - { - name: "no hash", - argOptions: nil, - expected: true, // having a hash is not enforced - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - inv, err := invocation.New( - clientPersona.DID(), - command.MustParse("/foo"), - servicePersona.DID(), - nil, - tc.argOptions..., // inject hash argument, if any - ) - require.NoError(t, err) - - ctx := NewJsonRpcExtArgs(pol, inv.Arguments(), req) - - if tc.expected { - require.NoError(t, ctx.Verify()) - } else { - require.Error(t, ctx.Verify()) - } - }) - } -} - -func must[T any](t T, err error) T { - if err != nil { - panic(err) - } - return t -}