mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-06 04:20:11 +00:00
Also ran `gofmt` across the entire project. Things need cleaning up. Signed-off-by: Dave Shanley <dave@quobix.com>
105 lines
3.4 KiB
Go
105 lines
3.4 KiB
Go
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package base
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"fmt"
|
|
"github.com/pb33f/libopenapi/datamodel/low"
|
|
"github.com/pb33f/libopenapi/index"
|
|
"gopkg.in/yaml.v3"
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
// SecurityRequirement is a low-level representation of a Swagger / OpenAPI 3 SecurityRequirement object.
|
|
//
|
|
// SecurityRequirement lists the required security schemes to execute this operation. The object can have multiple
|
|
// security schemes declared in it which are all required (that is, there is a logical AND between the schemes).
|
|
//
|
|
// The name used for each property MUST correspond to a security scheme declared in the Security Definitions
|
|
// - https://swagger.io/specification/v2/#securityDefinitionsObject
|
|
// - https://swagger.io/specification/#security-requirement-object
|
|
type SecurityRequirement struct {
|
|
Requirements low.ValueReference[map[low.KeyReference[string]]low.ValueReference[[]low.ValueReference[string]]]
|
|
*low.Reference
|
|
}
|
|
|
|
// Build will extract security requirements from the node (the structure is odd, to be honest)
|
|
func (s *SecurityRequirement) Build(root *yaml.Node, _ *index.SpecIndex) error {
|
|
s.Reference = new(low.Reference)
|
|
var labelNode *yaml.Node
|
|
valueMap := make(map[low.KeyReference[string]]low.ValueReference[[]low.ValueReference[string]])
|
|
var arr []low.ValueReference[string]
|
|
for i := range root.Content {
|
|
if i%2 == 0 {
|
|
labelNode = root.Content[i]
|
|
arr = []low.ValueReference[string]{} // reset roles.
|
|
continue
|
|
}
|
|
for j := range root.Content[i].Content {
|
|
arr = append(arr, low.ValueReference[string]{
|
|
Value: root.Content[i].Content[j].Value,
|
|
ValueNode: root.Content[i].Content[j],
|
|
})
|
|
}
|
|
valueMap[low.KeyReference[string]{
|
|
Value: labelNode.Value,
|
|
KeyNode: labelNode,
|
|
}] = low.ValueReference[[]low.ValueReference[string]]{
|
|
Value: arr,
|
|
ValueNode: root.Content[i],
|
|
}
|
|
}
|
|
s.Requirements = low.ValueReference[map[low.KeyReference[string]]low.ValueReference[[]low.ValueReference[string]]]{
|
|
Value: valueMap,
|
|
ValueNode: root,
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// FindRequirement will attempt to locate a security requirement string from a supplied name.
|
|
func (s *SecurityRequirement) FindRequirement(name string) []low.ValueReference[string] {
|
|
for k := range s.Requirements.Value {
|
|
if k.Value == name {
|
|
return s.Requirements.Value[k].Value
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetKeys returns a string slice of all the keys used in the requirement.
|
|
func (s *SecurityRequirement) GetKeys() []string {
|
|
keys := make([]string, len(s.Requirements.Value))
|
|
z := 0
|
|
for k := range s.Requirements.Value {
|
|
keys[z] = k.Value
|
|
}
|
|
return keys
|
|
}
|
|
|
|
// Hash will return a consistent SHA256 Hash of the SecurityRequirement object
|
|
func (s *SecurityRequirement) Hash() [32]byte {
|
|
var f []string
|
|
values := make(map[string][]string, len(s.Requirements.Value))
|
|
var valKeys []string
|
|
for k := range s.Requirements.Value {
|
|
var vals []string
|
|
for y := range s.Requirements.Value[k].Value {
|
|
vals = append(vals, s.Requirements.Value[k].Value[y].Value)
|
|
// lol, I know. -------^^^^^ <- this is the actual value.
|
|
}
|
|
sort.Strings(vals)
|
|
valKeys = append(valKeys, k.Value)
|
|
if len(vals) > 0 {
|
|
values[k.Value] = vals
|
|
}
|
|
}
|
|
sort.Strings(valKeys)
|
|
for val := range valKeys {
|
|
f = append(f, fmt.Sprintf("%s-%s", valKeys[val], strings.Join(values[valKeys[val]], "|")))
|
|
}
|
|
return sha256.Sum256([]byte(strings.Join(f, "|")))
|
|
}
|