NONRTRIC-946: Fix Capifcore intersection panic 85/12585/1
authorDenisGNoonan <denis.noonan@est.tech>
Fri, 1 Mar 2024 12:56:41 +0000 (12:56 +0000)
committerDenisGNoonan <denis.noonan@est.tech>
Fri, 1 Mar 2024 12:56:41 +0000 (12:56 +0000)
Change-Id: I1aae7245ec68f608f16f6b61f03d4ca335997b16
Signed-off-by: DenisGNoonan <denis.noonan@est.tech>
capifcore/internal/invokermanagement/invokermanagement.go
capifcore/internal/providermanagement/providermanagement.go
capifcore/internal/publishservice/publishservice.go
capifcore/internal/publishservice/publishservice_test.go
capifcore/internal/securityservice/security.go

index ae90164..fe0c2cb 100644 (file)
@@ -114,7 +114,7 @@ func (im *InvokerManager) PostOnboardedInvokers(ctx echo.Context) error {
                return sendCoreError(ctx, http.StatusForbidden, fmt.Sprintf(errMsg, err))
        }
 
-       if err = im.validateInvoker(newInvoker, ctx); err != nil {
+       if err = im.validateInvoker(newInvoker); err != nil {
                return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err))
        }
 
@@ -212,7 +212,7 @@ func (im *InvokerManager) PutOnboardedInvokersOnboardingId(ctx echo.Context, onb
                return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, errMismatch))
        }
 
-       if err := im.validateInvoker(newInvoker, ctx); err != nil {
+       if err := im.validateInvoker(newInvoker); err != nil {
                return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err))
        }
 
@@ -241,7 +241,7 @@ func (im *InvokerManager) ModifyIndApiInvokeEnrolment(ctx echo.Context, onboardi
        return ctx.NoContent(http.StatusNotImplemented)
 }
 
-func (im *InvokerManager) validateInvoker(invoker invokerapi.APIInvokerEnrolmentDetails, ctx echo.Context) error {
+func (im *InvokerManager) validateInvoker(invoker invokerapi.APIInvokerEnrolmentDetails) error {
        if err := invoker.Validate(); err != nil {
                return err
        }
index ebdfa9a..5fa786c 100644 (file)
@@ -2,7 +2,8 @@
 //   ========================LICENSE_START=================================
 //   O-RAN-SC
 //   %%
-//   Copyright (C) 2022: Nordix Foundation
+//   Copyright (C) 2022-2023: Nordix Foundation
+//   Copyright (C) 2024: OpenInfra Foundation Europe
 //   %%
 //   Licensed under the Apache License, Version 2.0 (the "License");
 //   you may not use this file except in compliance with the License.
@@ -138,7 +139,7 @@ func (pm *ProviderManager) deleteProvider(registrationId string) {
 
 func (pm *ProviderManager) PutRegistrationsRegistrationId(ctx echo.Context, registrationId string) error {
        errMsg := "Unable to update provider due to %s."
-       registeredProvider, err := pm.checkIfProviderIsRegistered(registrationId, ctx)
+       registeredProvider, err := pm.checkIfProviderIsRegistered(registrationId)
        if err != nil {
                return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err))
        }
@@ -173,7 +174,7 @@ func (pm *ProviderManager) ModifyIndApiProviderEnrolment(ctx echo.Context, regis
        return ctx.NoContent(http.StatusNotImplemented)
 }
 
-func (pm *ProviderManager) checkIfProviderIsRegistered(registrationId string, ctx echo.Context) (*provapi.APIProviderEnrolmentDetails, error) {
+func (pm *ProviderManager) checkIfProviderIsRegistered(registrationId string) (*provapi.APIProviderEnrolmentDetails, error) {
        registeredProvider, ok := pm.registeredProviders[registrationId]
        if !ok {
                return nil, fmt.Errorf("provider not onboarded")
index 372b1f8..670d2ed 100644 (file)
@@ -97,19 +97,20 @@ func (ps *PublishService) GetAllPublishedServices() []publishapi.ServiceAPIDescr
 
 func (ps *PublishService) GetAllowedPublishedServices(apiListRequestedServices []publishapi.ServiceAPIDescription) []publishapi.ServiceAPIDescription {
        apiListAllPublished := ps.GetAllPublishedServices()
-       if apiListRequestedServices != nil {
-               allowedPublishedServices := intersection(apiListAllPublished, apiListRequestedServices)
-               return allowedPublishedServices
-       }
-       return []publishapi.ServiceAPIDescription{}
+       allowedPublishedServices := intersection(apiListAllPublished, apiListRequestedServices)
+       return allowedPublishedServices
 }
 
 func intersection(a, b []publishapi.ServiceAPIDescription) []publishapi.ServiceAPIDescription {
        var result []publishapi.ServiceAPIDescription
 
+       if (a == nil) || (b == nil) || (len(a) == 0) || (len(b) == 0) {
+               return result
+       }
+
        for _, itemA := range a {
                for _, itemB := range b {
-                       if *itemA.ApiId == *itemB.ApiId {
+                       if (itemA.ApiId != nil) && (itemB.ApiId != nil) && (*itemA.ApiId == *itemB.ApiId) {
                                result = append(result, itemA)
                                break
                        }
@@ -283,7 +284,7 @@ func (ps *PublishService) PutApfIdServiceApisServiceApiId(ctx echo.Context, apfI
        defer ps.lock.Unlock()
        errMsg := "Unable to update service due to %s."
 
-       pos, publishedService, err := ps.checkIfServiceIsPublished(apfId, serviceApiId, ctx)
+       pos, publishedService, err := ps.checkIfServiceIsPublished(apfId, serviceApiId)
        if err != nil {
                return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err))
        }
@@ -304,7 +305,7 @@ func (ps *PublishService) PutApfIdServiceApisServiceApiId(ctx echo.Context, apfI
                return sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf(errMsg, err))
        }
 
-       ps.updateDescription(pos, apfId, &updatedServiceDescription, &publishedService)
+       ps.updateDescription(&updatedServiceDescription, &publishedService)
 
        publishedService.AefProfiles = updatedServiceDescription.AefProfiles
        ps.publishedServices[apfId][pos] = publishedService
@@ -317,7 +318,7 @@ func (ps *PublishService) PutApfIdServiceApisServiceApiId(ctx echo.Context, apfI
        return nil
 }
 
-func (ps *PublishService) checkIfServiceIsPublished(apfId string, serviceApiId string, ctx echo.Context) (int, publishapi.ServiceAPIDescription, error) {
+func (ps *PublishService) checkIfServiceIsPublished(apfId string, serviceApiId string) (int, publishapi.ServiceAPIDescription, error) {
        publishedServices, ok := ps.publishedServices[apfId]
        if !ok {
                return 0, publishapi.ServiceAPIDescription{}, fmt.Errorf("service must be published before updating it")
@@ -340,7 +341,7 @@ func getServiceFromRequest(ctx echo.Context) (publishapi.ServiceAPIDescription,
        return updatedServiceDescription, nil
 }
 
-func (ps *PublishService) updateDescription(pos int, apfId string, updatedServiceDescription, publishedService *publishapi.ServiceAPIDescription) {
+func (ps *PublishService) updateDescription(updatedServiceDescription, publishedService *publishapi.ServiceAPIDescription) {
        if updatedServiceDescription.Description != nil {
                publishedService.Description = updatedServiceDescription.Description
                go ps.sendEvent(*publishedService, eventsapi.CAPIFEventSERVICEAPIUPDATE)
index e63243f..3f1a71f 100644 (file)
@@ -68,7 +68,6 @@ func TestUnregisteredService(t *testing.T) {
        assert.Equal(t, http.StatusNotFound, *resultError.Status)
 }
 
-
 func TestPublishUnpublishService(t *testing.T) {
 
        apfId := "apfId"
@@ -262,17 +261,13 @@ func TestGetPublishedServices(t *testing.T) {
 func TestGetAllowedServices(t *testing.T) {
        serviceUnderTest := NewPublishService(nil, nil, nil)
 
-       aefProfiles1 := []publishapi.AefProfile{
-       }
+       aefProfiles1 := []publishapi.AefProfile{}
        apiId1 := "apiId1"
-       aefProfiles2 := []publishapi.AefProfile{
-       }
+       aefProfiles2 := []publishapi.AefProfile{}
        apiId2 := "apiId2"
-       aefProfiles3 := []publishapi.AefProfile{
-       }
+       aefProfiles3 := []publishapi.AefProfile{}
        apiId3 := "apiId3"
-       aefProfiles4 := []publishapi.AefProfile{
-       }
+       aefProfiles4 := []publishapi.AefProfile{}
        apiId4 := "apiId4"
 
        serviceUnderTest.publishedServices["publisher1"] = []publishapi.ServiceAPIDescription{
@@ -315,6 +310,22 @@ func TestGetAllowedServices(t *testing.T) {
 
        result := serviceUnderTest.GetAllowedPublishedServices(allowedApiList)
        assert.Len(t, result, 2)
+
+       result = serviceUnderTest.GetAllowedPublishedServices(nil)
+       assert.Len(t, result, 0)
+
+       result = serviceUnderTest.GetAllowedPublishedServices([]publishapi.ServiceAPIDescription{})
+       assert.Len(t, result, 0)
+
+       // Create a list with no ApiIds
+       badApiList := []publishapi.ServiceAPIDescription{
+               {
+               },
+               {
+               },
+       }
+       result = serviceUnderTest.GetAllowedPublishedServices(badApiList)
+       assert.Len(t, result, 0)
 }
 
 func TestUpdateDescription(t *testing.T) {
index ddedc85..4437123 100644 (file)
@@ -2,7 +2,8 @@
 //   ========================LICENSE_START=================================
 //   O-RAN-SC
 //   %%
-//   Copyright (C) 2022: Nordix Foundation
+//   Copyright (C) 2022-2023: Nordix Foundation
+//   Copyright (C) 2024: OpenInfra Foundation Europe
 //   %%
 //   Licensed under the Apache License, Version 2.0 (the "License");
 //   you may not use this file except in compliance with the License.
@@ -240,7 +241,7 @@ func (s *Security) PostTrustedInvokersApiInvokerIdDelete(ctx echo.Context, apiIn
        }
 
        if ss, ok := s.trustedInvokers[apiInvokerId]; ok {
-               securityInfoCopy := s.revokeTrustedInvoker(&ss, notification, apiInvokerId)
+               securityInfoCopy := s.revokeTrustedInvoker(&ss, notification)
 
                if len(securityInfoCopy) == 0 {
                        s.deleteTrustedInvoker(apiInvokerId)
@@ -257,7 +258,7 @@ func (s *Security) PostTrustedInvokersApiInvokerIdDelete(ctx echo.Context, apiIn
 
 }
 
-func (s *Security) revokeTrustedInvoker(ss *securityapi.ServiceSecurity, notification securityapi.SecurityNotification, apiInvokerId string) []securityapi.SecurityInformation {
+func (s *Security) revokeTrustedInvoker(ss *securityapi.ServiceSecurity, notification securityapi.SecurityNotification) []securityapi.SecurityInformation {
 
        data, _ := copystructure.Copy(ss.SecurityInfo)
        securityInfoCopy, _ := data.([]securityapi.SecurityInformation)