Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 0 additions & 54 deletions examples/go.sum

Large diffs are not rendered by default.

51 changes: 0 additions & 51 deletions internal/test/go.sum

Large diffs are not rendered by default.

174 changes: 174 additions & 0 deletions internal/test/issues/issue-2367/api.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions internal/test/issues/issue-2367/cfg.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# yaml-language-server: $schema=../../../../configuration-schema.json
package: issue2367
output: api.gen.go
generate:
gin-server: true
strict-server: true
models: true
3 changes: 3 additions & 0 deletions internal/test/issues/issue-2367/generate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package issue2367

//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=cfg.yaml spec.yaml
23 changes: 23 additions & 0 deletions internal/test/issues/issue-2367/issue_2367_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package issue2367

import (
"testing"

"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
)

// stubServer satisfies ServerInterface and lets the test prove the generated
// package compiles end-to-end. The bug in issue 2367 emitted a constant
// referencing a context-key type that was never declared (because the spec's
// `security:` named a scheme not present under components/securitySchemes),
// so the generated file failed to compile. Instantiating the interface here
// would not be reachable if that regression returned.
type stubServer struct{}

func (stubServer) GetHello(c *gin.Context) {}

func TestGeneratedServerCompilesWithUndefinedSecurityScheme(t *testing.T) {
var iface ServerInterface = stubServer{}
assert.NotNil(t, iface)
}
13 changes: 13 additions & 0 deletions internal/test/issues/issue-2367/spec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
openapi: "3.0.0"
info:
title: issue-2367
version: 1.0.0
security:
- api_key: []
paths:
/hello:
get:
operationId: getHello
responses:
"200":
description: ok
26 changes: 26 additions & 0 deletions pkg/codegen/operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,21 @@ func DescribeSecurityDefinition(securityRequirements openapi3.SecurityRequiremen
return outDefs
}

// filterOutUndefinedSecuritySchemes drops any SecurityDefinition whose ProviderName
// is not present in defined. A `security` requirement that references an
// unknown scheme would otherwise produce a constant declaration and middleware
// references against a context-key type that is never emitted (the type is
// only generated for entries in components/securitySchemes).
func filterOutUndefinedSecuritySchemes(defs []SecurityDefinition, defined map[string]struct{}) []SecurityDefinition {
out := make([]SecurityDefinition, 0, len(defs))
for _, d := range defs {
if _, ok := defined[d.ProviderName]; ok {
out = append(out, d)
}
}
return out
}

// OperationDefinition describes an Operation
type OperationDefinition struct {
// OperationId is the `operationId` field from the OpenAPI Specification, after going through a `nameNormalizer`, and will be used to generate function names
Expand Down Expand Up @@ -745,6 +760,16 @@ func OperationDefinitions(swagger *openapi3.T) ([]OperationDefinition, error) {
return operations, nil
}

// Collect the names of security schemes actually defined under
// components/securitySchemes. Requirements that reference an undefined
// scheme are filtered out below so generated code stays compilable.
definedSecuritySchemes := map[string]struct{}{}
if swagger.Components != nil {
for name := range swagger.Components.SecuritySchemes {
definedSecuritySchemes[name] = struct{}{}
}
}

// Track alias counters for generating unique client method names
// when multiple paths $ref the same path item.
aliasCounters := map[string]int{}
Expand Down Expand Up @@ -881,6 +906,7 @@ func OperationDefinitions(swagger *openapi3.T) ([]OperationDefinition, error) {
opDef.SecurityDefinitions = DescribeSecurityDefinition(swagger.Security)

}
opDef.SecurityDefinitions = filterOutUndefinedSecuritySchemes(opDef.SecurityDefinitions, definedSecuritySchemes)

if op.RequestBody != nil {
opDef.BodyRequired = op.RequestBody.Value.Required
Expand Down
Loading