Skip to content

Commit

Permalink
cleanup oauth constants
Browse files Browse the repository at this point in the history
  • Loading branch information
gerardsn committed May 15, 2024
1 parent 4c5afc8 commit 159bcc0
Show file tree
Hide file tree
Showing 12 changed files with 140 additions and 173 deletions.
18 changes: 9 additions & 9 deletions auth/api/iam/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ func (r Wrapper) handleAuthorizeRequest(ctx context.Context, ownDID did.DID, req
}

switch requestObject.get(oauth.ResponseTypeParam) {
case responseTypeCode:
case oauth.CodeResponseType:
// Options:
// - Regular authorization code flow for EHR data access through access token, authentication of end-user using OpenID4VP.
// - OpenID4VCI; authorization code flow for credential issuance to (end-user) wallet
Expand All @@ -359,7 +359,7 @@ func (r Wrapper) handleAuthorizeRequest(ctx context.Context, ownDID did.DID, req
Description: "client_id must be a did:web",
}
}
case responseTypeVPToken:
case oauth.VPTokenResponseType:
// Options:
// - OpenID4VP flow, vp_token is sent in Authorization Response
// non-spec: if the scheme is openid4vp (URL starts with openid4vp:), the OpenID4VP request should be handled by a user wallet, rather than an organization wallet.
Expand Down Expand Up @@ -773,13 +773,13 @@ func (r Wrapper) RequestOid4vciCredentialIssuance(ctx context.Context, request R
}
// Build the redirect URL, the client browser should be redirected to.
redirectUrl := nutsHttp.AddQueryParams(*endpoint, map[string]string{
"response_type": "code",
"state": state,
"client_id": requestHolder.String(),
"authorization_details": string(authorizationDetails),
"redirect_uri": redirectUri.String(),
"code_challenge": pkceParams.Challenge,
"code_challenge_method": pkceParams.ChallengeMethod,
oauth.ResponseTypeParam: oauth.CodeResponseType,
oauth.StateParam: state,
oauth.ClientIDParam: requestHolder.String(),
oauth.AuthorizationDetailsParam: string(authorizationDetails),
oauth.RedirectURIParam: redirectUri.String(),
oauth.CodeChallengeParam: pkceParams.Challenge,
oauth.CodeChallengeMethodParam: pkceParams.ChallengeMethod,
})

log.Logger().Debugf("generated the following redirect_uri for did %s, to issuer %s: %s", requestHolder.String(), issuerDid.String(), redirectUri.String())
Expand Down
34 changes: 17 additions & 17 deletions auth/api/iam/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ func TestWrapper_HandleAuthorizeRequest(t *testing.T) {
oauth.ClientIDParam: holderDID.String(),
oauth.NonceParam: "nonce",
oauth.RedirectURIParam: "https://example.com",
oauth.ResponseTypeParam: responseTypeCode,
oauth.ResponseTypeParam: oauth.CodeResponseType,
oauth.ScopeParam: "test",
oauth.StateParam: "state",
oauth.CodeChallengeParam: "code_challenge",
Expand All @@ -328,7 +328,7 @@ func TestWrapper_HandleAuthorizeRequest(t *testing.T) {
expectedURL := "https://example.com/authorize?client_id=did%3Aweb%3Aexample.com%3Aiam%3Averifier&request_uri=https://example.com/oauth2/" + verifierDID.String() + "/request.jwt/&request_uri_method=get"
serverMetadata := oauth.AuthorizationServerMetadata{
AuthorizationEndpoint: "https://example.com/authorize",
ClientIdSchemesSupported: []string{didScheme},
ClientIdSchemesSupported: []string{didClientIDScheme},
VPFormats: oauth.DefaultOpenIDSupportedFormats(),
RequireSignedRequestObject: true,
}
Expand All @@ -339,11 +339,11 @@ func TestWrapper_HandleAuthorizeRequest(t *testing.T) {
params := req.Claims
// check the parameters
assert.NotEmpty(t, params[oauth.NonceParam])
assert.Equal(t, didScheme, params[clientIDSchemeParam])
assert.Equal(t, responseTypeVPToken, params[oauth.ResponseTypeParam])
assert.Equal(t, "https://example.com/oauth2/did:web:example.com:iam:verifier/response", params[responseURIParam])
assert.Equal(t, "https://example.com/oauth2/did:web:example.com:iam:verifier/oauth-client", params[clientMetadataURIParam])
assert.Equal(t, responseModeDirectPost, params[responseModeParam])
assert.Equal(t, didClientIDScheme, params[oauth.ClientIDSchemeParam])
assert.Equal(t, oauth.VPTokenResponseType, params[oauth.ResponseTypeParam])
assert.Equal(t, "https://example.com/oauth2/did:web:example.com:iam:verifier/response", params[oauth.ResponseURIParam])
assert.Equal(t, "https://example.com/oauth2/did:web:example.com:iam:verifier/oauth-client", params[oauth.ClientMetadataURIParam])
assert.Equal(t, responseModeDirectPost, params[oauth.ResponseModeParam])
assert.NotEmpty(t, params[oauth.StateParam])
return req
})
Expand All @@ -370,16 +370,16 @@ func TestWrapper_HandleAuthorizeRequest(t *testing.T) {

// HandleAuthorizeRequest
requestParams := oauthParameters{
oauth.ClientIDParam: verifierDID.String(),
clientIDSchemeParam: didScheme,
clientMetadataURIParam: "https://example.com/.well-known/authorization-server/iam/verifier",
oauth.NonceParam: "nonce",
presentationDefUriParam: "https://example.com/oauth2/did:web:example.com:iam:verifier/presentation_definition?scope=test",
responseURIParam: "https://example.com/oauth2/did:web:example.com:iam:verifier/response",
responseModeParam: responseModeDirectPost,
oauth.ResponseTypeParam: responseTypeVPToken,
oauth.ScopeParam: "test",
oauth.StateParam: "state",
oauth.ClientIDParam: verifierDID.String(),
oauth.ClientIDSchemeParam: didClientIDScheme,
oauth.ClientMetadataURIParam: "https://example.com/.well-known/authorization-server/iam/verifier",
oauth.NonceParam: "nonce",
oauth.PresentationDefUriParam: "https://example.com/oauth2/did:web:example.com:iam:verifier/presentation_definition?scope=test",
oauth.ResponseURIParam: "https://example.com/oauth2/did:web:example.com:iam:verifier/response",
oauth.ResponseModeParam: responseModeDirectPost,
oauth.ResponseTypeParam: oauth.VPTokenResponseType,
oauth.ScopeParam: "test",
oauth.StateParam: "state",
}
ctx.vdr.EXPECT().IsOwner(gomock.Any(), holderDID).Return(true, nil)
ctx.jar.EXPECT().Parse(gomock.Any(), holderDID, gomock.Any()).Return(requestParams, nil)
Expand Down
4 changes: 2 additions & 2 deletions auth/api/iam/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func staticAuthorizationServerMetadata() oauth.AuthorizationServerMetadata {
return oauth.AuthorizationServerMetadata{
Issuer: "https://self-issued.me/v2",
AuthorizationEndpoint: "openid4vp:",
ResponseTypesSupported: []string{responseTypeVPToken},
ResponseTypesSupported: []string{oauth.VPTokenResponseType},
VPFormatsSupported: map[string]map[string][]string{
"jwt_vp_json": {"alg_values_supported": []string{string(jwa.ES256)}},
"jwt_vc_json": {"alg_values_supported": []string{string(jwa.ES256)}},
Expand All @@ -91,6 +91,6 @@ func clientMetadata(identity url.URL) oauth.OAuthClientMetadata {
SoftwareID: softwareID, // nuts-node-refimpl
SoftwareVersion: softwareVersion, // version tag or "unknown"
VPFormats: oauth.DefaultOpenIDSupportedFormats(),
ClientIdScheme: didScheme,
ClientIdScheme: didClientIDScheme,
}
}
4 changes: 2 additions & 2 deletions auth/api/iam/metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func Test_authorizationServerMetadata(t *testing.T) {
AuthorizationEndpoint: "openid4vp:",
ClientIdSchemesSupported: []string{"did"},
DPoPSigningAlgValuesSupported: jwx.SupportedAlgorithmsAsStrings(),
GrantTypesSupported: []string{"authorization_code", "vp_token", "urn:ietf:params:oauth:grant-type:pre-authorized_code"},
GrantTypesSupported: []string{"authorization_code", "vp_token-bearer"},
Issuer: didExample.String(),
PreAuthorizedGrantAnonymousAccessSupported: true,
PresentationDefinitionUriSupported: &presentationDefinitionURISupported,
Expand Down Expand Up @@ -75,7 +75,7 @@ func Test_clientMetadata(t *testing.T) {
expected := OAuthClientMetadata{
RedirectURIs: nil,
TokenEndpointAuthMethod: "none",
GrantTypes: []string{"authorization_code", "vp_token", "urn:ietf:params:oauth:grant-type:pre-authorized_code"},
GrantTypes: []string{"authorization_code", "vp_token-bearer"},
ResponseTypes: []string{"code", "vp_token"},
Scope: "",
Contacts: nil,
Expand Down
38 changes: 19 additions & 19 deletions auth/api/iam/openid4vp.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ func (r Wrapper) handleAuthorizeRequestFromHolder(ctx context.Context, verifier
return nil, withCallbackURI(oauthError(oauth.ServerError, "failed to get metadata from wallet", err), redirectURL)
}
// check metadata for supported client_id_schemes
if !slices.Contains(metadata.ClientIdSchemesSupported, didScheme) {
if !slices.Contains(metadata.ClientIdSchemesSupported, didClientIDScheme) {
return nil, withCallbackURI(oauthError(oauth.InvalidRequest, "wallet metadata does not contain did in client_id_schemes_supported"), redirectURL)
}

Expand Down Expand Up @@ -200,12 +200,12 @@ func (r Wrapper) nextOpenID4VPFlow(ctx context.Context, state string, session OA
metadataURL := ownURL.JoinPath(oauth.ClientMetadataPath)

modifier := func(values map[string]string) {
values[oauth.ResponseTypeParam] = responseTypeVPToken
values[clientIDSchemeParam] = didScheme
values[responseURIParam] = callbackURL.String()
values[presentationDefUriParam] = presentationDefinitionURI.String()
values[clientMetadataURIParam] = metadataURL.String()
values[responseModeParam] = responseModeDirectPost
values[oauth.ResponseTypeParam] = oauth.VPTokenResponseType
values[oauth.ClientIDSchemeParam] = didClientIDScheme
values[oauth.ResponseURIParam] = callbackURL.String()
values[oauth.PresentationDefUriParam] = presentationDefinitionURI.String()
values[oauth.ClientMetadataURIParam] = metadataURL.String()
values[oauth.ResponseModeParam] = responseModeDirectPost
values[oauth.NonceParam] = nonce
values[oauth.StateParam] = state
}
Expand Down Expand Up @@ -243,7 +243,7 @@ func (r Wrapper) nextOpenID4VPFlow(ctx context.Context, state string, session OA
// response_type, REQUIRED. Value MUST be set to "vp_token".
// client_id, REQUIRED. This must be a did:web
// client_id_scheme, REQUIRED. This must be did
// clientMetadataURIParam, REQUIRED. This must be the verifier metadata endpoint
// client_metadata_uri, REQUIRED. This must be the verifier metadata endpoint
// nonce, REQUIRED.
// response_uri, REQUIRED. This must be the verifier node url
// response_mode, REQUIRED. Value MUST be "direct_post"
Expand All @@ -253,13 +253,13 @@ func (r Wrapper) nextOpenID4VPFlow(ctx context.Context, state string, session OA
// missing or invalid parameters are all mapped to invalid_request
// any operation that fails is mapped to server_error, this includes unreachable or broken backends.
func (r Wrapper) handleAuthorizeRequestFromVerifier(ctx context.Context, tenantDID did.DID, params oauthParameters, walletOwnerType WalletOwnerType) (HandleAuthorizeRequestResponseObject, error) {
responseMode := params.get(responseModeParam)
responseMode := params.get(oauth.ResponseModeParam)
if responseMode != responseModeDirectPost {
return nil, oauth.OAuth2Error{Code: oauth.InvalidRequest, Description: "invalid response_mode parameter"}
}

// check the response URL because later errors will redirect to this URL
responseURI := params.get(responseURIParam)
responseURI := params.get(oauth.ResponseURIParam)
if responseURI == "" {
return nil, oauth.OAuth2Error{Code: oauth.InvalidRequest, Description: "missing response_uri parameter"}
}
Expand All @@ -269,7 +269,7 @@ func (r Wrapper) handleAuthorizeRequestFromVerifier(ctx context.Context, tenantD
return nil, oauth.OAuth2Error{Code: oauth.InvalidRequest, Description: "missing state parameter"}
}

if params.get(clientIDSchemeParam) != didScheme {
if params.get(oauth.ClientIDSchemeParam) != didClientIDScheme {
return r.sendAndHandleDirectPostError(ctx, oauth.OAuth2Error{Code: oauth.InvalidRequest, Description: "invalid client_id_scheme parameter"}, responseURI, state)
}

Expand Down Expand Up @@ -343,16 +343,16 @@ func (r Wrapper) handleAuthorizeRequestFromVerifier(ctx context.Context, tenantD
func (r Wrapper) getClientMetadataFromRequest(ctx context.Context, params oauthParameters) (*oauth.OAuthClientMetadata, *oauth.OAuth2Error) {
var metadata *oauth.OAuthClientMetadata
var err error
if metadataString := params.get(clientMetadataParam); metadataString != "" {
if params.get(clientMetadataURIParam) != "" {
if metadataString := params.get(oauth.ClientMetadataParam); metadataString != "" {
if params.get(oauth.ClientMetadataURIParam) != "" {
return nil, &oauth.OAuth2Error{Code: oauth.InvalidRequest, Description: "client_metadata and client_metadata_uri are mutually exclusive", InternalError: err}
}
err = json.Unmarshal([]byte(metadataString), &metadata)
if err != nil {
return nil, &oauth.OAuth2Error{Code: oauth.InvalidRequest, Description: "invalid client_metadata", InternalError: err}
}
} else {
metadata, err = r.auth.IAMClient().ClientMetadata(ctx, params.get(clientMetadataURIParam))
metadata, err = r.auth.IAMClient().ClientMetadata(ctx, params.get(oauth.ClientMetadataURIParam))
if err != nil {
return nil, &oauth.OAuth2Error{Code: oauth.ServerError, Description: "failed to get client metadata (verifier)", InternalError: err}
}
Expand All @@ -363,16 +363,16 @@ func (r Wrapper) getClientMetadataFromRequest(ctx context.Context, params oauthP
func (r Wrapper) getPresentationDefinitionFromRequest(ctx context.Context, params oauthParameters) (*pe.PresentationDefinition, *oauth.OAuth2Error) {
var presentationDefinition *pe.PresentationDefinition
var err error
if pdString := params.get(presentationDefParam); pdString != "" {
if params.get(presentationDefUriParam) != "" {
if pdString := params.get(oauth.PresentationDefParam); pdString != "" {
if params.get(oauth.PresentationDefUriParam) != "" {
return nil, &oauth.OAuth2Error{Code: oauth.InvalidRequest, Description: "presentation_definition and presentation_definition_uri are mutually exclusive"}
}
err = json.Unmarshal([]byte(pdString), &presentationDefinition)
if err != nil {
return nil, &oauth.OAuth2Error{Code: oauth.InvalidRequest, Description: "invalid presentation_definition", InternalError: err}
}
} else {
presentationDefinitionURI := params.get(presentationDefUriParam)
presentationDefinitionURI := params.get(oauth.PresentationDefUriParam)
presentationDefinition, err = r.auth.IAMClient().PresentationDefinition(ctx, presentationDefinitionURI)
if err != nil {
return nil, &oauth.OAuth2Error{Code: oauth.InvalidPresentationDefinitionURI, Description: fmt.Sprintf("failed to retrieve presentation definition on %s", presentationDefinitionURI), InternalError: err}
Expand Down Expand Up @@ -605,8 +605,8 @@ func (r Wrapper) handleAuthorizeResponseSubmission(ctx context.Context, request

// construct redirect URI according to RFC6749
redirectURI := httpNuts.AddQueryParams(*callbackURI, map[string]string{
oauth.CodeParam: authorizationCode,
oauth.StateParam: session.ClientState,
oauth.CodeResponseType: authorizationCode,
oauth.StateParam: session.ClientState,
})
return HandleAuthorizeResponse200JSONResponse{RedirectURI: redirectURI.String()}, nil
}
Expand Down
Loading

0 comments on commit 159bcc0

Please sign in to comment.