2 // ========================LICENSE_START=================================
5 // Copyright (C) 2022: Nordix Foundation
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 // ========================LICENSE_END===================================
30 "oransc.org/nonrtric/capifcore/internal/securityapi"
32 "oransc.org/nonrtric/capifcore/internal/invokermanagement"
33 "oransc.org/nonrtric/capifcore/internal/providermanagement"
34 "oransc.org/nonrtric/capifcore/internal/publishservice"
36 "github.com/labstack/echo/v4"
38 invokermocks "oransc.org/nonrtric/capifcore/internal/invokermanagement/mocks"
39 servicemocks "oransc.org/nonrtric/capifcore/internal/providermanagement/mocks"
40 publishmocks "oransc.org/nonrtric/capifcore/internal/publishservice/mocks"
42 "github.com/deepmap/oapi-codegen/pkg/middleware"
43 "github.com/deepmap/oapi-codegen/pkg/testutil"
44 echomiddleware "github.com/labstack/echo/v4/middleware"
45 "github.com/stretchr/testify/assert"
46 "github.com/stretchr/testify/mock"
49 func TestPostSecurityIdTokenInvokerRegistered(t *testing.T) {
50 invokerRegisterMock := invokermocks.InvokerRegister{}
51 invokerRegisterMock.On("IsInvokerRegistered", mock.AnythingOfType("string")).Return(true)
52 invokerRegisterMock.On("VerifyInvokerSecret", mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return(true)
53 serviceRegisterMock := servicemocks.ServiceRegister{}
54 serviceRegisterMock.On("IsFunctionRegistered", mock.AnythingOfType("string")).Return(true)
55 publishRegisterMock := publishmocks.PublishRegister{}
56 publishRegisterMock.On("IsAPIPublished", mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return(true)
58 requestHandler := getEcho(&serviceRegisterMock, &publishRegisterMock, &invokerRegisterMock)
62 clientSecret := "secret"
65 data.Set("client_id", clientId)
66 data.Set("client_secret", clientSecret)
67 data.Set("grant_type", "client_credentials")
68 data.Set("scope", "3gpp#"+aefId+":"+path)
70 encodedData := data.Encode()
72 result := testutil.NewRequest().Post("/securities/invokerId/token").WithContentType("application/x-www-form-urlencoded").WithBody([]byte(encodedData)).Go(t, requestHandler)
74 assert.Equal(t, http.StatusCreated, result.Code())
75 var resultResponse securityapi.AccessTokenRsp
76 err := result.UnmarshalBodyToObject(&resultResponse)
77 assert.NoError(t, err, "error unmarshaling response")
78 assert.NotEmpty(t, resultResponse.AccessToken)
79 assert.Equal(t, "3gpp#"+aefId+":"+path, *resultResponse.Scope)
80 assert.Equal(t, securityapi.AccessTokenRspTokenTypeBearer, resultResponse.TokenType)
81 invokerRegisterMock.AssertCalled(t, "IsInvokerRegistered", clientId)
82 invokerRegisterMock.AssertCalled(t, "VerifyInvokerSecret", clientId, clientSecret)
83 serviceRegisterMock.AssertCalled(t, "IsFunctionRegistered", aefId)
84 publishRegisterMock.AssertCalled(t, "IsAPIPublished", aefId, path)
87 func TestPostSecurityIdTokenInvokerNotRegistered(t *testing.T) {
88 invokerRegisterMock := invokermocks.InvokerRegister{}
89 invokerRegisterMock.On("IsInvokerRegistered", mock.AnythingOfType("string")).Return(false)
91 requestHandler := getEcho(nil, nil, &invokerRegisterMock)
94 data.Set("client_id", "id")
95 data.Add("client_secret", "secret")
96 data.Add("grant_type", "client_credentials")
97 data.Add("scope", "3gpp#aefId:path")
98 encodedData := data.Encode()
100 result := testutil.NewRequest().Post("/securities/invokerId/token").WithContentType("application/x-www-form-urlencoded").WithBody([]byte(encodedData)).Go(t, requestHandler)
102 assert.Equal(t, http.StatusBadRequest, result.Code())
103 var errDetails securityapi.AccessTokenErr
104 err := result.UnmarshalBodyToObject(&errDetails)
105 assert.NoError(t, err, "error unmarshaling response")
106 assert.Equal(t, securityapi.AccessTokenErrErrorInvalidClient, errDetails.Error)
107 errMsg := "Invoker not registered"
108 assert.Equal(t, &errMsg, errDetails.ErrorDescription)
111 func TestPostSecurityIdTokenInvokerSecretNotValid(t *testing.T) {
112 invokerRegisterMock := invokermocks.InvokerRegister{}
113 invokerRegisterMock.On("IsInvokerRegistered", mock.AnythingOfType("string")).Return(true)
114 invokerRegisterMock.On("VerifyInvokerSecret", mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return(false)
116 requestHandler := getEcho(nil, nil, &invokerRegisterMock)
119 data.Set("client_id", "id")
120 data.Add("client_secret", "secret")
121 data.Add("grant_type", "client_credentials")
122 data.Add("scope", "3gpp#aefId:path")
123 encodedData := data.Encode()
125 result := testutil.NewRequest().Post("/securities/invokerId/token").WithContentType("application/x-www-form-urlencoded").WithBody([]byte(encodedData)).Go(t, requestHandler)
127 assert.Equal(t, http.StatusBadRequest, result.Code())
128 var errDetails securityapi.AccessTokenErr
129 err := result.UnmarshalBodyToObject(&errDetails)
130 assert.NoError(t, err, "error unmarshaling response")
131 assert.Equal(t, securityapi.AccessTokenErrErrorUnauthorizedClient, errDetails.Error)
132 errMsg := "Invoker secret not valid"
133 assert.Equal(t, &errMsg, errDetails.ErrorDescription)
136 func TestPostSecurityIdTokenFunctionNotRegistered(t *testing.T) {
137 invokerRegisterMock := invokermocks.InvokerRegister{}
138 invokerRegisterMock.On("IsInvokerRegistered", mock.AnythingOfType("string")).Return(true)
139 invokerRegisterMock.On("VerifyInvokerSecret", mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return(true)
140 serviceRegisterMock := servicemocks.ServiceRegister{}
141 serviceRegisterMock.On("IsFunctionRegistered", mock.AnythingOfType("string")).Return(false)
143 requestHandler := getEcho(&serviceRegisterMock, nil, &invokerRegisterMock)
146 data.Set("client_id", "id")
147 data.Add("client_secret", "secret")
148 data.Add("grant_type", "client_credentials")
149 data.Add("scope", "3gpp#aefId:path")
150 encodedData := data.Encode()
152 result := testutil.NewRequest().Post("/securities/invokerId/token").WithContentType("application/x-www-form-urlencoded").WithBody([]byte(encodedData)).Go(t, requestHandler)
154 assert.Equal(t, http.StatusBadRequest, result.Code())
155 var errDetails securityapi.AccessTokenErr
156 err := result.UnmarshalBodyToObject(&errDetails)
157 assert.NoError(t, err, "error unmarshaling response")
158 assert.Equal(t, securityapi.AccessTokenErrErrorInvalidScope, errDetails.Error)
159 errMsg := "AEF Function not registered"
160 assert.Equal(t, &errMsg, errDetails.ErrorDescription)
163 func TestPostSecurityIdTokenAPINotPublished(t *testing.T) {
164 invokerRegisterMock := invokermocks.InvokerRegister{}
165 invokerRegisterMock.On("IsInvokerRegistered", mock.AnythingOfType("string")).Return(true)
166 invokerRegisterMock.On("VerifyInvokerSecret", mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return(true)
167 serviceRegisterMock := servicemocks.ServiceRegister{}
168 serviceRegisterMock.On("IsFunctionRegistered", mock.AnythingOfType("string")).Return(true)
169 publishRegisterMock := publishmocks.PublishRegister{}
170 publishRegisterMock.On("IsAPIPublished", mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return(false)
172 requestHandler := getEcho(&serviceRegisterMock, &publishRegisterMock, &invokerRegisterMock)
175 data.Set("client_id", "id")
176 data.Add("client_secret", "secret")
177 data.Add("grant_type", "client_credentials")
178 data.Add("scope", "3gpp#aefId:path")
179 encodedData := data.Encode()
181 result := testutil.NewRequest().Post("/securities/invokerId/token").WithContentType("application/x-www-form-urlencoded").WithBody([]byte(encodedData)).Go(t, requestHandler)
183 assert.Equal(t, http.StatusBadRequest, result.Code())
184 var errDetails securityapi.AccessTokenErr
185 err := result.UnmarshalBodyToObject(&errDetails)
186 assert.NoError(t, err, "error unmarshaling response")
187 assert.Equal(t, securityapi.AccessTokenErrErrorInvalidScope, errDetails.Error)
188 errMsg := "API not published"
189 assert.Equal(t, &errMsg, errDetails.ErrorDescription)
192 func getEcho(serviceRegister providermanagement.ServiceRegister, publishRegister publishservice.PublishRegister, invokerRegister invokermanagement.InvokerRegister) *echo.Echo {
193 swagger, err := securityapi.GetSwagger()
195 fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err)
199 swagger.Servers = nil
201 s := NewSecurity(serviceRegister, publishRegister, invokerRegister)
204 e.Use(echomiddleware.Logger())
205 e.Use(middleware.OapiRequestValidator(swagger))
207 securityapi.RegisterHandlers(e, s)