mirror of
https://github.com/hashicorp/vault.git
synced 2026-05-05 04:16:31 +02:00
Update OpenAPI path parsing of alternation parameters (#5710)
This will handle patterns of the form: `^plugins/catalog/(?P<type>auth|database|secret)/(?P<name>.+)$`
This commit is contained in:
parent
1a31603dcf
commit
583003cf42
@ -177,12 +177,14 @@ var OASStdRespNoContent = &OASResponse{
|
||||
// Both "(leases/)?renew" and "(/(?P<name>.+))?" formats are detected
|
||||
var optRe = regexp.MustCompile(`(?U)\([^(]*\)\?|\(/\(\?P<[^(]*\)\)\?`)
|
||||
|
||||
var reqdRe = regexp.MustCompile(`\(?\?P<(\w+)>[^)]*\)?`) // Capture required parameters, e.g. "(?P<name>regex)"
|
||||
var altRe = regexp.MustCompile(`\((.*)\|(.*)\)`) // Capture alternation elements, e.g. "(raw/?$|raw/(?P<path>.+))"
|
||||
var pathFieldsRe = regexp.MustCompile(`{(\w+)}`) // Capture OpenAPI-style named parameters, e.g. "lookup/{urltoken}",
|
||||
var cleanCharsRe = regexp.MustCompile("[()^$?]") // Set of regex characters that will be stripped during cleaning
|
||||
var cleanSuffixRe = regexp.MustCompile(`/\?\$?$`) // Path suffix patterns that will be stripped during cleaning
|
||||
var wsRe = regexp.MustCompile(`\s+`) // Match whitespace, to be compressed during cleaning
|
||||
var reqdRe = regexp.MustCompile(`\(?\?P<(\w+)>[^)]*\)?`) // Capture required parameters, e.g. "(?P<name>regex)"
|
||||
var altRe = regexp.MustCompile(`\((.*)\|(.*)\)`) // Capture alternation elements, e.g. "(raw/?$|raw/(?P<path>.+))"
|
||||
var pathFieldsRe = regexp.MustCompile(`{(\w+)}`) // Capture OpenAPI-style named parameters, e.g. "lookup/{urltoken}",
|
||||
var cleanCharsRe = regexp.MustCompile("[()^$?]") // Set of regex characters that will be stripped during cleaning
|
||||
var cleanSuffixRe = regexp.MustCompile(`/\?\$?$`) // Path suffix patterns that will be stripped during cleaning
|
||||
var wsRe = regexp.MustCompile(`\s+`) // Match whitespace, to be compressed during cleaning
|
||||
var altFieldsGroupRe = regexp.MustCompile(`\(\?P<\w+>\w+(\|\w+)+\)`) // Match named groups that limit options, e.g. "(?<foo>a|b|c)"
|
||||
var altFieldsRe = regexp.MustCompile(`\w+(\|\w+)+`) // Match an options set, e.g. "a|b|c"
|
||||
|
||||
// documentPaths parses all paths in a framework.Backend into OpenAPI paths.
|
||||
func documentPaths(backend *Backend, doc *OASDocument) error {
|
||||
@ -446,9 +448,13 @@ func expandPattern(pattern string) []string {
|
||||
if start != -1 && end != -1 && end > start {
|
||||
regexToRemove = base[start+1 : end]
|
||||
}
|
||||
|
||||
pattern = strings.Replace(pattern, regexToRemove, "", -1)
|
||||
|
||||
// Simplify named fields that have limited options, e.g. (?P<foo>a|b|c) -> (<P<foo>.+)
|
||||
pattern = altFieldsGroupRe.ReplaceAllStringFunc(pattern, func(s string) string {
|
||||
return altFieldsRe.ReplaceAllString(s, ".+")
|
||||
})
|
||||
|
||||
// Initialize paths with the original pattern or the halves of an
|
||||
// alternation, which is also present in some patterns.
|
||||
matches := altRe.FindAllStringSubmatch(pattern, -1)
|
||||
|
||||
@ -74,6 +74,18 @@ func TestOpenAPI_Regex(t *testing.T) {
|
||||
t.Fatalf("Expected nil match (%s), got %+v", input, matches)
|
||||
}
|
||||
})
|
||||
t.Run("Alternation Fields", func(t *testing.T) {
|
||||
input := `/foo/bar/(?P<type>auth|database|secret)/(?P<blah>a|b)`
|
||||
|
||||
act := altFieldsGroupRe.ReplaceAllStringFunc(input, func(s string) string {
|
||||
return altFieldsRe.ReplaceAllString(s, ".+")
|
||||
})
|
||||
|
||||
exp := "/foo/bar/(?P<type>.+)/(?P<blah>.+)"
|
||||
if act != exp {
|
||||
t.Fatalf("Replace error. Expected %s, got %v", exp, act)
|
||||
}
|
||||
})
|
||||
t.Run("Path fields", func(t *testing.T) {
|
||||
input := `/foo/bar/{inner}/baz/{outer}`
|
||||
|
||||
@ -180,6 +192,12 @@ func TestOpenAPI_ExpandPattern(t *testing.T) {
|
||||
"verify/{name}",
|
||||
"verify/{name}/{urlalgorithm}",
|
||||
}},
|
||||
{"^plugins/catalog/(?P<type>auth|database|secret)/(?P<name>.+)$", []string{
|
||||
"plugins/catalog/{type}/{name}",
|
||||
}},
|
||||
{"^plugins/catalog/(?P<type>auth|database|secret)/?$", []string{
|
||||
"plugins/catalog/{type}",
|
||||
}},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user