From 813e218a6325d871754b724df9d4e61e5e8b3621 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Fri, 3 Feb 2023 13:42:57 +0100 Subject: [PATCH 01/57] make it verifier --- back/views/layouts/main.html | 2 +- main.go | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/back/views/layouts/main.html b/back/views/layouts/main.html index 0593fbf0..c6d1ec26 100644 --- a/back/views/layouts/main.html +++ b/back/views/layouts/main.html @@ -9,7 +9,7 @@ - Credential Issuer + Credential Verifier diff --git a/main.go b/main.go index c338296d..baff7a4a 100644 --- a/main.go +++ b/main.go @@ -42,7 +42,6 @@ const walletPrefix = "/wallet/api/v1" var ( prod = flag.Bool("prod", false, "Enable prefork in Production") configFile = flag.String("config", LookupEnvOrString("CONFIG_FILE", defaultConfigFile), "path to configuration file") - password = flag.String("pass", LookupEnvOrString("PASSWORD", defaultPassword), "admin password for the server") ) type SSIKitConfig struct { @@ -60,7 +59,6 @@ type Server struct { WebAuthn *handlers.WebAuthnHandler Operations *operations.Manager verifierVault *vault.Vault - issuerDID string verifierDID string logger *zap.SugaredLogger storage *memory.Storage @@ -151,8 +149,7 @@ func BackendServer() { // ########################## // Application Home pages - s.Get("/", s.HandleHome) - s.Get("/verifier", s.HandleVerifierHome) + s.Get("/", s.HandleVerifierHome) // Info base path s.Get("/info", s.GetBackendInfo) From 37a633ce106899eca2eb4fc64dbd15744b78b245 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Fri, 3 Feb 2023 13:58:09 +0100 Subject: [PATCH 02/57] add more showcasing --- back/views/verifier_receivedcredential.html | 2 +- back/views/verifier_request_service.html | 31 ++++++++++++ verifier.go | 53 +++++++++++++++++++++ 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 back/views/verifier_request_service.html diff --git a/back/views/verifier_receivedcredential.html b/back/views/verifier_receivedcredential.html index 1be1a375..d5c8649c 100644 --- a/back/views/verifier_receivedcredential.html +++ b/back/views/verifier_receivedcredential.html @@ -12,7 +12,7 @@

Received credential:

diff --git a/back/views/verifier_request_service.html b/back/views/verifier_request_service.html new file mode 100644 index 00000000..2731afce --- /dev/null +++ b/back/views/verifier_request_service.html @@ -0,0 +1,31 @@ +{{define "verifier_request_service"}} {{template "partials/header" .}} + +
+ +
+

Enter URL:

+
+
+ + + +
+ + + {{if .returnBody}} +
+

Response

+

With status code {{.code}} and returned:

+

{{.returnBody}}

+
+ {{end}} + +
+ +{{template "partials/footer" .}} {{end}} \ No newline at end of file diff --git a/verifier.go b/verifier.go index 98491a99..e89e8e48 100644 --- a/verifier.go +++ b/verifier.go @@ -48,6 +48,8 @@ func setupVerifier(s *Server) { // Allow simulation of accessing protected resources, after successful login verifierRoutes.Get("/accessprotectedservice", verifier.VerifierPageAccessProtectedService) + verifierRoutes.Post("/accessService", verifier.VerifierPageAccessServicePost) + verifierRoutes.Get("/accessService", verifier.VerifierPageAccessServiceGet) // APIs @@ -196,6 +198,57 @@ func (v *Verifier) VerifierPageReceiveCredential(c *fiber.Ctx) error { return c.Render("verifier_receivedcredential", m) } +type AccessServiceForm struct { + Url string `form:"requestUrl,omitempty"` +} + +func (v *Verifier) VerifierPageAccessServiceGet(c *fiber.Ctx) error { + + protected := v.server.cfg.String("verifier.protectedResource.url") + // Render + m := fiber.Map{ + "protectedService": protected, + "verifierPrefix": verifierPrefix, + } + return c.Render("verifier_request_service", m) +} + +func (v *Verifier) VerifierPageAccessServicePost(c *fiber.Ctx) error { + var code int + var returnBody []byte + var errors []error + + // Get the access token from the cookie + accessToken := c.Cookies("dbsamvf") + service := &AccessServiceForm{} + if err := c.BodyParser(service); err != nil { + v.server.logger.Infof("Error parsing: %s", err) + return err + } + + // Prepare to GET to the url + agent := fiber.Get(service.Url) + + // Set the Authentication header + agent.Set("Authorization", "Bearer "+accessToken) + + agent.Set("accept", "application/json") + code, returnBody, errors = agent.Bytes() + if len(errors) > 0 { + v.server.logger.Errorw("error calling SSI Kit", zap.Errors("errors", errors)) + return fmt.Errorf("error calling SSI Kit: %v", errors[0]) + } + + // Render + m := fiber.Map{ + "protectedService": service.Url, + "verifierPrefix": verifierPrefix, + "code": code, + "returnBody": string(returnBody), + } + return c.Render("verifier_request_service", m) +} + func (v *Verifier) VerifierPageAccessProtectedService(c *fiber.Ctx) error { var code int From 22c3f480dc2b2fb7c0b0916e32df7c7cfae235d1 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Fri, 3 Feb 2023 14:02:44 +0100 Subject: [PATCH 03/57] nice body --- back/views/verifier_request_service.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/views/verifier_request_service.html b/back/views/verifier_request_service.html index 2731afce..55adb0bf 100644 --- a/back/views/verifier_request_service.html +++ b/back/views/verifier_request_service.html @@ -22,7 +22,7 @@

Enter URL:

Response

With status code {{.code}} and returned:

-

{{.returnBody}}

+

{{.returnBody}}

{{end}} From 4d26b1bfc2ee8ec0a6fa7fba7f777ff5c206c6de Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Fri, 3 Feb 2023 14:11:31 +0100 Subject: [PATCH 04/57] with logo --- back/views/partials/header.html | 1 + 1 file changed, 1 insertion(+) diff --git a/back/views/partials/header.html b/back/views/partials/header.html index b194ebc5..7d3b7487 100644 --- a/back/views/partials/header.html +++ b/back/views/partials/header.html @@ -2,4 +2,5 @@ FIWARE Verifiable Credentials +

FIWARE

From d89012ec47f51454013a6891fc7f46a1c4e32399 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Fri, 3 Feb 2023 14:27:46 +0100 Subject: [PATCH 05/57] try to submit --- back/views/verifier_loginexpired.html | 2 +- back/views/verifier_request_service.html | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/back/views/verifier_loginexpired.html b/back/views/verifier_loginexpired.html index cf7aadb2..854df89f 100644 --- a/back/views/verifier_loginexpired.html +++ b/back/views/verifier_loginexpired.html @@ -10,7 +10,7 @@

The login session has expired

Click the button to try again

- Home + Home
diff --git a/back/views/verifier_request_service.html b/back/views/verifier_request_service.html index 55adb0bf..0e0ae705 100644 --- a/back/views/verifier_request_service.html +++ b/back/views/verifier_request_service.html @@ -15,6 +15,13 @@

Enter URL:

id="requestUrl" placeholder="{{.protectedService}}" /> +
+ +
From 84448d38ca60df6fbfefa3a8ab41bd5e16a5d0ce Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Fri, 3 Feb 2023 14:28:29 +0100 Subject: [PATCH 06/57] token --- back/views/verifier_request_service.html | 1 + 1 file changed, 1 insertion(+) diff --git a/back/views/verifier_request_service.html b/back/views/verifier_request_service.html index 0e0ae705..d0a25a3f 100644 --- a/back/views/verifier_request_service.html +++ b/back/views/verifier_request_service.html @@ -16,6 +16,7 @@

Enter URL:

placeholder="{{.protectedService}}" />
+ Date: Fri, 3 Feb 2023 14:35:16 +0100 Subject: [PATCH 07/57] try --- back/views/partials/header.html | 3 ++- back/views/partials/logo.png | Bin 0 -> 13659 bytes 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 back/views/partials/logo.png diff --git a/back/views/partials/header.html b/back/views/partials/header.html index 7d3b7487..dd44b85c 100644 --- a/back/views/partials/header.html +++ b/back/views/partials/header.html @@ -2,5 +2,6 @@ FIWARE Verifiable Credentials -

FIWARE

+ FIWARE +
diff --git a/back/views/partials/logo.png b/back/views/partials/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..755f23f0b3948dfc58bd84d99daca29577211495 GIT binary patch literal 13659 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 Date: Fri, 3 Feb 2023 14:39:39 +0100 Subject: [PATCH 08/57] try both versions --- back/views/verifier_request_service.html | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/back/views/verifier_request_service.html b/back/views/verifier_request_service.html index d0a25a3f..869a0a92 100644 --- a/back/views/verifier_request_service.html +++ b/back/views/verifier_request_service.html @@ -23,6 +23,13 @@

Enter URL:

value="Request" /> +
+ +
From 3bdfec9cc13665b6e8dcbb8f627215938cf5b22c Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Fri, 3 Feb 2023 14:44:33 +0100 Subject: [PATCH 09/57] logging --- back/views/verifier_request_service.html | 4 ++-- verifier.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/back/views/verifier_request_service.html b/back/views/verifier_request_service.html index 869a0a92..f84dadfa 100644 --- a/back/views/verifier_request_service.html +++ b/back/views/verifier_request_service.html @@ -20,14 +20,14 @@

Enter URL:

diff --git a/verifier.go b/verifier.go index e89e8e48..a4c0fc08 100644 --- a/verifier.go +++ b/verifier.go @@ -235,8 +235,8 @@ func (v *Verifier) VerifierPageAccessServicePost(c *fiber.Ctx) error { agent.Set("accept", "application/json") code, returnBody, errors = agent.Bytes() if len(errors) > 0 { - v.server.logger.Errorw("error calling SSI Kit", zap.Errors("errors", errors)) - return fmt.Errorf("error calling SSI Kit: %v", errors[0]) + v.server.logger.Errorw("error calling backend at "+service.Url, zap.Errors("errors", errors)) + return fmt.Errorf("error calling backend: %v", errors[0]) } // Render From e3871b0f31b006ebeb123b302917ecd5b8553440 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Fri, 3 Feb 2023 14:58:22 +0100 Subject: [PATCH 10/57] more info --- verifier.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/verifier.go b/verifier.go index a4c0fc08..aaca4230 100644 --- a/verifier.go +++ b/verifier.go @@ -236,7 +236,7 @@ func (v *Verifier) VerifierPageAccessServicePost(c *fiber.Ctx) error { code, returnBody, errors = agent.Bytes() if len(errors) > 0 { v.server.logger.Errorw("error calling backend at "+service.Url, zap.Errors("errors", errors)) - return fmt.Errorf("error calling backend: %v", errors[0]) + return fmt.Errorf("error calling backend as %s: %v", service.Url, errors[0]) } // Render From 42189f705f601d0e6afd9c6d87680ccec88b4cfb Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Fri, 3 Feb 2023 15:10:15 +0100 Subject: [PATCH 11/57] change submit --- back/views/verifier_request_service.html | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/back/views/verifier_request_service.html b/back/views/verifier_request_service.html index f84dadfa..4b94f1c6 100644 --- a/back/views/verifier_request_service.html +++ b/back/views/verifier_request_service.html @@ -15,21 +15,11 @@

Enter URL:

id="requestUrl" placeholder="{{.protectedService}}" /> -
- - -
-
- -
+ /> From 429d65d60f0da107848ccd49e31d798c8ed5b630 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Fri, 3 Feb 2023 15:18:45 +0100 Subject: [PATCH 12/57] set default --- back/views/verifier_request_service.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/back/views/verifier_request_service.html b/back/views/verifier_request_service.html index 4b94f1c6..e0bb06ab 100644 --- a/back/views/verifier_request_service.html +++ b/back/views/verifier_request_service.html @@ -13,12 +13,12 @@

Enter URL:

type="text" name="Request" id="requestUrl" - placeholder="{{.protectedService}}" + value="{{.protectedService}}" /> From b22c8091eff8cc187536ad3f5175e11432e73b6d Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Fri, 3 Feb 2023 15:21:41 +0100 Subject: [PATCH 13/57] add the body to the message --- verifier.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/verifier.go b/verifier.go index aaca4230..cd7ce3fd 100644 --- a/verifier.go +++ b/verifier.go @@ -225,7 +225,7 @@ func (v *Verifier) VerifierPageAccessServicePost(c *fiber.Ctx) error { v.server.logger.Infof("Error parsing: %s", err) return err } - + v.server.logger.Errorw(string(c.Body())) // Prepare to GET to the url agent := fiber.Get(service.Url) From d5947519aea02b60341a0114ae3e1a94ab8607f2 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Fri, 3 Feb 2023 15:26:46 +0100 Subject: [PATCH 14/57] fix the name --- back/views/verifier_request_service.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/views/verifier_request_service.html b/back/views/verifier_request_service.html index e0bb06ab..c54de55d 100644 --- a/back/views/verifier_request_service.html +++ b/back/views/verifier_request_service.html @@ -11,7 +11,7 @@

Enter URL:

From 3cbb25754a4f3c161f13bc0256dc2cd15760af46 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Wed, 8 Feb 2023 10:08:16 +0100 Subject: [PATCH 15/57] reduce --- main.go | 18 ------------------ verifier.go | 54 ----------------------------------------------------- 2 files changed, 72 deletions(-) diff --git a/main.go b/main.go index baff7a4a..0ef0e40a 100644 --- a/main.go +++ b/main.go @@ -34,10 +34,7 @@ const defaultStoreDriverName = "sqlite3" const defaultStoreDataSourceName = "file:issuer.sqlite?mode=rwc&cache=shared&_fk=1" const defaultPassword = "ThePassword" -const corePrefix = "/core/api/v1" -const issuerPrefix = "/issuer/api/v1" const verifierPrefix = "/verifier/api/v1" -const walletPrefix = "/wallet/api/v1" var ( prod = flag.Bool("prod", false, "Enable prefork in Production") @@ -160,7 +157,6 @@ func BackendServer() { } setupVerifier(s) - setupCoreRoutes(s) // Setup static files s.Static("/static", cfg.String("server.staticDir", defaultStaticDir)) @@ -170,20 +166,6 @@ func BackendServer() { } -func setupCoreRoutes(s *Server) { - // ######################################## - // Core routes - coreRoutes := s.Group(corePrefix) - - // Create DID - coreRoutes.Get("/createdid", s.CoreAPICreateDID) - // List Templates - coreRoutes.Get("/listcredentialtemplates", s.CoreAPIListCredentialTemplates) - // Get one template - coreRoutes.Get("/getcredentialtemplate/:id", s.CoreAPIGetCredentialTemplate) - -} - func fromMap(configMap map[string]any) (skc *SSIKitConfig) { coreUrl, ok := configMap["coreURL"] if !ok { diff --git a/verifier.go b/verifier.go index cd7ce3fd..803905fb 100644 --- a/verifier.go +++ b/verifier.go @@ -40,9 +40,6 @@ func setupVerifier(s *Server) { // Error page when login session has expired without the user sending the credential verifierRoutes.Get("/loginexpired", verifier.VerifierPageLoginExpired) - // For same-device logins (e.g., with the enterprise wallet) - verifierRoutes.Get("/startsiopsamedevice", verifier.VerifierPageStartSIOPSameDevice) - // Page displaying the received credential, after successful login verifierRoutes.Get("/receivecredential/:state", verifier.VerifierPageReceiveCredential) @@ -95,9 +92,7 @@ func (v *Verifier) VerifierPageDisplayQRSIOP(c *fiber.Ctx) error { // Render the page m := fiber.Map{ - "issuerPrefix": issuerPrefix, "verifierPrefix": verifierPrefix, - "walletPrefix": walletPrefix, "qrcode": base64Img, "prefix": verifierPrefix, "state": state, @@ -112,45 +107,6 @@ func (v *Verifier) VerifierPageLoginExpired(c *fiber.Ctx) error { return c.Render("verifier_loginexpired", m) } -func (v *Verifier) VerifierPageStartSIOPSameDevice(c *fiber.Ctx) error { - - state := c.Query("state") - - const scope = "dsba.credentials.presentation.PacketDeliveryService" - const response_type = "vp_token" - redirect_uri := c.Protocol() + "://" + c.Hostname() + verifierPrefix + "/authenticationresponse" - - // template := "https://hesusruiz.github.io/faster/?scope={{scope}}" + - // "&response_type={{response_type}}" + - // "&response_mode=post" + - // "&client_id={{client_id}}" + - // "&redirect_uri={{redirect_uri}}" + - // "&state={{state}}" + - // "&nonce={{nonce}}" - - walletUri := c.Protocol() + "://" + c.Hostname() + walletPrefix + "/selectcredential" - template := walletUri + "/?scope={{scope}}" + - "&response_type={{response_type}}" + - "&response_mode=post" + - "&client_id={{client_id}}" + - "&redirect_uri={{redirect_uri}}" + - "&state={{state}}" + - "&nonce={{nonce}}" - - t := fasttemplate.New(template, "{{", "}}") - str := t.ExecuteString(map[string]interface{}{ - "scope": scope, - "response_type": response_type, - "client_id": v.server.verifierDID, - "redirect_uri": redirect_uri, - "state": state, - "nonce": generateNonce(), - }) - fmt.Println(str) - - return c.Redirect(str) -} - func (v *Verifier) VerifierPageReceiveCredential(c *fiber.Ctx) error { // Get the state as a path parameter @@ -189,9 +145,7 @@ func (v *Verifier) VerifierPageReceiveCredential(c *fiber.Ctx) error { // Render m := fiber.Map{ - "issuerPrefix": issuerPrefix, "verifierPrefix": verifierPrefix, - "walletPrefix": walletPrefix, "claims": claims, "prefix": verifierPrefix, } @@ -279,9 +233,7 @@ func (v *Verifier) VerifierPageAccessProtectedService(c *fiber.Ctx) error { // Render m := fiber.Map{ - "issuerPrefix": issuerPrefix, "verifierPrefix": verifierPrefix, - "walletPrefix": walletPrefix, "accesstoken": accessToken, "protected": protected, "code": code, @@ -419,10 +371,6 @@ func (v *Verifier) VerifierAPIAuthenticationResponse(c *fiber.Ctx) error { func (v *Verifier) VerifierPageDisplayQR(c *fiber.Ctx) error { - if sameDevice { - return v.VerifierPageStartSIOPSameDevice(c) - } - // Generate the state that will be used for checking expiration state := generateNonce() @@ -440,9 +388,7 @@ func (v *Verifier) VerifierPageDisplayQR(c *fiber.Ctx) error { // Render index m := fiber.Map{ - "issuerPrefix": issuerPrefix, "verifierPrefix": verifierPrefix, - "walletPrefix": walletPrefix, "qrcode": qrCode1, "prefix": verifierPrefix, "state": state, From 69fd6b35abc08ee515f54a4ba30590e9965ba14a Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Wed, 8 Feb 2023 10:10:18 +0100 Subject: [PATCH 16/57] clean api --- api/api.yaml | 257 --------------------------------------------------- 1 file changed, 257 deletions(-) diff --git a/api/api.yaml b/api/api.yaml index a228c430..ea12f262 100644 --- a/api/api.yaml +++ b/api/api.yaml @@ -10,133 +10,7 @@ tags: description: All api-endpoints, e.g. the once that can be reused by other applicatios - name: verifier description: All endpoints belonging to the verifier functionality - - name: issuer - description: All endpoints belonging to the issuer functionality - - name: core - description: All endpoints belonging to core functionality, e.g. setup and info stuff - - name: wallet - description: All endpoints belonging to the wallet functionality - - name: base - description: General endpoints, providing information or entrypoint routing paths: - /issuer/api/v1/newcredential: - get: - tags: - - issuer - - frontend - operationId: IssuerPageNewCredentialFormDisplay - summary: Returns the page to issue new credentials - responses: - '200': - description: Show the credentials input page - content: - text/html: - schema: - type: object - post: - tags: - - issuer - - frontend - operationId: IssuerPageNewCredentialFormPost - summary: Issues a new credentials and renders them to a page - requestBody: - required: true - content: - application/x-www-form-urlencoded: - schema: - $ref: '#/components/schemas/VCCreate' - responses: - '200': - description: Show the created credential on a rendered page - content: - text/html: - schema: - type: object - /issuer/api/v1/creddetails/{id}: - get: - tags: - - issuer - - frontend - parameters: - - $ref: '#/components/parameters/Id' - operationId: IssuerPageCredentialDetails - summary: Show the credential details on a rendered page - responses: - '200': - description: Present the credential details in a rendered html page - content: - text/html: - schema: - type: object - /issuer/api/v1/displayqrurl/{id}: - get: - tags: - - issuer - - frontend - parameters: - - $ref: '#/components/parameters/Id' - operationId: IssuerPageDisplayQRURL - summary: Show the credential encoded as a qr-code on a rendered html page - responses: - '200': - description: Present the credential qr-code in a rendered html page - content: - text/html: - schema: - type: object - - /issuer/api/v1/allcredentials: - get: - tags: - - issuer - - api - operationId: IssuerAPIAllCredentials - summary: Return the ids of all issued credentials - responses: - '200': - description: Returns the list of ids - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/CredentialId' - /issuer/api/v1/credential: - post: - tags: - - issuer - - api - operationId: CreateNewCredential - summary: Issues a new credentials and returns it - requestBody: - required: true - content: - application/x-www-form-urlencoded: - schema: - $ref: '#/components/schemas/VCCreate' - responses: - '200': - description: Return the created credential - content: - application/json: - schema: - $ref: '#/components/schemas/VerifiableCredential' - /issuer/api/v1/credential/{id}: - get: - tags: - - issuer - - api - parameters: - - $ref: '#/components/parameters/Id' - operationId: IssuerAPICredential - summary: Return credential with the given ID - responses: - '200': - description: The credential - content: - text/plain: - schema: - $ref: '#/components/schemas/VerifiableCredential' /verifier/api/v1/displayqr: get: tags: @@ -301,87 +175,6 @@ paths: application/json: schema: $ref: '#/components/schemas/JWKSet' - - /wallet/api/v1/selectcredential: - get: - tags: - - wallet - - frontend - operationId: WalletPageSelectCredential - summary: Present a rendered page with the available credentials - responses: - '200': - description: The rendered page - content: - text/html: - schema: - type: object - /wallet/api/v1/sendcredential: - get: - tags: - - wallet - - frontend - parameters: - - $ref: '#/components/parameters/QueryState' - - $ref: '#/components/parameters/QueryId' - - $ref: '#/components/parameters/RedirectUri' - operationId: WalletPageSendCredential - summary: Executes a post with the given credential to the redirect_uri and returns a rendered page, presenting the post-result - responses: - '200': - description: The rendered page - content: - text/html: - schema: - type: object - /core/api/v1/createdid: - get: - tags: - - core - - api - operationId: CoreAPICreateDID - summary: Wrapper for the waltid-ssikit custodian endpoint for creating did's of type key - responses: - '200': - description: Creation result from the ssikit - content: - application/json: - schema: - type: string - example: did:key:z6MkibsKombswvCMhej83YbHsyknL2uc5kVazwr4xB3JqeUX - /core/api/v1/listcredentialtemplates: - get: - tags: - - core - - api - operationId: CoreAPIListCredentialTemplates - summary: Wrapper for the waltid-ssikit signatory endpoint for listing templates - responses: - '200': - description: List of templates, no offical spec available from ssikit, format is assumed - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/CredentialTemplate' - /core/api/v1/getcredentialtemplate/{id}: - get: - tags: - - core - - api - parameters: - - $ref: '#/components/parameters/Id' - operationId: CoreAPIGetCredentialTemplate - summary: Wrapper for the waltid-ssikit signatory endpoint for retrieving a template - responses: - '200': - description: The requested template. - content: - application/json: - schema: - description: SSIKit doc says type string, but its a vc-object instead. - type: object /: get: tags: @@ -396,20 +189,6 @@ paths: text/plain: schema: type: object - /issuer: - get: - tags: - - base - - frontend - operationId: HandleIssuerHome - summary: Returns the rendered homepage for the issuer functionality - responses: - '200': - description: The issuer page - content: - text/plain: - schema: - type: object /verifier: get: tags: @@ -477,23 +256,6 @@ components: type: string example: https://my-verifier.com/verifier/api/v1/authenticationresponse schemas: - CredentialTemplate: - type: object - properties: - mutable: - type: boolean - example: false - name: - type: string - example: VerifiableId - template: - type: string - CredentialId: - type: object - properties: - id: - type: string - example: urn:uuid:e44beccc-a766-4baf-8cd0-17f86ef74a5c CredentialsType: type: array items: @@ -608,25 +370,6 @@ components: properties: credential: $ref: '#/components/schemas/VerifiableCredential' - VCCreate: - type: object - properties: - email: - type: string - format: email - example: test@test.org - firstName: - type: string - example: Test - familyName: - type: string - example: User - target: - type: string - example: did:key:myuserkey - roles: - type: string - example: GOLD_CUSTOMER,STANDARD_CUSTOMER BackendInfo: type: object properties: From 8b1e3f3b121c0a9c0988793040f85754c139a9e2 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Fri, 10 Feb 2023 10:41:24 +0100 Subject: [PATCH 17/57] split frontend and api --- README.md | 4 +- frontend.go | 216 ++++++++++++++++++++++++++++++++++++++++++++++++++++ main.go | 1 + verifier.go | 190 --------------------------------------------- 4 files changed, 219 insertions(+), 192 deletions(-) create mode 100644 frontend.go diff --git a/README.md b/README.md index 2427f6dd..dac956d5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# vcverifier +# VCVerifier -vcverifier includes in a single binary demo versions of Issuer, Verifier and Wallet (same-device only, for a cross-device wallet please see [VCWallet](https://github.com/hesusruiz/VCWallet)). +VCerifier includes in a single binary demo versions of Issuer, Verifier and Wallet (same-device only, for a cross-device wallet please see [VCWallet](https://github.com/hesusruiz/VCWallet)). This facilitates installation and allows to see how all components fit together and the protocol flows between them. diff --git a/frontend.go b/frontend.go new file mode 100644 index 00000000..71121cfa --- /dev/null +++ b/frontend.go @@ -0,0 +1,216 @@ +package main + +import ( + "encoding/base64" + "fmt" + "time" + + "github.com/gofiber/fiber/v2" + qrcode "github.com/skip2/go-qrcode" + "go.uber.org/zap" +) + +const frontendPrefix = "/" + +type Frontend struct { + server *Server +} + +// setupVerifier creates and setups the Issuer routes +func setupFrontend(s *Server) { + + frontend := &Frontend{s} + + // Define the prefix for Verifier routes + frontendRoutes := s.Group(frontendPrefix) + + // Pages + + // Display a QR code for mobile wallet or a link for enterprise wallet + frontendRoutes.Get("/displayqr", frontend.VerifierPageDisplayQRSIOP) + + // Error page when login session has expired without the user sending the credential + frontendRoutes.Get("/loginexpired", frontend.VerifierPageLoginExpired) + + // Page displaying the received credential, after successful login + frontendRoutes.Get("/receivecredential/:state", frontend.VerifierPageReceiveCredential) + + // Allow simulation of accessing protected resources, after successful login + frontendRoutes.Get("/accessprotectedservice", frontend.VerifierPageAccessProtectedService) + frontendRoutes.Post("/accessService", frontend.VerifierPageAccessServicePost) + frontendRoutes.Get("/accessService", frontend.VerifierPageAccessServiceGet) +} + +func (f *Frontend) VerifierPageDisplayQRSIOP(c *fiber.Ctx) error { + + // Generate the state that will be used for checking expiration and also successful logon + state := generateNonce() + + // Create an entry in storage that will expire. + // The entry is identified by the nonce + f.server.storage.Set(state, []byte("pending"), 200*time.Second) + + // This is the endpoint inside the QR that the wallet will use to send the VC/VP + redirect_uri := c.Protocol() + "://" + c.Hostname() + verifierPrefix + "/authenticationresponse" + + // Create the Authentication Request + authRequest := createAuthenticationRequest(f.server.verifierDID, redirect_uri, state) + f.server.logger.Info("AuthRequest", authRequest) + + // Create the QR code for cross-device SIOP + png, err := qrcode.Encode(authRequest, qrcode.Medium, 256) + if err != nil { + return err + } + + // Convert the image data to a dataURL + base64Img := base64.StdEncoding.EncodeToString(png) + base64Img = "data:image/png;base64," + base64Img + + // Render the page + m := fiber.Map{ + "verifierPrefix": frontendPrefix, + "qrcode": base64Img, + "prefix": frontendPrefix, + "state": state, + } + return c.Render("verifier_present_qr", m) +} + +func (f *Frontend) VerifierPageLoginExpired(c *fiber.Ctx) error { + m := fiber.Map{ + "prefix": frontendPrefix, + } + return c.Render("verifier_loginexpired", m) +} + +func (f *Frontend) VerifierPageReceiveCredential(c *fiber.Ctx) error { + + // Get the state as a path parameter + state := c.Params("state") + + // get the credential from the storage + rawCred, _ := f.server.storage.Get(state) + if len(rawCred) == 0 { + // Render an error + m := fiber.Map{ + "error": "No credential found", + } + return c.Render("displayerror", m) + } + + claims := string(rawCred) + + // Create an access token from the credential + accessToken, err := f.server.verifierVault.CreateAccessToken(claims, f.server.cfg.String("verifier.id")) + if err != nil { + return err + } + + // Set it in a cookie + cookie := new(fiber.Cookie) + cookie.Name = "dbsamvf" + cookie.Value = string(accessToken) + cookie.Expires = time.Now().Add(1 * time.Hour) + + // Set cookie + c.Cookie(cookie) + + // Set also the access token in the Authorization field of the response header + bearer := "Bearer " + string(accessToken) + c.Set("Authorization", bearer) + + // Render + m := fiber.Map{ + "verifierPrefix": frontendPrefix, + "claims": claims, + "prefix": frontendPrefix, + } + return c.Render("verifier_receivedcredential", m) +} + +func (f *Frontend) VerifierPageAccessServiceGet(c *fiber.Ctx) error { + + protected := f.server.cfg.String("verifier.protectedResource.url") + // Render + m := fiber.Map{ + "protectedService": protected, + "verifierPrefix": verifierPrefix, + } + return c.Render("frontendPrefix", m) +} + +func (f *Frontend) VerifierPageAccessServicePost(c *fiber.Ctx) error { + var code int + var returnBody []byte + var errors []error + + // Get the access token from the cookie + accessToken := c.Cookies("dbsamvf") + service := &AccessServiceForm{} + if err := c.BodyParser(service); err != nil { + f.server.logger.Infof("Error parsing: %s", err) + return err + } + f.server.logger.Errorw(string(c.Body())) + // Prepare to GET to the url + agent := fiber.Get(service.Url) + + // Set the Authentication header + agent.Set("Authorization", "Bearer "+accessToken) + + agent.Set("accept", "application/json") + code, returnBody, errors = agent.Bytes() + if len(errors) > 0 { + f.server.logger.Errorw("error calling backend at "+service.Url, zap.Errors("errors", errors)) + return fmt.Errorf("error calling backend as %s: %v", service.Url, errors[0]) + } + + // Render + m := fiber.Map{ + "protectedService": service.Url, + "verifierPrefix": frontendPrefix, + "code": code, + "returnBody": string(returnBody), + } + return c.Render("verifier_request_service", m) +} + +func (f *Frontend) VerifierPageAccessProtectedService(c *fiber.Ctx) error { + + var code int + var returnBody []byte + var errors []error + + // Get the access token from the cookie + accessToken := c.Cookies("dbsamvf") + + // Check if the user has configured a protected service to access + protected := f.server.cfg.String("verifier.protectedResource.url") + if len(protected) > 0 { + + // Prepare to GET to the url + agent := fiber.Get(protected) + + // Set the Authentication header + agent.Set("Authorization", "Bearer "+accessToken) + + agent.Set("accept", "application/json") + code, returnBody, errors = agent.Bytes() + if len(errors) > 0 { + f.server.logger.Errorw("error calling SSI Kit", zap.Errors("errors", errors)) + return fmt.Errorf("error calling SSI Kit: %v", errors[0]) + } + + } + + // Render + m := fiber.Map{ + "verifierPrefix": frontendPrefix, + "accesstoken": accessToken, + "protected": protected, + "code": code, + "returnBody": string(returnBody), + } + return c.Render("verifier_protectedservice", m) +} diff --git a/main.go b/main.go index 0ef0e40a..d5292724 100644 --- a/main.go +++ b/main.go @@ -157,6 +157,7 @@ func BackendServer() { } setupVerifier(s) + setupFrontend(s) // Setup static files s.Static("/static", cfg.String("server.staticDir", defaultStaticDir)) diff --git a/verifier.go b/verifier.go index 803905fb..46e5bcec 100644 --- a/verifier.go +++ b/verifier.go @@ -32,22 +32,6 @@ func setupVerifier(s *Server) { jwks_uri := s.cfg.String("verifier.uri_prefix") + s.cfg.String("verifier.jwks_uri") s.Get(jwks_uri, s.VerifierAPIJWKS) - // Pages - - // Display a QR code for mobile wallet or a link for enterprise wallet - verifierRoutes.Get("/displayqr", verifier.VerifierPageDisplayQRSIOP) - - // Error page when login session has expired without the user sending the credential - verifierRoutes.Get("/loginexpired", verifier.VerifierPageLoginExpired) - - // Page displaying the received credential, after successful login - verifierRoutes.Get("/receivecredential/:state", verifier.VerifierPageReceiveCredential) - - // Allow simulation of accessing protected resources, after successful login - verifierRoutes.Get("/accessprotectedservice", verifier.VerifierPageAccessProtectedService) - verifierRoutes.Post("/accessService", verifier.VerifierPageAccessServicePost) - verifierRoutes.Get("/accessService", verifier.VerifierPageAccessServiceGet) - // APIs // Used by the login page from the browser, to check successful login or expiration @@ -64,184 +48,10 @@ func setupVerifier(s *Server) { } -func (v *Verifier) VerifierPageDisplayQRSIOP(c *fiber.Ctx) error { - - // Generate the state that will be used for checking expiration and also successful logon - state := generateNonce() - - // Create an entry in storage that will expire. - // The entry is identified by the nonce - v.server.storage.Set(state, []byte("pending"), 200*time.Second) - - // This is the endpoint inside the QR that the wallet will use to send the VC/VP - redirect_uri := c.Protocol() + "://" + c.Hostname() + verifierPrefix + "/authenticationresponse" - - // Create the Authentication Request - authRequest := createAuthenticationRequest(v.server.verifierDID, redirect_uri, state) - v.server.logger.Info("AuthRequest", authRequest) - - // Create the QR code for cross-device SIOP - png, err := qrcode.Encode(authRequest, qrcode.Medium, 256) - if err != nil { - return err - } - - // Convert the image data to a dataURL - base64Img := base64.StdEncoding.EncodeToString(png) - base64Img = "data:image/png;base64," + base64Img - - // Render the page - m := fiber.Map{ - "verifierPrefix": verifierPrefix, - "qrcode": base64Img, - "prefix": verifierPrefix, - "state": state, - } - return c.Render("verifier_present_qr", m) -} - -func (v *Verifier) VerifierPageLoginExpired(c *fiber.Ctx) error { - m := fiber.Map{ - "prefix": verifierPrefix, - } - return c.Render("verifier_loginexpired", m) -} - -func (v *Verifier) VerifierPageReceiveCredential(c *fiber.Ctx) error { - - // Get the state as a path parameter - state := c.Params("state") - - // get the credential from the storage - rawCred, _ := v.server.storage.Get(state) - if len(rawCred) == 0 { - // Render an error - m := fiber.Map{ - "error": "No credential found", - } - return c.Render("displayerror", m) - } - - claims := string(rawCred) - - // Create an access token from the credential - accessToken, err := v.server.verifierVault.CreateAccessToken(claims, v.server.cfg.String("verifier.id")) - if err != nil { - return err - } - - // Set it in a cookie - cookie := new(fiber.Cookie) - cookie.Name = "dbsamvf" - cookie.Value = string(accessToken) - cookie.Expires = time.Now().Add(1 * time.Hour) - - // Set cookie - c.Cookie(cookie) - - // Set also the access token in the Authorization field of the response header - bearer := "Bearer " + string(accessToken) - c.Set("Authorization", bearer) - - // Render - m := fiber.Map{ - "verifierPrefix": verifierPrefix, - "claims": claims, - "prefix": verifierPrefix, - } - return c.Render("verifier_receivedcredential", m) -} - type AccessServiceForm struct { Url string `form:"requestUrl,omitempty"` } -func (v *Verifier) VerifierPageAccessServiceGet(c *fiber.Ctx) error { - - protected := v.server.cfg.String("verifier.protectedResource.url") - // Render - m := fiber.Map{ - "protectedService": protected, - "verifierPrefix": verifierPrefix, - } - return c.Render("verifier_request_service", m) -} - -func (v *Verifier) VerifierPageAccessServicePost(c *fiber.Ctx) error { - var code int - var returnBody []byte - var errors []error - - // Get the access token from the cookie - accessToken := c.Cookies("dbsamvf") - service := &AccessServiceForm{} - if err := c.BodyParser(service); err != nil { - v.server.logger.Infof("Error parsing: %s", err) - return err - } - v.server.logger.Errorw(string(c.Body())) - // Prepare to GET to the url - agent := fiber.Get(service.Url) - - // Set the Authentication header - agent.Set("Authorization", "Bearer "+accessToken) - - agent.Set("accept", "application/json") - code, returnBody, errors = agent.Bytes() - if len(errors) > 0 { - v.server.logger.Errorw("error calling backend at "+service.Url, zap.Errors("errors", errors)) - return fmt.Errorf("error calling backend as %s: %v", service.Url, errors[0]) - } - - // Render - m := fiber.Map{ - "protectedService": service.Url, - "verifierPrefix": verifierPrefix, - "code": code, - "returnBody": string(returnBody), - } - return c.Render("verifier_request_service", m) -} - -func (v *Verifier) VerifierPageAccessProtectedService(c *fiber.Ctx) error { - - var code int - var returnBody []byte - var errors []error - - // Get the access token from the cookie - accessToken := c.Cookies("dbsamvf") - - // Check if the user has configured a protected service to access - protected := v.server.cfg.String("verifier.protectedResource.url") - if len(protected) > 0 { - - // Prepare to GET to the url - agent := fiber.Get(protected) - - // Set the Authentication header - agent.Set("Authorization", "Bearer "+accessToken) - - agent.Set("accept", "application/json") - code, returnBody, errors = agent.Bytes() - if len(errors) > 0 { - v.server.logger.Errorw("error calling SSI Kit", zap.Errors("errors", errors)) - return fmt.Errorf("error calling SSI Kit: %v", errors[0]) - } - - } - - // Render - m := fiber.Map{ - "verifierPrefix": verifierPrefix, - "accesstoken": accessToken, - "protected": protected, - "code": code, - "returnBody": string(returnBody), - } - return c.Render("verifier_protectedservice", m) -} - func (v *Verifier) VerifierAPIPoll(c *fiber.Ctx) error { // get the state From 8fe5ed8a87f9d0d18a3f0872debc1b540fb1bdaf Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Fri, 10 Feb 2023 10:48:34 +0100 Subject: [PATCH 18/57] move index too --- frontend.go | 19 ++++++++++++++++++- main.go | 21 --------------------- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/frontend.go b/frontend.go index 71121cfa..80942c39 100644 --- a/frontend.go +++ b/frontend.go @@ -25,7 +25,7 @@ func setupFrontend(s *Server) { frontendRoutes := s.Group(frontendPrefix) // Pages - + frontendRoutes.Get("/", frontend.HandleVerifierHome) // Display a QR code for mobile wallet or a link for enterprise wallet frontendRoutes.Get("/displayqr", frontend.VerifierPageDisplayQRSIOP) @@ -41,6 +41,23 @@ func setupFrontend(s *Server) { frontendRoutes.Get("/accessService", frontend.VerifierPageAccessServiceGet) } +func (f *Frontend) HandleVerifierHome(c *fiber.Ctx) error { + + // Get the list of credentials + credsSummary, err := f.server.Operations.GetAllCredentials() + if err != nil { + return err + } + + // Render template + m := fiber.Map{ + "verifierPrefix": frontendPrefix, + "prefix": frontendPrefix, + "credlist": credsSummary, + } + return c.Render("verifier_home", m) +} + func (f *Frontend) VerifierPageDisplayQRSIOP(c *fiber.Ctx) error { // Generate the state that will be used for checking expiration and also successful logon diff --git a/main.go b/main.go index d5292724..df1d511f 100644 --- a/main.go +++ b/main.go @@ -144,10 +144,6 @@ func BackendServer() { s.storage = memory.New() defer s.storage.Close() - // ########################## - // Application Home pages - s.Get("/", s.HandleVerifierHome) - // Info base path s.Get("/info", s.GetBackendInfo) @@ -212,23 +208,6 @@ func (s *Server) HandleStop(c *fiber.Ctx) error { return nil } -func (s *Server) HandleVerifierHome(c *fiber.Ctx) error { - - // Get the list of credentials - credsSummary, err := s.Operations.GetAllCredentials() - if err != nil { - return err - } - - // Render template - m := fiber.Map{ - "verifierPrefix": verifierPrefix, - "prefix": verifierPrefix, - "credlist": credsSummary, - } - return c.Render("verifier_home", m) -} - func generateNonce() string { b := make([]byte, 16) io.ReadFull(rand.Reader, b) From 457cbb0b6cc41e05c0f07bc01a1e316028fd42e7 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Fri, 10 Feb 2023 10:57:04 +0100 Subject: [PATCH 19/57] try --- frontend.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend.go b/frontend.go index 80942c39..2325a973 100644 --- a/frontend.go +++ b/frontend.go @@ -52,7 +52,7 @@ func (f *Frontend) HandleVerifierHome(c *fiber.Ctx) error { // Render template m := fiber.Map{ "verifierPrefix": frontendPrefix, - "prefix": frontendPrefix, + "prefix": verifierPrefix, "credlist": credsSummary, } return c.Render("verifier_home", m) From 818569a0dba1b0228a53c0865f54cd89217c51a4 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Fri, 10 Feb 2023 11:03:26 +0100 Subject: [PATCH 20/57] no prefix for frontend --- frontend.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend.go b/frontend.go index 2325a973..4e2d7733 100644 --- a/frontend.go +++ b/frontend.go @@ -10,7 +10,7 @@ import ( "go.uber.org/zap" ) -const frontendPrefix = "/" +const frontendPrefix = "" type Frontend struct { server *Server @@ -52,7 +52,7 @@ func (f *Frontend) HandleVerifierHome(c *fiber.Ctx) error { // Render template m := fiber.Map{ "verifierPrefix": frontendPrefix, - "prefix": verifierPrefix, + "prefix": frontendPrefix, "credlist": credsSummary, } return c.Render("verifier_home", m) From d1fa3bba1eee01b0a83c3665da21ac0a89ca810a Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Fri, 10 Feb 2023 11:12:51 +0100 Subject: [PATCH 21/57] state --- back/views/verifier_present_qr.html | 4 ++-- frontend.go | 3 ++- main.go | 2 -- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/back/views/verifier_present_qr.html b/back/views/verifier_present_qr.html index 822d0c8e..937e9b5e 100644 --- a/back/views/verifier_present_qr.html +++ b/back/views/verifier_present_qr.html @@ -27,7 +27,7 @@

Or click this button to authenticate with the browser

} const data = await response.text() if (data === "expired") { - location = "{{.verifierPrefix}}/loginexpired" + location = "{{.frontendPrefix}}/loginexpired" return } if (data === "pending") { @@ -35,7 +35,7 @@

Or click this button to authenticate with the browser

} console.log("Received:", data) - location = "{{.verifierPrefix}}/receivecredential/{{.state}}" + location = "{{.frontendPrefix}}/receivecredential/{{.state}}" return } catch (error) { window.alert("A server error happened.") diff --git a/frontend.go b/frontend.go index 4e2d7733..8b16bf94 100644 --- a/frontend.go +++ b/frontend.go @@ -86,7 +86,8 @@ func (f *Frontend) VerifierPageDisplayQRSIOP(c *fiber.Ctx) error { // Render the page m := fiber.Map{ - "verifierPrefix": frontendPrefix, + "verifierPrefix": verifierPrefix, + "frontendPrefix": frontendPrefix, "qrcode": base64Img, "prefix": frontendPrefix, "state": state, diff --git a/main.go b/main.go index df1d511f..25ff7df2 100644 --- a/main.go +++ b/main.go @@ -215,8 +215,6 @@ func generateNonce() string { return nonce } -var sameDevice = false - type jwkSet struct { Keys []*jwk.JWK `json:"keys"` } From 0dcf6aa99ddd47a250ca43351b7087b821222a10 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Fri, 10 Feb 2023 11:24:56 +0100 Subject: [PATCH 22/57] show logo --- back/views/partials/header.html | 2 +- back/{views/partials => www/img}/logo.png | Bin 2 files changed, 1 insertion(+), 1 deletion(-) rename back/{views/partials => www/img}/logo.png (100%) diff --git a/back/views/partials/header.html b/back/views/partials/header.html index dd44b85c..f75bd2e5 100644 --- a/back/views/partials/header.html +++ b/back/views/partials/header.html @@ -2,6 +2,6 @@ FIWARE Verifiable Credentials - FIWARE + FIWARE diff --git a/back/views/partials/logo.png b/back/www/img/logo.png similarity index 100% rename from back/views/partials/logo.png rename to back/www/img/logo.png From 895e66bf5f3be7ad87809a122f78dbe479996c74 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Fri, 10 Feb 2023 11:30:36 +0100 Subject: [PATCH 23/57] other image --- back/www/img/logo.png | Bin 13659 -> 1338 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/back/www/img/logo.png b/back/www/img/logo.png index 755f23f0b3948dfc58bd84d99daca29577211495..beb19973fe397cb52684f9fd57ca5a18582e6810 100644 GIT binary patch literal 1338 zcmV-A1;zS_P)-}H%G`RLhz+}a9n$_{_ zizczb@&;Lu)tHw=%Z`G6CLB&fRBUPgQrRf%5x?fl|4XOY^Aae9U`-+tj{6~+ctpH1?rA;E4W zJDw*{7Gh&@bLtopmM07l;LR8SY5J{IhL<#5QxKbd=U7voR z!D(91y7<(ebuIClohD;)&{J9?QniLv#q>;-h}%(W?>6)cdyIvCVekp#)iS6f2wDLQ z;dw9R$*x&R`@DjT;YZsTG(-a)2YyH|1s&j752L;6#iO0^dyt?j$`-_!(qG^h5l;u{ zPxVM2kYnaT+mvLq3bYXhKRStzJM&+!yvI+vM7AKwBz>B`++t-ja$TKua;By#TAs_wN3m{J2(@R!*Na(WNC8@gp zCh+n9>ACg@40#c|RzPsdb#bPWKEj`8>wvVXfC9i6oiF{dLG_Yf^cxq)5_ z;=AXq8u*><9irb05d8&uy4Hh5LA6Bn6R#bfBZ6-$K=^$LRLj&a2Ibk`CIh0w5R~oqpf^%Ktd}{oVvb%@9VA5%Y`f0E zp1kgb*1yu@Ki8YFt39WfRWII^(BOq149c-|xL11e3B9@AE%mBNdb-w?Xuwoz2n&CG z)+6o^^I5%N3r}PGdNhyY7d9`0U}k@ui%k|~=o6LGQ^%N`hkrhe11g4Q*s2648UJhW z#;U?v6LTU2TH#u&A+3E6i%=81m6R&BY8on{Wv)Db9(ivUQ)bY z=~*Q4JAN)cjY__%=hu3CO>bX!4_peJ1mpm z#U1ytvd5m}vR=Xy3q5>@7xYkF=IjPp;r9*_u%WxIXZ)Th(8HjSxu7>ymx`(Ea6?&q zi6soiRXrq&7i*%m+r3#EjpYD?H}z0me81;%Vh=EV4R6g$vQyYy)x-47;F{OJ&f@BF zx~1n~hq}T-uGhGz7ya7qnjYF}K3~ #EIgCrdRx=~R@osPKP@=u`Pt@?g zQFk23LA6ZZKm{|- w6X*Vg-#W^vp)Yr=C+8$7goT$J+xzC^e0)68Rdh19v3g@=Zt3SXVkH6q z@Ej=0NNW2opX8vslE2M5|H#AbZ^)f)>h37Ny*R{~sYi_(o;ZL<+3_`kmANU+;Fo*N z5E&nV_pJ#tB(|53-#wxuJfL5$8>tDOXt>orZh}x&pUsRPvKTKFQp+i$gfZElARjz{ zea}hzfyY0-XeBRDh;ocpHScV8t+eB%r<`r%kIL=gZ0XcX;71R&xswwXM1TUd=AH}Z zsV)ESHP5UbtENJ#IkeR;Xh4LJ0=1qTpPOQeU?bsWau#J%l1&A68V-O26p#o7`hTa| zM|q~a{?(NjZFx6i`UejH1_9#oeV&Tt4JFRHYGgQmKrjI?fF#2ZYuHV4UOg*tZMX2_ z;{J1MyUI_h%GaWdGt$4dU`%PusFXF zLB8v{<{IDufPfN^YGT!lhm+@N$w{A5C!(jne{t)E^G7710FA5!T*=xk6A~sISg`dP zRn5nBW$w>cm5f2DE+w69epa)rS&k#;U#!$?$DH|vz5u<_w?Yx>LL>mcggDvIC_;1e z+a_6!-7~M77?p(nf>Q8M5+$o;4rExN#wW)LfY@LAWfp#M_4HgM}fPhnh>p9Wzjp=YGiLn&sX zEUnL3UP>cTu@0RMqc403j+wF-CyM3C7K9HAM@Fs~-AnA%dRB;1 zc-U7d^`~MW?B$%@Bd?f5`5Aa^He^7$LnvXNbbO#I+XC~DVuC^dsZE4sVe95w9bui) zil_@Q5Qu?LCeu~7M*>`XaRFW)sB4jqHhfn}1yRI=HJ z9FKRynwIWal!3tmJ7q0VR5aCKW?dzX%9sQ+TA#w|FDT4<^j9py^i2~IE4U=Ca3heY z5Z^OwZ7ghUgkaoR$d{6)J@TOrvNj&bpgp~)|Bc3B|HbsH$HvskcZ;dlR{5tSIBak; zk<7VbM|xqHLHn)eo%e<%cS;5Bc;*Ya5$nJR8e*J@wc{HjlnN1)ZAC;Y|7n>|h!8L| zIt|d6#e&DI8>`RBl?_82j|-1Rl8{<6{q|asjJPth35oy$YC|VYZMoed5!Usi*(@?F zhyEOnna{sqR7g_FG1QIV$D|^ldxYen)0pE8TcA;{J?-KXM3M8Kt{@FkPs)d@b9t~; zqWCc;a=PVBNs$*_L?bZMjL6@_;aFuf6cB#N6TgI^?JryZG6E2SI0Ul!j&J#eLtAje z`2ti6#oWvi$S^S=mioAyY=9NI&*;6O0Q62v(Lf&7*I3r_zx^4X!xh~YoqpKc^4n1$ zY+u!nJ-%b-<0#{K;I~k;#5BN_n?y2`4B^s6{IEBEwq7uE)g$k z1bU5$%Y~ea!h)&?>6NYc7B7%_{dl~<*W^r#3e$qddou)OygIzd~e;a4Vm3MSr)Fp-UBu_->U?*DoQ?Ic>*G5&oz{ zG2EAzr0#)Nx$XsF>m%dm${23H69{G|QP|{KqgcC*1hy9f=gn3UxW`jMkZ{a|GVjMJ zg1#hWsR>yXgq0B8vPFlnSAuB^J?--XK+8JCEU)UZD0y7j){>()HNS;|X)KdJ8B6sI z1MPQfg{FGT-!C2<;0S~zSqWTur{p-HAm5L==!pxJiAwtNu;R2a?Nt0{fn|%p> z?Z=MHx+_Z@=04je3A%1``aL9cAd`A>4~F$1wYlWKHp9-;LIlbb`;eJKmwj7cQ`a7G zi(pZVELC{-XkLldJ`&vZggq35aS2J|sY=!1jMJdhL0dk&ZQXC0FpnDkMdwFMENJ|A z3!oM%5_V=#M}vh*G-zHb>lV#@qF5h1&7PqnNMhcPe-5V^#T6WaX z%X><1a&=1^OtEuHo^oI&>6=jWebBtO?^@Z^yA}8p7oF+J^)6+t ztl^x?S52w)VCWsZb4~K`lWqoS@+(DG-2v+F<26;jqU&+h8z@P0*O*X-)MP_#S^=1enIIz?!PMeGY8PAnn$B6 z!`~ko3;{>?hqAA+q25aFk0=RYSEA_Q>>fY@YvK)XG%=K*kYM~MvA8V>5@oLR35JE_ zO4+MqTf$sAr!Ck zC82{blkj@U!*};UGG;Z?hoGxJ=a(-o&cix*lkcsSI}LRQpLXt+Uif&qFK>EkoXTx5 z3#M1k$Bymyu=45bP->di1|F?>5TsjZ+AkESA@*xC7=rIGL(uj9UEC<&RjGnjyH&T*5z+_;UJ_h z7tao;f-|Fc*D+xs5(0wDb<2w^?7{NY#bHEpXQ^(|^;J=Vu*}yc+XMZXcpp~h2;~jm zJ%84d;7M(vj1K>`KO362VB=I8_Scmfa`Vyihl=YK(I9deZDC&6ec#E=9INT`otFd4 zy$rSq`MsvOf4kC^Kl?|~;+U{vv)}9dYJoa< zq;`h^Ro6{9!S8*q$Paw~jz_e;UvMBCB%El6ew(hs;8^Ic!Z6xm=&`ZpNFu}s7a2)I z9qF4iq~}?~H*&^|>A}UFw9CE^=j$XdMRTE7ro*Ci$0f~d#_l`pTNNl)Z|8q&*D3Bs zDI$2*b9gdK6UE=MeC(!J07KVsSsY8DFkhKpm;SZw8A!z7@F4cdm9~X_-`=a+Y$*AU zVA7HKujo2cjtP8g_DxXy%x(cr`cuK0vWjOI1pz}tyfYZNt*Ci`O`rH&pD?<(XxJ*{ zB2ywdIa~s;G+nlhldUb6BTvt4PVMYsd?Q#vdrf7n)--~qGW8)_x?pKi)uAU^K9ILv z`N)Pbs=AggY#CK=HQeRNS!2ZEq^u*+Wh(#y}yJZ_i(k9 zW%=bRrUQ$MrF%O^-CJF=?8WKT-zCOg@>{eGm9O=Q7BZqE)QvQQRMY?qhh8lYNJuol zo#DoZ&bIOImc~t~E@Ocv+Trq0I~K`qlAS2TyDcL+?V49G3+9=YsVp^}a84yCxF6eI z*fe--k(BD1;7v4|!)f;wqzkRp%cE2Kp!(DiuV{P9I`iEM1hX>4meHcSVimD-NF<95 z-zs={qJ8XnFCdgb&ui_9+(vU^?M`T;(yHOjt*f5jkYy&R5b{F-`}3G{oj>KMLGtEy zOTWKuRSoN6Qddy}9j@3EusPZKE7{SF4y#K?0e)m|Po?N*JW4+m9y_+lohm&H7#NpF z`aYt8sK@MDWG8In=c;c_JXa1?-bs>^Xr*&mz{I3~C3cjWtvDa3i6V(!5@q73TM;it zT)#m|mPk8!#BgA;Tq5(Zc9w87J5&N-ZaJZ`zFfc47O-G?*%{A8F}f?x@F@0vcr z^1H2S_){lrgC#ndj0rCm3(a|BeVNO~n5mbN!Nr<$kg76UNiE@EC2W}zC#)7Q!I_Ao zSKNEG;T)sP**3Cf_5E|`vPN2!ve4M@@*gt%#lMpd-xqCypGS>Ww?0RV3&d&omyNH@ zC$s4u!+l-C@KcfNy^)?kHzsDQ0cH=YpDFK<3{Au;#)62=jo&@DZ5KxD+8V!=vTJD9 zxu84?{(|aSE;Ko$;yf_xMwEy?=qnedOlGUdq7A)PC_K8-FYgi)<6vB|$R?}Bv zJL{~!`{h?7#qA0?>V8hyf|VEVBG39=L#~H-lExKQZnH9zH`jf~;7G09DkNF}?rzHL zb)#8|4qtWk2y)$&np7Jq6&4QyW=7+s&lqu|d+x89JwmBD)g-qP>kCrS>To$&z~J!g z;nla2CD#&t^kd~&Q=<>d2&G3YO$BFUwpM%43_R7|6exZ`rl?(xqT>FcPl3O=WXNDr zTTQ6rvAJ(~=9M&sR*uG6ep4F*ekzA~R0TW3MJEK_tbqnV4?dg)R=d=8$HA<=0r}@Q z3l5}5Vjl_jV>M1JZ;JDi1%@*j)bw>o;D$@;m8}!4{v|pSv%*dN()Y{lil;XVx2796 z6b3VdRg;&}!np9O=`*wnTccaiq>5et;x z0tdb4t`n|Yvb@frNg=R~PFph_dX;8G8;*OM)9#OTcBhrb<;mR@LCc(zMBi=`5m9hB z*VAQEiZPduV4*0%iQepR^*y$bOF}$v+dcU_yWJgRj>4em`o`yWnSiS2<)Jx%yp_C* z|JBHT<7>#NEfNH5*O@dXPIDOuUyZx3CtS(s<1y{|5?zK6hrpPwuqM^JL6W!o`Uf)T9AyHVi`PwWhU_>!tAN?HedSiD5^bZLe z7KW5!dZDbFBGHn)p^4L^mq>@SP~lbOa4ipfCWzYD z2Z6+U3-HksX+L9LL6G1H){g+B(VH(J-EmXVd%`ERo1OLR-%oAnYoRQXIr)yaNUT-n zQ2{Zo?g>)f?nh&J{xzV*U872WDUOtzckF6@^k(Ju`qfBw(qg$Bo z33sN9mrSD3uZH+PW0J~dyem!6tdGBN^e?^y{Ca49uT>Q|vj6bTfCT%{ODVweWon~m zNNCw$A8W8ON&x-9eGLLuoQ_U0Vyd6&=&asj6`#Y?*V_nsUi2|if}=~^rRW3q{OF4y z!C+|U!~)NJPHRcQjm<=os}j9(0l8rYn_#}a&D%NZ(~r*`9)ius#>ZbzA4mL&E#Yys zTif>IXNvtflbg3sx^LwpzyGbc*`76F=0Eq$TUevL|9Xg0pQ7c{!^_uwp<>=Qb6qkl zmH(~($Ff2@C%OO7H+l{hExRvU7c;=edTZ6E3`~c`(+Y#tW=b$giXt~lhy+xCr@V2y z6EmsyJiTIG=qD+=K2Dq-q3On^8A-Stc zuUQtg+dC@K1$K*(3(eqTy_E22&z;kAGDXN-9}F+D#}9a+4IZ|Ah=DuFON_h)5Dc^P zq*dy%%uhH9u(Ir&K}&6S(SJ_3>9X6|&z#fdv#Xm4>8z_bY5nhv0L|=TKB3iv(mN%3 zCh77YHhgS$cOMPkvIQ-<+?tRk5p{ z9pP(yo_+P}r?C9yuwL}=oMUv^@^ZFi<6t!04vJ&n!@%mC`t0c{f2vsir~Y2D(i62n zXvXY2b}DOeVZkDw-nC?Q9GgG7E~nV`0pLyv@~MwC^~bAf#jVw46@vTTqLjp=&jedI z>vA9Y7dg#6sk`6r&;{)6OlLR>cx4QD6o)M{^hv&_KH(_HVKBh+Q+=E{vL-2`95Gex z3E-U)A8t)!3tAa1?xNCf=u0S;NyeQb&_k!026Bq%KebYwN#jMEl=NCN(c$7ZCTPFy zffU{2m_#P?V8P>nB(jQ)AES+M2(L|Pnz{G5IjRA*s-E_IeTqC)3W zxz)QJJ$vjgPv4^4K7Tjd&-0KbXL4>9T((?zTwuL0I)t_)NuUqZ1)3MQl#Cq?ele~FGWcmjuq zl_PuvtxOk_A@lX_^Q3 ze%dU}OJfnrgs_53eIOpOtTQE4THdkcyR;d2Y3DnOcY~~TB`A>Ibi}sggx&Amzjjz` zX*C|25Vs^?c1w11UA8(11mIHlD~}YdpPIt$QN8u;*=(o9s|61jZlr7W-?ePeQm|{B zDvx^yggmBWE8sXUmLJ>1VM^Xy<9r`JF~v7@vNVhW#L^Dd#S(doi-N);gBw-06L6LbS4Kl)qcyn4-uN}5I@RoB|Y!6W8YlO$RY2F2ppJa0~8?Z9xhLOVtPnq!T$7f0m}*^gnl7cx1}woR`4x~g&m^x~fpA>l)D#=p&gb%knRR*@=ZrN6KY)+1wB`AK5xjG(lUPd*4R>Q zCbA?gex-P&ARU4fYMm~Wc73tQ%S>4`r@Pkvc9}w@>8Cu2g=8Gwj|VL{LXE~bGvT_p zd*!mKIBIbsDu!cDeE7aW;?Umz6*f&|BEs{AP1QJ5VR|)+7|{ihC}pBG>Bs<$^=qJr zc<@hbGTOuGuEc|jLDcg{xXKOkVtO@R+y4V5xu!OP9WGK~>OdyEC7|^7(!JDVdKQhSPdI5nesNl(^pU!(ouy zs1K8Ug{oTkY~5{I25~Fm2%{c|0Cs#6;ZHUT`*Vd~WbkpRy3t`10YMe5CvW zs=+x8Ol2zQP2nAe6Wz;np}K@sn(O|tjnfu`Ez(c6Vc zH*>Il$4UXG0sjyI3FzwP&&9i(*QsIkDz=f#GQenw)7|R1F{%bX_NaP|)y>|v6UOo2 zJejRWc{SY!J^oxSP#^DbRl`2Eyo*Kw%g)h*gu|H4g?0!I)8flFhxE0>p;f$C;e(ZV zgUx$xqD3DQVPv>|6tJl#O}}Uqv+%HoacTV4?zMm$j`@~H(N7ueyi+@a1t-+{hf8$0 za0CLu#WhJrP23)`U3TQezrLZ+@TZXhriKA$QuQuc47X5QMkPK`j;NJE-{PSnRic0g zzKp9oc>?WE8f5@7z%plE4e0VjrEoTe%|dL`j=fMi`*cm}(P{)E7EA-V%3Q44Aj>mJ z;+N2(M&)MVvF`e2$(%&s?e)8jx_}&>Y^NY!U!FmZSJgByBYWC6I$kp$jwvZA18QQg zC23}e#qKeXK+lbIC>&<04v1l&-pcfp_Sv^JZVa-ko3>7!9m91y4v{D_Z*g%o8X17T zWlu`8DaK!|oWuShQM(e){gp;D+I`-I0SM8ZG01n~&-LqQ#Nvi-*PAV(&#k%v%2#fV z3P|WuioUf5BVCwGhQ;mW_G1ohPw2sh2!uv^6f;A!pR&o$b*u=Ca8XJt-?|syJGJ@h zL6Y4(?w!zdXSe*y=P^H2b~ifB9&98d3#?}ujST&sqwKOT`k5$#Mr|a_c4f+|<{9L5y z+~}Mc z>Nd^mI=EvB4mhsQI}7~Y-Z5hjg_PvWemgO_9Xzo84X2C9y2LtC!naQDcHUx{5Vzqe zdk=@L(tY~!VdLYR4CS=}S%HrJ8nJ+eNTiXot>`@XO6AC^De3(eSmerX{)a{N_=MSk zMzSuWJdy7rl5S}yJ3lk*<^}dNGKnIN(|Mk>$wUIz;@Td6BAaw`te!_ks43#}H}cT3 zk`ab`X-7*ROgAS48zP6)>rUb`PzCdT+CZ+baO062cIf-7F%wquCvA2ID^dD+G$TghGuvYHqvJ?dM z$+xB%*JV0LI_wxebuSk=>whLC+aSm1$4BjJFKOodfkK7G3TfZ2Ba0`?`HX zxamb9^q`f*g{kUzVy47!rno;eaZ((k(@m*qx5{paOH~Pd>oOm!lta`*-PyfdT9^+T zZq3W%kgX=BP4?-K8#fe!%KS|sH{|&vEDi7zo=l!q*g$dm*Eknwt*HK-_nK z2`=H7375nN(Ll;lCqS1ZWoQ$z!G}-3u?Ud0OiW6Kn9asCC*izk&jM)c)!e8oI}NL= zT#qze$S2*fo8Tvfh+;difjejmfZnI6t^Wx%9TYNG%b{T7m0+*^&8pg|{H37Wsxag7 z5Kmg&&kh^)S5O5ES+#LG_w`nYr>-8P`p++y7mi&S-FN~>CZcztQsj?7H*g=_8$Ae` zbiiG?iJa0%anP5G#t=s)ym(|q2nxKXeqE4cw;or^#ScJ5qVVA^I_+b^N5b?9UA|~U z7O)-;L;ljnvcfr}$|1ZId0e7lekA8AW!vUGsvA6e7HBOCN!|3kj6Jx8WB_Q&(sMv= z@N^ZjLG#^`);{G;=B|h3b8;m1W&|)!GRqZ(J;AeF1P}@bsZ{x0KOA()m5lX&c7p{6 zp_2&%f&vb=fo_ORi2k-%vLgv?`rt+3I}-9X9G0)+X4j$7Xb28x)ZnBt8pyVFi4jW} z{0qe}VPbDnpz^j0Z&QjQ%>czxh^uZ>kBebcx!oVcS#zj3)!AtKiyeQ6&U?} zXJX&*Uq1yS(&FNRSK$liVK>K4RW+yK_h;g^lwl0uk3F8jcU>kc=VZ)?5>OHB38P?m zfVFmfEBUI<&@f%(c1xp~*2^YGUwi7{bdP;i_)3uy4wmMSKSxsJfQSK8b+3&D6uT@+m| zvL{;6{1Q+gJ+8R8-&xth8?*_j;O+m+P{2|TR$U^Z74#qFeHHg;OYMNK{6iWFL`AB4 zR5QNI$d3jM^pUn7AFK}SRQ*R`t~)y$wl&`VJzhEcmJ%faB4n?Ac)b!N;asMtx^wt1 z8&UF%>cOl8`bVYyl%aNWckG;~(UofBL&(4d0bQT6mn@MD9G$F!P9+){ei*_dVj{W) zU|YOs3=<>EK zZyk4d3==>A!eqnIH+4Z@S0vXiB? zq4L%He)|w41QscM*8i+lSmp%q38lFXUdA*6^5UZSjh))wNk4xD*yDwlYGHz`P8oi& zGl7HtX;^KqiR)K6f<^4CoooRk>6B;A>Z503yI3hW5l69dqRbb=w^_t@T0V`+Is*VV{g~L?JS|U%g4cb)W!Mw;JwZBS zXFbt1f6?sW`yM|`H!NuLWRM*?hAO~{0Vk@K;)vmo=G&X?%bM|i^Lo{m87@Z*&nl!g zF+8yEP)a$%D{lVhR4qQ?w%b!|Az>MyTkz|$N%dMhoC5$3|Cld|@-OJeNzXvG&i9;i z_(a+rSxE73kMJP}R1PzQdeQSBgum^7+6rvF#=&%`CJkett8{Q4%#|@DPiIuvLbG}N^ zdo|y4P!};D+3o^8z<@#|h|#R`D9K)gS=KhGh9erwyKfk8ySA638sA%M(!z_5SR@bY zY`!!0xcmBEA-anDy~VfSO_IlPMTUUQI&|DDeNTicuR)psxM+1KJUU}6?G7yAxX`S; z-4VmLHJR1mZ~anzg93MwTcBugp;WxM?ZWMJ~0G@Y0;z z5JK=z(Ds>1up_et;h%pAtAD8`Rydu|?lHT}{zVQxv%aKgu5cReX`*hX&-kC>L0TXU z5Z(C&EExxyuIqxMAXhR3Fz7dLBkz%|+XHR3RgwU|m>=ezfl)J7`odgiQzKupGe%S{ zYz!;`mH1U~Cu{D%m%F;7Ee}_O`SUN5-*)yC1k}?djmsW52L4qca+uqxs7y8Q#|_@5 zxW=mxWc;H5yMBH7A#3*kkbex?#$L$W=?L)ZF_eKqIDM|JqV7VGm%F6!ewHP1;-7L{ zJ;Jl4BMH9*20>RF|Gde~qjK_RHBR7zzM-)fz<~q-J`0rZrl=CuYb&ew!sNt0<-P9y z+k5Tw5@~=4pFaSgml_@s!OKA5RdN68H~1{VZ~kAtO`{s#yZ>qX+j>*jwG(ZJ@?14x z(T3beYq)oQ)$%v_{cY))<9V7U&T`kmE_Y-y7YOW{OWF@QY7Zz=%6tZjW z1ov|!iWQd69*G;DOwJ#YG|R*lQ&-=2j&CS0IoDAV_q;Fv*eEq+;%%s&`m=P7kEiGF zUP|t5@U8a5-z{SoX*TDItYYM?)|>#~o{V6f>S ztXN83u2pEYTt%@Kn>I4ypKaPr_n!ZAAUm>O*VUhXOimU3gWp!k+h1nJj*IgA(7Q0{ z>A)}yZ!%nP6(ara(N=_uR^^*phaB%HS>}VXZy&|Wj4R~b@4s@Mb1dQvQ2c9rl-1e` zDL}P5dG;E-w5m8d@#YHM+E`9_qpE*KgJdM#%y5Ou zTEiCV-6#2wj(N(>vObrWf~X3_zD@^7?)rviRP+}(3}v-z1f6Ul_VO^FAGxnsC|vS2 z8V{mjysagDgDmd^0L3_qnZ0Ryw^~XOa6gQ1bQF>|mmuanLblcX_%$xB?T0oy4VGOr zBH(S(8zXY1!yO89jE|>i1->zYM8bw;n4+5zqva+t7Y$qH>g&H;gF(o@B(A~Vnkz%JAg%szahPjw^zRWIrLo4 z!UP4cMIhwZ&9$*pLo~HxAHz@tlUJ+;(Z$A{`{2N+tFyZywz=T``t8?A%W19b!Jk%t zkZ;_P)EsiWkb_Wv7r-kkij;MI@-PWigx`yyS_io= z@v-GAMl4SQ-s{@!y_whfDiN(a9*j#64g4)=9GW+E;WMH(rklrGr5=lSNW6v%HWUG$ z{290FqCNXHH9o$YI+={MG{MKy+mqtm5xQ>y38bJ&LR(XA$e_l80-{v}#x9a7wVbDd zgS!x5=Z-e^>dp;Pk#P)bRIF`Wwp--h(WS$`0z$-R8_@_1oVMr>X2Yptf)PQ08JN}& zq_-03Jw1Y-WTq;L?k-o@@4EOH7AEL$*=JCQ^>tor5=Dpi`n1ou0Q9imVt>vIxWv3l zYS6?*@C$DDJ!^6sU~j;@E~CRL2AcD5TTJg+)gWlZg#Q{ly@@6P*11NpTPO~D_QzO$ zc$JZ)Kk=5E7i|Cmgv#EvYAH+nK~^T~{Wc^nCY;P!ppd)ix_ERB7yK)Q|%dKu82WR7Qq}@=6W}gBvN-*3JKqsWU@y(}w4U0Dwv~8RUOv5uVTj!OtPC zG7MlT=(GvEl)mrab(P@%TxB`_c0gEfr%m)vguERjh7K?8frFNml&}zz*hbvzF!XQ)03=G zPQZ=BcV`1s$tsRM>Kz5aVy|99R`4AFD~h!|Ng-Q^0Hvx(wqO~gp5ytD2G!|Nw@?%D z)=Z(_VgNwvphVbUytjyj6!{H@CA%>v0J{(i@H-~}3LdzhnLIYJOpq2t&eS7ygu+K_ zmZPRExjR$lJ)Z74q>sLzGyw%s!XI4&G0h^Yu}Cfo>DwP(1rHAf}a;Y{+2#(xV4(PUbe_-4yeteNGk3G>z9^k7M8Z=fIq0eTP2 z>g6>nU@Y0GQo990M??hC!Bx^~g;fXukv;%Xgh@%Wa13($=ylbw1rTsIX8_fd0FeG$ z0vBoSGA#^L7P$Y2|BEeR6|o_9e#U}34G+0n-Ge}8PrZnkq37Sc=0ZE7qe*ezK8!a2 z7gi=^k(QJQdu0RxAw*EvBJ&+Ztn`3}7rd2_7iuCMwO^M`80f$M-3JR<)m{tTD6s0; zE)#_@bTskc2NY~jB{ifL3S7;{1Lnz2i)TX3Fk!!0!)l>L zsI(xO)-uA{n?S>Gi89zsqzqXJh!e~FXDGBFBJS1V{2e7;dX({b>i!B1sLv4iP4D-c zt6_iJh5|~M_@VVWh90AKr3yG)h?WW*e*LIg_zEevG6sw4--!MI%{_lM(3*W{Q?8{% zP_UEFi#cC}&A2;8NdWY73^m+aQ^s2ZVz#hdIT0Gpqm2=c<9lt=l%-%2Wnsg6M;)0j z+}TX7i|@3a5niOjkhl>Xghw}*U{oL})&>E_yZg+kW7?xXW0;+){CL=UJ{<=n2ii`* zP+%H0T0EnC>vtAnRZ$ecyz_T@7Klb4vO;)+#MqWXiSZpD-E>|Pl zFQ-qzLaOoj2zq7x1gLuQPPKAc4C{wKlr)kPMdsyC!* zviHM%Ka+dO|B8~48gi7hySFQrvhnc`&NLRv*y_;7A4X^LUGTtVLXV;qfvnV5`^Z@CDSmYuigv_^%q;?)9*u;ViBxT&5d8ei? zX&z#}q5xHkZ6m8Kfo-U<>kxyaoRT3i^;?N%dQAkGRK780^1aL4GzhTYkqReryyJC5 zTL2ad>qxIrWaT|d2EG_`Y+JVbk&XPxmwYD9#>^LP7BLy(5B^UlKhc`e7u9{U^iyL4*%!0POr#BrxO1sTi;gh Date: Fri, 10 Feb 2023 11:38:55 +0100 Subject: [PATCH 24/57] r --- back/www/img/logo.png | Bin 1338 -> 10284 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/back/www/img/logo.png b/back/www/img/logo.png index beb19973fe397cb52684f9fd57ca5a18582e6810..88974aee832760dab52cf9ab4976e95bcbf05d1f 100644 GIT binary patch literal 10284 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�RBUY8yG1P$8GC&J1sM7f3+w8IF?mo&(8 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 #EIgCrdRx=~R@osPKP@=u`Pt@?g zQFk23LA6ZZKm{|- w6X*Vg-#W^vp)Yr=C+8$7goT$J+xzC^e Date: Mon, 13 Feb 2023 14:58:37 +0100 Subject: [PATCH 25/57] verify something --- back/operations/ssikit.go | 53 +++++++++++++++++++++++++++++++ configs/server.yaml | 1 + go.mod | 4 ++- go.sum | 12 +++++++ model/verifiablecredential.go | 33 +++++++++++++++++++ verifier.go | 60 +++++++++++++++++++++++++++++++---- 6 files changed, 156 insertions(+), 7 deletions(-) create mode 100644 model/verifiablecredential.go diff --git a/back/operations/ssikit.go b/back/operations/ssikit.go index 5745a9aa..5d5adbd8 100644 --- a/back/operations/ssikit.go +++ b/back/operations/ssikit.go @@ -1,15 +1,19 @@ package operations import ( + "encoding/json" "errors" "fmt" "net/http" + model "github.com/fiware/vcverifier/model" "github.com/fiware/vcverifier/vault" "github.com/gofiber/fiber/v2" "go.uber.org/zap" ) +const verificationPath = "/v1/verify" + var logger = zap.Must(zap.NewDevelopment()) func SSIKitCreateDID(custodianURL string, v *vault.Vault, userid string) (string, error) { @@ -46,3 +50,52 @@ func SSIKitCreateDID(custodianURL string, v *vault.Vault, userid string) (string return did, nil } + +type verificationRequest struct { + Policies []model.Policy `json:"policies"` + Credentials []model.VerifiableCredential `json:"credentials"` +} + +type verificationResult struct { + Valid bool `json:"valid"` + PolicyResults map[string]string `json:"policyResults` +} + +type verificationResponse struct { + Valid bool `json:"valid"` + Results []verificationResult `json:"results"` +} + +func VerifyVC(auditorURL string, policies []model.Policy, verifiableCredential model.VerifiableCredential) (result bool, err error) { + defer logger.Sync() + // Call the SSI Kit + agent := fiber.Post(auditorURL + verificationPath) + verificationRequest := verificationRequest{policies, []model.VerifiableCredential{verifiableCredential}} + + agent.JSON(verificationRequest) + agent.ContentType("application/json") + agent.Set("accept", "application/json") + + code, returnBody, reqErr := agent.Bytes() + if len(reqErr) > 0 { + err := fmt.Errorf("error calling SSI Kit: %v", reqErr[0]) + logger.Error("error calling SSI Kit", zap.Error(err)) + return false, err + } + if code != http.StatusOK { + err := fmt.Errorf("error calling SSI Kit - status was %d", code) + logger.Error(fmt.Sprintf("error calling SSI Kit - response was %d: %s", code, string(returnBody)), zap.Error(err)) + return false, err + } + + var vr verificationResponse + json.Unmarshal(returnBody, &vr) + + if vr.Valid { + return true, err + } else { + logger.Info("Verfication failed.") + logger.Debug(fmt.Sprintf("Detailed result is %v", vr.Results)) + return false, err + } +} diff --git a/configs/server.yaml b/configs/server.yaml index d59da7e5..c0bba5b4 100644 --- a/configs/server.yaml +++ b/configs/server.yaml @@ -18,6 +18,7 @@ verifier: dataSourceName: "file:verifier.sqlite?mode=rwc&cache=shared&_fk=1" uri_prefix: /verifier jwks_uri: /.well-known/jwks_uri + tirAddress: "https://api-pilot.ebsi.eu/trusted-issuers-registry/v2/issuers/" protectedResource: url: "https://www.google.com" diff --git a/go.mod b/go.mod index 2ab9e924..ce8c77a8 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,9 @@ require ( require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.1.1 // indirect + github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect github.com/benbjohnson/clock v1.3.0 // indirect + github.com/deepmap/oapi-codegen v1.12.3 // indirect github.com/goccy/go-yaml v1.9.6 // indirect github.com/huandu/xstrings v1.3.3 // indirect github.com/imdario/mergo v0.3.13 // indirect @@ -43,7 +45,7 @@ require ( github.com/fxamacker/cbor/v2 v2.4.0 // indirect github.com/go-openapi/inflect v0.19.0 // indirect github.com/gofiber/template v1.7.2 - github.com/golang-jwt/jwt/v4 v4.4.2 + github.com/golang-jwt/jwt/v4 v4.4.3 github.com/google/certificate-transparency-go v1.1.4 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/uuid v1.3.0 diff --git a/go.sum b/go.sum index 2f1b1b31..a1b22c8d 100644 --- a/go.sum +++ b/go.sum @@ -95,6 +95,7 @@ github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuN github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8= github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= @@ -116,6 +117,8 @@ github.com/aokoli/goutils v1.0.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g github.com/apache/beam v2.28.0+incompatible/go.mod h1:/8NX3Qi8vGstDLLaeaU7+lzVEu/ACaQhYjeefzQ0y1o= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= +github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= github.com/apex/log v1.1.4/go.mod h1:AlpoD9aScyQfJDVHmLMEcx4oU6LqzkWp4Mg9GdAcEvQ= github.com/apex/logs v0.0.4/go.mod h1:XzxuLZ5myVHDy9SAmYpamKKRNApGj54PfYLcFrXqDwo= github.com/aphistic/golf v0.0.0-20180712155816-02c07f170c5a/go.mod h1:3NqKYiepwy8kCu4PNA+aP7WUV72eXWJeP9/r3/K9aLE= @@ -149,6 +152,7 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= +github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= github.com/caarlos0/ctrlc v1.0.0/go.mod h1:CdXpj4rmq0q/1Eb44M9zi2nKB0QraNKuRGYGrrHhcQw= github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e/go.mod h1:9IOqJGCPMSc6E5ydlp5NIonxObaeu/Iub/X03EKPVYo= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= @@ -216,6 +220,8 @@ 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= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= +github.com/deepmap/oapi-codegen v1.12.3 h1:+DDYKeIwlKChzHjhVtlISegatFevDDazBhtk/dnp4V4= +github.com/deepmap/oapi-codegen v1.12.3/go.mod h1:ao2aFwsl/muMHbez870+KelJ1yusV01RznwAFFrVjDc= github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= @@ -250,6 +256,8 @@ github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fiware/dsba-pdp v0.0.0-20230111112802-540544166240 h1:8YP/LLW4jrDR20YJFirqn+XO7wZdVJlGZBAipQMqOH4= +github.com/fiware/dsba-pdp v0.0.0-20230111112802-540544166240/go.mod h1:HpYuQF4RWRFxAFkqItyaCszNbOarnCOFuqKxWMGvFEI= github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= @@ -316,6 +324,8 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs= github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.4.3 h1:Hxl6lhQFj4AnOX6MLrsCb/+7tCj7DxP7VA+2rDIq5AU= +github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20210429001901-424d2337a529/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -532,6 +542,7 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= @@ -812,6 +823,7 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM= +github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= diff --git a/model/verifiablecredential.go b/model/verifiablecredential.go new file mode 100644 index 00000000..c06acbe4 --- /dev/null +++ b/model/verifiablecredential.go @@ -0,0 +1,33 @@ +package model + +type VerifiableCredential struct { + Context []string `json:"@context,omitempty"` + Id string `json:"id,omitempty"` + Type []string `json:"type,omitempty"` + Issuer string `json:"issuer,omitempty"` + IssuanceDate string `json:"issuanceDate,omitempty"` + ValidFrom string `json:"validFrom,omitempty"` + ExpirationDate string `json:"expirationDate,omitempty"` + CredentialSubject CredentialSubject `json:"credentialSubject,omitempty"` +} + +type Role struct { + // name of the role, for example READER + Names []string `json:"names,omitempty"` + Target string `json:"target,omitempty"` + Provider string `json:"provider,omitempty"` +} + +type CredentialSubject struct { + Id string `json:"id,omitempty"` + Roles []Role `json:"roles,omitempty"` +} + +type Policy struct { + Policy string `json:"policy"` + Argument *TirArgument `json:"argument"` +} + +type TirArgument struct { + RegistryAddress string `json:"registryAddress"` +} diff --git a/verifier.go b/verifier.go index 46e5bcec..f07dfd6d 100644 --- a/verifier.go +++ b/verifier.go @@ -5,8 +5,11 @@ import ( "encoding/json" "errors" "fmt" + "net/http" "time" + "github.com/fiware/vcverifier/back/operations" + model "github.com/fiware/vcverifier/model" "github.com/gofiber/fiber/v2" "github.com/hesusruiz/vcutils/yaml" qrcode "github.com/skip2/go-qrcode" @@ -15,13 +18,26 @@ import ( ) type Verifier struct { - server *Server + server *Server + tirAddress *string } // setupVerifier creates and setups the Issuer routes func setupVerifier(s *Server) { - verifier := &Verifier{s} + configuredAddress := s.cfg.String("tirAddress") + + var tirAddress *string + + if configuredAddress == "" { + s.logger.Warn("No trusted issuer registry configured. Will not use the tir check") + tirAddress = nil + } else { + s.logger.Infof("Will use tir at %s to verify the credentials.", configuredAddress) + tirAddress = &configuredAddress + } + + verifier := &Verifier{s, tirAddress} // Define the prefix for Verifier routes verifierRoutes := s.Group(verifierPrefix) @@ -126,6 +142,10 @@ func (v *Verifier) VerifierAPIStartSIOP(c *fiber.Ctx) error { return c.SendString(str) } +type verficationMsg struct { + Msg string `json:"message"` +} + // VerifierAPIAuthenticationResponseVP receives a VP, extracts the VC and display a page func (v *Verifier) VerifierAPIAuthenticationResponseVP(c *fiber.Ctx) error { @@ -144,16 +164,44 @@ func (v *Verifier) VerifierAPIAuthenticationResponseVP(c *fiber.Ctx) error { return err } - credential := vp.String("credential") + credential := []byte(vp.String("credential")) // Validate the credential + res, err := v.verifyCredential(credential) + if err != nil { + v.server.logger.Errorw("Was not able to verify credential.", zap.Error(err)) + return err + } + if !res { + v.server.logger.Info("Credential is not valid.") + return c.Status(http.StatusUnauthorized).JSON(verficationMsg{"Credential is invalid."}) + } // Set the credential in storage, and wait for the polling from client - v.server.storage.Set(state, []byte(credential), 10*time.Second) + v.server.storage.Set(state, credential, 10*time.Second) return c.SendString("ok") } -type verifiableCredential struct { +func (v *Verifier) verifyCredential(credential []byte) (result bool, err error) { + + var vcToVerify model.VerifiableCredential + + json.Unmarshal(credential, &vcToVerify) + + policies := []model.Policy{ + {Policy: "SignaturePolicy"}, + {Policy: "IssuedDateBeforePolicy"}, + {Policy: "ValidFromBeforePolicy"}, + {Policy: "ExpirationDateAfterPolicy"}, + } + if v.tirAddress != nil { + policies = append(policies, model.Policy{Policy: "TrustedIssuerRegistryPolicy", Argument: &model.TirArgument{RegistryAddress: *v.tirAddress}}) + } + + return operations.VerifyVC(v.server.ssiKit.auditorUrl, policies, vcToVerify) +} + +type VerifiableCredential struct { Credential *json.RawMessage `json:"credential"` } @@ -167,7 +215,7 @@ func (v *Verifier) VerifierAPIAuthenticationResponse(c *fiber.Ctx) error { v.server.logger.Infof("Authenticate for state '%s' with %s", state, body) // Decode into a map - vc := &verifiableCredential{} + vc := &VerifiableCredential{} json.Unmarshal(body, vc) // Validate the credential From 5150244da549218991fa955e06b0bb64818d849d Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Mon, 13 Feb 2023 15:53:52 +0100 Subject: [PATCH 26/57] fix read version --- verifier.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/verifier.go b/verifier.go index f07dfd6d..ca0c7572 100644 --- a/verifier.go +++ b/verifier.go @@ -25,7 +25,7 @@ type Verifier struct { // setupVerifier creates and setups the Issuer routes func setupVerifier(s *Server) { - configuredAddress := s.cfg.String("tirAddress") + configuredAddress := s.cfg.String("verifier.tirAddress") var tirAddress *string From 3e815f6c94345549df63a8305b26c119189d4ea6 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Mon, 13 Feb 2023 16:17:26 +0100 Subject: [PATCH 27/57] add the frontendprefix --- frontend.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/frontend.go b/frontend.go index 8b16bf94..02cb92ca 100644 --- a/frontend.go +++ b/frontend.go @@ -112,7 +112,8 @@ func (f *Frontend) VerifierPageReceiveCredential(c *fiber.Ctx) error { if len(rawCred) == 0 { // Render an error m := fiber.Map{ - "error": "No credential found", + "error": "No credential found", + "frontendPrefix": frontendPrefix, } return c.Render("displayerror", m) } @@ -141,6 +142,7 @@ func (f *Frontend) VerifierPageReceiveCredential(c *fiber.Ctx) error { // Render m := fiber.Map{ "verifierPrefix": frontendPrefix, + "frontendPrefix": frontendPrefix, "claims": claims, "prefix": frontendPrefix, } @@ -153,6 +155,7 @@ func (f *Frontend) VerifierPageAccessServiceGet(c *fiber.Ctx) error { // Render m := fiber.Map{ "protectedService": protected, + "frontendPrefix": frontendPrefix, "verifierPrefix": verifierPrefix, } return c.Render("frontendPrefix", m) @@ -188,6 +191,7 @@ func (f *Frontend) VerifierPageAccessServicePost(c *fiber.Ctx) error { m := fiber.Map{ "protectedService": service.Url, "verifierPrefix": frontendPrefix, + "frontendPrefix": frontendPrefix, "code": code, "returnBody": string(returnBody), } @@ -226,6 +230,7 @@ func (f *Frontend) VerifierPageAccessProtectedService(c *fiber.Ctx) error { m := fiber.Map{ "verifierPrefix": frontendPrefix, "accesstoken": accessToken, + "frontendPrefix": frontendPrefix, "protected": protected, "code": code, "returnBody": string(returnBody), From 8ba2ab05fdb548e73e4c1879410722d8eb59ba10 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Mon, 13 Feb 2023 16:24:12 +0100 Subject: [PATCH 28/57] use right template --- frontend.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend.go b/frontend.go index 02cb92ca..7e67d605 100644 --- a/frontend.go +++ b/frontend.go @@ -158,7 +158,7 @@ func (f *Frontend) VerifierPageAccessServiceGet(c *fiber.Ctx) error { "frontendPrefix": frontendPrefix, "verifierPrefix": verifierPrefix, } - return c.Render("frontendPrefix", m) + return c.Render("verifier_request_service", m) } func (f *Frontend) VerifierPageAccessServicePost(c *fiber.Ctx) error { From 7a7288804bfc0d9815ee082653fd875669fd3ba9 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Mon, 13 Feb 2023 16:35:50 +0100 Subject: [PATCH 29/57] verify --- verifier.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/verifier.go b/verifier.go index ca0c7572..28eb33eb 100644 --- a/verifier.go +++ b/verifier.go @@ -219,6 +219,16 @@ func (v *Verifier) VerifierAPIAuthenticationResponse(c *fiber.Ctx) error { json.Unmarshal(body, vc) // Validate the credential + res, err := v.verifyCredential(*vc.Credential) + if err != nil { + v.server.logger.Errorw("Was not able to verify credential.", zap.Error(err)) + return err + } + if !res { + v.server.logger.Info("Credential is not valid.") + return c.Status(http.StatusUnauthorized).JSON(verficationMsg{"Credential is invalid."}) + } + v.server.logger.Infof("Store credential %s", *vc.Credential) // Set the credential in storage, and wait for the polling from client v.server.storage.Set(state, *vc.Credential, 10*time.Second) From 72f722b1db454a23a4311ccbd7d1de3af08ee5ac Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Tue, 14 Feb 2023 12:12:22 +0100 Subject: [PATCH 30/57] auditor address --- back/operations/ssikit.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/back/operations/ssikit.go b/back/operations/ssikit.go index 5d5adbd8..23ca4fc8 100644 --- a/back/operations/ssikit.go +++ b/back/operations/ssikit.go @@ -35,7 +35,7 @@ func SSIKitCreateDID(custodianURL string, v *vault.Vault, userid string) (string agent.Set("accept", "application/json") code, returnBody, reqErr := agent.Bytes() if len(reqErr) > 0 { - err := fmt.Errorf("error calling SSI Kit: %v", reqErr[0]) + err := fmt.Errorf("error calling SSI Kit at: %v", reqErr[0]) logger.Error("error calling SSI Kit", zap.Error(err)) return "", err } @@ -68,6 +68,7 @@ type verificationResponse struct { func VerifyVC(auditorURL string, policies []model.Policy, verifiableCredential model.VerifiableCredential) (result bool, err error) { defer logger.Sync() + auditorAddress := auditorURL + verificationPath // Call the SSI Kit agent := fiber.Post(auditorURL + verificationPath) verificationRequest := verificationRequest{policies, []model.VerifiableCredential{verifiableCredential}} @@ -78,7 +79,7 @@ func VerifyVC(auditorURL string, policies []model.Policy, verifiableCredential m code, returnBody, reqErr := agent.Bytes() if len(reqErr) > 0 { - err := fmt.Errorf("error calling SSI Kit: %v", reqErr[0]) + err := fmt.Errorf("error calling SSI Kit at %s: %v", auditorAddress, reqErr[0]) logger.Error("error calling SSI Kit", zap.Error(err)) return false, err } From bf0150fcc17066178b4b9b5e7219de7030fa973b Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Tue, 14 Feb 2023 13:15:59 +0100 Subject: [PATCH 31/57] more logging --- back/operations/ssikit.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/operations/ssikit.go b/back/operations/ssikit.go index 23ca4fc8..1e95a54e 100644 --- a/back/operations/ssikit.go +++ b/back/operations/ssikit.go @@ -84,7 +84,7 @@ func VerifyVC(auditorURL string, policies []model.Policy, verifiableCredential m return false, err } if code != http.StatusOK { - err := fmt.Errorf("error calling SSI Kit - status was %d", code) + err := fmt.Errorf("error calling SSI Kit - status was %d: %s", code, string(returnBody)) logger.Error(fmt.Sprintf("error calling SSI Kit - response was %d: %s", code, string(returnBody)), zap.Error(err)) return false, err } From fbfd374b45fe2343d603f956b6954e909bcfa906 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Tue, 14 Feb 2023 13:22:03 +0100 Subject: [PATCH 32/57] readable output --- back/operations/ssikit.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/back/operations/ssikit.go b/back/operations/ssikit.go index 1e95a54e..6ed8d23d 100644 --- a/back/operations/ssikit.go +++ b/back/operations/ssikit.go @@ -96,7 +96,16 @@ func VerifyVC(auditorURL string, policies []model.Policy, verifiableCredential m return true, err } else { logger.Info("Verfication failed.") - logger.Debug(fmt.Sprintf("Detailed result is %v", vr.Results)) + logger.Debug(fmt.Sprintf("Detailed result is %v", prettyPrintObject(vr))) return false, err } } + +func prettyPrintObject(objectInterface interface{}) string { + jsonBytes, err := json.Marshal(objectInterface) + if err != nil { + logger.Debug(fmt.Sprintf("Was not able to pretty print the object: %v", objectInterface)) + return "" + } + return string(jsonBytes) +} From 2536bebbecbd5edaad76b34b88cb68b3c458c530 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Tue, 14 Feb 2023 13:29:13 +0100 Subject: [PATCH 33/57] cahnge type --- back/operations/ssikit.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/back/operations/ssikit.go b/back/operations/ssikit.go index 6ed8d23d..534eb7a2 100644 --- a/back/operations/ssikit.go +++ b/back/operations/ssikit.go @@ -57,8 +57,8 @@ type verificationRequest struct { } type verificationResult struct { - Valid bool `json:"valid"` - PolicyResults map[string]string `json:"policyResults` + Valid bool `json:"valid"` + PolicyResults map[string]bool `json:"policyResults` } type verificationResponse struct { From 2938fca1065e865b576fc738e8580e5f5055b353 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Tue, 14 Feb 2023 14:08:17 +0100 Subject: [PATCH 34/57] logging --- back/operations/ssikit.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/back/operations/ssikit.go b/back/operations/ssikit.go index 534eb7a2..6f8f54dc 100644 --- a/back/operations/ssikit.go +++ b/back/operations/ssikit.go @@ -74,6 +74,8 @@ func VerifyVC(auditorURL string, policies []model.Policy, verifiableCredential m verificationRequest := verificationRequest{policies, []model.VerifiableCredential{verifiableCredential}} agent.JSON(verificationRequest) + + logger.Debug(fmt.Sprintf("Request is %s", prettyPrintObject(verificationRequest))) agent.ContentType("application/json") agent.Set("accept", "application/json") From 17e0a812f3ea7d9fa992637746e1dc66d53adac1 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Tue, 14 Feb 2023 14:20:21 +0100 Subject: [PATCH 35/57] add the proof --- model/verifiablecredential.go | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/model/verifiablecredential.go b/model/verifiablecredential.go index c06acbe4..5fae998f 100644 --- a/model/verifiablecredential.go +++ b/model/verifiablecredential.go @@ -1,14 +1,15 @@ package model type VerifiableCredential struct { - Context []string `json:"@context,omitempty"` - Id string `json:"id,omitempty"` - Type []string `json:"type,omitempty"` - Issuer string `json:"issuer,omitempty"` - IssuanceDate string `json:"issuanceDate,omitempty"` - ValidFrom string `json:"validFrom,omitempty"` - ExpirationDate string `json:"expirationDate,omitempty"` - CredentialSubject CredentialSubject `json:"credentialSubject,omitempty"` + Context []string `json:"@context,omitempty"` + Id string `json:"id,omitempty"` + Type []string `json:"type,omitempty"` + Issuer string `json:"issuer,omitempty"` + IssuanceDate string `json:"issuanceDate,omitempty"` + ValidFrom string `json:"validFrom,omitempty"` + ExpirationDate string `json:"expirationDate,omitempty"` + CredentialSubject CredentialSubject `json:"credentialSubject,omitempty"` + Proof map[string]interface{} `json:"proof"` } type Role struct { From dc6dfa69d52f99fd1add4ed39ef0cf6160f32f39 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Tue, 14 Feb 2023 14:38:10 +0100 Subject: [PATCH 36/57] just take it as it is --- model/verifiablecredential.go | 24 ------------------------ verifier.go | 2 +- 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/model/verifiablecredential.go b/model/verifiablecredential.go index 5fae998f..fae7b61a 100644 --- a/model/verifiablecredential.go +++ b/model/verifiablecredential.go @@ -1,29 +1,5 @@ package model -type VerifiableCredential struct { - Context []string `json:"@context,omitempty"` - Id string `json:"id,omitempty"` - Type []string `json:"type,omitempty"` - Issuer string `json:"issuer,omitempty"` - IssuanceDate string `json:"issuanceDate,omitempty"` - ValidFrom string `json:"validFrom,omitempty"` - ExpirationDate string `json:"expirationDate,omitempty"` - CredentialSubject CredentialSubject `json:"credentialSubject,omitempty"` - Proof map[string]interface{} `json:"proof"` -} - -type Role struct { - // name of the role, for example READER - Names []string `json:"names,omitempty"` - Target string `json:"target,omitempty"` - Provider string `json:"provider,omitempty"` -} - -type CredentialSubject struct { - Id string `json:"id,omitempty"` - Roles []Role `json:"roles,omitempty"` -} - type Policy struct { Policy string `json:"policy"` Argument *TirArgument `json:"argument"` diff --git a/verifier.go b/verifier.go index 28eb33eb..80a3f1d0 100644 --- a/verifier.go +++ b/verifier.go @@ -184,7 +184,7 @@ func (v *Verifier) VerifierAPIAuthenticationResponseVP(c *fiber.Ctx) error { func (v *Verifier) verifyCredential(credential []byte) (result bool, err error) { - var vcToVerify model.VerifiableCredential + var vcToVerify map[string]interface{} json.Unmarshal(credential, &vcToVerify) From 3699617c852399b7eca981b1d85840f0162c59a4 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Tue, 14 Feb 2023 14:43:51 +0100 Subject: [PATCH 37/57] add back --- back/operations/ssikit.go | 2 +- model/verifiablecredential.go | 12 ++++++++++++ verifier.go | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/back/operations/ssikit.go b/back/operations/ssikit.go index 6f8f54dc..fd0fbcc4 100644 --- a/back/operations/ssikit.go +++ b/back/operations/ssikit.go @@ -75,7 +75,7 @@ func VerifyVC(auditorURL string, policies []model.Policy, verifiableCredential m agent.JSON(verificationRequest) - logger.Debug(fmt.Sprintf("Request is %s", prettyPrintObject(verificationRequest))) + logger.Debug(fmt.Sprintf("Request is %s", prettyPrintObject())) agent.ContentType("application/json") agent.Set("accept", "application/json") diff --git a/model/verifiablecredential.go b/model/verifiablecredential.go index fae7b61a..6531fdbc 100644 --- a/model/verifiablecredential.go +++ b/model/verifiablecredential.go @@ -1,5 +1,17 @@ package model +type VerifiableCredential struct { + Context []string `json:"@context,omitempty"` + Id string `json:"id,omitempty"` + Type []string `json:"type,omitempty"` + Issuer string `json:"issuer,omitempty"` + IssuanceDate string `json:"issuanceDate,omitempty"` + ValidFrom string `json:"validFrom,omitempty"` + ExpirationDate string `json:"expirationDate,omitempty"` + CredentialSubject map[string]interface{} `json:"credentialSubject,omitempty"` + Proof map[string]interface{} `json:"proof"` +} + type Policy struct { Policy string `json:"policy"` Argument *TirArgument `json:"argument"` diff --git a/verifier.go b/verifier.go index 80a3f1d0..28eb33eb 100644 --- a/verifier.go +++ b/verifier.go @@ -184,7 +184,7 @@ func (v *Verifier) VerifierAPIAuthenticationResponseVP(c *fiber.Ctx) error { func (v *Verifier) verifyCredential(credential []byte) (result bool, err error) { - var vcToVerify map[string]interface{} + var vcToVerify model.VerifiableCredential json.Unmarshal(credential, &vcToVerify) From b504a5972f4fbae3d6fcbfdfdd20dfdc7e9f1ca0 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Tue, 14 Feb 2023 14:46:17 +0100 Subject: [PATCH 38/57] fix --- back/operations/ssikit.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/operations/ssikit.go b/back/operations/ssikit.go index fd0fbcc4..6f8f54dc 100644 --- a/back/operations/ssikit.go +++ b/back/operations/ssikit.go @@ -75,7 +75,7 @@ func VerifyVC(auditorURL string, policies []model.Policy, verifiableCredential m agent.JSON(verificationRequest) - logger.Debug(fmt.Sprintf("Request is %s", prettyPrintObject())) + logger.Debug(fmt.Sprintf("Request is %s", prettyPrintObject(verificationRequest))) agent.ContentType("application/json") agent.Set("accept", "application/json") From 22f537f78b8729112ad8af5979579e1885e18a6e Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Tue, 14 Feb 2023 14:54:13 +0100 Subject: [PATCH 39/57] omit empty --- model/verifiablecredential.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/verifiablecredential.go b/model/verifiablecredential.go index 6531fdbc..d3ba777d 100644 --- a/model/verifiablecredential.go +++ b/model/verifiablecredential.go @@ -14,7 +14,7 @@ type VerifiableCredential struct { type Policy struct { Policy string `json:"policy"` - Argument *TirArgument `json:"argument"` + Argument *TirArgument `json:"argument,omitempty"` } type TirArgument struct { From 1244f9bc989828776ebc107272c2cbf29ef4a4b2 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Tue, 14 Feb 2023 14:56:14 +0100 Subject: [PATCH 40/57] schema needs to be included --- model/verifiablecredential.go | 1 + 1 file changed, 1 insertion(+) diff --git a/model/verifiablecredential.go b/model/verifiablecredential.go index d3ba777d..851524e2 100644 --- a/model/verifiablecredential.go +++ b/model/verifiablecredential.go @@ -8,6 +8,7 @@ type VerifiableCredential struct { IssuanceDate string `json:"issuanceDate,omitempty"` ValidFrom string `json:"validFrom,omitempty"` ExpirationDate string `json:"expirationDate,omitempty"` + CredentialSchema map[string]interface{} `json:"credentialSchema,omitempty"` CredentialSubject map[string]interface{} `json:"credentialSubject,omitempty"` Proof map[string]interface{} `json:"proof"` } From 0c982cdece0910f288396841cf1b4a6329a9479a Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Tue, 14 Feb 2023 14:59:30 +0100 Subject: [PATCH 41/57] dont decode --- back/operations/ssikit.go | 8 ++++---- model/verifiablecredential.go | 13 ------------- verifier.go | 2 +- 3 files changed, 5 insertions(+), 18 deletions(-) diff --git a/back/operations/ssikit.go b/back/operations/ssikit.go index 6f8f54dc..95b2dcf7 100644 --- a/back/operations/ssikit.go +++ b/back/operations/ssikit.go @@ -52,8 +52,8 @@ func SSIKitCreateDID(custodianURL string, v *vault.Vault, userid string) (string } type verificationRequest struct { - Policies []model.Policy `json:"policies"` - Credentials []model.VerifiableCredential `json:"credentials"` + Policies []model.Policy `json:"policies"` + Credentials []map[string]interface{} `json:"credentials"` } type verificationResult struct { @@ -66,12 +66,12 @@ type verificationResponse struct { Results []verificationResult `json:"results"` } -func VerifyVC(auditorURL string, policies []model.Policy, verifiableCredential model.VerifiableCredential) (result bool, err error) { +func VerifyVC(auditorURL string, policies []model.Policy, verifiableCredential map[string]interface{}) (result bool, err error) { defer logger.Sync() auditorAddress := auditorURL + verificationPath // Call the SSI Kit agent := fiber.Post(auditorURL + verificationPath) - verificationRequest := verificationRequest{policies, []model.VerifiableCredential{verifiableCredential}} + verificationRequest := verificationRequest{policies, []map[string]interface{}{verifiableCredential}} agent.JSON(verificationRequest) diff --git a/model/verifiablecredential.go b/model/verifiablecredential.go index 851524e2..37585875 100644 --- a/model/verifiablecredential.go +++ b/model/verifiablecredential.go @@ -1,18 +1,5 @@ package model -type VerifiableCredential struct { - Context []string `json:"@context,omitempty"` - Id string `json:"id,omitempty"` - Type []string `json:"type,omitempty"` - Issuer string `json:"issuer,omitempty"` - IssuanceDate string `json:"issuanceDate,omitempty"` - ValidFrom string `json:"validFrom,omitempty"` - ExpirationDate string `json:"expirationDate,omitempty"` - CredentialSchema map[string]interface{} `json:"credentialSchema,omitempty"` - CredentialSubject map[string]interface{} `json:"credentialSubject,omitempty"` - Proof map[string]interface{} `json:"proof"` -} - type Policy struct { Policy string `json:"policy"` Argument *TirArgument `json:"argument,omitempty"` diff --git a/verifier.go b/verifier.go index 28eb33eb..80a3f1d0 100644 --- a/verifier.go +++ b/verifier.go @@ -184,7 +184,7 @@ func (v *Verifier) VerifierAPIAuthenticationResponseVP(c *fiber.Ctx) error { func (v *Verifier) verifyCredential(credential []byte) (result bool, err error) { - var vcToVerify model.VerifiableCredential + var vcToVerify map[string]interface{} json.Unmarshal(credential, &vcToVerify) From 285d4b8f3dc6307f1a4a0e615a39319445078fc3 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Wed, 15 Feb 2023 09:52:12 +0100 Subject: [PATCH 42/57] setup with configured did --- back/operations/ssikit.go | 15 ++++++++++----- configs/server.yaml | 1 + main.go | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/back/operations/ssikit.go b/back/operations/ssikit.go index 95b2dcf7..9a7c1049 100644 --- a/back/operations/ssikit.go +++ b/back/operations/ssikit.go @@ -16,13 +16,18 @@ const verificationPath = "/v1/verify" var logger = zap.Must(zap.NewDevelopment()) -func SSIKitCreateDID(custodianURL string, v *vault.Vault, userid string) (string, error) { +func SSIKitCreateDID(custodianURL string, v *vault.Vault, userid string, configueredDid string) (did string, err error) { defer logger.Sync() - // Create a new DID only if it does not exist - did, _ := v.GetDIDForUser(userid) - if len(did) > 0 { - return did, nil + if len(configueredDid) == 0 { + // Create a new DID only if it does not exist + did, err = v.GetDIDForUser(userid) + if len(did) > 0 { + return did, err + } + } else { + v.SetDIDForUser(userid, configueredDid) + return did, err } // Call the SSI Kit diff --git a/configs/server.yaml b/configs/server.yaml index c0bba5b4..857ddc1c 100644 --- a/configs/server.yaml +++ b/configs/server.yaml @@ -11,6 +11,7 @@ store: verifier: id: PacketDelivery + did: did:key:z6Mkv4Lh9zBTPLoFhLHHMFJA7YAeVw5HFYZV8rkdfY9fNtm3 name: PacketDelivery password: ThePassword store: diff --git a/main.go b/main.go index 25ff7df2..264668d7 100644 --- a/main.go +++ b/main.go @@ -125,7 +125,7 @@ func BackendServer() { s.logger.Infof("SSIKit is configured at: %v", s.ssiKit) - s.verifierDID, err = operations.SSIKitCreateDID(s.ssiKit.custodianUrl, s.verifierVault, cfg.String("verifier.id")) + s.verifierDID, err = operations.SSIKitCreateDID(s.ssiKit.custodianUrl, s.verifierVault, cfg.String("verifier.id"), s.cfg.String("verifier.did")) if err != nil { panic(err) } From dffea496991aeef96010b81c1c5738151211567b Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Wed, 15 Feb 2023 10:19:45 +0100 Subject: [PATCH 43/57] fix the path --- back/views/verifier_request_service.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/views/verifier_request_service.html b/back/views/verifier_request_service.html index c54de55d..13b3253f 100644 --- a/back/views/verifier_request_service.html +++ b/back/views/verifier_request_service.html @@ -5,7 +5,7 @@

Enter URL:

-
+ Date: Mon, 13 Mar 2023 11:04:43 +0100 Subject: [PATCH 44/57] add logs --- frontend.go | 2 ++ verifier.go | 2 ++ 2 files changed, 4 insertions(+) diff --git a/frontend.go b/frontend.go index 7e67d605..51b3ef2c 100644 --- a/frontend.go +++ b/frontend.go @@ -104,6 +104,8 @@ func (f *Frontend) VerifierPageLoginExpired(c *fiber.Ctx) error { func (f *Frontend) VerifierPageReceiveCredential(c *fiber.Ctx) error { + f.server.logger.Infof("Received credential") + // Get the state as a path parameter state := c.Params("state") diff --git a/verifier.go b/verifier.go index 80a3f1d0..4d59f11f 100644 --- a/verifier.go +++ b/verifier.go @@ -207,6 +207,8 @@ type VerifiableCredential struct { func (v *Verifier) VerifierAPIAuthenticationResponse(c *fiber.Ctx) error { + v.server.logger.Infof("Authenticate") + // Get the state state := c.Query("state") From 9f728acd68fed67d883aa9c6dd19ae9fa0271935 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Mon, 13 Mar 2023 11:19:06 +0100 Subject: [PATCH 45/57] maybe there --- verifier.go | 1 + 1 file changed, 1 insertion(+) diff --git a/verifier.go b/verifier.go index 4d59f11f..aa6d4a15 100644 --- a/verifier.go +++ b/verifier.go @@ -149,6 +149,7 @@ type verficationMsg struct { // VerifierAPIAuthenticationResponseVP receives a VP, extracts the VC and display a page func (v *Verifier) VerifierAPIAuthenticationResponseVP(c *fiber.Ctx) error { + v.server.logger.Infof("Authenticate") // Get the state, which indicates the login session to which this request belongs state := c.Query("state") From 97415121b068cfb9dad90f2791e66ac42565df04 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Mon, 13 Mar 2023 11:33:18 +0100 Subject: [PATCH 46/57] something must be logged --- verifier.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/verifier.go b/verifier.go index aa6d4a15..4d56c612 100644 --- a/verifier.go +++ b/verifier.go @@ -61,7 +61,9 @@ func setupVerifier(s *Server) { // Used by the wallet (both enterprise and mobile) to send the VC/VP as Authentication Response verifierRoutes.Post("/authenticationresponse", verifier.VerifierAPIAuthenticationResponse) - + s.logger.Info("Routes are setup") + s.logger.Warn("W") + s.logger.Error("E") } type AccessServiceForm struct { @@ -149,7 +151,6 @@ type verficationMsg struct { // VerifierAPIAuthenticationResponseVP receives a VP, extracts the VC and display a page func (v *Verifier) VerifierAPIAuthenticationResponseVP(c *fiber.Ctx) error { - v.server.logger.Infof("Authenticate") // Get the state, which indicates the login session to which this request belongs state := c.Query("state") @@ -208,8 +209,6 @@ type VerifiableCredential struct { func (v *Verifier) VerifierAPIAuthenticationResponse(c *fiber.Ctx) error { - v.server.logger.Infof("Authenticate") - // Get the state state := c.Query("state") From ac693c95585ba069c02165e4af377500e1532477 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Mon, 13 Mar 2023 11:40:20 +0100 Subject: [PATCH 47/57] change logs --- verifier.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/verifier.go b/verifier.go index 4d56c612..ff39ed1e 100644 --- a/verifier.go +++ b/verifier.go @@ -4,7 +4,6 @@ import ( "encoding/base64" "encoding/json" "errors" - "fmt" "net/http" "time" @@ -62,8 +61,6 @@ func setupVerifier(s *Server) { // Used by the wallet (both enterprise and mobile) to send the VC/VP as Authentication Response verifierRoutes.Post("/authenticationresponse", verifier.VerifierAPIAuthenticationResponse) s.logger.Info("Routes are setup") - s.logger.Warn("W") - s.logger.Error("E") } type AccessServiceForm struct { @@ -151,13 +148,13 @@ type verficationMsg struct { // VerifierAPIAuthenticationResponseVP receives a VP, extracts the VC and display a page func (v *Verifier) VerifierAPIAuthenticationResponseVP(c *fiber.Ctx) error { + v.server.logger.Info("Received VP") + // Get the state, which indicates the login session to which this request belongs state := c.Query("state") // We should receive the Verifiable Presentation in the body as JSON body := c.Body() - fmt.Println(string(body)) - fmt.Println(string(state)) // Decode into a map vp, err := yaml.ParseJson(string(body)) @@ -185,6 +182,7 @@ func (v *Verifier) VerifierAPIAuthenticationResponseVP(c *fiber.Ctx) error { } func (v *Verifier) verifyCredential(credential []byte) (result bool, err error) { + v.server.logger.Info("Verify Credential") var vcToVerify map[string]interface{} @@ -209,6 +207,8 @@ type VerifiableCredential struct { func (v *Verifier) VerifierAPIAuthenticationResponse(c *fiber.Ctx) error { + v.server.logger.Info("Auth") + // Get the state state := c.Query("state") From 3bf2e248db8aae87c3ebb5d73bd87f7ace8886ec Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Mon, 13 Mar 2023 11:47:06 +0100 Subject: [PATCH 48/57] more log --- verifier.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/verifier.go b/verifier.go index ff39ed1e..8e99e181 100644 --- a/verifier.go +++ b/verifier.go @@ -61,6 +61,7 @@ func setupVerifier(s *Server) { // Used by the wallet (both enterprise and mobile) to send the VC/VP as Authentication Response verifierRoutes.Post("/authenticationresponse", verifier.VerifierAPIAuthenticationResponse) s.logger.Info("Routes are setup") + } type AccessServiceForm struct { @@ -69,6 +70,7 @@ type AccessServiceForm struct { func (v *Verifier) VerifierAPIPoll(c *fiber.Ctx) error { + v.server.logger.Info("VerifierAPIPoll") // get the state state := c.Params("state") @@ -113,6 +115,8 @@ func (v *Verifier) VerifierAPIToken(c *fiber.Ctx) error { func (v *Verifier) VerifierAPIStartSIOP(c *fiber.Ctx) error { + v.server.logger.Info("Start siop") + // Get the state state := c.Query("state") From 9a001be0069b6f1efaddc6814d54a33222870932 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Mon, 13 Mar 2023 11:58:10 +0100 Subject: [PATCH 49/57] direct to the console --- verifier.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/verifier.go b/verifier.go index 8e99e181..81de1d8d 100644 --- a/verifier.go +++ b/verifier.go @@ -4,6 +4,7 @@ import ( "encoding/base64" "encoding/json" "errors" + "fmt" "net/http" "time" @@ -70,7 +71,7 @@ type AccessServiceForm struct { func (v *Verifier) VerifierAPIPoll(c *fiber.Ctx) error { - v.server.logger.Info("VerifierAPIPoll") + fmt.Println("VerifierAPIPoll") // get the state state := c.Params("state") @@ -86,7 +87,7 @@ func (v *Verifier) VerifierAPIPoll(c *fiber.Ctx) error { // retrieve token for the given session("state"-paramter) func (v *Verifier) VerifierAPIToken(c *fiber.Ctx) error { - v.server.logger.Info("Get the token") + fmt.Println("Get the token") // get the state state := c.Params("state") @@ -115,6 +116,7 @@ func (v *Verifier) VerifierAPIToken(c *fiber.Ctx) error { func (v *Verifier) VerifierAPIStartSIOP(c *fiber.Ctx) error { + fmt.Println("Start siop") v.server.logger.Info("Start siop") // Get the state @@ -152,7 +154,7 @@ type verficationMsg struct { // VerifierAPIAuthenticationResponseVP receives a VP, extracts the VC and display a page func (v *Verifier) VerifierAPIAuthenticationResponseVP(c *fiber.Ctx) error { - v.server.logger.Info("Received VP") + fmt.Println("Received VP") // Get the state, which indicates the login session to which this request belongs state := c.Query("state") @@ -186,7 +188,7 @@ func (v *Verifier) VerifierAPIAuthenticationResponseVP(c *fiber.Ctx) error { } func (v *Verifier) verifyCredential(credential []byte) (result bool, err error) { - v.server.logger.Info("Verify Credential") + fmt.Println("Verify Credential") var vcToVerify map[string]interface{} @@ -211,7 +213,7 @@ type VerifiableCredential struct { func (v *Verifier) VerifierAPIAuthenticationResponse(c *fiber.Ctx) error { - v.server.logger.Info("Auth") + fmt.Println("Auth") // Get the state state := c.Query("state") From e8ec7b0d1145362b17a30b7db33bcf01e58079cc Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Mon, 13 Mar 2023 12:05:46 +0100 Subject: [PATCH 50/57] more logging --- main.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index 264668d7..f2634677 100644 --- a/main.go +++ b/main.go @@ -17,7 +17,6 @@ import ( "github.com/hesusruiz/vcutils/yaml" "flag" - "log" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/cors" @@ -158,8 +157,10 @@ func BackendServer() { // Setup static files s.Static("/static", cfg.String("server.staticDir", defaultStaticDir)) + s.logger.Info("Start") // Start the server - log.Fatal(s.Listen(cfg.String("server.listenAddress"))) + s.logger.Info(s.Listen(cfg.String("server.listenAddress"))) + s.logger.Info("Started") } From 53eaa21ee3f2289e95c9bd9c067afbb8091115de Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Mon, 13 Mar 2023 12:13:43 +0100 Subject: [PATCH 51/57] log --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index f2634677..2b82e92e 100644 --- a/main.go +++ b/main.go @@ -159,7 +159,7 @@ func BackendServer() { s.logger.Info("Start") // Start the server - s.logger.Info(s.Listen(cfg.String("server.listenAddress"))) + s.Listen(cfg.String("server.listenAddress")) s.logger.Info("Started") } From ed3487f8d0e2f935d937fbfba67180f633c05cad Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Mon, 13 Mar 2023 12:58:01 +0100 Subject: [PATCH 52/57] and more --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 2b82e92e..2708ba1f 100644 --- a/main.go +++ b/main.go @@ -157,7 +157,7 @@ func BackendServer() { // Setup static files s.Static("/static", cfg.String("server.staticDir", defaultStaticDir)) - s.logger.Info("Start") + s.logger.Infof("Start %s", cfg.String("server.listenAddress")) // Start the server s.Listen(cfg.String("server.listenAddress")) s.logger.Info("Started") From 84b56c2dc07186fcf91ad1556ae696b17229b9aa Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Mon, 13 Mar 2023 13:05:07 +0100 Subject: [PATCH 53/57] log err --- main.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/main.go b/main.go index 2708ba1f..ae1499f7 100644 --- a/main.go +++ b/main.go @@ -159,7 +159,10 @@ func BackendServer() { s.logger.Infof("Start %s", cfg.String("server.listenAddress")) // Start the server - s.Listen(cfg.String("server.listenAddress")) + err = s.Listen(cfg.String("server.listenAddress")) + if err != nil { + s.logger.Warn("Failed to start.", err) + } s.logger.Info("Started") } From 1996cd456a6a3b2edd692f375d244fed3a41243f Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Mon, 13 Mar 2023 13:11:34 +0100 Subject: [PATCH 54/57] m --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index ae1499f7..dee3c850 100644 --- a/main.go +++ b/main.go @@ -164,7 +164,7 @@ func BackendServer() { s.logger.Warn("Failed to start.", err) } s.logger.Info("Started") - + s.logger.Info("now") } func fromMap(configMap map[string]any) (skc *SSIKitConfig) { From abebfe40cbf3354b3aeac36823249098f7be3c44 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Mon, 13 Mar 2023 13:34:13 +0100 Subject: [PATCH 55/57] clean again --- main.go | 2 -- verifier.go | 14 ++++++-------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/main.go b/main.go index dee3c850..877af66b 100644 --- a/main.go +++ b/main.go @@ -163,8 +163,6 @@ func BackendServer() { if err != nil { s.logger.Warn("Failed to start.", err) } - s.logger.Info("Started") - s.logger.Info("now") } func fromMap(configMap map[string]any) (skc *SSIKitConfig) { diff --git a/verifier.go b/verifier.go index 81de1d8d..73012ced 100644 --- a/verifier.go +++ b/verifier.go @@ -4,7 +4,6 @@ import ( "encoding/base64" "encoding/json" "errors" - "fmt" "net/http" "time" @@ -71,7 +70,7 @@ type AccessServiceForm struct { func (v *Verifier) VerifierAPIPoll(c *fiber.Ctx) error { - fmt.Println("VerifierAPIPoll") + s.logger.Debug("VerifierAPIPoll") // get the state state := c.Params("state") @@ -87,7 +86,7 @@ func (v *Verifier) VerifierAPIPoll(c *fiber.Ctx) error { // retrieve token for the given session("state"-paramter) func (v *Verifier) VerifierAPIToken(c *fiber.Ctx) error { - fmt.Println("Get the token") + v.server.logger.Debug("Get the token") // get the state state := c.Params("state") @@ -116,8 +115,7 @@ func (v *Verifier) VerifierAPIToken(c *fiber.Ctx) error { func (v *Verifier) VerifierAPIStartSIOP(c *fiber.Ctx) error { - fmt.Println("Start siop") - v.server.logger.Info("Start siop") + v.server.logger.Debug("Start siop") // Get the state state := c.Query("state") @@ -154,7 +152,7 @@ type verficationMsg struct { // VerifierAPIAuthenticationResponseVP receives a VP, extracts the VC and display a page func (v *Verifier) VerifierAPIAuthenticationResponseVP(c *fiber.Ctx) error { - fmt.Println("Received VP") + v.server.logger.Debug("Received VP") // Get the state, which indicates the login session to which this request belongs state := c.Query("state") @@ -188,7 +186,7 @@ func (v *Verifier) VerifierAPIAuthenticationResponseVP(c *fiber.Ctx) error { } func (v *Verifier) verifyCredential(credential []byte) (result bool, err error) { - fmt.Println("Verify Credential") + v.server.logger.Debug("Verify Credential") var vcToVerify map[string]interface{} @@ -213,7 +211,7 @@ type VerifiableCredential struct { func (v *Verifier) VerifierAPIAuthenticationResponse(c *fiber.Ctx) error { - fmt.Println("Auth") + v.server.logger.Debug("Auth") // Get the state state := c.Query("state") From 52aa9cf214c44d8a19aee2950b92e4ab2c6d680e Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Mon, 13 Mar 2023 13:40:26 +0100 Subject: [PATCH 56/57] fix --- verifier.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/verifier.go b/verifier.go index 73012ced..361dd660 100644 --- a/verifier.go +++ b/verifier.go @@ -70,7 +70,7 @@ type AccessServiceForm struct { func (v *Verifier) VerifierAPIPoll(c *fiber.Ctx) error { - s.logger.Debug("VerifierAPIPoll") + v.server.logger.Debug("VerifierAPIPoll") // get the state state := c.Params("state") From d47af7fcde842c57046df3af21ffa6c7f511c3ed Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Tue, 14 Mar 2023 08:46:53 +0100 Subject: [PATCH 57/57] more logging --- verifier.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/verifier.go b/verifier.go index 361dd660..c41317b7 100644 --- a/verifier.go +++ b/verifier.go @@ -180,8 +180,10 @@ func (v *Verifier) VerifierAPIAuthenticationResponseVP(c *fiber.Ctx) error { } // Set the credential in storage, and wait for the polling from client - v.server.storage.Set(state, credential, 10*time.Second) - + err = v.server.storage.Set(state, credential, 10*time.Second) + if err != nil { + v.server.logger.Warnf("Was not able to store for %s", state) + } return c.SendString("ok") }