From c865c910a6a04fc202c8eb8b6403544c44784d5f Mon Sep 17 00:00:00 2001 From: ychacon Date: Wed, 1 Mar 2023 19:00:59 +0100 Subject: [PATCH] Implementation for PUT trustedInvokers endpoint Issue-ID: NONRTRIC-848 Signed-off-by: ychacon Change-Id: Iba953bfb8aa11d77c8aeac906d640fb470769bbc --- capifcore/internal/publishserviceapi/typeaccess.go | 11 ++ capifcore/internal/securityapi/typeupdate.go | 84 +++++++++ capifcore/internal/securityapi/typeupdate_test.go | 106 +++++++++++ capifcore/internal/securityapi/typevalidation.go | 29 +++ .../internal/securityapi/typevalidation_test.go | 48 +++++ capifcore/internal/securityservice/security.go | 69 ++++++- .../internal/securityservice/security_test.go | 207 +++++++++++++++++++++ 7 files changed, 553 insertions(+), 1 deletion(-) create mode 100644 capifcore/internal/securityapi/typeupdate.go create mode 100644 capifcore/internal/securityapi/typeupdate_test.go diff --git a/capifcore/internal/publishserviceapi/typeaccess.go b/capifcore/internal/publishserviceapi/typeaccess.go index 32c1a7a..c8a7afc 100644 --- a/capifcore/internal/publishserviceapi/typeaccess.go +++ b/capifcore/internal/publishserviceapi/typeaccess.go @@ -28,3 +28,14 @@ func (sd ServiceAPIDescription) GetAefIds() []string { } return allIds } + +func (sd ServiceAPIDescription) GetAefProfileById(id *string) *AefProfile { + if sd.AefProfiles != nil { + for _, aefProfile := range *sd.AefProfiles { + if aefProfile.AefId == *id { + return &aefProfile + } + } + } + return nil +} diff --git a/capifcore/internal/securityapi/typeupdate.go b/capifcore/internal/securityapi/typeupdate.go new file mode 100644 index 0000000..364c123 --- /dev/null +++ b/capifcore/internal/securityapi/typeupdate.go @@ -0,0 +1,84 @@ +// - +// +// ========================LICENSE_START================================= +// O-RAN-SC +// %% +// Copyright (C) 2023: Nordix Foundation +// %% +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ========================LICENSE_END=================================== +package securityapi + +import ( + "fmt" + "strings" + + "oransc.org/nonrtric/capifcore/internal/publishserviceapi" +) + +var securityMethods []publishserviceapi.SecurityMethod + +func (newContext *ServiceSecurity) PrepareNewSecurityContext(services []publishserviceapi.ServiceAPIDescription) error { + securityMethods = []publishserviceapi.SecurityMethod{} + for i, securityInfo := range newContext.SecurityInfo { + + if securityInfo.InterfaceDetails != nil { + addSecurityMethodsFromInterfaceDetails(securityInfo.InterfaceDetails.SecurityMethods, &securityInfo.PrefSecurityMethods) + + } else { + checkNil := securityInfo.ApiId != nil && securityInfo.AefId != nil + if checkNil { + service := getServiceByApiId(&services, securityInfo.ApiId) + afpProfile := service.GetAefProfileById(securityInfo.AefId) + + addSecurityMethodsFromAefProfile(afpProfile) + } + } + + if isSecuryMethodsEmpty() { + return fmt.Errorf("not found compatible security method") + } + newContext.SecurityInfo[i].SelSecurityMethod = &securityMethods[0] + } + return nil +} + +func isSecuryMethodsEmpty() bool { + return len(securityMethods) <= 0 +} + +func addSecurityMethodsFromInterfaceDetails(methodsFromInterface *[]publishserviceapi.SecurityMethod, prefMethods *[]publishserviceapi.SecurityMethod) { + + if methodsFromInterface != nil { + securityMethods = append(securityMethods, *methodsFromInterface...) + } + if prefMethods != nil { + securityMethods = append(securityMethods, *prefMethods...) + } +} + +func addSecurityMethodsFromAefProfile(afpProfile *publishserviceapi.AefProfile) { + if afpProfile.SecurityMethods != nil { + securityMethods = append(securityMethods, *afpProfile.SecurityMethods...) + } +} + +func getServiceByApiId(services *[]publishserviceapi.ServiceAPIDescription, apiId *string) *publishserviceapi.ServiceAPIDescription { + + for _, service := range *services { + if apiId != nil && strings.Compare(*service.ApiId, *apiId) == 0 { + return &service + } + } + return nil +} diff --git a/capifcore/internal/securityapi/typeupdate_test.go b/capifcore/internal/securityapi/typeupdate_test.go new file mode 100644 index 0000000..1ad530d --- /dev/null +++ b/capifcore/internal/securityapi/typeupdate_test.go @@ -0,0 +1,106 @@ +// - +// ========================LICENSE_START================================= +// O-RAN-SC +// %% +// Copyright (C) 2023: Nordix Foundation +// %% +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ========================LICENSE_END=================================== +// + +package securityapi + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "oransc.org/nonrtric/capifcore/internal/common29122" + publishapi "oransc.org/nonrtric/capifcore/internal/publishserviceapi" +) + +func TestPrepareNewSecurityContext(t *testing.T) { + apiId := "app-management" + aefId := "aefId" + description := "Description" + services := []publishapi.ServiceAPIDescription{ + { + AefProfiles: &[]publishapi.AefProfile{ + { + AefId: aefId, + Versions: []publishapi.Version{ + { + Resources: &[]publishapi.Resource{ + { + CommType: "REQUEST_RESPONSE", + }, + }, + }, + }, + SecurityMethods: &[]publishapi.SecurityMethod{ + publishapi.SecurityMethodPKI, + }, + }, + }, + ApiId: &apiId, + Description: &description, + }, + } + + servSecurityUnderTest := ServiceSecurity{ + NotificationDestination: common29122.Uri("http://golang.cafe/"), + SecurityInfo: []SecurityInformation{ + { + PrefSecurityMethods: []publishapi.SecurityMethod{ + publishapi.SecurityMethodOAUTH, + }, + }, + }, + } + + err := servSecurityUnderTest.PrepareNewSecurityContext(services) + + assert.NotNil(t, err) + assert.Contains(t, err.Error(), "not found ") + assert.Contains(t, err.Error(), "security method") + + servSecurityUnderTest.SecurityInfo = []SecurityInformation{ + { + ApiId: &apiId, + AefId: &aefId, + PrefSecurityMethods: []publishapi.SecurityMethod{ + publishapi.SecurityMethodOAUTH, + }, + }, + } + + servSecurityUnderTest.PrepareNewSecurityContext(services) + assert.Equal(t, publishapi.SecurityMethodPKI, *servSecurityUnderTest.SecurityInfo[0].SelSecurityMethod) + + servSecurityUnderTest.SecurityInfo = []SecurityInformation{ + { + ApiId: &apiId, + PrefSecurityMethods: []publishapi.SecurityMethod{ + publishapi.SecurityMethodOAUTH, + }, + InterfaceDetails: &publishapi.InterfaceDescription{ + SecurityMethods: &[]publishapi.SecurityMethod{ + publishapi.SecurityMethodPSK, + }, + }, + }, + } + + servSecurityUnderTest.PrepareNewSecurityContext(services) + assert.Equal(t, publishapi.SecurityMethodPSK, *servSecurityUnderTest.SecurityInfo[0].SelSecurityMethod) + +} diff --git a/capifcore/internal/securityapi/typevalidation.go b/capifcore/internal/securityapi/typevalidation.go index 1241f96..4be8aee 100644 --- a/capifcore/internal/securityapi/typevalidation.go +++ b/capifcore/internal/securityapi/typevalidation.go @@ -21,6 +21,9 @@ package securityapi import ( + "errors" + "fmt" + "net/url" "strings" ) @@ -54,6 +57,32 @@ func (tokenReq AccessTokenReq) Validate() (bool, AccessTokenErr) { return true, AccessTokenErr{} } +func (ss ServiceSecurity) Validate() error { + + if len(strings.TrimSpace(string(ss.NotificationDestination))) == 0 { + return errors.New("ServiceSecurity missing required notificationDestination") + } + + if _, err := url.ParseRequestURI(string(ss.NotificationDestination)); err != nil { + return fmt.Errorf("ServiceSecurity has invalid notificationDestination, err=%s", err) + } + + if len(ss.SecurityInfo) == 0 { + return errors.New("ServiceSecurity missing required SecurityInfo") + } + for _, securityInfo := range ss.SecurityInfo { + securityInfo.Validate() + } + return nil +} + +func (si SecurityInformation) Validate() error { + if len(si.PrefSecurityMethods) == 0 { + return errors.New("SecurityInformation missing required PrefSecurityMethods") + } + return nil +} + func createAccessTokenError(err AccessTokenErrError, message string) AccessTokenErr { return AccessTokenErr{ Error: err, diff --git a/capifcore/internal/securityapi/typevalidation_test.go b/capifcore/internal/securityapi/typevalidation_test.go index 0515d06..f44de2f 100644 --- a/capifcore/internal/securityapi/typevalidation_test.go +++ b/capifcore/internal/securityapi/typevalidation_test.go @@ -24,6 +24,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "oransc.org/nonrtric/capifcore/internal/publishserviceapi" ) func TestValidateClientIdNotPresent(t *testing.T) { @@ -95,3 +96,50 @@ func TestValidateScopeMalformed(t *testing.T) { valid, err = accessTokenUnderTest.Validate() assert.Equal(t, true, valid) } + +func TestValidateServiceSecurity(t *testing.T) { + serviceSecurityUnderTest := ServiceSecurity{} + + err := serviceSecurityUnderTest.Validate() + assert.NotNil(t, err) + assert.Contains(t, err.Error(), "missing") + assert.Contains(t, err.Error(), "notificationDestination") + + serviceSecurityUnderTest.NotificationDestination = "invalid dest" + err = serviceSecurityUnderTest.Validate() + if assert.Error(t, err) { + assert.Contains(t, err.Error(), "invalid") + assert.Contains(t, err.Error(), "notificationDestination") + } + + serviceSecurityUnderTest.NotificationDestination = "http://golang.cafe/" + err = serviceSecurityUnderTest.Validate() + assert.NotNil(t, err) + assert.Contains(t, err.Error(), "missing") + assert.Contains(t, err.Error(), "SecurityInfo") + + serviceSecurityUnderTest.SecurityInfo = []SecurityInformation{ + { + PrefSecurityMethods: []publishserviceapi.SecurityMethod{ + publishserviceapi.SecurityMethodOAUTH, + }, + }, + } + err = serviceSecurityUnderTest.Validate() + assert.Nil(t, err) +} + +func TestValidatePrefSecurityMethodsNotPresent(t *testing.T) { + securityInfoUnderTest := SecurityInformation{} + err := securityInfoUnderTest.Validate() + + assert.NotNil(t, err) + assert.Contains(t, err.Error(), "missing") + assert.Contains(t, err.Error(), "PrefSecurityMethods") + + securityInfoUnderTest.PrefSecurityMethods = []publishserviceapi.SecurityMethod{ + publishserviceapi.SecurityMethodOAUTH, + } + err = securityInfoUnderTest.Validate() + assert.Nil(t, err) +} diff --git a/capifcore/internal/securityservice/security.go b/capifcore/internal/securityservice/security.go index dcf1dbb..52d28ce 100644 --- a/capifcore/internal/securityservice/security.go +++ b/capifcore/internal/securityservice/security.go @@ -21,8 +21,11 @@ package security import ( + "fmt" "net/http" + "path" "strings" + "sync" "github.com/labstack/echo/v4" @@ -40,6 +43,8 @@ type Security struct { publishRegister publishservice.PublishRegister invokerRegister invokermanagement.InvokerRegister keycloak keycloak.AccessManagement + trustedInvokers map[string]securityapi.ServiceSecurity + lock sync.Mutex } func NewSecurity(serviceRegister providermanagement.ServiceRegister, publishRegister publishservice.PublishRegister, invokerRegister invokermanagement.InvokerRegister, km keycloak.AccessManagement) *Security { @@ -48,6 +53,7 @@ func NewSecurity(serviceRegister providermanagement.ServiceRegister, publishRegi publishRegister: publishRegister, invokerRegister: invokerRegister, keycloak: km, + trustedInvokers: make(map[string]securityapi.ServiceSecurity), } } @@ -112,7 +118,57 @@ func (s *Security) GetTrustedInvokersApiInvokerId(ctx echo.Context, apiInvokerId } func (s *Security) PutTrustedInvokersApiInvokerId(ctx echo.Context, apiInvokerId string) error { - return ctx.NoContent(http.StatusNotImplemented) + errMsg := "Unable to update security context due to %s." + + if !s.invokerRegister.IsInvokerRegistered(apiInvokerId) { + return sendCoreError(ctx, http.StatusBadRequest, "Unable to update security context due to Invoker not registered") + } + serviceSecurity, err := getServiceSecurityFromRequest(ctx) + if err != nil { + return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err)) + } + + if err := serviceSecurity.Validate(); err != nil { + return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err)) + } + + err = s.prepareNewSecurityContext(&serviceSecurity, apiInvokerId) + if err != nil { + return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err)) + } + + uri := ctx.Request().Host + ctx.Request().URL.String() + ctx.Response().Header().Set(echo.HeaderLocation, ctx.Scheme()+`://`+path.Join(uri, apiInvokerId)) + + err = ctx.JSON(http.StatusCreated, s.trustedInvokers[apiInvokerId]) + if err != nil { + // Something really bad happened, tell Echo that our handler failed + return err + } + + return nil +} + +func getServiceSecurityFromRequest(ctx echo.Context) (securityapi.ServiceSecurity, error) { + var serviceSecurity securityapi.ServiceSecurity + err := ctx.Bind(&serviceSecurity) + if err != nil { + return securityapi.ServiceSecurity{}, fmt.Errorf("invalid format for service security") + } + return serviceSecurity, nil +} + +func (s *Security) prepareNewSecurityContext(newContext *securityapi.ServiceSecurity, apiInvokerId string) error { + s.lock.Lock() + defer s.lock.Unlock() + + err := newContext.PrepareNewSecurityContext(s.publishRegister.GetAllPublishedServices()) + if err != nil { + return err + } + + s.trustedInvokers[apiInvokerId] = *newContext + return nil } func (s *Security) PostTrustedInvokersApiInvokerIdDelete(ctx echo.Context, apiInvokerId string) error { @@ -130,3 +186,14 @@ func sendAccessTokenError(ctx echo.Context, code int, err securityapi.AccessToke } return ctx.JSON(code, accessTokenErr) } + +// This function wraps sending of an error in the Error format, and +// handling the failure to marshal that. +func sendCoreError(ctx echo.Context, code int, message string) error { + pd := common29122.ProblemDetails{ + Cause: &message, + Status: &code, + } + err := ctx.JSON(code, pd) + return err +} diff --git a/capifcore/internal/securityservice/security_test.go b/capifcore/internal/securityservice/security_test.go index 13af737..d31ff6e 100644 --- a/capifcore/internal/securityservice/security_test.go +++ b/capifcore/internal/securityservice/security_test.go @@ -28,7 +28,9 @@ import ( "os" "testing" + "oransc.org/nonrtric/capifcore/internal/common29122" "oransc.org/nonrtric/capifcore/internal/keycloak" + "oransc.org/nonrtric/capifcore/internal/publishserviceapi" "oransc.org/nonrtric/capifcore/internal/securityapi" "oransc.org/nonrtric/capifcore/internal/invokermanagement" @@ -240,6 +242,181 @@ func TestPostSecurityIdTokenInvokerInvalidCredentials(t *testing.T) { accessMgmMock.AssertCalled(t, "GetToken", clientId, clientSecret, "3gpp#"+aefId+":"+path, "invokerrealm") } +func TestPutTrustedInvokerSuccessfully(t *testing.T) { + invokerRegisterMock := invokermocks.InvokerRegister{} + invokerRegisterMock.On("IsInvokerRegistered", mock.AnythingOfType("string")).Return(true) + aefId := "aefId" + aefProfile := getAefProfile(aefId) + aefProfile.SecurityMethods = &[]publishserviceapi.SecurityMethod{ + publishserviceapi.SecurityMethodPKI, + } + aefProfiles := []publishserviceapi.AefProfile{ + aefProfile, + } + apiId := "apiId" + publishedServices := []publishserviceapi.ServiceAPIDescription{ + { + ApiId: &apiId, + AefProfiles: &aefProfiles, + }, + } + publishRegisterMock := publishmocks.PublishRegister{} + publishRegisterMock.On("GetAllPublishedServices").Return(publishedServices) + + requestHandler := getEcho(nil, &publishRegisterMock, &invokerRegisterMock, nil) + + invokerId := "invokerId" + serviceSecurityUnderTest := getServiceSecurity(aefId, apiId) + serviceSecurityUnderTest.SecurityInfo[0].ApiId = &apiId + + result := testutil.NewRequest().Put("/trustedInvokers/"+invokerId).WithJsonBody(serviceSecurityUnderTest).Go(t, requestHandler) + + assert.Equal(t, http.StatusCreated, result.Code()) + var resultResponse securityapi.ServiceSecurity + err := result.UnmarshalBodyToObject(&resultResponse) + assert.NoError(t, err, "error unmarshaling response") + assert.NotEmpty(t, resultResponse.NotificationDestination) + + for _, security := range resultResponse.SecurityInfo { + assert.Equal(t, *security.ApiId, apiId) + assert.Equal(t, *security.SelSecurityMethod, publishserviceapi.SecurityMethodPKI) + } + invokerRegisterMock.AssertCalled(t, "IsInvokerRegistered", invokerId) + +} + +func TestPutTrustedInkoverNotRegistered(t *testing.T) { + invokerRegisterMock := invokermocks.InvokerRegister{} + invokerRegisterMock.On("IsInvokerRegistered", mock.AnythingOfType("string")).Return(false) + + requestHandler := getEcho(nil, nil, &invokerRegisterMock, nil) + + invokerId := "invokerId" + serviceSecurityUnderTest := getServiceSecurity("aefId", "apiId") + + result := testutil.NewRequest().Put("/trustedInvokers/"+invokerId).WithJsonBody(serviceSecurityUnderTest).Go(t, requestHandler) + + badRequest := http.StatusBadRequest + assert.Equal(t, badRequest, result.Code()) + var problemDetails common29122.ProblemDetails + err := result.UnmarshalBodyToObject(&problemDetails) + assert.NoError(t, err, "error unmarshaling response") + assert.Equal(t, &badRequest, problemDetails.Status) + assert.Contains(t, *problemDetails.Cause, "Invoker not registered") + invokerRegisterMock.AssertCalled(t, "IsInvokerRegistered", invokerId) +} + +func TestPutTrustedInkoverInvalidInputServiceSecurity(t *testing.T) { + invokerRegisterMock := invokermocks.InvokerRegister{} + invokerRegisterMock.On("IsInvokerRegistered", mock.AnythingOfType("string")).Return(true) + + requestHandler := getEcho(nil, nil, &invokerRegisterMock, nil) + + invokerId := "invokerId" + notificationUrl := "url" + serviceSecurityUnderTest := getServiceSecurity("aefId", "apiId") + serviceSecurityUnderTest.NotificationDestination = common29122.Uri(notificationUrl) + + result := testutil.NewRequest().Put("/trustedInvokers/"+invokerId).WithJsonBody(serviceSecurityUnderTest).Go(t, requestHandler) + + badRequest := http.StatusBadRequest + assert.Equal(t, badRequest, result.Code()) + var problemDetails common29122.ProblemDetails + err := result.UnmarshalBodyToObject(&problemDetails) + assert.NoError(t, err, "error unmarshaling response") + assert.Equal(t, &badRequest, problemDetails.Status) + assert.Contains(t, *problemDetails.Cause, "ServiceSecurity has invalid notificationDestination") + invokerRegisterMock.AssertCalled(t, "IsInvokerRegistered", invokerId) +} + +func TestPutTrustedInvokerInterfaceDetailsNotNil(t *testing.T) { + invokerRegisterMock := invokermocks.InvokerRegister{} + invokerRegisterMock.On("IsInvokerRegistered", mock.AnythingOfType("string")).Return(true) + aefId := "aefId" + aefProfile := getAefProfile(aefId) + aefProfile.SecurityMethods = &[]publishserviceapi.SecurityMethod{ + publishserviceapi.SecurityMethodPKI, + } + aefProfiles := []publishserviceapi.AefProfile{ + aefProfile, + } + apiId := "apiId" + publishedServices := []publishserviceapi.ServiceAPIDescription{ + { + ApiId: &apiId, + AefProfiles: &aefProfiles, + }, + } + publishRegisterMock := publishmocks.PublishRegister{} + publishRegisterMock.On("GetAllPublishedServices").Return(publishedServices) + + requestHandler := getEcho(nil, &publishRegisterMock, &invokerRegisterMock, nil) + + invokerId := "invokerId" + serviceSecurityUnderTest := getServiceSecurity(aefId, apiId) + serviceSecurityUnderTest.SecurityInfo[0] = securityapi.SecurityInformation{ + ApiId: &apiId, + PrefSecurityMethods: []publishserviceapi.SecurityMethod{ + publishserviceapi.SecurityMethodOAUTH, + }, + InterfaceDetails: &publishserviceapi.InterfaceDescription{ + SecurityMethods: &[]publishserviceapi.SecurityMethod{ + publishserviceapi.SecurityMethodPSK, + }, + }, + } + + result := testutil.NewRequest().Put("/trustedInvokers/"+invokerId).WithJsonBody(serviceSecurityUnderTest).Go(t, requestHandler) + + assert.Equal(t, http.StatusCreated, result.Code()) + var resultResponse securityapi.ServiceSecurity + err := result.UnmarshalBodyToObject(&resultResponse) + assert.NoError(t, err, "error unmarshaling response") + assert.NotEmpty(t, resultResponse.NotificationDestination) + + for _, security := range resultResponse.SecurityInfo { + assert.Equal(t, apiId, *security.ApiId) + assert.Equal(t, publishserviceapi.SecurityMethodPSK, *security.SelSecurityMethod) + } + invokerRegisterMock.AssertCalled(t, "IsInvokerRegistered", invokerId) + +} + +func TestPutTrustedInvokerNotFoundSecurityMethod(t *testing.T) { + invokerRegisterMock := invokermocks.InvokerRegister{} + invokerRegisterMock.On("IsInvokerRegistered", mock.AnythingOfType("string")).Return(true) + + aefProfiles := []publishserviceapi.AefProfile{ + getAefProfile("aefId"), + } + apiId := "apiId" + publishedServices := []publishserviceapi.ServiceAPIDescription{ + { + ApiId: &apiId, + AefProfiles: &aefProfiles, + }, + } + publishRegisterMock := publishmocks.PublishRegister{} + publishRegisterMock.On("GetAllPublishedServices").Return(publishedServices) + + requestHandler := getEcho(nil, &publishRegisterMock, &invokerRegisterMock, nil) + + invokerId := "invokerId" + serviceSecurityUnderTest := getServiceSecurity("aefId", "apiId") + + result := testutil.NewRequest().Put("/trustedInvokers/"+invokerId).WithJsonBody(serviceSecurityUnderTest).Go(t, requestHandler) + + badRequest := http.StatusBadRequest + assert.Equal(t, badRequest, result.Code()) + var problemDetails common29122.ProblemDetails + err := result.UnmarshalBodyToObject(&problemDetails) + assert.NoError(t, err, "error unmarshaling response") + assert.Equal(t, &badRequest, problemDetails.Status) + assert.Contains(t, *problemDetails.Cause, "not found") + assert.Contains(t, *problemDetails.Cause, "security method") + invokerRegisterMock.AssertCalled(t, "IsInvokerRegistered", invokerId) +} + func getEcho(serviceRegister providermanagement.ServiceRegister, publishRegister publishservice.PublishRegister, invokerRegister invokermanagement.InvokerRegister, keycloakMgm keycloak.AccessManagement) *echo.Echo { swagger, err := securityapi.GetSwagger() if err != nil { @@ -258,3 +435,33 @@ func getEcho(serviceRegister providermanagement.ServiceRegister, publishRegister securityapi.RegisterHandlers(e, s) return e } + +func getServiceSecurity(aefId string, apiId string) securityapi.ServiceSecurity { + return securityapi.ServiceSecurity{ + NotificationDestination: common29122.Uri("http://golang.cafe/"), + SecurityInfo: []securityapi.SecurityInformation{ + { + AefId: &aefId, + ApiId: &apiId, + PrefSecurityMethods: []publishserviceapi.SecurityMethod{ + publishserviceapi.SecurityMethodOAUTH, + }, + }, + }, + } +} + +func getAefProfile(aefId string) publishserviceapi.AefProfile { + return publishserviceapi.AefProfile{ + AefId: aefId, + Versions: []publishserviceapi.Version{ + { + Resources: &[]publishserviceapi.Resource{ + { + CommType: "REQUEST_RESPONSE", + }, + }, + }, + }, + } +} -- 2.16.6