Skip to content

Commit

Permalink
feat: change well-known url path for signed cred issuer config (trust…
Browse files Browse the repository at this point in the history
…bloc#1432)

Signed-off-by: Mykhailo Sizov <[email protected]>
  • Loading branch information
mishasizov-SK authored Sep 21, 2023
1 parent 7e624a4 commit 232ab83
Show file tree
Hide file tree
Showing 10 changed files with 439 additions and 223 deletions.
56 changes: 56 additions & 0 deletions docs/v1/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,34 @@ paths:
$ref: '#/components/schemas/WellKnownOpenIDIssuerConfiguration'
operationId: openid-credential-issuer-config
description: Returns openid-config.
deprecated: true
tags:
- issuer
'/oidc/idp/{profileID}/{profileVersion}/.well-known/openid-credential-issuer':
parameters:
- schema:
type: string
name: profileID
in: path
required: true
description: Profile ID
- schema:
type: string
name: profileVersion
in: path
required: true
description: Profile Version
get:
summary: Request openid-credential-issuer public endpoint.
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/WellKnownOpenIDIssuerConfiguration'
operationId: openid-credential-issuer-config-v2
description: Returns openid-config.
tags:
- issuer
'/issuer/{profileID}/{profileVersion}/.well-known/openid-configuration':
Expand Down Expand Up @@ -78,6 +106,34 @@ paths:
$ref: '#/components/schemas/WellKnownOpenIDConfiguration'
operationId: openid-config
description: Returns openid-config.
deprecated: true
tags:
- issuer
'/oidc/idp/{profileID}/{profileVersion}/.well-known/openid-configuration':
parameters:
- schema:
type: string
name: profileID
in: path
required: true
description: Profile Id
- schema:
type: string
name: profileVersion
in: path
required: true
description: Profile Version
get:
summary: Request openid-config public endpoint.
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/WellKnownOpenIDConfiguration'
operationId: openid-config-v2
description: Returns openid-config.
tags:
- issuer
'/issuer/profiles/{profileID}/{profileVersion}/credentials/issue':
Expand Down
12 changes: 12 additions & 0 deletions pkg/restapi/v1/issuer/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,12 @@ func (c *Controller) OpenidConfig(ctx echo.Context, profileID, profileVersion st
return util.WriteOutput(ctx)(c.getOpenIDConfig(profileID, profileVersion))
}

// OpenidConfigV2 request openid configuration for issuer.
// GET /oidc/idp/{profileID}/{profileVersion}/.well-known/openid-configuration.
func (c *Controller) OpenidConfigV2(ctx echo.Context, profileID, profileVersion string) error {
return c.OpenidConfig(ctx, profileID, profileVersion)
}

// OpenidCredentialIssuerConfig request openid credentials configuration for issuer.
// GET /issuer/{profileID}/{profileVersion}/.well-known/openid-credential-issuer.
func (c *Controller) OpenidCredentialIssuerConfig(ctx echo.Context, profileID, profileVersion string) error {
Expand All @@ -806,6 +812,12 @@ func (c *Controller) OpenidCredentialIssuerConfig(ctx echo.Context, profileID, p
return util.WriteOutput(ctx)(config, nil)
}

// OpenidCredentialIssuerConfigV2 request openid credentials configuration for issuer.
// GET /oidc/idp/{profileID}/{profileVersion}/.well-known/openid-credential-issuer.
func (c *Controller) OpenidCredentialIssuerConfigV2(ctx echo.Context, profileID, profileVersion string) error {
return c.OpenidCredentialIssuerConfig(ctx, profileID, profileVersion)
}

func (c *Controller) getOpenIDConfig(profileID, profileVersion string) (*WellKnownOpenIDConfiguration, error) {
host := c.externalHostURL
if !strings.HasSuffix(host, "/") {
Expand Down
83 changes: 56 additions & 27 deletions pkg/restapi/v1/issuer/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1500,17 +1500,24 @@ func TestOpenIDConfigurationController(t *testing.T) {
},
},
},
}, nil)
}, nil).Times(2)

c := &Controller{
externalHostURL: "https://localhost",
profileSvc: profileSvc,
}

assert.NoError(t, c.OpenidConfig(echoContext(), profileID, profileVersion))
for _, handlerMethod := range []func(ctx echo.Context, profileID, profileVersion string) error{
c.OpenidConfig,
c.OpenidConfigV2,
} {
assert.NoError(t, handlerMethod(echoContext(), profileID, profileVersion))
}
}

func TestOpenIdCredentialIssuerConfiguration(t *testing.T) {
type handler func(ctx echo.Context, profileID, profileVersion string) error

host := "https://localhost"

profile := &profileapi.Issuer{
Expand All @@ -1531,76 +1538,98 @@ func TestOpenIdCredentialIssuerConfiguration(t *testing.T) {

t.Run("Success JWT", func(t *testing.T) {
openidIssuerConfigProvider := NewMockOpenIDCredentialIssuerConfigProvider(gomock.NewController(t))
openidIssuerConfigProvider.EXPECT().GetOpenIDCredentialIssuerConfig(profile).Return(nil, "aa.bb.cc", nil).Times(1)
openidIssuerConfigProvider.EXPECT().GetOpenIDCredentialIssuerConfig(profile).Return(nil, "aa.bb.cc", nil).Times(2)

profileSvc := NewMockProfileService(gomock.NewController(t))
profileSvc.EXPECT().GetProfile(profileID, profileVersion).Return(profile, nil).Times(1)
profileSvc.EXPECT().GetProfile(profileID, profileVersion).Return(profile, nil).Times(2)

c := &Controller{
externalHostURL: host,
profileSvc: profileSvc,
openidIssuerConfigProvider: openidIssuerConfigProvider,
}

recorder := httptest.NewRecorder()
handlers := []handler{
c.OpenidCredentialIssuerConfig,
c.OpenidCredentialIssuerConfigV2,
}

echoCtx := echoContext(withRecorder(recorder))
for _, handlerMethod := range handlers {
recorder := httptest.NewRecorder()

err := c.OpenidCredentialIssuerConfig(echoCtx, profileID, profileVersion)
assert.NoError(t, err)
echoCtx := echoContext(withRecorder(recorder))

bodyBytes, err := io.ReadAll(recorder.Body)
assert.NoError(t, err)
err := handlerMethod(echoCtx, profileID, profileVersion)
assert.NoError(t, err)

bodyBytes, err := io.ReadAll(recorder.Body)
assert.NoError(t, err)

assert.Equal(t, "aa.bb.cc", string(bodyBytes))
assert.Equal(t, "application/jwt", recorder.Header().Get("Content-Type"))
assert.Equal(t, "aa.bb.cc", string(bodyBytes))
assert.Equal(t, "application/jwt", recorder.Header().Get("Content-Type"))
}
})

t.Run("Success JSON", func(t *testing.T) {
openidIssuerConfigProvider := NewMockOpenIDCredentialIssuerConfigProvider(gomock.NewController(t))
openidIssuerConfigProvider.EXPECT().GetOpenIDCredentialIssuerConfig(profile).Return(
&WellKnownOpenIDIssuerConfiguration{
CredentialIssuer: "https://example.com",
}, "", nil).Times(1)
}, "", nil).Times(2)

profileSvc := NewMockProfileService(gomock.NewController(t))
profileSvc.EXPECT().GetProfile(profileID, profileVersion).Return(profile, nil).Times(1)
profileSvc.EXPECT().GetProfile(profileID, profileVersion).Return(profile, nil).Times(2)

c := &Controller{
externalHostURL: host,
profileSvc: profileSvc,
openidIssuerConfigProvider: openidIssuerConfigProvider,
}

recorder := httptest.NewRecorder()
handlers := []handler{
c.OpenidCredentialIssuerConfig,
c.OpenidCredentialIssuerConfigV2,
}

for _, handlerMethod := range handlers {
recorder := httptest.NewRecorder()

echoCtx := echoContext(withRecorder(recorder))
echoCtx := echoContext(withRecorder(recorder))

err := c.OpenidCredentialIssuerConfig(echoCtx, profileID, profileVersion)
assert.NoError(t, err)
err := handlerMethod(echoCtx, profileID, profileVersion)
assert.NoError(t, err)

bodyBytes, err := io.ReadAll(recorder.Body)
assert.NoError(t, err)
bodyBytes, err := io.ReadAll(recorder.Body)
assert.NoError(t, err)

assert.Contains(t, string(bodyBytes), "\"credential_issuer\":\"https://example.com\"")
assert.Equal(t, "application/json; charset=UTF-8", recorder.Header().Get("Content-Type"))
assert.Contains(t, string(bodyBytes), "\"credential_issuer\":\"https://example.com\"")
assert.Equal(t, "application/json; charset=UTF-8", recorder.Header().Get("Content-Type"))
}
})

t.Run("profile error", func(t *testing.T) {
svc := NewMockProfileService(gomock.NewController(t))
svc.EXPECT().GetProfile(profileID, profileVersion).Return(nil, errors.New("unexpected error"))
svc.EXPECT().GetProfile(profileID, profileVersion).
Return(nil, errors.New("unexpected error")).Times(2)

c := &Controller{
externalHostURL: host + "/",
profileSvc: svc,
}

recorder := httptest.NewRecorder()
handlers := []handler{
c.OpenidCredentialIssuerConfig,
c.OpenidCredentialIssuerConfigV2,
}

for _, handlerMethod := range handlers {
recorder := httptest.NewRecorder()

echoCtx := echoContext(withRecorder(recorder))
echoCtx := echoContext(withRecorder(recorder))

err := c.OpenidCredentialIssuerConfig(echoCtx, profileID, profileVersion)
assert.Error(t, err)
err := handlerMethod(echoCtx, profileID, profileVersion)
assert.Error(t, err)
}
})
}

Expand Down
Loading

0 comments on commit 232ab83

Please sign in to comment.