Skip to content

Commit

Permalink
wip4
Browse files Browse the repository at this point in the history
  • Loading branch information
woutslakhorst committed Dec 12, 2023
1 parent d452ee8 commit 93ff9b8
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 2 deletions.
31 changes: 30 additions & 1 deletion auth/api/iam/openid4vp.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (
"github.com/nuts-foundation/nuts-node/storage"
"github.com/nuts-foundation/nuts-node/vcr/credential"
"github.com/nuts-foundation/nuts-node/vcr/holder"
"github.com/nuts-foundation/nuts-node/vcr/pe"
"github.com/nuts-foundation/nuts-node/vdr/didweb"
"net/http"
"net/url"
Expand Down Expand Up @@ -266,8 +267,36 @@ func (r Wrapper) handleAuthorizeRequestFromVerifier(ctx context.Context, walletD
}, nil
}

// sendAndHandleDirectPost sends OpenID4VP direct_post to the verifier. The verifier responds with a redirect to the client (including error fields if needed).
// If the direct post fails, the user-agent will be redirected back to the client with an error. (Original redirect_uri).
// If no redirect_uri is present, the user-agent will be redirected to the error page.
func (r Wrapper) sendAndHandleDirectPost(ctx context.Context, vp vc.VerifiablePresentation, presentationSubmission pe.PresentationSubmission, verifierResponseURI string, clientRedirectURI string) (HandleAuthorizeRequestResponseObject, error) {
redirectURI, err := r.auth.Holder().PostAuthorizationResponse(ctx, vp, presentationSubmission, verifierResponseURI)
if err == nil {
return HandleAuthorizeRequest302Response{
HandleAuthorizeRequest302ResponseHeaders{
Location: redirectURI,
},
}, nil
}

msg := fmt.Sprintf("failed to post authorization response to verifier @ %s", verifierResponseURI)
log.Logger().WithError(err).Error(msg)

// clientRedirectURI has been checked earlier in te process.
redirectURI, _ = url.Parse(clientRedirectURI)

Check failure on line 287 in auth/api/iam/openid4vp.go

View workflow job for this annotation

GitHub Actions / Run govulncheck

cannot use url.Parse(clientRedirectURI) (value of type *url.URL) as string value in assignment
clientRedirectURL := httpNuts.AddQueryParams(*redirectURI, map[string]string{

Check failure on line 288 in auth/api/iam/openid4vp.go

View workflow job for this annotation

GitHub Actions / Run govulncheck

invalid operation: cannot indirect redirectURI (variable of type string)
oauth.ErrorParam: string(oauth.ServerError),
oauth.ErrorDescriptionParam: msg,
})
return HandleAuthorizeRequest302Response{
HandleAuthorizeRequest302ResponseHeaders{
Location: clientRedirectURL.String(),
},
}, nil
}

// sendAndHandleDirectPostError sends errors from handleAuthorizeRequestFromVerifier as direct_post to the verifier. The verifier responds with a redirect to the client (including error fields).
// This methods can never return an error, if an error occurs it will be logged and the request will be redirected to the client with an error.
// If the direct post fails, the user-agent will be redirected back to the client with an error. (Original redirect_uri).
// If no redirect_uri is present, the user-agent will be redirected to the error page.
func (r Wrapper) sendAndHandleDirectPostError(ctx context.Context, auth2Error oauth.OAuth2Error, verifierResponseURI string) (HandleAuthorizeRequestResponseObject, error) {
Expand Down
30 changes: 30 additions & 0 deletions auth/client/iam/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,3 +250,33 @@ func (hb HTTPClient) PostError(ctx context.Context, auth2Error oauth.OAuth2Error
}
return redirect.RedirectURI, nil
}

func (hb HTTPClient) PostAuthorizationResponse(ctx context.Context, vp vc.VerifiablePresentation, presentationSubmission pe.PresentationSubmission, verifierResponseURI string) (string, error) {
// initiate http client, create a POST request with x-www-form-urlencoded body and send it to the redirect URL
data := url.Values{}
data.Set(oauth.VpTokenParam, vp.Raw())
data.Set(oauth.PresentationSubmissionParam, string(presentationSubmission))

Check failure on line 258 in auth/client/iam/client.go

View workflow job for this annotation

GitHub Actions / Run govulncheck

cannot convert presentationSubmission (variable of type pe.PresentationSubmission) to type string
request, err := http.NewRequestWithContext(ctx, http.MethodPost, verifierResponseURI, strings.NewReader(data.Encode()))
request.Header.Add("Accept", "application/json")
request.Header.Add("Content-Type", "application/x-www-form-urlencoded")
if err != nil {
return "", err
}
response, err := hb.httpClient.Do(request.WithContext(ctx))
if err != nil {
return "", err
}
if err = core.TestResponseCode(http.StatusOK, response); err != nil {
return "", err
}
// take the redirectURL from the response body and return it
var responseData []byte
if responseData, err = io.ReadAll(response.Body); err != nil {
return "", fmt.Errorf("unable to read response: %w", err)
}
var redirect oauth.Redirect
if err = json.Unmarshal(responseData, &redirect); err != nil {
return "", fmt.Errorf("unable to unmarshal response: %w, %s", err, string(responseData))
}
return redirect.RedirectURI, nil
}
2 changes: 2 additions & 0 deletions auth/oauth/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ const (
ScopeParam = "scope"
// PresentationSubmissionParam is the parameter name for the presentation_submission parameter
PresentationSubmissionParam = "presentation_submission"
// VpTokenParam is the parameter name for the vp_token parameter
VpTokenParam = "vp_token"
// VpTokenGrantType is the grant_type for the vp_token-bearer grant type
VpTokenGrantType = "vp_token-bearer"
)
Expand Down
13 changes: 12 additions & 1 deletion auth/services/oauth/holder.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,5 +109,16 @@ func (v *HolderService) PostError(ctx context.Context, auth2Error oauth.OAuth2Er
return redirectURL, nil
}

return "", fmt.Errorf("failed to post error to verifier: %s", err.Error())
return "", fmt.Errorf("failed to post error to verifier: %w", err)
}

func (v *HolderService) PostAuthorizationResponse(ctx context.Context, vp vc.VerifiablePresentation, presentationSubmission pe.PresentationSubmission, verifierResponseURI string) (string, error) {
iamClient := iam.NewHTTPClient(v.strictMode, v.httpClientTimeout, v.httpClientTLS)

redirectURL, err := iamClient.PostAuthorizationResponse(ctx, vp, presentationSubmission, verifierResponseURI)
if err == nil {
return redirectURL, nil
}

return "", fmt.Errorf("failed to post authorization response to verifier: %w", err)
}
2 changes: 2 additions & 0 deletions auth/services/oauth/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,6 @@ type Holder interface {
ClientMetadata(ctx context.Context, endpoint string) (*oauth.AuthorizationServerMetadata, error)
// PostError posts an error to the verifier. If it fails, an error is returned.
PostError(ctx context.Context, auth2Error oauth.OAuth2Error, verifierResponseURI string) (string, error)
// PostAuthorizationResponse posts the authorization response to the verifier. If it fails, an error is returned.
PostAuthorizationResponse(ctx context.Context, vp vc.VerifiablePresentation, presentationSubmission pe.PresentationSubmission, verifierResponseURI string) (string, error)
}

0 comments on commit 93ff9b8

Please sign in to comment.