@@ -3,6 +3,7 @@ package oas
3
3
import (
4
4
"context"
5
5
"encoding/json"
6
+ "fmt"
6
7
"net/http"
7
8
"testing"
8
9
@@ -1294,6 +1295,169 @@ func TestAPIContext_getValidationOptionsFromConfig(t *testing.T) {
1294
1295
})
1295
1296
}
1296
1297
1298
+ func TestOAS_ValidateSecurity (t * testing.T ) {
1299
+ apiKey := "api_key"
1300
+ oauth2 := "oauth2"
1301
+
1302
+ createSecurityReq := func (oas * OAS , key string , value []string ) {
1303
+ securityRequirement := openapi3 .NewSecurityRequirement ()
1304
+ securityRequirement [key ] = value
1305
+ oas .Security = append (oas .Security , securityRequirement )
1306
+ }
1307
+
1308
+ addSingleSecurityReq := func (oas * OAS ) {
1309
+ createSecurityReq (oas , apiKey , []string {})
1310
+ }
1311
+
1312
+ addMultipleSecurityReq := func (oas * OAS ) {
1313
+ addSingleSecurityReq (oas )
1314
+ createSecurityReq (oas , oauth2 , []string {"read" , "write" })
1315
+ }
1316
+
1317
+ expectedErrorForNoComponentOrSchemes := "No components or security schemes present in OAS"
1318
+ expectedErrorForMissingSchema := func (s string ) string {
1319
+ return fmt .Sprintf ("Missing required Security Scheme '%s' in Components.SecuritySchemes" , s )
1320
+ }
1321
+
1322
+ tests := []struct {
1323
+ name string
1324
+ setupOAS func (oas * OAS )
1325
+ expectedError string
1326
+ }{
1327
+ {
1328
+ name : "no security requirements" ,
1329
+ setupOAS : func (oas * OAS ) {
1330
+ oas .Security = openapi3.SecurityRequirements {}
1331
+ },
1332
+ expectedError : "" ,
1333
+ },
1334
+ {
1335
+ name : "security requirements with matching security schemes" ,
1336
+ setupOAS : func (oas * OAS ) {
1337
+ addSingleSecurityReq (oas )
1338
+
1339
+ if oas .Components == nil {
1340
+ oas .Components = & openapi3.Components {}
1341
+ }
1342
+ if oas .Components .SecuritySchemes == nil {
1343
+ oas .Components .SecuritySchemes = make (openapi3.SecuritySchemes )
1344
+ }
1345
+ oas .Components .SecuritySchemes [apiKey ] = & openapi3.SecuritySchemeRef {
1346
+ Value : openapi3 .NewJWTSecurityScheme (),
1347
+ }
1348
+ },
1349
+ expectedError : "" ,
1350
+ },
1351
+ {
1352
+ name : "security requirements but no Components" ,
1353
+ setupOAS : func (oas * OAS ) {
1354
+ addSingleSecurityReq (oas )
1355
+
1356
+ oas .Components = nil
1357
+ },
1358
+ expectedError : expectedErrorForNoComponentOrSchemes ,
1359
+ },
1360
+ {
1361
+ name : "security requirements but no SecuritySchemes" ,
1362
+ setupOAS : func (oas * OAS ) {
1363
+ addSingleSecurityReq (oas )
1364
+
1365
+ // Add Components but not SecuritySchemes
1366
+ oas .Components = & openapi3.Components {}
1367
+ oas .Components .SecuritySchemes = nil
1368
+ },
1369
+ expectedError : expectedErrorForNoComponentOrSchemes ,
1370
+ },
1371
+ {
1372
+ name : "security requirements but empty SecuritySchemes" ,
1373
+ setupOAS : func (oas * OAS ) {
1374
+ addSingleSecurityReq (oas )
1375
+
1376
+ oas .Components = & openapi3.Components {}
1377
+ oas .Components .SecuritySchemes = make (openapi3.SecuritySchemes )
1378
+ },
1379
+ expectedError : expectedErrorForNoComponentOrSchemes ,
1380
+ },
1381
+ {
1382
+ name : "security requirements with missing security scheme for this requirement" ,
1383
+ setupOAS : func (oas * OAS ) {
1384
+ addSingleSecurityReq (oas )
1385
+
1386
+ if oas .Components == nil {
1387
+ oas .Components = & openapi3.Components {}
1388
+ }
1389
+ if oas .Components .SecuritySchemes == nil {
1390
+ oas .Components .SecuritySchemes = make (openapi3.SecuritySchemes )
1391
+ }
1392
+ oas .Components .SecuritySchemes ["other_key" ] = & openapi3.SecuritySchemeRef {
1393
+ Value : openapi3 .NewJWTSecurityScheme (),
1394
+ }
1395
+ },
1396
+ expectedError : expectedErrorForMissingSchema (apiKey ),
1397
+ },
1398
+ {
1399
+ name : "multiple security requirements with all matching security schemes" ,
1400
+ setupOAS : func (oas * OAS ) {
1401
+ addMultipleSecurityReq (oas )
1402
+
1403
+ if oas .Components == nil {
1404
+ oas .Components = & openapi3.Components {}
1405
+ }
1406
+ if oas .Components .SecuritySchemes == nil {
1407
+ oas .Components .SecuritySchemes = make (openapi3.SecuritySchemes )
1408
+ }
1409
+ oas .Components .SecuritySchemes [apiKey ] = & openapi3.SecuritySchemeRef {
1410
+ Value : openapi3 .NewJWTSecurityScheme (),
1411
+ }
1412
+ oas .Components .SecuritySchemes [oauth2 ] = & openapi3.SecuritySchemeRef {
1413
+ Value : openapi3 .NewJWTSecurityScheme (),
1414
+ }
1415
+ },
1416
+ expectedError : "" ,
1417
+ },
1418
+ {
1419
+ name : "multiple security requirements with one missing security scheme" ,
1420
+ setupOAS : func (oas * OAS ) {
1421
+ addMultipleSecurityReq (oas )
1422
+
1423
+ if oas .Components == nil {
1424
+ oas .Components = & openapi3.Components {}
1425
+ }
1426
+ if oas .Components .SecuritySchemes == nil {
1427
+ oas .Components .SecuritySchemes = make (openapi3.SecuritySchemes )
1428
+ }
1429
+ oas .Components .SecuritySchemes [apiKey ] = & openapi3.SecuritySchemeRef {}
1430
+ },
1431
+ expectedError : expectedErrorForMissingSchema (oauth2 ),
1432
+ },
1433
+ }
1434
+
1435
+ for _ , tt := range tests {
1436
+ t .Run (tt .name , func (t * testing.T ) {
1437
+ oas := & OAS {
1438
+ T : openapi3.T {
1439
+ OpenAPI : "3.0.3" ,
1440
+ Info : & openapi3.Info {
1441
+ Title : "Test API" ,
1442
+ Version : "1.0.0" ,
1443
+ },
1444
+ Paths : openapi3.Paths {},
1445
+ },
1446
+ }
1447
+
1448
+ tt .setupOAS (oas )
1449
+
1450
+ err := oas .Validate (context .Background ())
1451
+ if tt .expectedError == "" {
1452
+ assert .NoError (t , err )
1453
+ } else {
1454
+ assert .Error (t , err )
1455
+ assert .Contains (t , err .Error (), tt .expectedError )
1456
+ }
1457
+ })
1458
+ }
1459
+ }
1460
+
1297
1461
func TestYaml (t * testing.T ) {
1298
1462
oasDoc := OAS {}
1299
1463
Fill (t , & oasDoc , 0 )
0 commit comments