X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=capifcore%2Finternal%2Fsecurityservice%2Fsecurity_test.go;h=ea0fbe6930f176de773fdcf542e56a63f70734a8;hb=HEAD;hp=d31ff6ea3c1205b21c0fec1005fe4f3fdda20bd8;hpb=c865c910a6a04fc202c8eb8b6403544c44784d5f;p=nonrtric%2Fplt%2Fsme.git diff --git a/capifcore/internal/securityservice/security_test.go b/capifcore/internal/securityservice/security_test.go index d31ff6e..ea0fbe6 100644 --- a/capifcore/internal/securityservice/security_test.go +++ b/capifcore/internal/securityservice/security_test.go @@ -66,9 +66,9 @@ func TestPostSecurityIdTokenInvokerRegistered(t *testing.T) { Scope: "3gpp#aefIdpath", } accessMgmMock := keycloackmocks.AccessManagement{} - accessMgmMock.On("GetToken", mock.AnythingOfType("string"), mock.AnythingOfType("string"), mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return(jwt, nil) + accessMgmMock.On("GetToken", mock.AnythingOfType("string"), mock.AnythingOfType("map[string][]string")).Return(jwt, nil) - requestHandler := getEcho(&serviceRegisterMock, &publishRegisterMock, &invokerRegisterMock, &accessMgmMock) + requestHandler, _ := getEcho(&serviceRegisterMock, &publishRegisterMock, &invokerRegisterMock, &accessMgmMock) data := url.Values{} clientId := "id" @@ -94,14 +94,14 @@ func TestPostSecurityIdTokenInvokerRegistered(t *testing.T) { invokerRegisterMock.AssertCalled(t, "VerifyInvokerSecret", clientId, clientSecret) serviceRegisterMock.AssertCalled(t, "IsFunctionRegistered", aefId) publishRegisterMock.AssertCalled(t, "IsAPIPublished", aefId, path) - accessMgmMock.AssertCalled(t, "GetToken", clientId, clientSecret, "3gpp#"+aefId+":"+path, "invokerrealm") + accessMgmMock.AssertNumberOfCalls(t, "GetToken", 1) } func TestPostSecurityIdTokenInvokerNotRegistered(t *testing.T) { invokerRegisterMock := invokermocks.InvokerRegister{} invokerRegisterMock.On("IsInvokerRegistered", mock.AnythingOfType("string")).Return(false) - requestHandler := getEcho(nil, nil, &invokerRegisterMock, nil) + requestHandler, _ := getEcho(nil, nil, &invokerRegisterMock, nil) data := url.Values{} data.Set("client_id", "id") @@ -126,7 +126,7 @@ func TestPostSecurityIdTokenInvokerSecretNotValid(t *testing.T) { invokerRegisterMock.On("IsInvokerRegistered", mock.AnythingOfType("string")).Return(true) invokerRegisterMock.On("VerifyInvokerSecret", mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return(false) - requestHandler := getEcho(nil, nil, &invokerRegisterMock, nil) + requestHandler, _ := getEcho(nil, nil, &invokerRegisterMock, nil) data := url.Values{} data.Set("client_id", "id") @@ -153,7 +153,7 @@ func TestPostSecurityIdTokenFunctionNotRegistered(t *testing.T) { serviceRegisterMock := servicemocks.ServiceRegister{} serviceRegisterMock.On("IsFunctionRegistered", mock.AnythingOfType("string")).Return(false) - requestHandler := getEcho(&serviceRegisterMock, nil, &invokerRegisterMock, nil) + requestHandler, _ := getEcho(&serviceRegisterMock, nil, &invokerRegisterMock, nil) data := url.Values{} data.Set("client_id", "id") @@ -182,7 +182,7 @@ func TestPostSecurityIdTokenAPINotPublished(t *testing.T) { publishRegisterMock := publishmocks.PublishRegister{} publishRegisterMock.On("IsAPIPublished", mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return(false) - requestHandler := getEcho(&serviceRegisterMock, &publishRegisterMock, &invokerRegisterMock, nil) + requestHandler, _ := getEcho(&serviceRegisterMock, &publishRegisterMock, &invokerRegisterMock, nil) data := url.Values{} data.Set("client_id", "id") @@ -213,9 +213,9 @@ func TestPostSecurityIdTokenInvokerInvalidCredentials(t *testing.T) { jwt := keycloak.Jwttoken{} accessMgmMock := keycloackmocks.AccessManagement{} - accessMgmMock.On("GetToken", mock.AnythingOfType("string"), mock.AnythingOfType("string"), mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return(jwt, errors.New("invalid_credentials")) + accessMgmMock.On("GetToken", mock.AnythingOfType("string"), mock.AnythingOfType("map[string][]string")).Return(jwt, errors.New("invalid_credentials")) - requestHandler := getEcho(&serviceRegisterMock, &publishRegisterMock, &invokerRegisterMock, &accessMgmMock) + requestHandler, _ := getEcho(&serviceRegisterMock, &publishRegisterMock, &invokerRegisterMock, &accessMgmMock) data := url.Values{} clientId := "id" @@ -239,7 +239,7 @@ func TestPostSecurityIdTokenInvokerInvalidCredentials(t *testing.T) { invokerRegisterMock.AssertCalled(t, "VerifyInvokerSecret", clientId, clientSecret) serviceRegisterMock.AssertCalled(t, "IsFunctionRegistered", aefId) publishRegisterMock.AssertCalled(t, "IsAPIPublished", aefId, path) - accessMgmMock.AssertCalled(t, "GetToken", clientId, clientSecret, "3gpp#"+aefId+":"+path, "invokerrealm") + accessMgmMock.AssertNumberOfCalls(t, "GetToken", 1) } func TestPutTrustedInvokerSuccessfully(t *testing.T) { @@ -263,7 +263,7 @@ func TestPutTrustedInvokerSuccessfully(t *testing.T) { publishRegisterMock := publishmocks.PublishRegister{} publishRegisterMock.On("GetAllPublishedServices").Return(publishedServices) - requestHandler := getEcho(nil, &publishRegisterMock, &invokerRegisterMock, nil) + requestHandler, _ := getEcho(nil, &publishRegisterMock, &invokerRegisterMock, nil) invokerId := "invokerId" serviceSecurityUnderTest := getServiceSecurity(aefId, apiId) @@ -282,14 +282,13 @@ func TestPutTrustedInvokerSuccessfully(t *testing.T) { 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) + requestHandler, _ := getEcho(nil, nil, &invokerRegisterMock, nil) invokerId := "invokerId" serviceSecurityUnderTest := getServiceSecurity("aefId", "apiId") @@ -310,7 +309,7 @@ func TestPutTrustedInkoverInvalidInputServiceSecurity(t *testing.T) { invokerRegisterMock := invokermocks.InvokerRegister{} invokerRegisterMock.On("IsInvokerRegistered", mock.AnythingOfType("string")).Return(true) - requestHandler := getEcho(nil, nil, &invokerRegisterMock, nil) + requestHandler, _ := getEcho(nil, nil, &invokerRegisterMock, nil) invokerId := "invokerId" notificationUrl := "url" @@ -350,7 +349,7 @@ func TestPutTrustedInvokerInterfaceDetailsNotNil(t *testing.T) { publishRegisterMock := publishmocks.PublishRegister{} publishRegisterMock.On("GetAllPublishedServices").Return(publishedServices) - requestHandler := getEcho(nil, &publishRegisterMock, &invokerRegisterMock, nil) + requestHandler, _ := getEcho(nil, &publishRegisterMock, &invokerRegisterMock, nil) invokerId := "invokerId" serviceSecurityUnderTest := getServiceSecurity(aefId, apiId) @@ -379,7 +378,6 @@ func TestPutTrustedInvokerInterfaceDetailsNotNil(t *testing.T) { assert.Equal(t, publishserviceapi.SecurityMethodPSK, *security.SelSecurityMethod) } invokerRegisterMock.AssertCalled(t, "IsInvokerRegistered", invokerId) - } func TestPutTrustedInvokerNotFoundSecurityMethod(t *testing.T) { @@ -399,7 +397,10 @@ func TestPutTrustedInvokerNotFoundSecurityMethod(t *testing.T) { publishRegisterMock := publishmocks.PublishRegister{} publishRegisterMock.On("GetAllPublishedServices").Return(publishedServices) - requestHandler := getEcho(nil, &publishRegisterMock, &invokerRegisterMock, nil) + accessMgmMock := keycloackmocks.AccessManagement{} + accessMgmMock.On("AddClient", mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return(nil) + + requestHandler, _ := getEcho(nil, &publishRegisterMock, &invokerRegisterMock, &accessMgmMock) invokerId := "invokerId" serviceSecurityUnderTest := getServiceSecurity("aefId", "apiId") @@ -417,7 +418,180 @@ func TestPutTrustedInvokerNotFoundSecurityMethod(t *testing.T) { invokerRegisterMock.AssertCalled(t, "IsInvokerRegistered", invokerId) } -func getEcho(serviceRegister providermanagement.ServiceRegister, publishRegister publishservice.PublishRegister, invokerRegister invokermanagement.InvokerRegister, keycloakMgm keycloak.AccessManagement) *echo.Echo { +func TestDeleteSecurityContext(t *testing.T) { + + requestHandler, securityUnderTest := getEcho(nil, nil, nil, nil) + + aefId := "aefId" + apiId := "apiId" + serviceSecurityUnderTest := getServiceSecurity(aefId, apiId) + serviceSecurityUnderTest.SecurityInfo[0].ApiId = &apiId + + invokerId := "invokerId" + securityUnderTest.trustedInvokers[invokerId] = serviceSecurityUnderTest + + // Delete the security context + result := testutil.NewRequest().Delete("/trustedInvokers/"+invokerId).Go(t, requestHandler) + + assert.Equal(t, http.StatusNoContent, result.Code()) + _, ok := securityUnderTest.trustedInvokers[invokerId] + assert.False(t, ok) +} + +func TestGetSecurityContextByInvokerId(t *testing.T) { + + requestHandler, securityUnderTest := getEcho(nil, nil, nil, nil) + + aefId := "aefId" + apiId := "apiId" + authenticationInfo := "authenticationInfo" + authorizationInfo := "authorizationInfo" + serviceSecurityUnderTest := getServiceSecurity(aefId, apiId) + serviceSecurityUnderTest.SecurityInfo[0].AuthenticationInfo = &authenticationInfo + serviceSecurityUnderTest.SecurityInfo[0].AuthorizationInfo = &authorizationInfo + + invokerId := "invokerId" + securityUnderTest.trustedInvokers[invokerId] = serviceSecurityUnderTest + + // Get security context + result := testutil.NewRequest().Get("/trustedInvokers/"+invokerId).Go(t, requestHandler) + + assert.Equal(t, http.StatusOK, result.Code()) + var resultService securityapi.ServiceSecurity + err := result.UnmarshalBodyToObject(&resultService) + assert.NoError(t, err, "error unmarshaling response") + + for _, secInfo := range resultService.SecurityInfo { + assert.Equal(t, apiId, *secInfo.ApiId) + assert.Equal(t, aefId, *secInfo.AefId) + assert.Equal(t, "", *secInfo.AuthenticationInfo) + assert.Equal(t, "", *secInfo.AuthorizationInfo) + } + + result = testutil.NewRequest().Get("/trustedInvokers/"+invokerId+"?authenticationInfo=true&authorizationInfo=false").Go(t, requestHandler) + assert.Equal(t, http.StatusOK, result.Code()) + err = result.UnmarshalBodyToObject(&resultService) + assert.NoError(t, err, "error unmarshaling response") + + for _, secInfo := range resultService.SecurityInfo { + assert.Equal(t, authenticationInfo, *secInfo.AuthenticationInfo) + assert.Equal(t, "", *secInfo.AuthorizationInfo) + } + + result = testutil.NewRequest().Get("/trustedInvokers/"+invokerId+"?authenticationInfo=true&authorizationInfo=true").Go(t, requestHandler) + assert.Equal(t, http.StatusOK, result.Code()) + err = result.UnmarshalBodyToObject(&resultService) + assert.NoError(t, err, "error unmarshaling response") + + for _, secInfo := range resultService.SecurityInfo { + assert.Equal(t, authenticationInfo, *secInfo.AuthenticationInfo) + assert.Equal(t, authorizationInfo, *secInfo.AuthorizationInfo) + } +} + +func TestUpdateTrustedInvoker(t *testing.T) { + + requestHandler, securityUnderTest := getEcho(nil, nil, nil, nil) + + aefId := "aefId" + apiId := "apiId" + invokerId := "invokerId" + serviceSecurityTest := getServiceSecurity(aefId, apiId) + serviceSecurityTest.SecurityInfo[0].ApiId = &apiId + securityUnderTest.trustedInvokers[invokerId] = serviceSecurityTest + + // Update the service security with valid invoker, should return 200 with updated service security + newNotifURL := "http://golang.org/" + serviceSecurityTest.NotificationDestination = common29122.Uri(newNotifURL) + result := testutil.NewRequest().Post("/trustedInvokers/"+invokerId+"/update").WithJsonBody(serviceSecurityTest).Go(t, requestHandler) + + var resultResponse securityapi.ServiceSecurity + assert.Equal(t, http.StatusOK, result.Code()) + err := result.UnmarshalBodyToObject(&resultResponse) + assert.NoError(t, err, "error unmarshaling response") + assert.Equal(t, newNotifURL, string(resultResponse.NotificationDestination)) + + // Update with a service security missing required NotificationDestination, should get 400 with problem details + invalidServiceSecurity := securityapi.ServiceSecurity{ + SecurityInfo: []securityapi.SecurityInformation{ + { + AefId: &aefId, + ApiId: &apiId, + PrefSecurityMethods: []publishserviceapi.SecurityMethod{ + publishserviceapi.SecurityMethodOAUTH, + }, + }, + }, + } + + result = testutil.NewRequest().Post("/trustedInvokers/"+invokerId+"/update").WithJsonBody(invalidServiceSecurity).Go(t, requestHandler) + + assert.Equal(t, http.StatusBadRequest, result.Code()) + var problemDetails common29122.ProblemDetails + err = result.UnmarshalBodyToObject(&problemDetails) + assert.NoError(t, err, "error unmarshaling response") + assert.Equal(t, http.StatusBadRequest, *problemDetails.Status) + assert.Contains(t, *problemDetails.Cause, "missing") + assert.Contains(t, *problemDetails.Cause, "notificationDestination") + + // Update a service security that has not been registered, should get 404 with problem details + missingId := "1" + result = testutil.NewRequest().Post("/trustedInvokers/"+missingId+"/update").WithJsonBody(serviceSecurityTest).Go(t, requestHandler) + + assert.Equal(t, http.StatusNotFound, result.Code()) + err = result.UnmarshalBodyToObject(&problemDetails) + assert.NoError(t, err, "error unmarshaling response") + assert.Equal(t, http.StatusNotFound, *problemDetails.Status) + assert.Contains(t, *problemDetails.Cause, "not register") + assert.Contains(t, *problemDetails.Cause, "trusted invoker") +} + +func TestRevokeAuthorizationToInvoker(t *testing.T) { + aefId := "aefId" + apiId := "apiId" + invokerId := "invokerId" + + notification := securityapi.SecurityNotification{ + AefId: &aefId, + ApiInvokerId: invokerId, + ApiIds: []string{apiId}, + Cause: securityapi.CauseUNEXPECTEDREASON, + } + + requestHandler, securityUnderTest := getEcho(nil, nil, nil, nil) + + serviceSecurityTest := getServiceSecurity(aefId, apiId) + serviceSecurityTest.SecurityInfo[0].ApiId = &apiId + + apiIdTwo := "apiIdTwo" + secInfo := securityapi.SecurityInformation{ + AefId: &aefId, + ApiId: &apiIdTwo, + PrefSecurityMethods: []publishserviceapi.SecurityMethod{ + publishserviceapi.SecurityMethodPKI, + }, + } + + serviceSecurityTest.SecurityInfo = append(serviceSecurityTest.SecurityInfo, secInfo) + + securityUnderTest.trustedInvokers[invokerId] = serviceSecurityTest + + // Revoke apiId + result := testutil.NewRequest().Post("/trustedInvokers/"+invokerId+"/delete").WithJsonBody(notification).Go(t, requestHandler) + + assert.Equal(t, http.StatusNoContent, result.Code()) + assert.Equal(t, 1, len(securityUnderTest.trustedInvokers[invokerId].SecurityInfo)) + + notification.ApiIds = []string{apiIdTwo} + // Revoke apiIdTwo + result = testutil.NewRequest().Post("/trustedInvokers/"+invokerId+"/delete").WithJsonBody(notification).Go(t, requestHandler) + + assert.Equal(t, http.StatusNoContent, result.Code()) + _, ok := securityUnderTest.trustedInvokers[invokerId] + assert.False(t, ok) +} + +func getEcho(serviceRegister providermanagement.ServiceRegister, publishRegister publishservice.PublishRegister, invokerRegister invokermanagement.InvokerRegister, keycloakMgm keycloak.AccessManagement) (*echo.Echo, *Security) { swagger, err := securityapi.GetSwagger() if err != nil { fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err) @@ -433,7 +607,7 @@ func getEcho(serviceRegister providermanagement.ServiceRegister, publishRegister e.Use(middleware.OapiRequestValidator(swagger)) securityapi.RegisterHandlers(e, s) - return e + return e, s } func getServiceSecurity(aefId string, apiId string) securityapi.ServiceSecurity {