mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-07 12:37:48 +00:00
Refactored SecurityRequirement **breaking change**
The v3 model is wrong and out of sync with the spec. It's been corrected, so the v2 and v2 model for SecurityRequirement have been collapsed down into a base model., they are the same data structures. This has allowed me to delete the complexity of sharing two different models for the same structure, by unifying the model correctly. I am not sure why I decided to change the v3 model, oh well, its been corrected. Long live swagger!
This commit is contained in:
@@ -1,9 +1,11 @@
|
|||||||
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
|
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
package v2
|
package base
|
||||||
|
|
||||||
import low "github.com/pb33f/libopenapi/datamodel/low/v2"
|
import (
|
||||||
|
"github.com/pb33f/libopenapi/datamodel/low/base"
|
||||||
|
)
|
||||||
|
|
||||||
// SecurityRequirement is a high-level representation of a Swagger / OpenAPI 2 SecurityRequirement object.
|
// SecurityRequirement is a high-level representation of a Swagger / OpenAPI 2 SecurityRequirement object.
|
||||||
//
|
//
|
||||||
@@ -14,19 +16,19 @@ import low "github.com/pb33f/libopenapi/datamodel/low/v2"
|
|||||||
// - https://swagger.io/specification/v2/#securityDefinitionsObject
|
// - https://swagger.io/specification/v2/#securityDefinitionsObject
|
||||||
type SecurityRequirement struct {
|
type SecurityRequirement struct {
|
||||||
Requirements map[string][]string
|
Requirements map[string][]string
|
||||||
low *low.SecurityRequirement
|
low *base.SecurityRequirement
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSecurityRequirement creates a new high-level SecurityRequirement from a low-level one.
|
// NewSecurityRequirement creates a new high-level SecurityRequirement from a low-level one.
|
||||||
func NewSecurityRequirement(req *low.SecurityRequirement) *SecurityRequirement {
|
func NewSecurityRequirement(req *base.SecurityRequirement) *SecurityRequirement {
|
||||||
r := new(SecurityRequirement)
|
r := new(SecurityRequirement)
|
||||||
r.low = req
|
r.low = req
|
||||||
values := make(map[string][]string)
|
values := make(map[string][]string)
|
||||||
// to keep things fast, avoiding copying anything - makes it a little hard to read.
|
// to keep things fast, avoiding copying anything - makes it a little hard to read.
|
||||||
for reqK := range req.Values.Value {
|
for reqK := range req.Requirements.Value {
|
||||||
var vals []string
|
var vals []string
|
||||||
for valK := range req.Values.Value[reqK].Value {
|
for valK := range req.Requirements.Value[reqK].Value {
|
||||||
vals = append(vals, req.Values.Value[reqK].Value[valK].Value)
|
vals = append(vals, req.Requirements.Value[reqK].Value[valK].Value)
|
||||||
}
|
}
|
||||||
values[reqK.Value] = vals
|
values[reqK.Value] = vals
|
||||||
}
|
}
|
||||||
@@ -35,6 +37,6 @@ func NewSecurityRequirement(req *low.SecurityRequirement) *SecurityRequirement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GoLow returns the low-level SecurityRequirement used to create the high-level one.
|
// GoLow returns the low-level SecurityRequirement used to create the high-level one.
|
||||||
func (s *SecurityRequirement) GoLow() *low.SecurityRequirement {
|
func (s *SecurityRequirement) GoLow() *base.SecurityRequirement {
|
||||||
return s.low
|
return s.low
|
||||||
}
|
}
|
||||||
@@ -24,7 +24,7 @@ type Operation struct {
|
|||||||
Responses *Responses
|
Responses *Responses
|
||||||
Schemes []string
|
Schemes []string
|
||||||
Deprecated bool
|
Deprecated bool
|
||||||
Security []*SecurityRequirement
|
Security []*base.SecurityRequirement
|
||||||
Extensions map[string]any
|
Extensions map[string]any
|
||||||
low *low.Operation
|
low *low.Operation
|
||||||
}
|
}
|
||||||
@@ -88,9 +88,9 @@ func NewOperation(operation *low.Operation) *Operation {
|
|||||||
o.Deprecated = operation.Deprecated.Value
|
o.Deprecated = operation.Deprecated.Value
|
||||||
}
|
}
|
||||||
if !operation.Security.IsEmpty() {
|
if !operation.Security.IsEmpty() {
|
||||||
var sec []*SecurityRequirement
|
var sec []*base.SecurityRequirement
|
||||||
for s := range operation.Security.Value {
|
for s := range operation.Security.Value {
|
||||||
sec = append(sec, NewSecurityRequirement(operation.Security.Value[s].Value))
|
sec = append(sec, base.NewSecurityRequirement(operation.Security.Value[s].Value))
|
||||||
}
|
}
|
||||||
o.Security = sec
|
o.Security = sec
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ type Swagger struct {
|
|||||||
// The basePath does not support path templating.
|
// The basePath does not support path templating.
|
||||||
BasePath string
|
BasePath string
|
||||||
|
|
||||||
// Schemes represents the transfer protocol of the API. Values MUST be from the list: "http", "https", "ws", "wss".
|
// Schemes represents the transfer protocol of the API. Requirements MUST be from the list: "http", "https", "ws", "wss".
|
||||||
// If the schemes is not included, the default scheme to be used is the one used to access
|
// If the schemes is not included, the default scheme to be used is the one used to access
|
||||||
// the Swagger definition itself.
|
// the Swagger definition itself.
|
||||||
Schemes []string
|
Schemes []string
|
||||||
@@ -77,7 +77,7 @@ type Swagger struct {
|
|||||||
// describes alternative security schemes that can be used (that is, there is a logical OR between the security
|
// describes alternative security schemes that can be used (that is, there is a logical OR between the security
|
||||||
// requirements). Individual operations can override this definition.
|
// requirements). Individual operations can override this definition.
|
||||||
// - https://swagger.io/specification/v2/#securityRequirementObject
|
// - https://swagger.io/specification/v2/#securityRequirementObject
|
||||||
Security []*SecurityRequirement
|
Security []*base.SecurityRequirement
|
||||||
|
|
||||||
// Tags are A list of tags used by the specification with additional metadata.
|
// Tags are A list of tags used by the specification with additional metadata.
|
||||||
// The order of the tags can be used to reflect on their order by the parsing tools. Not all tags that are used
|
// The order of the tags can be used to reflect on their order by the parsing tools. Not all tags that are used
|
||||||
@@ -150,9 +150,9 @@ func NewSwaggerDocument(document *low.Swagger) *Swagger {
|
|||||||
d.SecurityDefinitions = NewSecurityDefinitions(document.SecurityDefinitions.Value)
|
d.SecurityDefinitions = NewSecurityDefinitions(document.SecurityDefinitions.Value)
|
||||||
}
|
}
|
||||||
if !document.Security.IsEmpty() {
|
if !document.Security.IsEmpty() {
|
||||||
var security []*SecurityRequirement
|
var security []*base.SecurityRequirement
|
||||||
for s := range document.Security.Value {
|
for s := range document.Security.Value {
|
||||||
security = append(security, NewSecurityRequirement(document.Security.Value[s].Value))
|
security = append(security, base.NewSecurityRequirement(document.Security.Value[s].Value))
|
||||||
}
|
}
|
||||||
d.Security = security
|
d.Security = security
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,8 +103,8 @@ func TestNewSwaggerDocument_Security(t *testing.T) {
|
|||||||
assert.Len(t, highDoc.Security[0].Requirements["global_auth"], 2)
|
assert.Len(t, highDoc.Security[0].Requirements["global_auth"], 2)
|
||||||
|
|
||||||
wentLow := highDoc.Security[0].GoLow()
|
wentLow := highDoc.Security[0].GoLow()
|
||||||
assert.Equal(t, 25, wentLow.Values.ValueNode.Line)
|
assert.Equal(t, 25, wentLow.Requirements.ValueNode.Line)
|
||||||
assert.Equal(t, 5, wentLow.Values.ValueNode.Column)
|
assert.Equal(t, 5, wentLow.Requirements.ValueNode.Column)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ type Document struct {
|
|||||||
// to authorize a request. Individual operations can override this definition. To make security optional,
|
// to authorize a request. Individual operations can override this definition. To make security optional,
|
||||||
// an empty security requirement ({}) can be included in the array.
|
// an empty security requirement ({}) can be included in the array.
|
||||||
// - https://spec.openapis.org/oas/v3.1.0#security-requirement-object
|
// - https://spec.openapis.org/oas/v3.1.0#security-requirement-object
|
||||||
Security *SecurityRequirement
|
Security *base.SecurityRequirement
|
||||||
|
|
||||||
// Tags is a slice of base.Tag instances defined by the specification
|
// Tags is a slice of base.Tag instances defined by the specification
|
||||||
// A list of tags used by the document with additional metadata. The order of the tags can be used to reflect on
|
// A list of tags used by the document with additional metadata. The order of the tags can be used to reflect on
|
||||||
|
|||||||
@@ -337,10 +337,10 @@ func TestNewDocument_Paths(t *testing.T) {
|
|||||||
assert.Len(t, okResp.Links, 2)
|
assert.Len(t, okResp.Links, 2)
|
||||||
assert.Equal(t, "locateBurger", okResp.Links["LocateBurger"].OperationId)
|
assert.Equal(t, "locateBurger", okResp.Links["LocateBurger"].OperationId)
|
||||||
assert.Equal(t, 305, okResp.Links["LocateBurger"].GoLow().OperationId.ValueNode.Line)
|
assert.Equal(t, 305, okResp.Links["LocateBurger"].GoLow().OperationId.ValueNode.Line)
|
||||||
assert.Len(t, burgersOp.Post.Security.ValueRequirements[0], 1)
|
assert.Len(t, burgersOp.Post.Security[0].Requirements, 1)
|
||||||
assert.Len(t, burgersOp.Post.Security.ValueRequirements[0]["OAuthScheme"], 2)
|
assert.Len(t, burgersOp.Post.Security[0].Requirements["OAuthScheme"], 2)
|
||||||
assert.Equal(t, "read:burgers", burgersOp.Post.Security.ValueRequirements[0]["OAuthScheme"][0])
|
assert.Equal(t, "read:burgers", burgersOp.Post.Security[0].Requirements["OAuthScheme"][0])
|
||||||
assert.Equal(t, 118, burgersOp.Post.Security.GoLow().ValueRequirements[0].ValueNode.Line)
|
assert.Equal(t, 118, burgersOp.Post.Security[0].GoLow().Requirements.ValueNode.Line)
|
||||||
assert.Len(t, burgersOp.Post.Servers, 1)
|
assert.Len(t, burgersOp.Post.Servers, 1)
|
||||||
assert.Equal(t, "https://pb33f.io", burgersOp.Post.Servers[0].URL)
|
assert.Equal(t, "https://pb33f.io", burgersOp.Post.Servers[0].URL)
|
||||||
|
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ type Operation struct {
|
|||||||
RequestBody *RequestBody
|
RequestBody *RequestBody
|
||||||
Responses *Responses
|
Responses *Responses
|
||||||
Callbacks map[string]*Callback
|
Callbacks map[string]*Callback
|
||||||
Deprecated bool
|
Deprecated *bool
|
||||||
Security *SecurityRequirement
|
Security []*base.SecurityRequirement
|
||||||
Servers []*Server
|
Servers []*Server
|
||||||
Extensions map[string]any
|
Extensions map[string]any
|
||||||
low *low.Operation
|
low *low.Operation
|
||||||
@@ -42,6 +42,7 @@ func NewOperation(operation *low.Operation) *Operation {
|
|||||||
}
|
}
|
||||||
o.Tags = tags
|
o.Tags = tags
|
||||||
o.Summary = operation.Summary.Value
|
o.Summary = operation.Summary.Value
|
||||||
|
o.Deprecated = &operation.Deprecated.Value
|
||||||
o.Description = operation.Description.Value
|
o.Description = operation.Description.Value
|
||||||
if !operation.ExternalDocs.IsEmpty() {
|
if !operation.ExternalDocs.IsEmpty() {
|
||||||
o.ExternalDocs = base.NewExternalDoc(operation.ExternalDocs.Value)
|
o.ExternalDocs = base.NewExternalDoc(operation.ExternalDocs.Value)
|
||||||
@@ -61,7 +62,11 @@ func NewOperation(operation *low.Operation) *Operation {
|
|||||||
o.Responses = NewResponses(operation.Responses.Value)
|
o.Responses = NewResponses(operation.Responses.Value)
|
||||||
}
|
}
|
||||||
if !operation.Security.IsEmpty() {
|
if !operation.Security.IsEmpty() {
|
||||||
o.Security = NewSecurityRequirement(operation.Security.Value)
|
var sec []*base.SecurityRequirement
|
||||||
|
for s := range operation.Security.Value {
|
||||||
|
sec = append(sec, base.NewSecurityRequirement(operation.Security.Value[s].Value))
|
||||||
|
}
|
||||||
|
o.Security = sec
|
||||||
}
|
}
|
||||||
var servers []*Server
|
var servers []*Server
|
||||||
for i := range operation.Servers.Value {
|
for i := range operation.Servers.Value {
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
package v3
|
|
||||||
|
|
||||||
import low "github.com/pb33f/libopenapi/datamodel/low/v3"
|
|
||||||
|
|
||||||
// SecurityRequirement is a high-level representation of an OpenAPI 3+ SecurityRequirement object that is backed
|
|
||||||
// by a low-level one.
|
|
||||||
//
|
|
||||||
// It lists the required security schemes to execute this operation. The name used for each property MUST correspond
|
|
||||||
// to a security scheme declared in the Security Schemes under the Components Object.
|
|
||||||
//
|
|
||||||
// Security Requirement Objects that contain multiple schemes require that all schemes MUST be satisfied for a
|
|
||||||
// request to be authorized. This enables support for scenarios where multiple query parameters or HTTP headers are
|
|
||||||
// required to convey security information.
|
|
||||||
//
|
|
||||||
// When a list of Security Requirement Objects is defined on the OpenAPI Object or Operation Object, only one of the
|
|
||||||
// Security Requirement Objects in the list needs to be satisfied to authorize the request.
|
|
||||||
// - https://spec.openapis.org/oas/v3.1.0#security-requirement-object
|
|
||||||
type SecurityRequirement struct {
|
|
||||||
ValueRequirements []map[string][]string
|
|
||||||
low *low.SecurityRequirement
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewSecurityRequirement will create a new high-level SecurityRequirement instance, from a low-level one.
|
|
||||||
func NewSecurityRequirement(req *low.SecurityRequirement) *SecurityRequirement {
|
|
||||||
r := new(SecurityRequirement)
|
|
||||||
r.low = req
|
|
||||||
var values []map[string][]string
|
|
||||||
for i := range req.ValueRequirements {
|
|
||||||
valmap := make(map[string][]string)
|
|
||||||
for k, v := range req.ValueRequirements[i].Value {
|
|
||||||
var mItems []string
|
|
||||||
for h := range v.Value {
|
|
||||||
mItems = append(mItems, v.Value[h].Value)
|
|
||||||
}
|
|
||||||
valmap[k.Value] = mItems
|
|
||||||
}
|
|
||||||
values = append(values, valmap)
|
|
||||||
}
|
|
||||||
r.ValueRequirements = values
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
// GoLow returns the low-level SecurityRequirement instance used to create the high-level one.
|
|
||||||
func (s *SecurityRequirement) GoLow() *low.SecurityRequirement {
|
|
||||||
return s.low
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
|
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
package v2
|
package base
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
@@ -13,15 +13,16 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SecurityRequirement is a low-level representation of a Swagger / OpenAPI 2 SecurityRequirement object.
|
// 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
|
// 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).
|
// 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
|
// 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/v2/#securityDefinitionsObject
|
||||||
|
// - https://swagger.io/specification/#security-requirement-object
|
||||||
type SecurityRequirement struct {
|
type SecurityRequirement struct {
|
||||||
Values low.ValueReference[map[low.KeyReference[string]]low.ValueReference[[]low.ValueReference[string]]]
|
Requirements low.ValueReference[map[low.KeyReference[string]]low.ValueReference[[]low.ValueReference[string]]]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build will extract security requirements from the node (the structure is odd, to be honest)
|
// Build will extract security requirements from the node (the structure is odd, to be honest)
|
||||||
@@ -49,22 +50,32 @@ func (s *SecurityRequirement) Build(root *yaml.Node, _ *index.SpecIndex) error {
|
|||||||
ValueNode: root.Content[i],
|
ValueNode: root.Content[i],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.Values = low.ValueReference[map[low.KeyReference[string]]low.ValueReference[[]low.ValueReference[string]]]{
|
s.Requirements = low.ValueReference[map[low.KeyReference[string]]low.ValueReference[[]low.ValueReference[string]]]{
|
||||||
Value: valueMap,
|
Value: valueMap,
|
||||||
ValueNode: root,
|
ValueNode: root,
|
||||||
}
|
}
|
||||||
return nil
|
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
|
||||||
|
}
|
||||||
|
|
||||||
// Hash will return a consistent SHA256 Hash of the SecurityRequirement object
|
// Hash will return a consistent SHA256 Hash of the SecurityRequirement object
|
||||||
func (s *SecurityRequirement) Hash() [32]byte {
|
func (s *SecurityRequirement) Hash() [32]byte {
|
||||||
var f []string
|
var f []string
|
||||||
values := make(map[string][]string, len(s.Values.Value))
|
values := make(map[string][]string, len(s.Requirements.Value))
|
||||||
var valKeys []string
|
var valKeys []string
|
||||||
for k := range s.Values.Value {
|
for k := range s.Requirements.Value {
|
||||||
var vals []string
|
var vals []string
|
||||||
for y := range s.Values.Value[k].Value {
|
for y := range s.Requirements.Value[k].Value {
|
||||||
vals = append(vals, s.Values.Value[k].Value[y].Value)
|
vals = append(vals, s.Requirements.Value[k].Value[y].Value)
|
||||||
// lol, I know. -------^^^^^ <- this is the actual value.
|
// lol, I know. -------^^^^^ <- this is the actual value.
|
||||||
}
|
}
|
||||||
sort.Strings(vals)
|
sort.Strings(vals)
|
||||||
@@ -487,7 +487,7 @@ func ExtractMap[PT Buildable[N], N any](
|
|||||||
return nil, labelNode, valueNode, nil
|
return nil, labelNode, valueNode, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtractExtensions will extract any 'x-' prefixed key nodes from a root node into a map. Values have been pre-cast:
|
// ExtractExtensions will extract any 'x-' prefixed key nodes from a root node into a map. Requirements have been pre-cast:
|
||||||
//
|
//
|
||||||
// Maps
|
// Maps
|
||||||
// map[string]interface{} for maps
|
// map[string]interface{} for maps
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ type Operation struct {
|
|||||||
Responses low.NodeReference[*Responses]
|
Responses low.NodeReference[*Responses]
|
||||||
Schemes low.NodeReference[[]low.ValueReference[string]]
|
Schemes low.NodeReference[[]low.ValueReference[string]]
|
||||||
Deprecated low.NodeReference[bool]
|
Deprecated low.NodeReference[bool]
|
||||||
Security low.NodeReference[[]low.ValueReference[*SecurityRequirement]]
|
Security low.NodeReference[[]low.ValueReference[*base.SecurityRequirement]]
|
||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,13 +65,13 @@ func (o *Operation) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
}
|
}
|
||||||
o.Responses = respBody
|
o.Responses = respBody
|
||||||
|
|
||||||
// extract parameters
|
// extract security
|
||||||
sec, sln, svn, sErr := low.ExtractArray[*SecurityRequirement](SecurityLabel, root, idx)
|
sec, sln, svn, sErr := low.ExtractArray[*base.SecurityRequirement](SecurityLabel, root, idx)
|
||||||
if sErr != nil {
|
if sErr != nil {
|
||||||
return sErr
|
return sErr
|
||||||
}
|
}
|
||||||
if sec != nil {
|
if sec != nil {
|
||||||
o.Security = low.NodeReference[[]low.ValueReference[*SecurityRequirement]]{
|
o.Security = low.NodeReference[[]low.ValueReference[*base.SecurityRequirement]]{
|
||||||
Value: sec,
|
Value: sec,
|
||||||
KeyNode: sln,
|
KeyNode: sln,
|
||||||
ValueNode: svn,
|
ValueNode: svn,
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ type Swagger struct {
|
|||||||
// The basePath does not support path templating.
|
// The basePath does not support path templating.
|
||||||
BasePath low.NodeReference[string]
|
BasePath low.NodeReference[string]
|
||||||
|
|
||||||
// Schemes represents the transfer protocol of the API. Values MUST be from the list: "http", "https", "ws", "wss".
|
// Schemes represents the transfer protocol of the API. Requirements MUST be from the list: "http", "https", "ws", "wss".
|
||||||
// If the schemes is not included, the default scheme to be used is the one used to access
|
// If the schemes is not included, the default scheme to be used is the one used to access
|
||||||
// the Swagger definition itself.
|
// the Swagger definition itself.
|
||||||
Schemes low.NodeReference[[]low.ValueReference[string]]
|
Schemes low.NodeReference[[]low.ValueReference[string]]
|
||||||
@@ -83,7 +83,7 @@ type Swagger struct {
|
|||||||
// describes alternative security schemes that can be used (that is, there is a logical OR between the security
|
// describes alternative security schemes that can be used (that is, there is a logical OR between the security
|
||||||
// requirements). Individual operations can override this definition.
|
// requirements). Individual operations can override this definition.
|
||||||
// - https://swagger.io/specification/v2/#securityRequirementObject
|
// - https://swagger.io/specification/v2/#securityRequirementObject
|
||||||
Security low.NodeReference[[]low.ValueReference[*SecurityRequirement]]
|
Security low.NodeReference[[]low.ValueReference[*base.SecurityRequirement]]
|
||||||
|
|
||||||
// Tags are A list of tags used by the specification with additional metadata.
|
// Tags are A list of tags used by the specification with additional metadata.
|
||||||
// The order of the tags can be used to reflect on their order by the parsing tools. Not all tags that are used
|
// The order of the tags can be used to reflect on their order by the parsing tools. Not all tags that are used
|
||||||
@@ -245,12 +245,12 @@ func extractTags(root *yaml.Node, doc *Swagger, idx *index.SpecIndex, c chan<- b
|
|||||||
}
|
}
|
||||||
|
|
||||||
func extractSecurity(root *yaml.Node, doc *Swagger, idx *index.SpecIndex, c chan<- bool, e chan<- error) {
|
func extractSecurity(root *yaml.Node, doc *Swagger, idx *index.SpecIndex, c chan<- bool, e chan<- error) {
|
||||||
sec, ln, vn, err := low.ExtractArray[*SecurityRequirement](SecurityLabel, root, idx)
|
sec, ln, vn, err := low.ExtractArray[*base.SecurityRequirement](SecurityLabel, root, idx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e <- err
|
e <- err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
doc.Security = low.NodeReference[[]low.ValueReference[*SecurityRequirement]]{
|
doc.Security = low.NodeReference[[]low.ValueReference[*base.SecurityRequirement]]{
|
||||||
Value: sec,
|
Value: sec,
|
||||||
KeyNode: ln,
|
KeyNode: ln,
|
||||||
ValueNode: vn,
|
ValueNode: vn,
|
||||||
|
|||||||
@@ -76,11 +76,15 @@ func extractInfo(info *datamodel.SpecInfo, doc *Document, idx *index.SpecIndex)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func extractSecurity(info *datamodel.SpecInfo, doc *Document, idx *index.SpecIndex) error {
|
func extractSecurity(info *datamodel.SpecInfo, doc *Document, idx *index.SpecIndex) error {
|
||||||
sec, sErr := low.ExtractObject[*SecurityRequirement](SecurityLabel, info.RootNode, idx)
|
sec, ln, vn, err := low.ExtractArray[*base.SecurityRequirement](SecurityLabel, info.RootNode, idx)
|
||||||
if sErr != nil {
|
if err != nil {
|
||||||
return sErr
|
return err
|
||||||
|
}
|
||||||
|
doc.Security = low.NodeReference[[]low.ValueReference[*base.SecurityRequirement]]{
|
||||||
|
Value: sec,
|
||||||
|
KeyNode: ln,
|
||||||
|
ValueNode: vn,
|
||||||
}
|
}
|
||||||
doc.Security = sec
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -317,11 +317,7 @@ func TestCreateDocument_Paths(t *testing.T) {
|
|||||||
assert.Equal(t, "$response.body#/id", burgerIdParam.Value)
|
assert.Equal(t, "$response.body#/id", burgerIdParam.Value)
|
||||||
|
|
||||||
// check security requirements
|
// check security requirements
|
||||||
security := burgersPost.Security.Value
|
oAuthReq := burgersPost.FindSecurityRequirement("OAuthScheme")
|
||||||
assert.NotNil(t, security)
|
|
||||||
assert.Len(t, security.ValueRequirements, 1)
|
|
||||||
|
|
||||||
oAuthReq := security.FindRequirement("OAuthScheme")
|
|
||||||
assert.Len(t, oAuthReq, 2)
|
assert.Len(t, oAuthReq, 2)
|
||||||
assert.Equal(t, "read:burgers", oAuthReq[0].Value)
|
assert.Equal(t, "read:burgers", oAuthReq[0].Value)
|
||||||
|
|
||||||
@@ -453,11 +449,7 @@ func TestCreateDocument_Components_Links(t *testing.T) {
|
|||||||
|
|
||||||
func TestCreateDocument_Doc_Security(t *testing.T) {
|
func TestCreateDocument_Doc_Security(t *testing.T) {
|
||||||
initTest()
|
initTest()
|
||||||
security := doc.Security.Value
|
oAuth := doc.FindSecurityRequirement("OAuthScheme")
|
||||||
assert.NotNil(t, security)
|
|
||||||
assert.Len(t, security.ValueRequirements, 1)
|
|
||||||
|
|
||||||
oAuth := security.FindRequirement("OAuthScheme")
|
|
||||||
assert.Len(t, oAuth, 2)
|
assert.Len(t, oAuth, 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ type Document struct {
|
|||||||
// to authorize a request. Individual operations can override this definition. To make security optional,
|
// to authorize a request. Individual operations can override this definition. To make security optional,
|
||||||
// an empty security requirement ({}) can be included in the array.
|
// an empty security requirement ({}) can be included in the array.
|
||||||
// - https://spec.openapis.org/oas/v3.1.0#security-requirement-object
|
// - https://spec.openapis.org/oas/v3.1.0#security-requirement-object
|
||||||
Security low.NodeReference[*SecurityRequirement]
|
Security low.NodeReference[[]low.ValueReference[*base.SecurityRequirement]]
|
||||||
|
|
||||||
// Tags is a slice of base.Tag instances defined by the specification
|
// Tags is a slice of base.Tag instances defined by the specification
|
||||||
// A list of tags used by the document with additional metadata. The order of the tags can be used to reflect on
|
// A list of tags used by the document with additional metadata. The order of the tags can be used to reflect on
|
||||||
@@ -84,6 +84,18 @@ type Document struct {
|
|||||||
Index *index.SpecIndex
|
Index *index.SpecIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindSecurityRequirement will attempt to locate a security requirement string from a supplied name.
|
||||||
|
func (d *Document) FindSecurityRequirement(name string) []low.ValueReference[string] {
|
||||||
|
for k := range d.Security.Value {
|
||||||
|
for i := range d.Security.Value[k].Value.Requirements.Value {
|
||||||
|
if i.Value == name {
|
||||||
|
return d.Security.Value[k].Value.Requirements.Value[i].Value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: this is early prototype mutation/modification code, keeping it around for later.
|
// TODO: this is early prototype mutation/modification code, keeping it around for later.
|
||||||
//func (d *Document) AddTag() *base.Tag {
|
//func (d *Document) AddTag() *base.Tag {
|
||||||
// t := base.NewTag()
|
// t := base.NewTag()
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ type Operation struct {
|
|||||||
Responses low.NodeReference[*Responses]
|
Responses low.NodeReference[*Responses]
|
||||||
Callbacks low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Callback]]
|
Callbacks low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Callback]]
|
||||||
Deprecated low.NodeReference[bool]
|
Deprecated low.NodeReference[bool]
|
||||||
Security low.NodeReference[*SecurityRequirement]
|
Security low.NodeReference[[]low.ValueReference[*base.SecurityRequirement]]
|
||||||
Servers low.NodeReference[[]low.ValueReference[*Server]]
|
Servers low.NodeReference[[]low.ValueReference[*Server]]
|
||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
}
|
}
|
||||||
@@ -40,6 +40,18 @@ func (o *Operation) FindCallback(callback string) *low.ValueReference[*Callback]
|
|||||||
return low.FindItemInMap[*Callback](callback, o.Callbacks.Value)
|
return low.FindItemInMap[*Callback](callback, o.Callbacks.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindSecurityRequirement will attempt to locate a security requirement string from a supplied name.
|
||||||
|
func (o *Operation) FindSecurityRequirement(name string) []low.ValueReference[string] {
|
||||||
|
for k := range o.Security.Value {
|
||||||
|
for i := range o.Security.Value[k].Value.Requirements.Value {
|
||||||
|
if i.Value == name {
|
||||||
|
return o.Security.Value[k].Value.Requirements.Value[i].Value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Build will extract external docs, parameters, request body, responses, callbacks, security and servers.
|
// Build will extract external docs, parameters, request body, responses, callbacks, security and servers.
|
||||||
func (o *Operation) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
func (o *Operation) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
o.Extensions = low.ExtractExtensions(root)
|
o.Extensions = low.ExtractExtensions(root)
|
||||||
@@ -92,11 +104,17 @@ func (o *Operation) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// extract security
|
// extract security
|
||||||
sec, sErr := low.ExtractObject[*SecurityRequirement](SecurityLabel, root, idx)
|
sec, sln, svn, sErr := low.ExtractArray[*base.SecurityRequirement](SecurityLabel, root, idx)
|
||||||
if sErr != nil {
|
if sErr != nil {
|
||||||
return sErr
|
return sErr
|
||||||
}
|
}
|
||||||
o.Security = sec
|
if sec != nil {
|
||||||
|
o.Security = low.NodeReference[[]low.ValueReference[*base.SecurityRequirement]]{
|
||||||
|
Value: sec,
|
||||||
|
KeyNode: sln,
|
||||||
|
ValueNode: svn,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// extract servers
|
// extract servers
|
||||||
servers, sl, sn, serErr := low.ExtractArray[*Server](ServersLabel, root, idx)
|
servers, sl, sn, serErr := low.ExtractArray[*Server](ServersLabel, root, idx)
|
||||||
|
|||||||
@@ -65,10 +65,10 @@ servers:
|
|||||||
assert.Equal(t, "a nice callback",
|
assert.Equal(t, "a nice callback",
|
||||||
n.FindCallback("niceCallback").Value.FindExpression("ohISee").Value.Description.Value)
|
n.FindCallback("niceCallback").Value.FindExpression("ohISee").Value.Description.Value)
|
||||||
assert.True(t, n.Deprecated.Value)
|
assert.True(t, n.Deprecated.Value)
|
||||||
assert.Len(t, n.Security.Value.ValueRequirements, 1)
|
assert.Len(t, n.Security.Value, 1)
|
||||||
assert.Len(t, n.Security.Value.FindRequirement("books"), 2)
|
assert.Len(t, n.FindSecurityRequirement("books"), 2)
|
||||||
assert.Equal(t, "read:books", n.Security.Value.FindRequirement("books")[0].Value)
|
assert.Equal(t, "read:books", n.FindSecurityRequirement("books")[0].Value)
|
||||||
assert.Equal(t, "write:books", n.Security.Value.FindRequirement("books")[1].Value)
|
assert.Equal(t, "write:books", n.FindSecurityRequirement("books")[1].Value)
|
||||||
assert.Len(t, n.Servers.Value, 1)
|
assert.Len(t, n.Servers.Value, 1)
|
||||||
assert.Equal(t, "https://pb33f.io", n.Servers.Value[0].Value.URL.Value)
|
assert.Equal(t, "https://pb33f.io", n.Servers.Value[0].Value.URL.Value)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
"github.com/pb33f/libopenapi/index"
|
"github.com/pb33f/libopenapi/index"
|
||||||
"github.com/pb33f/libopenapi/utils"
|
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"sort"
|
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -48,11 +46,11 @@ type SecurityScheme struct {
|
|||||||
// When a list of Security Requirement Objects is defined on the OpenAPI Object or Operation Object, only one of the
|
// When a list of Security Requirement Objects is defined on the OpenAPI Object or Operation Object, only one of the
|
||||||
// Security Requirement Objects in the list needs to be satisfied to authorize the request.
|
// Security Requirement Objects in the list needs to be satisfied to authorize the request.
|
||||||
// - https://spec.openapis.org/oas/v3.1.0#security-requirement-object
|
// - https://spec.openapis.org/oas/v3.1.0#security-requirement-object
|
||||||
type SecurityRequirement struct {
|
//type SecurityRequirement struct {
|
||||||
|
//
|
||||||
// FYI, I hate this data structure. Even without the low level wrapping, it sucks.
|
// // FYI, I hate this data structure. Even without the low level wrapping, it sucks.
|
||||||
ValueRequirements []low.ValueReference[map[low.KeyReference[string]]low.ValueReference[[]low.ValueReference[string]]]
|
// ValueRequirements []low.ValueReference[map[low.KeyReference[string]]low.ValueReference[[]low.ValueReference[string]]]
|
||||||
}
|
//}
|
||||||
|
|
||||||
// FindExtension attempts to locate an extension using the supplied key.
|
// FindExtension attempts to locate an extension using the supplied key.
|
||||||
func (ss *SecurityScheme) FindExtension(ext string) *low.ValueReference[any] {
|
func (ss *SecurityScheme) FindExtension(ext string) *low.ValueReference[any] {
|
||||||
@@ -105,89 +103,3 @@ func (ss *SecurityScheme) Hash() [32]byte {
|
|||||||
}
|
}
|
||||||
return sha256.Sum256([]byte(strings.Join(f, "|")))
|
return sha256.Sum256([]byte(strings.Join(f, "|")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindRequirement will attempt to locate a security requirement string from a supplied name.
|
|
||||||
func (sr *SecurityRequirement) FindRequirement(name string) []low.ValueReference[string] {
|
|
||||||
for _, r := range sr.ValueRequirements {
|
|
||||||
for k, v := range r.Value {
|
|
||||||
if k.Value == name {
|
|
||||||
return v.Value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build will extract all security requirements
|
|
||||||
func (sr *SecurityRequirement) Build(root *yaml.Node, _ *index.SpecIndex) error {
|
|
||||||
if utils.IsNodeArray(root) {
|
|
||||||
var requirements []low.ValueReference[map[low.KeyReference[string]]low.ValueReference[[]low.ValueReference[string]]]
|
|
||||||
for _, n := range root.Content {
|
|
||||||
var currSec *yaml.Node
|
|
||||||
if utils.IsNodeMap(n) {
|
|
||||||
res := make(map[low.KeyReference[string]]low.ValueReference[[]low.ValueReference[string]])
|
|
||||||
var dat []low.ValueReference[string]
|
|
||||||
for i, r := range n.Content {
|
|
||||||
if i%2 == 0 {
|
|
||||||
currSec = r
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if utils.IsNodeArray(r) {
|
|
||||||
// value (should be) an array of strings
|
|
||||||
var keyValues []low.ValueReference[string]
|
|
||||||
for _, strN := range r.Content {
|
|
||||||
keyValues = append(keyValues, low.ValueReference[string]{
|
|
||||||
Value: strN.Value,
|
|
||||||
ValueNode: strN,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
dat = keyValues
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if currSec != nil {
|
|
||||||
res[low.KeyReference[string]{
|
|
||||||
Value: currSec.Value,
|
|
||||||
KeyNode: currSec,
|
|
||||||
}] = low.ValueReference[[]low.ValueReference[string]]{
|
|
||||||
Value: dat,
|
|
||||||
ValueNode: currSec,
|
|
||||||
}
|
|
||||||
requirements = append(requirements,
|
|
||||||
low.ValueReference[map[low.KeyReference[string]]low.ValueReference[[]low.ValueReference[string]]]{
|
|
||||||
Value: res,
|
|
||||||
ValueNode: n,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sr.ValueRequirements = requirements
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hash will return a consistent SHA256 Hash of the SecurityRequirement object
|
|
||||||
func (sr *SecurityRequirement) Hash() [32]byte {
|
|
||||||
var f []string
|
|
||||||
for i := range sr.ValueRequirements {
|
|
||||||
req := sr.ValueRequirements[i].Value
|
|
||||||
values := make(map[string][]string, len(req))
|
|
||||||
var valKeys []string
|
|
||||||
for k := range req {
|
|
||||||
var vals []string
|
|
||||||
for y := range req[k].Value {
|
|
||||||
vals = append(vals, req[k].Value[y].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, "|")))
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ package v3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/datamodel/low/base"
|
||||||
"github.com/pb33f/libopenapi/index"
|
"github.com/pb33f/libopenapi/index"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
@@ -12,7 +13,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestSecurityRequirement_Build(t *testing.T) {
|
func TestSecurityRequirement_Build(t *testing.T) {
|
||||||
yml := `- something:
|
yml := `something:
|
||||||
- read:me
|
- read:me
|
||||||
- write:me`
|
- write:me`
|
||||||
|
|
||||||
@@ -20,13 +21,14 @@ func TestSecurityRequirement_Build(t *testing.T) {
|
|||||||
_ = yaml.Unmarshal([]byte(yml), &idxNode)
|
_ = yaml.Unmarshal([]byte(yml), &idxNode)
|
||||||
idx := index.NewSpecIndex(&idxNode)
|
idx := index.NewSpecIndex(&idxNode)
|
||||||
|
|
||||||
var n SecurityRequirement
|
var n base.SecurityRequirement
|
||||||
err := low.BuildModel(&idxNode, &n)
|
err := low.BuildModel(&idxNode, &n)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
err = n.Build(idxNode.Content[0], idx)
|
err = n.Build(idxNode.Content[0], idx)
|
||||||
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, n.ValueRequirements, 1)
|
assert.Len(t, n.Requirements.Value, 1)
|
||||||
assert.Equal(t, "read:me", n.FindRequirement("something")[0].Value)
|
assert.Equal(t, "read:me", n.FindRequirement("something")[0].Value)
|
||||||
assert.Equal(t, "write:me", n.FindRequirement("something")[1].Value)
|
assert.Equal(t, "write:me", n.FindRequirement("something")[1].Value)
|
||||||
assert.Nil(t, n.FindRequirement("none"))
|
assert.Nil(t, n.FindRequirement("none"))
|
||||||
|
|||||||
@@ -5,10 +5,9 @@ package model
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
"github.com/pb33f/libopenapi/datamodel/low/v2"
|
"github.com/pb33f/libopenapi/datamodel/low/base"
|
||||||
"github.com/pb33f/libopenapi/datamodel/low/v3"
|
"github.com/pb33f/libopenapi/datamodel/low/v3"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"reflect"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type SecurityRequirementChanges struct {
|
type SecurityRequirementChanges struct {
|
||||||
@@ -33,76 +32,15 @@ func addedSecurityRequirement(vn *yaml.Node, name string, changes *[]*Change) {
|
|||||||
nil, vn, false, nil, name)
|
nil, vn, false, nil, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CompareSecurityRequirement(l, r any) *SecurityRequirementChanges {
|
func CompareSecurityRequirement(l, r *base.SecurityRequirement) *SecurityRequirementChanges {
|
||||||
|
|
||||||
var changes []*Change
|
var changes []*Change
|
||||||
sc := new(SecurityRequirementChanges)
|
sc := new(SecurityRequirementChanges)
|
||||||
|
|
||||||
if reflect.TypeOf(&v2.SecurityRequirement{}) == reflect.TypeOf(l) &&
|
if low.AreEqual(l, r) {
|
||||||
reflect.TypeOf(&v2.SecurityRequirement{}) == reflect.TypeOf(r) {
|
return nil
|
||||||
|
|
||||||
lSec := l.(*v2.SecurityRequirement)
|
|
||||||
rSec := r.(*v2.SecurityRequirement)
|
|
||||||
|
|
||||||
if low.AreEqual(lSec, rSec) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
checkSecurityRequirement(lSec.Values.Value, rSec.Values.Value, &changes)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
checkSecurityRequirement(l.Requirements.Value, r.Requirements.Value, &changes)
|
||||||
if reflect.TypeOf(&v3.SecurityRequirement{}) == reflect.TypeOf(l) &&
|
|
||||||
reflect.TypeOf(&v3.SecurityRequirement{}) == reflect.TypeOf(r) {
|
|
||||||
|
|
||||||
lSec := l.(*v3.SecurityRequirement)
|
|
||||||
rSec := r.(*v3.SecurityRequirement)
|
|
||||||
|
|
||||||
if low.AreEqual(lSec, rSec) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// can we find anyone to dance with?
|
|
||||||
findPartner := func(key string,
|
|
||||||
search map[low.KeyReference[string]]map[low.KeyReference[string]]low.ValueReference[[]low.ValueReference[string]]) map[low.KeyReference[string]]low.ValueReference[[]low.ValueReference[string]] {
|
|
||||||
for k := range search {
|
|
||||||
if k.Value == key {
|
|
||||||
return search[k]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Yes, this exists.
|
|
||||||
lValues := make(map[low.KeyReference[string]]map[low.KeyReference[string]]low.ValueReference[[]low.ValueReference[string]])
|
|
||||||
rValues := make(map[low.KeyReference[string]]map[low.KeyReference[string]]low.ValueReference[[]low.ValueReference[string]])
|
|
||||||
for i := range lSec.ValueRequirements {
|
|
||||||
for k := range lSec.ValueRequirements[i].Value {
|
|
||||||
lValues[k] = lSec.ValueRequirements[i].Value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i := range rSec.ValueRequirements {
|
|
||||||
for k := range rSec.ValueRequirements[i].Value {
|
|
||||||
rValues[k] = rSec.ValueRequirements[i].Value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// look through left and right slices to see if we recognize anything.
|
|
||||||
for k := range lValues {
|
|
||||||
if p := findPartner(k.Value, rValues); p != nil {
|
|
||||||
checkSecurityRequirement(lValues[k], p, &changes)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
CreateChange(&changes, ObjectRemoved, v3.SecurityLabel,
|
|
||||||
k.KeyNode, nil, true, lValues[k], nil)
|
|
||||||
}
|
|
||||||
for k := range rValues {
|
|
||||||
if ok := findPartner(k.Value, lValues); ok == nil {
|
|
||||||
CreateChange(&changes, ObjectAdded, v3.SecurityLabel,
|
|
||||||
nil, k.KeyNode, false, nil, rValues[k])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sc.Changes = changes
|
sc.Changes = changes
|
||||||
return sc
|
return sc
|
||||||
}
|
}
|
||||||
@@ -199,11 +137,3 @@ func checkSecurityRequirement(lSec, rSec map[low.KeyReference[string]]low.ValueR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func CompareSecurityRequirementV3(l, r *v3.SecurityRequirement) *SecurityRequirementChanges {
|
|
||||||
return CompareSecurityRequirement(l, r)
|
|
||||||
}
|
|
||||||
|
|
||||||
func CompareSecurityRequirementV2(l, r *v2.SecurityRequirement) *SecurityRequirementChanges {
|
|
||||||
return CompareSecurityRequirement(l, r)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -5,8 +5,7 @@ package model
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
"github.com/pb33f/libopenapi/datamodel/low/v2"
|
"github.com/pb33f/libopenapi/datamodel/low/base"
|
||||||
"github.com/pb33f/libopenapi/datamodel/low/v3"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -27,15 +26,15 @@ func TestCompareSecurityRequirement_V2(t *testing.T) {
|
|||||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||||
|
|
||||||
// create low level objects
|
// create low level objects
|
||||||
var lDoc v2.SecurityRequirement
|
var lDoc base.SecurityRequirement
|
||||||
var rDoc v2.SecurityRequirement
|
var rDoc base.SecurityRequirement
|
||||||
_ = low.BuildModel(&lNode, &lDoc)
|
_ = low.BuildModel(&lNode, &lDoc)
|
||||||
_ = low.BuildModel(&rNode, &rDoc)
|
_ = low.BuildModel(&rNode, &rDoc)
|
||||||
_ = lDoc.Build(lNode.Content[0], nil)
|
_ = lDoc.Build(lNode.Content[0], nil)
|
||||||
_ = rDoc.Build(rNode.Content[0], nil)
|
_ = rDoc.Build(rNode.Content[0], nil)
|
||||||
|
|
||||||
// compare
|
// compare
|
||||||
extChanges := CompareSecurityRequirementV2(&lDoc, &rDoc)
|
extChanges := CompareSecurityRequirement(&lDoc, &rDoc)
|
||||||
assert.Nil(t, extChanges)
|
assert.Nil(t, extChanges)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,15 +59,15 @@ biscuit:
|
|||||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||||
|
|
||||||
// create low level objects
|
// create low level objects
|
||||||
var lDoc v2.SecurityRequirement
|
var lDoc base.SecurityRequirement
|
||||||
var rDoc v2.SecurityRequirement
|
var rDoc base.SecurityRequirement
|
||||||
_ = low.BuildModel(&lNode, &lDoc)
|
_ = low.BuildModel(&lNode, &lDoc)
|
||||||
_ = low.BuildModel(&rNode, &rDoc)
|
_ = low.BuildModel(&rNode, &rDoc)
|
||||||
_ = lDoc.Build(lNode.Content[0], nil)
|
_ = lDoc.Build(lNode.Content[0], nil)
|
||||||
_ = rDoc.Build(rNode.Content[0], nil)
|
_ = rDoc.Build(rNode.Content[0], nil)
|
||||||
|
|
||||||
// compare
|
// compare
|
||||||
extChanges := CompareSecurityRequirementV2(&lDoc, &rDoc)
|
extChanges := CompareSecurityRequirement(&lDoc, &rDoc)
|
||||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||||
@@ -92,15 +91,15 @@ biscuit:
|
|||||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||||
|
|
||||||
// create low level objects
|
// create low level objects
|
||||||
var lDoc v2.SecurityRequirement
|
var lDoc base.SecurityRequirement
|
||||||
var rDoc v2.SecurityRequirement
|
var rDoc base.SecurityRequirement
|
||||||
_ = low.BuildModel(&lNode, &lDoc)
|
_ = low.BuildModel(&lNode, &lDoc)
|
||||||
_ = low.BuildModel(&rNode, &rDoc)
|
_ = low.BuildModel(&rNode, &rDoc)
|
||||||
_ = lDoc.Build(lNode.Content[0], nil)
|
_ = lDoc.Build(lNode.Content[0], nil)
|
||||||
_ = rDoc.Build(rNode.Content[0], nil)
|
_ = rDoc.Build(rNode.Content[0], nil)
|
||||||
|
|
||||||
// compare
|
// compare
|
||||||
extChanges := CompareSecurityRequirementV2(&rDoc, &lDoc)
|
extChanges := CompareSecurityRequirement(&rDoc, &lDoc)
|
||||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||||
}
|
}
|
||||||
@@ -124,15 +123,15 @@ milk:
|
|||||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||||
|
|
||||||
// create low level objects
|
// create low level objects
|
||||||
var lDoc v2.SecurityRequirement
|
var lDoc base.SecurityRequirement
|
||||||
var rDoc v2.SecurityRequirement
|
var rDoc base.SecurityRequirement
|
||||||
_ = low.BuildModel(&lNode, &lDoc)
|
_ = low.BuildModel(&lNode, &lDoc)
|
||||||
_ = low.BuildModel(&rNode, &rDoc)
|
_ = low.BuildModel(&rNode, &rDoc)
|
||||||
_ = lDoc.Build(lNode.Content[0], nil)
|
_ = lDoc.Build(lNode.Content[0], nil)
|
||||||
_ = rDoc.Build(rNode.Content[0], nil)
|
_ = rDoc.Build(rNode.Content[0], nil)
|
||||||
|
|
||||||
// compare
|
// compare
|
||||||
extChanges := CompareSecurityRequirementV2(&lDoc, &rDoc)
|
extChanges := CompareSecurityRequirement(&lDoc, &rDoc)
|
||||||
assert.Equal(t, 4, extChanges.TotalChanges())
|
assert.Equal(t, 4, extChanges.TotalChanges())
|
||||||
assert.Equal(t, 2, extChanges.TotalBreakingChanges())
|
assert.Equal(t, 2, extChanges.TotalBreakingChanges())
|
||||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||||
@@ -160,15 +159,15 @@ milk:
|
|||||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||||
|
|
||||||
// create low level objects
|
// create low level objects
|
||||||
var lDoc v2.SecurityRequirement
|
var lDoc base.SecurityRequirement
|
||||||
var rDoc v2.SecurityRequirement
|
var rDoc base.SecurityRequirement
|
||||||
_ = low.BuildModel(&lNode, &lDoc)
|
_ = low.BuildModel(&lNode, &lDoc)
|
||||||
_ = low.BuildModel(&rNode, &rDoc)
|
_ = low.BuildModel(&rNode, &rDoc)
|
||||||
_ = lDoc.Build(lNode.Content[0], nil)
|
_ = lDoc.Build(lNode.Content[0], nil)
|
||||||
_ = rDoc.Build(rNode.Content[0], nil)
|
_ = rDoc.Build(rNode.Content[0], nil)
|
||||||
|
|
||||||
// compare
|
// compare
|
||||||
extChanges := CompareSecurityRequirementV2(&lDoc, &rDoc)
|
extChanges := CompareSecurityRequirement(&lDoc, &rDoc)
|
||||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||||
@@ -195,15 +194,15 @@ biscuit:
|
|||||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||||
|
|
||||||
// create low level objects
|
// create low level objects
|
||||||
var lDoc v2.SecurityRequirement
|
var lDoc base.SecurityRequirement
|
||||||
var rDoc v2.SecurityRequirement
|
var rDoc base.SecurityRequirement
|
||||||
_ = low.BuildModel(&lNode, &lDoc)
|
_ = low.BuildModel(&lNode, &lDoc)
|
||||||
_ = low.BuildModel(&rNode, &rDoc)
|
_ = low.BuildModel(&rNode, &rDoc)
|
||||||
_ = lDoc.Build(lNode.Content[0], nil)
|
_ = lDoc.Build(lNode.Content[0], nil)
|
||||||
_ = rDoc.Build(rNode.Content[0], nil)
|
_ = rDoc.Build(rNode.Content[0], nil)
|
||||||
|
|
||||||
// compare
|
// compare
|
||||||
extChanges := CompareSecurityRequirementV2(&lDoc, &rDoc)
|
extChanges := CompareSecurityRequirement(&lDoc, &rDoc)
|
||||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||||
@@ -233,15 +232,15 @@ biscuit:
|
|||||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||||
|
|
||||||
// create low level objects
|
// create low level objects
|
||||||
var lDoc v2.SecurityRequirement
|
var lDoc base.SecurityRequirement
|
||||||
var rDoc v2.SecurityRequirement
|
var rDoc base.SecurityRequirement
|
||||||
_ = low.BuildModel(&lNode, &lDoc)
|
_ = low.BuildModel(&lNode, &lDoc)
|
||||||
_ = low.BuildModel(&rNode, &rDoc)
|
_ = low.BuildModel(&rNode, &rDoc)
|
||||||
_ = lDoc.Build(lNode.Content[0], nil)
|
_ = lDoc.Build(lNode.Content[0], nil)
|
||||||
_ = rDoc.Build(rNode.Content[0], nil)
|
_ = rDoc.Build(rNode.Content[0], nil)
|
||||||
|
|
||||||
// compare
|
// compare
|
||||||
extChanges := CompareSecurityRequirementV2(&lDoc, &rDoc)
|
extChanges := CompareSecurityRequirement(&lDoc, &rDoc)
|
||||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||||
@@ -267,15 +266,15 @@ biscuit:
|
|||||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||||
|
|
||||||
// create low level objects
|
// create low level objects
|
||||||
var lDoc v2.SecurityRequirement
|
var lDoc base.SecurityRequirement
|
||||||
var rDoc v2.SecurityRequirement
|
var rDoc base.SecurityRequirement
|
||||||
_ = low.BuildModel(&lNode, &lDoc)
|
_ = low.BuildModel(&lNode, &lDoc)
|
||||||
_ = low.BuildModel(&rNode, &rDoc)
|
_ = low.BuildModel(&rNode, &rDoc)
|
||||||
_ = lDoc.Build(lNode.Content[0], nil)
|
_ = lDoc.Build(lNode.Content[0], nil)
|
||||||
_ = rDoc.Build(rNode.Content[0], nil)
|
_ = rDoc.Build(rNode.Content[0], nil)
|
||||||
|
|
||||||
// compare
|
// compare
|
||||||
extChanges := CompareSecurityRequirementV2(&lDoc, &rDoc)
|
extChanges := CompareSecurityRequirement(&lDoc, &rDoc)
|
||||||
assert.Equal(t, 3, extChanges.TotalChanges())
|
assert.Equal(t, 3, extChanges.TotalChanges())
|
||||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||||
}
|
}
|
||||||
@@ -301,15 +300,15 @@ biscuit:
|
|||||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||||
|
|
||||||
// create low level objects
|
// create low level objects
|
||||||
var lDoc v2.SecurityRequirement
|
var lDoc base.SecurityRequirement
|
||||||
var rDoc v2.SecurityRequirement
|
var rDoc base.SecurityRequirement
|
||||||
_ = low.BuildModel(&lNode, &lDoc)
|
_ = low.BuildModel(&lNode, &lDoc)
|
||||||
_ = low.BuildModel(&rNode, &rDoc)
|
_ = low.BuildModel(&rNode, &rDoc)
|
||||||
_ = lDoc.Build(lNode.Content[0], nil)
|
_ = lDoc.Build(lNode.Content[0], nil)
|
||||||
_ = rDoc.Build(rNode.Content[0], nil)
|
_ = rDoc.Build(rNode.Content[0], nil)
|
||||||
|
|
||||||
// compare
|
// compare
|
||||||
extChanges := CompareSecurityRequirementV2(&lDoc, &rDoc)
|
extChanges := CompareSecurityRequirement(&lDoc, &rDoc)
|
||||||
assert.Nil(t, extChanges)
|
assert.Nil(t, extChanges)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,15 +332,15 @@ biscuit:
|
|||||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||||
|
|
||||||
// create low level objects
|
// create low level objects
|
||||||
var lDoc v2.SecurityRequirement
|
var lDoc base.SecurityRequirement
|
||||||
var rDoc v2.SecurityRequirement
|
var rDoc base.SecurityRequirement
|
||||||
_ = low.BuildModel(&lNode, &lDoc)
|
_ = low.BuildModel(&lNode, &lDoc)
|
||||||
_ = low.BuildModel(&rNode, &rDoc)
|
_ = low.BuildModel(&rNode, &rDoc)
|
||||||
_ = lDoc.Build(lNode.Content[0], nil)
|
_ = lDoc.Build(lNode.Content[0], nil)
|
||||||
_ = rDoc.Build(rNode.Content[0], nil)
|
_ = rDoc.Build(rNode.Content[0], nil)
|
||||||
|
|
||||||
// compare
|
// compare
|
||||||
extChanges := CompareSecurityRequirementV2(&rDoc, &lDoc)
|
extChanges := CompareSecurityRequirement(&rDoc, &lDoc)
|
||||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||||
@@ -369,167 +368,168 @@ biscuit:
|
|||||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||||
|
|
||||||
// create low level objects
|
// create low level objects
|
||||||
var lDoc v2.SecurityRequirement
|
var lDoc base.SecurityRequirement
|
||||||
var rDoc v2.SecurityRequirement
|
var rDoc base.SecurityRequirement
|
||||||
_ = low.BuildModel(&lNode, &lDoc)
|
_ = low.BuildModel(&lNode, &lDoc)
|
||||||
_ = low.BuildModel(&rNode, &rDoc)
|
_ = low.BuildModel(&rNode, &rDoc)
|
||||||
_ = lDoc.Build(lNode.Content[0], nil)
|
_ = lDoc.Build(lNode.Content[0], nil)
|
||||||
_ = rDoc.Build(rNode.Content[0], nil)
|
_ = rDoc.Build(rNode.Content[0], nil)
|
||||||
|
|
||||||
// compare
|
// compare
|
||||||
extChanges := CompareSecurityRequirementV2(&lDoc, &rDoc)
|
extChanges := CompareSecurityRequirement(&lDoc, &rDoc)
|
||||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCompareSecurityRequirement_V3(t *testing.T) {
|
//
|
||||||
|
//func TestCompareSecurityRequirement_V3(t *testing.T) {
|
||||||
left := `- auth:
|
//
|
||||||
- pizza
|
// left := `- auth:
|
||||||
- pie`
|
// - pizza
|
||||||
|
// - pie`
|
||||||
right := `- auth:
|
//
|
||||||
- pie
|
// right := `- auth:
|
||||||
- pizza`
|
// - pie
|
||||||
|
// - pizza`
|
||||||
var lNode, rNode yaml.Node
|
//
|
||||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
// var lNode, rNode yaml.Node
|
||||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
// _ = yaml.Unmarshal([]byte(left), &lNode)
|
||||||
|
// _ = yaml.Unmarshal([]byte(right), &rNode)
|
||||||
// create low level objects
|
//
|
||||||
var lDoc v3.SecurityRequirement
|
// // create low level objects
|
||||||
var rDoc v3.SecurityRequirement
|
// var lDoc v3.SecurityRequirement
|
||||||
_ = low.BuildModel(&lNode, &lDoc)
|
// var rDoc v3.SecurityRequirement
|
||||||
_ = low.BuildModel(&rNode, &rDoc)
|
// _ = low.BuildModel(&lNode, &lDoc)
|
||||||
_ = lDoc.Build(lNode.Content[0], nil)
|
// _ = low.BuildModel(&rNode, &rDoc)
|
||||||
_ = rDoc.Build(rNode.Content[0], nil)
|
// _ = lDoc.Build(lNode.Content[0], nil)
|
||||||
|
// _ = rDoc.Build(rNode.Content[0], nil)
|
||||||
// compare
|
//
|
||||||
extChanges := CompareSecurityRequirementV3(&lDoc, &rDoc)
|
// // compare
|
||||||
assert.Nil(t, extChanges)
|
// extChanges := CompareSecurityRequirementV3(&lDoc, &rDoc)
|
||||||
}
|
// assert.Nil(t, extChanges)
|
||||||
|
//}
|
||||||
func TestCompareSecurityRequirement_V3_AddARole(t *testing.T) {
|
//
|
||||||
|
//func TestCompareSecurityRequirement_V3_AddARole(t *testing.T) {
|
||||||
left := `- auth:
|
//
|
||||||
- pizza
|
// left := `- auth:
|
||||||
- pie`
|
// - pizza
|
||||||
|
// - pie`
|
||||||
right := `- auth:
|
//
|
||||||
- pie
|
// right := `- auth:
|
||||||
- pizza
|
// - pie
|
||||||
- beer`
|
// - pizza
|
||||||
|
// - beer`
|
||||||
var lNode, rNode yaml.Node
|
//
|
||||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
// var lNode, rNode yaml.Node
|
||||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
// _ = yaml.Unmarshal([]byte(left), &lNode)
|
||||||
|
// _ = yaml.Unmarshal([]byte(right), &rNode)
|
||||||
// create low level objects
|
//
|
||||||
var lDoc v3.SecurityRequirement
|
// // create low level objects
|
||||||
var rDoc v3.SecurityRequirement
|
// var lDoc v3.SecurityRequirement
|
||||||
_ = low.BuildModel(&lNode, &lDoc)
|
// var rDoc v3.SecurityRequirement
|
||||||
_ = low.BuildModel(&rNode, &rDoc)
|
// _ = low.BuildModel(&lNode, &lDoc)
|
||||||
_ = lDoc.Build(lNode.Content[0], nil)
|
// _ = low.BuildModel(&rNode, &rDoc)
|
||||||
_ = rDoc.Build(rNode.Content[0], nil)
|
// _ = lDoc.Build(lNode.Content[0], nil)
|
||||||
|
// _ = rDoc.Build(rNode.Content[0], nil)
|
||||||
// compare
|
//
|
||||||
extChanges := CompareSecurityRequirementV3(&lDoc, &rDoc)
|
// // compare
|
||||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
// extChanges := CompareSecurityRequirementV3(&lDoc, &rDoc)
|
||||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
// assert.Equal(t, 1, extChanges.TotalChanges())
|
||||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
// assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||||
}
|
// assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||||
|
//}
|
||||||
func TestCompareSecurityRequirement_V3_RemoveRole(t *testing.T) {
|
//
|
||||||
|
//func TestCompareSecurityRequirement_V3_RemoveRole(t *testing.T) {
|
||||||
left := `- auth:
|
//
|
||||||
- pizza
|
// left := `- auth:
|
||||||
- pie`
|
// - pizza
|
||||||
|
// - pie`
|
||||||
right := `- auth:
|
//
|
||||||
- pie
|
// right := `- auth:
|
||||||
- pizza
|
// - pie
|
||||||
- beer`
|
// - pizza
|
||||||
|
// - beer`
|
||||||
var lNode, rNode yaml.Node
|
//
|
||||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
// var lNode, rNode yaml.Node
|
||||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
// _ = yaml.Unmarshal([]byte(left), &lNode)
|
||||||
|
// _ = yaml.Unmarshal([]byte(right), &rNode)
|
||||||
// create low level objects
|
//
|
||||||
var lDoc v3.SecurityRequirement
|
// // create low level objects
|
||||||
var rDoc v3.SecurityRequirement
|
// var lDoc v3.SecurityRequirement
|
||||||
_ = low.BuildModel(&lNode, &lDoc)
|
// var rDoc v3.SecurityRequirement
|
||||||
_ = low.BuildModel(&rNode, &rDoc)
|
// _ = low.BuildModel(&lNode, &lDoc)
|
||||||
_ = lDoc.Build(lNode.Content[0], nil)
|
// _ = low.BuildModel(&rNode, &rDoc)
|
||||||
_ = rDoc.Build(rNode.Content[0], nil)
|
// _ = lDoc.Build(lNode.Content[0], nil)
|
||||||
|
// _ = rDoc.Build(rNode.Content[0], nil)
|
||||||
// compare
|
//
|
||||||
extChanges := CompareSecurityRequirementV3(&rDoc, &lDoc)
|
// // compare
|
||||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
// extChanges := CompareSecurityRequirementV3(&rDoc, &lDoc)
|
||||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
// assert.Equal(t, 1, extChanges.TotalChanges())
|
||||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
// assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||||
}
|
// assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||||
|
//}
|
||||||
func TestCompareSecurityRequirement_V3_AddAReq(t *testing.T) {
|
//
|
||||||
|
//func TestCompareSecurityRequirement_V3_AddAReq(t *testing.T) {
|
||||||
left := `- auth:
|
//
|
||||||
- pizza
|
// left := `- auth:
|
||||||
- pie`
|
// - pizza
|
||||||
|
// - pie`
|
||||||
right := `- auth:
|
//
|
||||||
- pie
|
// right := `- auth:
|
||||||
- pizza
|
// - pie
|
||||||
- coffee:
|
// - pizza
|
||||||
- filter
|
//- coffee:
|
||||||
- espresso`
|
// - filter
|
||||||
|
// - espresso`
|
||||||
var lNode, rNode yaml.Node
|
//
|
||||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
// var lNode, rNode yaml.Node
|
||||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
// _ = yaml.Unmarshal([]byte(left), &lNode)
|
||||||
|
// _ = yaml.Unmarshal([]byte(right), &rNode)
|
||||||
// create low level objects
|
//
|
||||||
var lDoc v3.SecurityRequirement
|
// // create low level objects
|
||||||
var rDoc v3.SecurityRequirement
|
// var lDoc v3.SecurityRequirement
|
||||||
_ = low.BuildModel(&lNode, &lDoc)
|
// var rDoc v3.SecurityRequirement
|
||||||
_ = low.BuildModel(&rNode, &rDoc)
|
// _ = low.BuildModel(&lNode, &lDoc)
|
||||||
_ = lDoc.Build(lNode.Content[0], nil)
|
// _ = low.BuildModel(&rNode, &rDoc)
|
||||||
_ = rDoc.Build(rNode.Content[0], nil)
|
// _ = lDoc.Build(lNode.Content[0], nil)
|
||||||
|
// _ = rDoc.Build(rNode.Content[0], nil)
|
||||||
// compare
|
//
|
||||||
extChanges := CompareSecurityRequirementV3(&lDoc, &rDoc)
|
// // compare
|
||||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
// extChanges := CompareSecurityRequirementV3(&lDoc, &rDoc)
|
||||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
// assert.Equal(t, 1, extChanges.TotalChanges())
|
||||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
// assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||||
}
|
// assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||||
|
//}
|
||||||
func TestCompareSecurityRequirement_V3_RemoveAReq(t *testing.T) {
|
//
|
||||||
|
//func TestCompareSecurityRequirement_V3_RemoveAReq(t *testing.T) {
|
||||||
left := `- coffee:
|
//
|
||||||
- filter
|
// left := `- coffee:
|
||||||
- espresso`
|
// - filter
|
||||||
|
// - espresso`
|
||||||
right := `- coffee:
|
//
|
||||||
- filter
|
// right := `- coffee:
|
||||||
- espresso
|
// - filter
|
||||||
- auth:
|
// - espresso
|
||||||
- pizza
|
//- auth:
|
||||||
- pie`
|
// - pizza
|
||||||
|
// - pie`
|
||||||
var lNode, rNode yaml.Node
|
//
|
||||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
// var lNode, rNode yaml.Node
|
||||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
// _ = yaml.Unmarshal([]byte(left), &lNode)
|
||||||
|
// _ = yaml.Unmarshal([]byte(right), &rNode)
|
||||||
// create low level objects
|
//
|
||||||
var lDoc v3.SecurityRequirement
|
// // create low level objects
|
||||||
var rDoc v3.SecurityRequirement
|
// var lDoc v3.SecurityRequirement
|
||||||
_ = low.BuildModel(&lNode, &lDoc)
|
// var rDoc v3.SecurityRequirement
|
||||||
_ = low.BuildModel(&rNode, &rDoc)
|
// _ = low.BuildModel(&lNode, &lDoc)
|
||||||
_ = lDoc.Build(lNode.Content[0], nil)
|
// _ = low.BuildModel(&rNode, &rDoc)
|
||||||
_ = rDoc.Build(rNode.Content[0], nil)
|
// _ = lDoc.Build(lNode.Content[0], nil)
|
||||||
|
// _ = rDoc.Build(rNode.Content[0], nil)
|
||||||
// compare
|
//
|
||||||
extChanges := CompareSecurityRequirementV3(&rDoc, &lDoc)
|
// // compare
|
||||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
// extChanges := CompareSecurityRequirementV3(&rDoc, &lDoc)
|
||||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
// assert.Equal(t, 1, extChanges.TotalChanges())
|
||||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
// assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||||
}
|
// assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||||
|
//}
|
||||||
|
|||||||
Reference in New Issue
Block a user