{{ 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 }}