Files
catalyst/generator/templates/parameter.gotmpl
2021-12-13 00:39:15 +01:00

348 lines
16 KiB
Go Template

{{ define "sliceparamvalidator"}}
{{ if or .MinItems .MaxItems }}
{{ camelize .Name }}Size := int64(len({{ if and (not .IsArray) (not .HasDiscriminator) (not .IsInterface) (not .IsStream) .IsNullable }}*{{ end }}{{ .ValueExpression }}))
{{ end }}
{{ if .MinItems }}
if err := validate.MinItems({{ .Path }}, {{ printf "%q" .Location }}, {{ camelize .Name }}Size, {{ .MinItems }}); err != nil {
return err
}
{{ end }}
{{ if .MaxItems }}
if err := validate.MaxItems({{ .Path }}, {{ printf "%q" .Location }}, {{ camelize .Name }}Size, {{.MaxItems}}); err != nil {
return err
}
{{ end }}
{{ if .UniqueItems }}
if err := validate.UniqueItems({{ .Path }}, {{ printf "%q" .Location }}, {{ if and (not .IsArray) (not .HasDiscriminator) (not .IsInterface) (not .IsStream) .IsNullable }}*{{ end }}{{ .ValueExpression }}); err != nil {
return err
}
{{ end }}
{{ if .Enum }}
if err := validate.Enum({{ .Path }}, {{ printf "%q" .Location }}, {{ if and (not .IsArray) (not .HasDiscriminator) (not .IsInterface) (not .IsStream) .IsNullable }}*{{ end }}{{ .ValueExpression }}, {{ .Enum }}); err != nil {
return err
}
{{ end }}
{{ end }}
{{ define "customValidationPrimitive" }}
{{if .MinLength}}
if err := validate.MinLength({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf "%q" .Location }}, {{ if .IsNullable }}(*{{ end }}{{.ValueExpression}}{{ if .IsNullable }}){{ end }}{{ if .IsCustomFormatter }}.String(){{ end }}, {{.MinLength}}); err != nil {
return err
}
{{end}}
{{if .MaxLength}}
if err := validate.MaxLength({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf "%q" .Location }}, {{ if .IsNullable }}(*{{ end }}{{.ValueExpression}}{{ if .IsNullable }}){{ end }}{{ if .IsCustomFormatter }}.String(){{ end }}, {{.MaxLength}}); err != nil {
return err
}
{{end}}
{{if .Pattern}}
if err := validate.Pattern({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf "%q" .Location }}, {{ if .IsNullable }}(*{{ end }}{{.ValueExpression}}{{ if .IsNullable }}){{ end }}{{ if .IsCustomFormatter }}.String(){{ end }}, `{{.Pattern}}`); err != nil {
return err
}
{{end}}
{{if .Minimum}}
if err := validate.Minimum{{ if eq .SwaggerType "integer" }}Int{{ end }}({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf "%q" .Location }}, {{ if eq .SwaggerType "integer" }}int{{ else }}float{{ end }}64({{ if .IsNullable }}*{{ end }}{{.ValueExpression}}), {{.Minimum}}, {{.ExclusiveMinimum}}); err != nil {
return err
}
{{end}}
{{if .Maximum}}
if err := validate.Maximum{{ if eq .SwaggerType "integer" }}Int{{ end }}({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf "%q" .Location }}, {{ if eq .SwaggerType "integer" }}int{{ else }}float{{ end }}64({{ if .IsNullable }}*{{ end }}{{.ValueExpression}}), {{.Maximum}}, {{.ExclusiveMaximum}}); err != nil {
return err
}
{{end}}
{{if .MultipleOf}}
if err := validate.MultipleOf({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf "%q" .Location }}, float64({{ if .IsNullable }}*{{ end }}{{.ValueExpression}}), {{.MultipleOf}}); err != nil {
return err
}
{{end}}
{{if .Enum}}
if err := validate.Enum({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf "%q" .Location }}, {{ if and (not .IsArray) (not .HasDiscriminator) (not .IsInterface) .IsNullable }}*{{ end }}{{.ValueExpression}}{{ if .IsCustomFormatter }}.String(){{ end }}, {{ printf "%#v" .Enum}}); err != nil {
return err
}
{{end}}
{{end}}
{{ define "propertyparamvalidator" }}
{{ if .IsPrimitive }}{{ template "customValidationPrimitive" . }}{{ end }}
{{ if .IsCustomFormatter }}
if err := validate.FormatOf({{.Path}}, "{{.Location}}", "{{.SwaggerFormat}}", {{.ValueExpression}}.String(), formats); err != nil {
return err
}{{ end }}
{{ if .IsArray }}{{ template "sliceparamvalidator" . }}{{ end -}}
{{ end }}
{{define "bindprimitiveparam" }}
{{ end }}
{{ define "sliceparambinder" }}
var {{ varname .Child.ValueExpression }}R {{ .GoType }}
for {{ if or .Child.HasValidations .Child.Converter .Child.IsCustomFormatter }}{{ .IndexVar }}{{ else }}_{{ end }}, {{ varname .Child.ValueExpression }}V := range {{ varname .Child.ValueExpression }}C {
{{ if or .Child.IsArray -}}
{{ .Child.Child.ValueExpression }}C := swag.SplitByFormat({{ varname .Child.ValueExpression }}V, {{ printf "%q" .Child.CollectionFormat }})
{{ template "sliceparambinder" .Child }}
{{- else -}}
{{ if .Child.Converter -}}
{{ varname .Child.ValueExpression }}, err := {{ .Child.Converter }}({{ varname .Child.ValueExpression }}V)
if err != nil {
return errors.InvalidType({{ .Child.Path }}, {{ printf "%q" .Child.Location }}, "{{ .Child.GoType }}", {{ varname .Child.ValueExpression }})
}
{{- else if .Child.IsCustomFormatter -}}
{{ varname .Child.ValueExpression }}, err := formats.Parse({{ varname .Child.ValueExpression }}V)
if err != nil {
return errors.InvalidType({{ .Child.Path }}, {{ printf "%q" .Child.Location }}, "{{ .Child.GoType }}", {{ varname .Child.ValueExpression }})
}
{{- else -}}
{{ varname .Child.ValueExpression }} := {{ varname .Child.ValueExpression }}V
{{ end }}
{{- end }}
{{ template "propertyparamvalidator" .Child }}
{{ varname .Child.ValueExpression }}R = append({{ varname .Child.ValueExpression }}R, {{ varname .Child.ValueExpression }})
}
{{ end }}
package {{ .Package }}
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"github.com/gin-gonic/gin"
"github.com/go-openapi/errors"
"github.com/go-openapi/validate"
"github.com/go-openapi/runtime"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/swag"
strfmt "github.com/go-openapi/strfmt"
{{ range .DefaultImports }}{{ printf "%q" .}}
{{ end }}
{{ range $key, $value := .Imports }}{{ $key }} {{ printf "%q" $value }}
{{ end }}
"github.com/SecurityBrewery/catalyst/generated/restapi/api"
)
// {{ pascalize .Name }}Endpoint executes the core logic of the related
// route endpoint.
func {{ pascalize .Name }}Endpoint(handler func(ctx context.Context{{ if .Params }}, params *{{ pascalize .Name }}Params{{ end }}) *api.Response) gin.HandlerFunc {
return func (ctx *gin.Context) {
{{ if .Params }}// generate params from request
params := New{{ pascalize .Name }}Params()
err := params.ReadRequest(ctx)
if err != nil {
errObj := err.(*errors.CompositeError)
ctx.Writer.Header().Set("Content-Type", "application/problem+json")
ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()})
return
}
{{ end }}
resp := handler(ctx{{ if .Params }}, params{{end}})
switch resp.Code {
case http.StatusNoContent:
ctx.AbortWithStatus(resp.Code)
default:
ctx.JSON(resp.Code, resp.Body)
}
}
}
// New{{ pascalize .Name }}Params creates a new {{ pascalize .Name }}Params object
// with the default values initialized.
func New{{ pascalize .Name }}Params() *{{ pascalize .Name }}Params {
var (
{{ range .Params }}{{ if .HasDefault }}{{ if not .IsFileParam }}{{ varname .ID}}Default = {{ if .IsPrimitive}}{{.GoType}}({{ end}}{{ printf "%#v" .Default }}{{ if .IsPrimitive }}){{ end }}
{{ end }}{{ end }}{{end}}
)
return &{{ pascalize .Name }}Params{ {{ range .Params }}{{ if .HasDefault }}
{{ pascalize .ID}}: {{ if and (not .IsArray) (not .HasDiscriminator) (not .IsInterface) (not .IsStream) .IsNullable }}&{{ end }}{{ varname .ID }}Default,
{{ end }}{{ end }} }
}
// {{ pascalize .Name }}Params contains all the bound params for the {{ humanize .Name }} operation
// typically these are obtained from a http.Request
//
// swagger:parameters {{ .Name }}
type {{ pascalize .Name }}Params struct {
{{ range .Params }}/*{{ if .Description }}{{ .Description }}{{ end }}{{ if .Required }}
Required: true{{ end }}{{ if .Maximum }}
Maximum: {{ if .ExclusiveMaximum }}< {{ end }}{{ .Maximum }}{{ end }}{{ if .Minimum }}
Minimum: {{ if .ExclusiveMinimum }}> {{ end }}{{ .Minimum }}{{ end }}{{ if .MultipleOf }}
Multiple Of: {{ .MultipleOf }}{{ end }}{{ if .MaxLength }}
Max Length: {{ .MaxLength }}{{ end }}{{ if .MinLength }}
Min Length: {{ .MinLength }}{{ end }}{{ if .Pattern }}
Pattern: {{ .Pattern }}{{ end }}{{ if .MaxItems }}
Max Items: {{ .MaxItems }}{{ end }}{{ if .MinItems }}
Min Items: {{ .MinItems }}{{ end }}{{ if .UniqueItems }}
Unique: true{{ end }}{{ if .Location }}
In: {{ .Location }}{{ end }}{{ if .CollectionFormat }}
Collection Format: {{ .CollectionFormat }}{{ end }}{{ if .HasDefault }}
Default: {{ printf "%#v" .Default }}{{ end }}
*/
{{ if not .Schema }}{{ pascalize .ID }} {{ if and (not .IsArray) (not .HasDiscriminator) (not .IsInterface) (not .IsFileParam) (not .IsStream) .IsNullable }}*{{ end }}{{.GoType}}{{ else }}{{ pascalize .Name }} {{ if and (not .Schema.IsBaseType) .IsNullable (not .Schema.IsStream) }}*{{ end }}{{.GoType}}{{ end }}
{{ end}}
}
// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
// for simple values it will use straight method calls
func ({{ .ReceiverName }} *{{ pascalize .Name }}Params) ReadRequest(ctx *gin.Context) error {
var res []error
{{ if .HasQueryParams }}qs := runtime.Values(ctx.Request.URL.Query()){{ end }}
{{ if .HasFormParams }}if err := ctx.Request.ParseMultipartForm(32 << 20); err != nil {
if err != http.ErrNotMultipart {
return err
} else if err := ctx.Request.ParseForm(); err != nil {
return err
}
}{{ if .HasFormValueParams }}
fds := runtime.Values(ctx.Request.Form)
{{ end }}{{ end }}
{{ range .Params }}
{{ if not .IsArray }}{{ if .IsQueryParam }}q{{ pascalize .Name }}, qhk{{ pascalize .Name }}, _ := qs.GetOK({{ .Path }})
if err := {{ .ReceiverName }}.bind{{ pascalize .ID }}(q{{ pascalize .Name }}, qhk{{ pascalize .Name }}); err != nil {
res = append(res, err)
}
{{ else if .IsPathParam }}r{{ pascalize .Name }} := []string{ctx.Param({{ .Path }})}
if err := {{ .ReceiverName }}.bind{{ pascalize .ID }}(r{{ pascalize .Name }}, true); err != nil {
res = append(res, err)
}
{{ else if .IsHeaderParam }}if err := {{ .ReceiverName }}.bind{{ pascalize .ID }}(ctx.Request.Header[http.CanonicalHeaderKey({{ .Path }})], true); err != nil {
res = append(res, err)
}
{{ else if .IsFormParam }}{{if .IsFileParam }}{{ camelize .Name }}, {{ camelize .Name }}Header, err := ctx.Request.FormFile({{ .Path }})
if err != nil {
res = append(res, errors.New(400, "reading file %q failed: %v", {{ printf "%q" (camelize .Name) }}, err))
} else {
{{ .ReceiverName }}.{{ pascalize .Name }} = &runtime.File{Data: {{ camelize .Name }}, Header: {{ camelize .Name }}Header}
}
{{ else }}fd{{ pascalize .Name }}, fdhk{{ pascalize .Name }}, _ := fds.GetOK({{ .Path }})
if err := {{ .ReceiverName }}.bind{{ pascalize .ID }}(fd{{ pascalize .Name }}, fdhk{{ pascalize .Name }}); err != nil {
res = append(res, err)
}
{{ end }}{{ end }}
{{ else if .IsArray }}{{ if .IsQueryParam }}q{{ pascalize .Name }}, qhk{{ pascalize .Name }}, _ := qs.GetOK({{ .Path }})
if err := {{ .ReceiverName }}.bind{{ pascalize .ID }}(q{{ pascalize .Name }}, qhk{{ pascalize .Name }}); err != nil {
res = append(res, err)
}
{{ else if and .IsFormParam }}fd{{ pascalize .Name }}, fdhk{{ pascalize .Name }}, _ := fds.GetOK({{ .Path }})
if err := {{ .ReceiverName }}.bind{{ pascalize .ID }}(fd{{ pascalize .Name }}, fdhk{{ pascalize .Name }}); err != nil {
res = append(res, err)
}
{{ end }}{{ end }}
{{ if and .IsBodyParam .Schema }}if runtime.HasBody(ctx.Request) {
{{ if .Schema.IsStream }}{{ .ReceiverName }}.{{ pascalize .Name }} = ctx.Request.Body
{{ else }}{{ if and .Schema.IsBaseType .Schema.IsExported }}body, err := {{ .ModelsPackage }}.Unmarshal{{ dropPackage .GoType }}{{ if .IsArray }}Slice{{ end }}(ctx.Request.Body, route.Consumer)
if err != nil { {{ if .Required }}
if err == io.EOF {
err = errors.Required({{ .Path }}, {{ printf "%q" .Location }}, "")
}
{{ end }}res = append(res, err)
{{ else }}var body {{ .GoType }}
if err := ctx.BindJSON(&body); err != nil { {{ if .Required }}
if err == io.EOF {
res = append(res, errors.Required({{ printf "%q" (camelize .Name) }}, {{ printf "%q" .Location }}, ""))
} else { {{ end }}
res = append(res, errors.NewParseError({{ printf "%q" (camelize .Name) }}, {{ printf "%q" .Location }}, "", err)){{ if .Required }}
}
{{ end }}
{{ end }}} else {
{{ .ReceiverName }}.{{ pascalize .Name }} = {{ if and (not .Schema.IsBaseType) .IsNullable }}&{{ end }}body
}{{ end }}
}{{ if .Required }} else {
res = append(res, errors.Required({{ printf "%q" (camelize .Name) }}, {{ printf "%q" .Location }}, ""))
} {{ end }}
{{ end }}
{{ end }}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
{{ $className := (pascalize .Name) }}
{{ range .Params }}
{{ if not (or .IsBodyParam .IsFileParam) }}
{{ if or .IsPrimitive .IsCustomFormatter }}
func ({{ .ReceiverName }} *{{ $className }}Params) bind{{ pascalize .ID }}(rawData []string, hasKey bool) error {
{{ if and (not .IsPathParam) .Required }}if !hasKey {
return errors.Required({{ .Path }}, {{ printf "%q" .Location }}, rawData)
}
{{ end }}var raw string
if len(rawData) > 0 {
raw = rawData[len(rawData)-1]
}
{{ if and (not .IsPathParam) .Required (not .AllowEmptyValue) }}if err := validate.RequiredString({{ .Path }}, {{ printf "%q" .Location }}, raw); err != nil {
return err
}
{{ else if and ( not .IsPathParam ) (or (not .Required) .AllowEmptyValue) }}if raw == "" { // empty values pass all other validations
{{ if .HasDefault }}var {{ camelize .Name}}Default {{ if not .IsFileParam }}{{ .GoType }}{{ else }}os.File{{end}} = {{ if .IsPrimitive}}{{.GoType}}({{ end}}{{ printf "%#v" .Default }}{{ if .IsPrimitive }}){{ end }}
{{ .ValueExpression }} = {{ if and (not .IsArray) (not .HasDiscriminator) (or .IsNullable ) (not .IsStream) }}&{{ end }}{{ camelize .Name }}Default
{{ end }}return nil
}
{{ end }}
{{ if .Converter }}value, err := {{ .Converter }}(raw)
if err != nil {
return errors.InvalidType({{ .Path }}, {{ printf "%q" .Location }}, {{ printf "%q" .GoType }}, raw)
}
{{ .ValueExpression }} = {{ if .IsNullable }}&{{ end }}value
{{ else if .IsCustomFormatter }}value, err := formats.Parse({{ printf "%q" .SwaggerFormat }}, raw)
if err != nil {
return errors.InvalidType({{ .Path }}, {{ printf "%q" .Location }}, {{ printf "%q" .GoType }}, raw)
}
{{ .ValueExpression }} = {{ if and (not .IsArray) (not .HasDiscriminator) (not .IsFileParam) (not .IsStream) (not .IsNullable) }}*{{ end }}(value.(*{{ .GoType }}))
{{else}}{{ .ValueExpression }} = {{ if .IsNullable }}&{{ end }}raw
{{ end }}
{{if .HasValidations }}if err := {{ .ReceiverName }}.validate{{ pascalize .ID }}(); err != nil {
return err
}
{{ end }}
return nil
}
{{else if .IsArray}}
func ({{ .ReceiverName }} *{{ $className }}Params) bind{{ pascalize .ID }}(rawData []string, hasKey bool) error {
{{if .Required }}if !hasKey {
return errors.Required({{ .Path }}, {{ printf "%q" .Location }}, rawData)
}
{{ end }}
{{ if eq .CollectionFormat "multi" }}{{ varname .Child.ValueExpression }}C := rawData{{ else }}var qv{{ pascalize .Name }} string
if len(rawData) > 0 {
qv{{ pascalize .Name }} = rawData[len(rawData) - 1]
}
{{ varname .Child.ValueExpression }}C := swag.SplitByFormat(qv{{ pascalize .Name }}, {{ printf "%q" .CollectionFormat }}){{ end }}
{{if and .Required (not .AllowEmptyValue) }}
if len({{ varname .Child.ValueExpression }}C) == 0 {
return errors.Required({{ .Path }}, {{ printf "%q" .Location }}, {{ varname .Child.ValueExpression }}C)
}
{{ end }}
{{ if not .Required }}{{ if .HasDefault }}defValue := swag.SplitByFormat({{ .Default }}, {{ printf "%q" .CollectionFormat }})
if len({{ varname .Child.ValueExpression }}C) == 0 && len(defValue) > 0 {
{{ .ValueExpression }} = defValue
{{ else }}if len({{ varname .Child.ValueExpression }}C) == 0 {
return nil{{ end }}
}{{ end }}
{{ template "sliceparambinder" . }}
{{ .ValueExpression }} = {{ varname .Child.ValueExpression }}R
{{ if .HasSliceValidations }}if err := {{ .ReceiverName }}.validate{{ pascalize .ID }}(); err != nil {
return err
}
{{ end }}
return nil
}
{{ end }}
{{ if or .HasValidations .HasSliceValidations }}
func ({{ .ReceiverName }} *{{ $className }}Params) validate{{ pascalize .ID }}() error {
{{ template "propertyparamvalidator" . }}
return nil
}
{{ end }}
{{ end }}
{{ end }}