Roll versions after J-Relase (master branch)
[nonrtric/plt/sme.git] / capifcore / internal / securityservice / security_test.go
index d31ff6e..ea0fbe6 100644 (file)
@@ -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 {