oapi-codegen icon indicating copy to clipboard operation
oapi-codegen copied to clipboard

staticcheck failes: define your own type to avoid collisions (SA1029)

Open tempcke opened this issue 2 years ago • 3 comments

when security is defined in the openapi yaml like the following

paths:
  /foo:
    get:
      # ...
      security:
        - key: []
          secret: []
components:
  securitySchemes:
    key:
      type: apiKey
      in: header
      name: X-API-Key
    secret:
      type: apiKey
      in: header
      name: X-API-Secret

Then in the generated code it creates constants which it uses as context value keys like so

const (
	KeyScopes    = "key.Scopes"
	SecretScopes = "secret.Scopes"
)

func (siw *ServerInterfaceWrapper) GetFoo(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	ctx = context.WithValue(ctx, KeyScopes, []string{})

	ctx = context.WithValue(ctx, SecretScopes, []string{})

	handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		siw.Handler.GetFoo(w, r)
	}))

	for _, middleware := range siw.HandlerMiddlewares {
		handler = middleware(handler)
	}

	handler.ServeHTTP(w, r.WithContext(ctx))
}

which fails staticcheck

$ staticcheck ./...
api.gen.go:117:31:  should not use built-in type string as key for value; define your own type to avoid collisions (SA1029)

solution is to simply have the constants use a custom unexported type like this

type ctxKey string

const (
	KeyScopes    ctxKey = "key.Scopes"
	SecretScopes ctxKey = "secret.Scopes"
)

tempcke avatar Aug 20 '23 13:08 tempcke

I'm also having this issue. As far as I can see this is the section in need of modification. https://github.com/deepmap/oapi-codegen/blob/46d269400f4bd1f4da2f5e6b84cdf7f3f2d753dd/pkg/codegen/templates/constants.tmpl#L1-L6

asger-noer avatar Sep 21 '23 00:09 asger-noer

But @tempcke, if you want to fix this before a fix is made in oapi-codegen there is an option to do the following:

Create a local templates/constants.tmpl:

{{- if gt (len .SecuritySchemeProviderNames) 0 }}

// contextKey provides a type for use with context.WithValue.
type contextKey string

const (
{{range $ProviderName := .SecuritySchemeProviderNames}}
    {{- $ProviderName | sanitizeGoIdentity | ucFirst}}Scopes contextKey = "{{$ProviderName}}.Scopes"
{{end}}
)
{{end}}
{{range $Enum := .EnumDefinitions}}
// Defines values for {{$Enum.TypeName}}.
const (
{{range $name, $value := $Enum.GetValues}}
  {{$name}} {{$Enum.TypeName}} = {{$Enum.ValueWrapper}}{{$value}}{{$Enum.ValueWrapper -}}
{{end}}
)
{{end}}

Then add this to your config file:

# ...
output-options:
  user-templates: 
    constants.tmpl: templates/constants.tmpl
# ...

asger-noer avatar Sep 21 '23 00:09 asger-noer

The snippet from @asger-noer works like a charm, would be great to get this fix included.

tboerger avatar May 13 '24 15:05 tboerger