Skip to content
Snippets Groups Projects
Commit 1eb46b69 authored by Lyuben Penkovski's avatar Lyuben Penkovski
Browse files

Merge branch '4-verifiable-presentation-proof' into 'main'

Add proof to verifiable presentation

Closes #4

See merge request !3
parents e81d3b6e 0e01fa31
No related branches found
No related tags found
1 merge request!3Add proof to verifiable presentation
Pipeline #51476 passed
Showing
with 530 additions and 30 deletions
...@@ -11,3 +11,6 @@ TODO - how key is selected if the request doesn't mention explicit key ...@@ -11,3 +11,6 @@ TODO - how key is selected if the request doesn't mention explicit key
TODO - how signature suite is constructed based on key type TODO - how signature suite is constructed based on key type
### Counterfeiter
TODO - how to use it for generating fake implementations of interfaces
\ No newline at end of file
...@@ -105,6 +105,8 @@ func main() { ...@@ -105,6 +105,8 @@ func main() {
openapiServer = goaopenapisrv.New(openapiEndpoints, mux, dec, enc, nil, errFormatter, nil, nil) openapiServer = goaopenapisrv.New(openapiEndpoints, mux, dec, enc, nil, errFormatter, nil, nil)
} }
// set custom request decoder, so that request body bytes are simply
// read and not decoded in some other way
signerServer.CredentialProof = goasignersrv.NewCredentialProofHandler( signerServer.CredentialProof = goasignersrv.NewCredentialProofHandler(
signerEndpoints.CredentialProof, signerEndpoints.CredentialProof,
mux, mux,
...@@ -114,6 +116,17 @@ func main() { ...@@ -114,6 +116,17 @@ func main() {
errFormatter, errFormatter,
) )
// set custom request decoder, so that request body bytes are simply
// read and not decoded in some other way
signerServer.PresentationProof = goasignersrv.NewPresentationProofHandler(
signerEndpoints.PresentationProof,
mux,
decoder.RequestDecoder,
enc,
nil,
errFormatter,
)
// Configure the mux. // Configure the mux.
goasignersrv.Mount(mux, signerServer) goasignersrv.Mount(mux, signerServer)
goahealthsrv.Mount(mux, healthServer) goahealthsrv.Mount(mux, healthServer)
......
...@@ -30,6 +30,19 @@ var _ = Service("signer", func() { ...@@ -30,6 +30,19 @@ var _ = Service("signer", func() {
Response(StatusOK) Response(StatusOK)
}) })
}) })
Method("PresentationProof", func() {
Description("PresentationProof adds a proof to a given Verifiable Presentation.")
Payload(PresentationProofRequest)
Result(Any)
HTTP(func() {
POST("/v1/presentation/proof")
Param("key")
Body("presentation")
Response(StatusOK)
})
})
}) })
var _ = Service("health", func() { var _ = Service("health", func() {
......
...@@ -10,3 +10,11 @@ var CredentialProofRequest = Type("CredentialProofRequest", func() { ...@@ -10,3 +10,11 @@ var CredentialProofRequest = Type("CredentialProofRequest", func() {
Field(2, "credential", Bytes, "Verifiable Credential in JSON format.") Field(2, "credential", Bytes, "Verifiable Credential in JSON format.")
Required("credential") Required("credential")
}) })
var PresentationProofRequest = Type("PresentationProofRequest", func() {
Field(1, "key", String, "Key to use for the proof signature (optional).", func() {
Example("key1")
})
Field(2, "presentation", Bytes, "Verifiable Presentation in JSON format.")
Required("presentation")
})
...@@ -25,14 +25,14 @@ import ( ...@@ -25,14 +25,14 @@ import (
// //
func UsageCommands() string { func UsageCommands() string {
return `health (liveness|readiness) return `health (liveness|readiness)
signer credential-proof signer (credential-proof|presentation-proof)
` `
} }
// UsageExamples produces an example of a valid invocation of the CLI tool. // UsageExamples produces an example of a valid invocation of the CLI tool.
func UsageExamples() string { func UsageExamples() string {
return os.Args[0] + ` health liveness` + "\n" + return os.Args[0] + ` health liveness` + "\n" +
os.Args[0] + ` signer credential-proof --body "QXV0IGZ1Z2lhdCBoYXJ1bS4=" --key "key1"` + "\n" + os.Args[0] + ` signer credential-proof --body "SXRhcXVlIG9mZmljaWEgY29tbW9kaSBhdXRlbSBhdCBiZWF0YWUu" --key "key1"` + "\n" +
"" ""
} }
...@@ -57,6 +57,10 @@ func ParseEndpoint( ...@@ -57,6 +57,10 @@ func ParseEndpoint(
signerCredentialProofFlags = flag.NewFlagSet("credential-proof", flag.ExitOnError) signerCredentialProofFlags = flag.NewFlagSet("credential-proof", flag.ExitOnError)
signerCredentialProofBodyFlag = signerCredentialProofFlags.String("body", "REQUIRED", "") signerCredentialProofBodyFlag = signerCredentialProofFlags.String("body", "REQUIRED", "")
signerCredentialProofKeyFlag = signerCredentialProofFlags.String("key", "", "") signerCredentialProofKeyFlag = signerCredentialProofFlags.String("key", "", "")
signerPresentationProofFlags = flag.NewFlagSet("presentation-proof", flag.ExitOnError)
signerPresentationProofBodyFlag = signerPresentationProofFlags.String("body", "REQUIRED", "")
signerPresentationProofKeyFlag = signerPresentationProofFlags.String("key", "", "")
) )
healthFlags.Usage = healthUsage healthFlags.Usage = healthUsage
healthLivenessFlags.Usage = healthLivenessUsage healthLivenessFlags.Usage = healthLivenessUsage
...@@ -64,6 +68,7 @@ func ParseEndpoint( ...@@ -64,6 +68,7 @@ func ParseEndpoint(
signerFlags.Usage = signerUsage signerFlags.Usage = signerUsage
signerCredentialProofFlags.Usage = signerCredentialProofUsage signerCredentialProofFlags.Usage = signerCredentialProofUsage
signerPresentationProofFlags.Usage = signerPresentationProofUsage
if err := flag.CommandLine.Parse(os.Args[1:]); err != nil { if err := flag.CommandLine.Parse(os.Args[1:]); err != nil {
return nil, nil, err return nil, nil, err
...@@ -114,6 +119,9 @@ func ParseEndpoint( ...@@ -114,6 +119,9 @@ func ParseEndpoint(
case "credential-proof": case "credential-proof":
epf = signerCredentialProofFlags epf = signerCredentialProofFlags
case "presentation-proof":
epf = signerPresentationProofFlags
} }
} }
...@@ -152,6 +160,9 @@ func ParseEndpoint( ...@@ -152,6 +160,9 @@ func ParseEndpoint(
case "credential-proof": case "credential-proof":
endpoint = c.CredentialProof() endpoint = c.CredentialProof()
data, err = signerc.BuildCredentialProofPayload(*signerCredentialProofBodyFlag, *signerCredentialProofKeyFlag) data, err = signerc.BuildCredentialProofPayload(*signerCredentialProofBodyFlag, *signerCredentialProofKeyFlag)
case "presentation-proof":
endpoint = c.PresentationProof()
data, err = signerc.BuildPresentationProofPayload(*signerPresentationProofBodyFlag, *signerPresentationProofKeyFlag)
} }
} }
} }
...@@ -204,6 +215,7 @@ Usage: ...@@ -204,6 +215,7 @@ Usage:
COMMAND: COMMAND:
credential-proof: CredentialProof adds a proof to a given Verifiable Credential. credential-proof: CredentialProof adds a proof to a given Verifiable Credential.
presentation-proof: PresentationProof adds a proof to a given Verifiable Presentation.
Additional help: Additional help:
%[1]s signer COMMAND --help %[1]s signer COMMAND --help
...@@ -217,6 +229,18 @@ CredentialProof adds a proof to a given Verifiable Credential. ...@@ -217,6 +229,18 @@ CredentialProof adds a proof to a given Verifiable Credential.
-key STRING: -key STRING:
Example: Example:
%[1]s signer credential-proof --body "QXV0IGZ1Z2lhdCBoYXJ1bS4=" --key "key1" %[1]s signer credential-proof --body "SXRhcXVlIG9mZmljaWEgY29tbW9kaSBhdXRlbSBhdCBiZWF0YWUu" --key "key1"
`, os.Args[0])
}
func signerPresentationProofUsage() {
fmt.Fprintf(os.Stderr, `%[1]s [flags] signer presentation-proof -body STRING -key STRING
PresentationProof adds a proof to a given Verifiable Presentation.
-body STRING:
-key STRING:
Example:
%[1]s signer presentation-proof --body "QXBlcmlhbSBxdWlhIGNvbnNlcXVhdHVyIGRvbG9yZW0u" --key "key1"
`, os.Args[0]) `, os.Args[0])
} }
{"swagger":"2.0","info":{"title":"Signer Service","description":"The signer service exposes HTTP API for creating and verifying digital signatures.","version":""},"host":"localhost:8085","consumes":["application/json","application/xml","application/gob"],"produces":["application/json","application/xml","application/gob"],"paths":{"/liveness":{"get":{"tags":["health"],"summary":"Liveness health","operationId":"health#Liveness","responses":{"200":{"description":"OK response."}},"schemes":["http"]}},"/readiness":{"get":{"tags":["health"],"summary":"Readiness health","operationId":"health#Readiness","responses":{"200":{"description":"OK response."}},"schemes":["http"]}},"/v1/credential/proof":{"post":{"tags":["signer"],"summary":"CredentialProof signer","description":"CredentialProof adds a proof to a given Verifiable Credential.","operationId":"signer#CredentialProof","parameters":[{"name":"key","in":"query","description":"Key to use for the proof signature (optional).","required":false,"type":"string"},{"name":"bytes","in":"body","description":"Verifiable Credential in JSON format.","required":true,"schema":{"type":"string","format":"byte"}}],"responses":{"200":{"description":"OK response.","schema":{"type":"string","format":"binary"}}},"schemes":["http"]}}}} {"swagger":"2.0","info":{"title":"Signer Service","description":"The signer service exposes HTTP API for creating and verifying digital signatures.","version":""},"host":"localhost:8085","consumes":["application/json","application/xml","application/gob"],"produces":["application/json","application/xml","application/gob"],"paths":{"/liveness":{"get":{"tags":["health"],"summary":"Liveness health","operationId":"health#Liveness","responses":{"200":{"description":"OK response."}},"schemes":["http"]}},"/readiness":{"get":{"tags":["health"],"summary":"Readiness health","operationId":"health#Readiness","responses":{"200":{"description":"OK response."}},"schemes":["http"]}},"/v1/credential/proof":{"post":{"tags":["signer"],"summary":"CredentialProof signer","description":"CredentialProof adds a proof to a given Verifiable Credential.","operationId":"signer#CredentialProof","parameters":[{"name":"key","in":"query","description":"Key to use for the proof signature (optional).","required":false,"type":"string"},{"name":"bytes","in":"body","description":"Verifiable Credential in JSON format.","required":true,"schema":{"type":"string","format":"byte"}}],"responses":{"200":{"description":"OK response.","schema":{"type":"string","format":"binary"}}},"schemes":["http"]}},"/v1/presentation/proof":{"post":{"tags":["signer"],"summary":"PresentationProof signer","description":"PresentationProof adds a proof to a given Verifiable Presentation.","operationId":"signer#PresentationProof","parameters":[{"name":"key","in":"query","description":"Key to use for the proof signature (optional).","required":false,"type":"string"},{"name":"bytes","in":"body","description":"Verifiable Presentation in JSON format.","required":true,"schema":{"type":"string","format":"byte"}}],"responses":{"200":{"description":"OK response.","schema":{"type":"string","format":"binary"}}},"schemes":["http"]}}}}
\ No newline at end of file \ No newline at end of file
...@@ -63,3 +63,31 @@ paths: ...@@ -63,3 +63,31 @@ paths:
format: binary format: binary
schemes: schemes:
- http - http
/v1/presentation/proof:
post:
tags:
- signer
summary: PresentationProof signer
description: PresentationProof adds a proof to a given Verifiable Presentation.
operationId: signer#PresentationProof
parameters:
- name: key
in: query
description: Key to use for the proof signature (optional).
required: false
type: string
- name: bytes
in: body
description: Verifiable Presentation in JSON format.
required: true
schema:
type: string
format: byte
responses:
"200":
description: OK response.
schema:
type: string
format: binary
schemes:
- http
{"openapi":"3.0.3","info":{"title":"Signer Service","description":"The signer service exposes HTTP API for creating and verifying digital signatures.","version":"1.0"},"servers":[{"url":"http://localhost:8085","description":"Signer Server"}],"paths":{"/liveness":{"get":{"tags":["health"],"summary":"Liveness health","operationId":"health#Liveness","responses":{"200":{"description":"OK response."}}}},"/readiness":{"get":{"tags":["health"],"summary":"Readiness health","operationId":"health#Readiness","responses":{"200":{"description":"OK response."}}}},"/v1/credential/proof":{"post":{"tags":["signer"],"summary":"CredentialProof signer","description":"CredentialProof adds a proof to a given Verifiable Credential.","operationId":"signer#CredentialProof","parameters":[{"name":"key","in":"query","description":"Key to use for the proof signature (optional).","allowEmptyValue":true,"schema":{"type":"string","description":"Key to use for the proof signature (optional).","example":"key1"},"example":"key1"}],"requestBody":{"description":"Verifiable Credential in JSON format.","required":true,"content":{"application/json":{"schema":{"type":"string","description":"Verifiable Credential in JSON format.","example":"RXVtIGl1cmUgbmVtby4=","format":"binary"},"example":"VmVuaWFtIHF1aWEu"}}},"responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"type":"string","example":"Ut voluptas sed.","format":"binary"},"example":"Ad magni."}}}}}}},"components":{},"tags":[{"name":"health","description":"Health service provides health check endpoints."},{"name":"signer","description":"Sign service provides endpoints for making digital signatures and proofs for verifiable credentials and presentations."}]} {"openapi":"3.0.3","info":{"title":"Signer Service","description":"The signer service exposes HTTP API for creating and verifying digital signatures.","version":"1.0"},"servers":[{"url":"http://localhost:8085","description":"Signer Server"}],"paths":{"/liveness":{"get":{"tags":["health"],"summary":"Liveness health","operationId":"health#Liveness","responses":{"200":{"description":"OK response."}}}},"/readiness":{"get":{"tags":["health"],"summary":"Readiness health","operationId":"health#Readiness","responses":{"200":{"description":"OK response."}}}},"/v1/credential/proof":{"post":{"tags":["signer"],"summary":"CredentialProof signer","description":"CredentialProof adds a proof to a given Verifiable Credential.","operationId":"signer#CredentialProof","parameters":[{"name":"key","in":"query","description":"Key to use for the proof signature (optional).","allowEmptyValue":true,"schema":{"type":"string","description":"Key to use for the proof signature (optional).","example":"key1"},"example":"key1"}],"requestBody":{"description":"Verifiable Credential in JSON format.","required":true,"content":{"application/json":{"schema":{"type":"string","description":"Verifiable Credential in JSON format.","example":"Q3VscGEgb2NjYWVjYXRpIGRvbG9ydW0gcXVpIGVuaW0gaW5jaWR1bnQu","format":"binary"},"example":"SXRhcXVlIGFkaXBpc2NpIHZvbHVwdGFzLg=="}}},"responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"type":"string","example":"Ipsam facere.","format":"binary"},"example":"Asperiores molestias qui."}}}}}},"/v1/presentation/proof":{"post":{"tags":["signer"],"summary":"PresentationProof signer","description":"PresentationProof adds a proof to a given Verifiable Presentation.","operationId":"signer#PresentationProof","parameters":[{"name":"key","in":"query","description":"Key to use for the proof signature (optional).","allowEmptyValue":true,"schema":{"type":"string","description":"Key to use for the proof signature (optional).","example":"key1"},"example":"key1"}],"requestBody":{"description":"Verifiable Presentation in JSON format.","required":true,"content":{"application/json":{"schema":{"type":"string","description":"Verifiable Presentation in JSON format.","example":"RXN0IHF1aWRlbSBoYXJ1bSB2ZXJvLg==","format":"binary"},"example":"SXBzYSB2ZWwgaW4gcmVwdWRpYW5kYWUgcmVwZWxsYXQu"}}},"responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"type":"string","example":"Deleniti ipsa.","format":"binary"},"example":"Laudantium exercitationem quis sunt eos."}}}}}}},"components":{},"tags":[{"name":"health","description":"Health service provides health check endpoints."},{"name":"signer","description":"Sign service provides endpoints for making digital signatures and proofs for verifiable credentials and presentations."}]}
\ No newline at end of file \ No newline at end of file
...@@ -51,33 +51,167 @@ paths: ...@@ -51,33 +51,167 @@ paths:
type: string type: string
description: Verifiable Credential in JSON format. description: Verifiable Credential in JSON format.
example: example:
- 69 - 67
- 117 - 117
- 109 - 108
- 112
- 97
- 32 - 32
- 111
- 99
- 99
- 97
- 101
- 99
- 97
- 116
- 105 - 105
- 117 - 32
- 100
- 111
- 108
- 111
- 114 - 114
- 117
- 109
- 32
- 113
- 117
- 105
- 32
- 101 - 101
- 110
- 105
- 109
- 32 - 32
- 105
- 110 - 110
- 99
- 105
- 100
- 117
- 110
- 116
- 46
format: binary
example:
- 73
- 116
- 97
- 113
- 117
- 101
- 32
- 97
- 100
- 105
- 112
- 105
- 115
- 99
- 105
- 32
- 118
- 111
- 108
- 117
- 112
- 116
- 97
- 115
- 46
responses:
"200":
description: OK response.
content:
application/json:
schema:
type: string
example: Ipsam facere.
format: binary
example: Asperiores molestias qui.
/v1/presentation/proof:
post:
tags:
- signer
summary: PresentationProof signer
description: PresentationProof adds a proof to a given Verifiable Presentation.
operationId: signer#PresentationProof
parameters:
- name: key
in: query
description: Key to use for the proof signature (optional).
allowEmptyValue: true
schema:
type: string
description: Key to use for the proof signature (optional).
example: key1
example: key1
requestBody:
description: Verifiable Presentation in JSON format.
required: true
content:
application/json:
schema:
type: string
description: Verifiable Presentation in JSON format.
example:
- 69
- 115
- 116
- 32
- 113
- 117
- 105
- 100
- 101 - 101
- 109 - 109
- 32
- 104
- 97
- 114
- 117
- 109
- 32
- 118
- 101
- 114
- 111 - 111
- 46 - 46
format: binary format: binary
example: example:
- 86 - 73
- 112
- 115
- 97
- 32
- 118
- 101 - 101
- 110 - 108
- 32
- 105 - 105
- 97 - 110
- 109
- 32 - 32
- 113 - 114
- 101
- 112
- 117 - 117
- 100
- 105 - 105
- 97 - 97
- 110
- 100
- 97
- 101
- 32
- 114
- 101
- 112
- 101
- 108
- 108
- 97
- 116
- 46 - 46
responses: responses:
"200": "200":
...@@ -86,9 +220,9 @@ paths: ...@@ -86,9 +220,9 @@ paths:
application/json: application/json:
schema: schema:
type: string type: string
example: Ut voluptas sed. example: Deleniti ipsa.
format: binary format: binary
example: Ad magni. example: Laudantium exercitationem quis sunt eos.
components: {} components: {}
tags: tags:
- name: health - name: health
......
...@@ -32,3 +32,25 @@ func BuildCredentialProofPayload(signerCredentialProofBody string, signerCredent ...@@ -32,3 +32,25 @@ func BuildCredentialProofPayload(signerCredentialProofBody string, signerCredent
return res, nil return res, nil
} }
// BuildPresentationProofPayload builds the payload for the signer
// PresentationProof endpoint from CLI flags.
func BuildPresentationProofPayload(signerPresentationProofBody string, signerPresentationProofKey string) (*signer.PresentationProofRequest, error) {
var body []byte
{
body = []byte(signerPresentationProofBody)
}
var key *string
{
if signerPresentationProofKey != "" {
key = &signerPresentationProofKey
}
}
v := body
res := &signer.PresentationProofRequest{
Presentation: v,
}
res.Key = key
return res, nil
}
...@@ -21,6 +21,10 @@ type Client struct { ...@@ -21,6 +21,10 @@ type Client struct {
// CredentialProof endpoint. // CredentialProof endpoint.
CredentialProofDoer goahttp.Doer CredentialProofDoer goahttp.Doer
// PresentationProof Doer is the HTTP client used to make requests to the
// PresentationProof endpoint.
PresentationProofDoer goahttp.Doer
// RestoreResponseBody controls whether the response bodies are reset after // RestoreResponseBody controls whether the response bodies are reset after
// decoding so they can be read again. // decoding so they can be read again.
RestoreResponseBody bool RestoreResponseBody bool
...@@ -41,12 +45,13 @@ func NewClient( ...@@ -41,12 +45,13 @@ func NewClient(
restoreBody bool, restoreBody bool,
) *Client { ) *Client {
return &Client{ return &Client{
CredentialProofDoer: doer, CredentialProofDoer: doer,
RestoreResponseBody: restoreBody, PresentationProofDoer: doer,
scheme: scheme, RestoreResponseBody: restoreBody,
host: host, scheme: scheme,
decoder: dec, host: host,
encoder: enc, decoder: dec,
encoder: enc,
} }
} }
...@@ -73,3 +78,27 @@ func (c *Client) CredentialProof() goa.Endpoint { ...@@ -73,3 +78,27 @@ func (c *Client) CredentialProof() goa.Endpoint {
return decodeResponse(resp) return decodeResponse(resp)
} }
} }
// PresentationProof returns an endpoint that makes HTTP requests to the signer
// service PresentationProof server.
func (c *Client) PresentationProof() goa.Endpoint {
var (
encodeRequest = EncodePresentationProofRequest(c.encoder)
decodeResponse = DecodePresentationProofResponse(c.decoder, c.RestoreResponseBody)
)
return func(ctx context.Context, v interface{}) (interface{}, error) {
req, err := c.BuildPresentationProofRequest(ctx, v)
if err != nil {
return nil, err
}
err = encodeRequest(req, v)
if err != nil {
return nil, err
}
resp, err := c.PresentationProofDoer.Do(req)
if err != nil {
return nil, goahttp.ErrRequestError("signer", "PresentationProof", err)
}
return decodeResponse(resp)
}
}
...@@ -88,3 +88,74 @@ func DecodeCredentialProofResponse(decoder func(*http.Response) goahttp.Decoder, ...@@ -88,3 +88,74 @@ func DecodeCredentialProofResponse(decoder func(*http.Response) goahttp.Decoder,
} }
} }
} }
// BuildPresentationProofRequest instantiates a HTTP request object with method
// and path set to call the "signer" service "PresentationProof" endpoint
func (c *Client) BuildPresentationProofRequest(ctx context.Context, v interface{}) (*http.Request, error) {
u := &url.URL{Scheme: c.scheme, Host: c.host, Path: PresentationProofSignerPath()}
req, err := http.NewRequest("POST", u.String(), nil)
if err != nil {
return nil, goahttp.ErrInvalidURL("signer", "PresentationProof", u.String(), err)
}
if ctx != nil {
req = req.WithContext(ctx)
}
return req, nil
}
// EncodePresentationProofRequest returns an encoder for requests sent to the
// signer PresentationProof server.
func EncodePresentationProofRequest(encoder func(*http.Request) goahttp.Encoder) func(*http.Request, interface{}) error {
return func(req *http.Request, v interface{}) error {
p, ok := v.(*signer.PresentationProofRequest)
if !ok {
return goahttp.ErrInvalidType("signer", "PresentationProof", "*signer.PresentationProofRequest", v)
}
values := req.URL.Query()
if p.Key != nil {
values.Add("key", *p.Key)
}
req.URL.RawQuery = values.Encode()
body := p.Presentation
if err := encoder(req).Encode(&body); err != nil {
return goahttp.ErrEncodingError("signer", "PresentationProof", err)
}
return nil
}
}
// DecodePresentationProofResponse returns a decoder for responses returned by
// the signer PresentationProof endpoint. restoreBody controls whether the
// response body should be restored after having been read.
func DecodePresentationProofResponse(decoder func(*http.Response) goahttp.Decoder, restoreBody bool) func(*http.Response) (interface{}, error) {
return func(resp *http.Response) (interface{}, error) {
if restoreBody {
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
resp.Body = ioutil.NopCloser(bytes.NewBuffer(b))
defer func() {
resp.Body = ioutil.NopCloser(bytes.NewBuffer(b))
}()
} else {
defer resp.Body.Close()
}
switch resp.StatusCode {
case http.StatusOK:
var (
body interface{}
err error
)
err = decoder(resp).Decode(&body)
if err != nil {
return nil, goahttp.ErrDecodingError("signer", "PresentationProof", err)
}
return body, nil
default:
body, _ := ioutil.ReadAll(resp.Body)
return nil, goahttp.ErrInvalidResponse("signer", "PresentationProof", resp.StatusCode, string(body))
}
}
}
...@@ -11,3 +11,8 @@ package client ...@@ -11,3 +11,8 @@ package client
func CredentialProofSignerPath() string { func CredentialProofSignerPath() string {
return "/v1/credential/proof" return "/v1/credential/proof"
} }
// PresentationProofSignerPath returns the URL path to the signer service PresentationProof HTTP endpoint.
func PresentationProofSignerPath() string {
return "/v1/presentation/proof"
}
...@@ -56,3 +56,44 @@ func DecodeCredentialProofRequest(mux goahttp.Muxer, decoder func(*http.Request) ...@@ -56,3 +56,44 @@ func DecodeCredentialProofRequest(mux goahttp.Muxer, decoder func(*http.Request)
return payload, nil return payload, nil
} }
} }
// EncodePresentationProofResponse returns an encoder for responses returned by
// the signer PresentationProof endpoint.
func EncodePresentationProofResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, interface{}) error {
return func(ctx context.Context, w http.ResponseWriter, v interface{}) error {
res, _ := v.(interface{})
enc := encoder(ctx, w)
body := res
w.WriteHeader(http.StatusOK)
return enc.Encode(body)
}
}
// DecodePresentationProofRequest returns a decoder for requests sent to the
// signer PresentationProof endpoint.
func DecodePresentationProofRequest(mux goahttp.Muxer, decoder func(*http.Request) goahttp.Decoder) func(*http.Request) (interface{}, error) {
return func(r *http.Request) (interface{}, error) {
var (
body []byte
err error
)
err = decoder(r).Decode(&body)
if err != nil {
if err == io.EOF {
return nil, goa.MissingPayloadError()
}
return nil, goa.DecodePayloadError(err.Error())
}
var (
key *string
)
keyRaw := r.URL.Query().Get("key")
if keyRaw != "" {
key = &keyRaw
}
payload := NewPresentationProofRequest(body, key)
return payload, nil
}
}
...@@ -11,3 +11,8 @@ package server ...@@ -11,3 +11,8 @@ package server
func CredentialProofSignerPath() string { func CredentialProofSignerPath() string {
return "/v1/credential/proof" return "/v1/credential/proof"
} }
// PresentationProofSignerPath returns the URL path to the signer service PresentationProof HTTP endpoint.
func PresentationProofSignerPath() string {
return "/v1/presentation/proof"
}
...@@ -18,8 +18,9 @@ import ( ...@@ -18,8 +18,9 @@ import (
// Server lists the signer service endpoint HTTP handlers. // Server lists the signer service endpoint HTTP handlers.
type Server struct { type Server struct {
Mounts []*MountPoint Mounts []*MountPoint
CredentialProof http.Handler CredentialProof http.Handler
PresentationProof http.Handler
} }
// ErrorNamer is an interface implemented by generated error structs that // ErrorNamer is an interface implemented by generated error structs that
...@@ -56,8 +57,10 @@ func New( ...@@ -56,8 +57,10 @@ func New(
return &Server{ return &Server{
Mounts: []*MountPoint{ Mounts: []*MountPoint{
{"CredentialProof", "POST", "/v1/credential/proof"}, {"CredentialProof", "POST", "/v1/credential/proof"},
{"PresentationProof", "POST", "/v1/presentation/proof"},
}, },
CredentialProof: NewCredentialProofHandler(e.CredentialProof, mux, decoder, encoder, errhandler, formatter), CredentialProof: NewCredentialProofHandler(e.CredentialProof, mux, decoder, encoder, errhandler, formatter),
PresentationProof: NewPresentationProofHandler(e.PresentationProof, mux, decoder, encoder, errhandler, formatter),
} }
} }
...@@ -67,11 +70,13 @@ func (s *Server) Service() string { return "signer" } ...@@ -67,11 +70,13 @@ func (s *Server) Service() string { return "signer" }
// Use wraps the server handlers with the given middleware. // Use wraps the server handlers with the given middleware.
func (s *Server) Use(m func(http.Handler) http.Handler) { func (s *Server) Use(m func(http.Handler) http.Handler) {
s.CredentialProof = m(s.CredentialProof) s.CredentialProof = m(s.CredentialProof)
s.PresentationProof = m(s.PresentationProof)
} }
// Mount configures the mux to serve the signer endpoints. // Mount configures the mux to serve the signer endpoints.
func Mount(mux goahttp.Muxer, h *Server) { func Mount(mux goahttp.Muxer, h *Server) {
MountCredentialProofHandler(mux, h.CredentialProof) MountCredentialProofHandler(mux, h.CredentialProof)
MountPresentationProofHandler(mux, h.PresentationProof)
} }
// Mount configures the mux to serve the signer endpoints. // Mount configures the mux to serve the signer endpoints.
...@@ -129,3 +134,54 @@ func NewCredentialProofHandler( ...@@ -129,3 +134,54 @@ func NewCredentialProofHandler(
} }
}) })
} }
// MountPresentationProofHandler configures the mux to serve the "signer"
// service "PresentationProof" endpoint.
func MountPresentationProofHandler(mux goahttp.Muxer, h http.Handler) {
f, ok := h.(http.HandlerFunc)
if !ok {
f = func(w http.ResponseWriter, r *http.Request) {
h.ServeHTTP(w, r)
}
}
mux.Handle("POST", "/v1/presentation/proof", f)
}
// NewPresentationProofHandler creates a HTTP handler which loads the HTTP
// request and calls the "signer" service "PresentationProof" endpoint.
func NewPresentationProofHandler(
endpoint goa.Endpoint,
mux goahttp.Muxer,
decoder func(*http.Request) goahttp.Decoder,
encoder func(context.Context, http.ResponseWriter) goahttp.Encoder,
errhandler func(context.Context, http.ResponseWriter, error),
formatter func(err error) goahttp.Statuser,
) http.Handler {
var (
decodeRequest = DecodePresentationProofRequest(mux, decoder)
encodeResponse = EncodePresentationProofResponse(encoder)
encodeError = goahttp.ErrorEncoder(encoder, formatter)
)
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := context.WithValue(r.Context(), goahttp.AcceptTypeKey, r.Header.Get("Accept"))
ctx = context.WithValue(ctx, goa.MethodKey, "PresentationProof")
ctx = context.WithValue(ctx, goa.ServiceKey, "signer")
payload, err := decodeRequest(r)
if err != nil {
if err := encodeError(ctx, w, err); err != nil {
errhandler(ctx, w, err)
}
return
}
res, err := endpoint(ctx, payload)
if err != nil {
if err := encodeError(ctx, w, err); err != nil {
errhandler(ctx, w, err)
}
return
}
if err := encodeResponse(ctx, w, res); err != nil {
errhandler(ctx, w, err)
}
})
}
...@@ -22,3 +22,15 @@ func NewCredentialProofRequest(body []byte, key *string) *signer.CredentialProof ...@@ -22,3 +22,15 @@ func NewCredentialProofRequest(body []byte, key *string) *signer.CredentialProof
return res return res
} }
// NewPresentationProofRequest builds a signer service PresentationProof
// endpoint payload.
func NewPresentationProofRequest(body []byte, key *string) *signer.PresentationProofRequest {
v := body
res := &signer.PresentationProofRequest{
Presentation: v,
}
res.Key = key
return res
}
...@@ -15,13 +15,15 @@ import ( ...@@ -15,13 +15,15 @@ import (
// Client is the "signer" service client. // Client is the "signer" service client.
type Client struct { type Client struct {
CredentialProofEndpoint goa.Endpoint CredentialProofEndpoint goa.Endpoint
PresentationProofEndpoint goa.Endpoint
} }
// NewClient initializes a "signer" service client given the endpoints. // NewClient initializes a "signer" service client given the endpoints.
func NewClient(credentialProof goa.Endpoint) *Client { func NewClient(credentialProof, presentationProof goa.Endpoint) *Client {
return &Client{ return &Client{
CredentialProofEndpoint: credentialProof, CredentialProofEndpoint: credentialProof,
PresentationProofEndpoint: presentationProof,
} }
} }
...@@ -34,3 +36,14 @@ func (c *Client) CredentialProof(ctx context.Context, p *CredentialProofRequest) ...@@ -34,3 +36,14 @@ func (c *Client) CredentialProof(ctx context.Context, p *CredentialProofRequest)
} }
return ires.(interface{}), nil return ires.(interface{}), nil
} }
// PresentationProof calls the "PresentationProof" endpoint of the "signer"
// service.
func (c *Client) PresentationProof(ctx context.Context, p *PresentationProofRequest) (res interface{}, err error) {
var ires interface{}
ires, err = c.PresentationProofEndpoint(ctx, p)
if err != nil {
return
}
return ires.(interface{}), nil
}
...@@ -15,19 +15,22 @@ import ( ...@@ -15,19 +15,22 @@ import (
// Endpoints wraps the "signer" service endpoints. // Endpoints wraps the "signer" service endpoints.
type Endpoints struct { type Endpoints struct {
CredentialProof goa.Endpoint CredentialProof goa.Endpoint
PresentationProof goa.Endpoint
} }
// NewEndpoints wraps the methods of the "signer" service with endpoints. // NewEndpoints wraps the methods of the "signer" service with endpoints.
func NewEndpoints(s Service) *Endpoints { func NewEndpoints(s Service) *Endpoints {
return &Endpoints{ return &Endpoints{
CredentialProof: NewCredentialProofEndpoint(s), CredentialProof: NewCredentialProofEndpoint(s),
PresentationProof: NewPresentationProofEndpoint(s),
} }
} }
// Use applies the given middleware to all the "signer" service endpoints. // Use applies the given middleware to all the "signer" service endpoints.
func (e *Endpoints) Use(m func(goa.Endpoint) goa.Endpoint) { func (e *Endpoints) Use(m func(goa.Endpoint) goa.Endpoint) {
e.CredentialProof = m(e.CredentialProof) e.CredentialProof = m(e.CredentialProof)
e.PresentationProof = m(e.PresentationProof)
} }
// NewCredentialProofEndpoint returns an endpoint function that calls the // NewCredentialProofEndpoint returns an endpoint function that calls the
...@@ -38,3 +41,12 @@ func NewCredentialProofEndpoint(s Service) goa.Endpoint { ...@@ -38,3 +41,12 @@ func NewCredentialProofEndpoint(s Service) goa.Endpoint {
return s.CredentialProof(ctx, p) return s.CredentialProof(ctx, p)
} }
} }
// NewPresentationProofEndpoint returns an endpoint function that calls the
// method "PresentationProof" of service "signer".
func NewPresentationProofEndpoint(s Service) goa.Endpoint {
return func(ctx context.Context, req interface{}) (interface{}, error) {
p := req.(*PresentationProofRequest)
return s.PresentationProof(ctx, p)
}
}
...@@ -16,6 +16,8 @@ import ( ...@@ -16,6 +16,8 @@ import (
type Service interface { type Service interface {
// CredentialProof adds a proof to a given Verifiable Credential. // CredentialProof adds a proof to a given Verifiable Credential.
CredentialProof(context.Context, *CredentialProofRequest) (res interface{}, err error) CredentialProof(context.Context, *CredentialProofRequest) (res interface{}, err error)
// PresentationProof adds a proof to a given Verifiable Presentation.
PresentationProof(context.Context, *PresentationProofRequest) (res interface{}, err error)
} }
// ServiceName is the name of the service as defined in the design. This is the // ServiceName is the name of the service as defined in the design. This is the
...@@ -26,7 +28,7 @@ const ServiceName = "signer" ...@@ -26,7 +28,7 @@ const ServiceName = "signer"
// MethodNames lists the service method names as defined in the design. These // MethodNames lists the service method names as defined in the design. These
// are the same values that are set in the endpoint request contexts under the // are the same values that are set in the endpoint request contexts under the
// MethodKey key. // MethodKey key.
var MethodNames = [1]string{"CredentialProof"} var MethodNames = [2]string{"CredentialProof", "PresentationProof"}
// CredentialProofRequest is the payload type of the signer service // CredentialProofRequest is the payload type of the signer service
// CredentialProof method. // CredentialProof method.
...@@ -36,3 +38,12 @@ type CredentialProofRequest struct { ...@@ -36,3 +38,12 @@ type CredentialProofRequest struct {
// Verifiable Credential in JSON format. // Verifiable Credential in JSON format.
Credential []byte Credential []byte
} }
// PresentationProofRequest is the payload type of the signer service
// PresentationProof method.
type PresentationProofRequest struct {
// Key to use for the proof signature (optional).
Key *string
// Verifiable Presentation in JSON format.
Presentation []byte
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment