Skip to content

Commit

Permalink
fix: fix cleanup of securitySchemes (#10)
Browse files Browse the repository at this point in the history
Fix lookup of references to securitySchemes before cleaning it.

/components/securitySchemes are not referenced by $ref like other components.
We now implement the correct algorithm to lookup for references before cleaning:
- look for references in Security Requirements in /security
- look for references in Security Requirements in /paths/<path>/<method>/security
  • Loading branch information
dolmen committed Dec 8, 2024
1 parent 7a348f4 commit c16c459
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 0 deletions.
32 changes: 32 additions & 0 deletions testdata/80-unused-securitySchemes-01/input.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
openapi: "3.1.1"
info:
version: "0.0.1"
security:
- {}
- {
"api-key": []
}
paths:
/:
get:
responses:
404:
description: Not found.
security:
- { "api-key-cookie": [] }
- {}
components:
securitySchemes:
unused:
type: apiKey
in: header
name: unused
api-key:
type: apiKey
in: header
name: Api-Key
api-key-cookie:
type: apiKey
in: cookie
name: apiKey
43 changes: 43 additions & 0 deletions testdata/80-unused-securitySchemes-01/result.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"openapi": "3.1.1",
"info": {
"version": "0.0.1"
},
"security": [
{},
{
"api-key": []
}
],
"paths": {
"/": {
"get": {
"responses": {
"404": {
"description": "Not found."
}
},
"security": [
{
"api-key-cookie": []
},
{}
]
}
}
},
"components": {
"securitySchemes": {
"api-key": {
"in": "header",
"name": "Api-Key",
"type": "apiKey"
},
"api-key-cookie": {
"in": "cookie",
"name": "apiKey",
"type": "apiKey"
}
}
}
}
24 changes: 24 additions & 0 deletions unused.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,29 @@ func CleanUnused(rdoc *interface{}) error {
return err
}

// If there are securitySchemes components, look for references.
if secSchemesAny, err := jsonptr.Get(*rdoc, `/components/securitySchemes`); err == nil {
if secSchemes, isObj := secSchemesAny.(map[string]any); isObj && len(secSchemes) > 0 {

markUsedSecuritySchemes := func(ptr string, doc map[string]any) {
for _, req := range iterSecurity(ptr, doc) {
// https://spec.openapis.org/oas/v3.1.1.html#security-requirement-object
for name := range req {
// fmt.Println("used: " + `/components/securitySchemes/` + jsonptr.EscapeString(name))
// TODO: signal if the securityScheme is not present in /components/securitySchemes
delete(unused, `/components/securitySchemes/`+jsonptr.EscapeString(name))
}
}
}

markUsedSecuritySchemes(``, root) // process /security
// https://spec.openapis.org/oas/v3.1.1.html#operation-object
for ptr, op := range iterOperations(root) {
markUsedSecuritySchemes(ptr, op) // process /paths/<path>/<method>/security
}
}
}

nextUnused:
for p := range unused {
// Look for deep references in unused schemas
Expand All @@ -135,6 +158,7 @@ func CleanUnused(rdoc *interface{}) error {
removeEmptyObject(rdoc, `/components/schemas`)
removeEmptyObject(rdoc, `/components/parameters`)
removeEmptyObject(rdoc, `/components/responses`)
removeEmptyObject(rdoc, `/components/securitySchemes`)
removeEmptyObject(rdoc, `/components`)
removeEmptyObject(rdoc, `/definitions`)
removeEmptyObject(rdoc, `/parameters`)
Expand Down
7 changes: 7 additions & 0 deletions unused_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package main

import "testing"

func TestUnusedSecuritySchemes01(t *testing.T) {
runExpandRefs(t, "testdata/80-unused-securityschemes-01")
}

0 comments on commit c16c459

Please sign in to comment.