Files
libopenapi/datamodel/low/base/security_requirement.go
Dave Shanley c3cf5f1e38 Added support for unevaluatedProperties as Schema and bool #118
Also ran `gofmt` across the entire project. Things need cleaning up.

Signed-off-by: Dave Shanley <dave@quobix.com>
2023-06-17 14:12:27 -04:00

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, "|")))
}