[Vault-4628] OpenAPI endpoint not expanding root alternations (#13487)

This commit is contained in:
Vinny Mannello 2021-12-22 15:36:47 -08:00 committed by GitHub
parent ef8e4008a8
commit 2680f0b198
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 9 deletions

3
changelog/13487.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:bug
sdk/framework: Generate proper OpenAPI specs for path patterns that use an alternation as the root.
```

View File

@ -191,15 +191,16 @@ var OASStdRespNoContent = &OASResponse{
var optRe = regexp.MustCompile(`(?U)\([^(]*\)\?|\(/\(\?P<[^(]*\)\)\?`)
var (
reqdRe = regexp.MustCompile(`\(?\?P<(\w+)>[^)]*\)?`) // Capture required parameters, e.g. "(?P<name>regex)"
altRe = regexp.MustCompile(`\((.*)\|(.*)\)`) // Capture alternation elements, e.g. "(raw/?$|raw/(?P<path>.+))"
pathFieldsRe = regexp.MustCompile(`{(\w+)}`) // Capture OpenAPI-style named parameters, e.g. "lookup/{urltoken}",
cleanCharsRe = regexp.MustCompile("[()^$?]") // Set of regex characters that will be stripped during cleaning
cleanSuffixRe = regexp.MustCompile(`/\?\$?$`) // Path suffix patterns that will be stripped during cleaning
wsRe = regexp.MustCompile(`\s+`) // Match whitespace, to be compressed during cleaning
altFieldsGroupRe = regexp.MustCompile(`\(\?P<\w+>\w+(\|\w+)+\)`) // Match named groups that limit options, e.g. "(?<foo>a|b|c)"
altFieldsRe = regexp.MustCompile(`\w+(\|\w+)+`) // Match an options set, e.g. "a|b|c"
nonWordRe = regexp.MustCompile(`[^\w]+`) // Match a sequence of non-word characters
altFieldsGroupRe = regexp.MustCompile(`\(\?P<\w+>\w+(\|\w+)+\)`) // Match named groups that limit options, e.g. "(?<foo>a|b|c)"
altFieldsRe = regexp.MustCompile(`\w+(\|\w+)+`) // Match an options set, e.g. "a|b|c"
altRe = regexp.MustCompile(`\((.*)\|(.*)\)`) // Capture alternation elements, e.g. "(raw/?$|raw/(?P<path>.+))"
altRootsRe = regexp.MustCompile(`^\(([\w\-_]+(?:\|[\w\-_]+)+)\)(/.*)$`) // Pattern starting with alts, e.g. "(root1|root2)/(?P<name>regex)"
cleanCharsRe = regexp.MustCompile("[()^$?]") // Set of regex characters that will be stripped during cleaning
cleanSuffixRe = regexp.MustCompile(`/\?\$?$`) // Path suffix patterns that will be stripped during cleaning
nonWordRe = regexp.MustCompile(`[^\w]+`) // Match a sequence of non-word characters
pathFieldsRe = regexp.MustCompile(`{(\w+)}`) // Capture OpenAPI-style named parameters, e.g. "lookup/{urltoken}",
reqdRe = regexp.MustCompile(`\(?\?P<(\w+)>[^)]*\)?`) // Capture required parameters, e.g. "(?P<name>regex)"
wsRe = regexp.MustCompile(`\s+`) // Match whitespace, to be compressed during cleaning
)
// documentPaths parses all paths in a framework.Backend into OpenAPI paths.
@ -464,6 +465,17 @@ func specialPathMatch(path string, specialPaths []string) bool {
func expandPattern(pattern string) []string {
var paths []string
// Determine if the pattern starts with an alternation for multiple roots
// example (root1|root2)/(?P<name>regex) -> match['(root1|root2)/(?P<name>regex)','root1|root2','/(?P<name>regex)']
match := altRootsRe.FindStringSubmatch(pattern)
if len(match) == 3 {
var expandedRoots []string
for _, root := range strings.Split(match[1], "|") {
expandedRoots = append(expandedRoots, expandPattern(root+match[2])...)
}
return expandedRoots
}
// GenericNameRegex adds a regex that complicates our parsing. It is much easier to
// detect and remove it now than to compensate for in the other regexes.
//

View File

@ -199,6 +199,10 @@ func TestOpenAPI_ExpandPattern(t *testing.T) {
{"^plugins/catalog/(?P<type>auth|database|secret)/?$", []string{
"plugins/catalog/{type}",
}},
{"(pathOne|pathTwo)/", []string{"pathOne/", "pathTwo/"}},
{"(pathOne|pathTwo)/" + GenericNameRegex("name"), []string{"pathOne/{name}", "pathTwo/{name}"}},
{"(pathOne|path-2|Path_3)/" + GenericNameRegex("name"),
[]string{"Path_3/{name}", "path-2/{name}", "pathOne/{name}"}},
}
for i, test := range tests {