snapshot of https://github.com/ory/keto.git (master, 2026-09-16; blobs > 131072B omitted)
Some checks failed
CI / Run lints and checks (push) Failing after 47s
CI / Run tests (push) Failing after 1s
CI / Run race tests (push) Failing after 5s
CI / Build CLI docs (push) Has been skipped
CI / Run buf actions (push) Failing after 5s
CodeQL / Analyze (go) (push) Failing after 3s
CodeQL / Analyze (javascript) (push) Failing after 2s
Docker Image Scanners / scanners (push) Failing after 3s
Format / format (push) Failing after 3s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Draft newsletter (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped

This commit is contained in:
upstream-mirror
2026-09-16 01:08:34 +05:00
commit 9456a4e922
2560 changed files with 120911 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
disallowAdditionalPropertiesIfNotPresent: true
packageName: client
generateInterfaces: true
isGoSubmodule: false
structPrefix: true
enumClassPrefix: true

View File

@@ -0,0 +1,7 @@
npmName: "@ory/kratos-client"
npmVersion: 0.0.0
# typescriptThreePlus: true
#npmRepository: https://github.com/ory/sdk.git
supportsES6: true
ensureUniqueParams: true
modelPropertyNaming: original

View File

@@ -0,0 +1,94 @@
- op: replace
path: /paths/~1health~1alive
value:
get:
description: |-
This endpoint returns a HTTP 200 status code when {{.ProjectHumanName}} is accepting incoming
HTTP requests. This status does currently not include checks whether the database connection is working.
If the service supports TLS Edge Termination, this endpoint does not require the
`X-Forwarded-Proto` header to be set.
Be aware that if you are running multiple nodes of this service, the health status will never
refer to the cluster state, only to a single instance.
operationId: isAlive
responses:
'200':
content:
application/json:
schema:
"$ref": "#/components/schemas/healthStatus"
description: {{.ProjectHumanName}} is ready to accept connections.
'500':
content:
application/json:
schema:
"$ref": "#/components/schemas/genericError"
description: genericError
summary: Check HTTP Server Status
tags: {{ .HealthPathTags | toJson }}
- op: replace
path: /paths/~1health~1ready
value:
get:
operationId: isReady
description: |-
This endpoint returns a HTTP 200 status code when {{.ProjectHumanName}} is up running and the environment dependencies (e.g.
the database) are responsive as well.
If the service supports TLS Edge Termination, this endpoint does not require the
`X-Forwarded-Proto` header to be set.
Be aware that if you are running multiple nodes of {{.ProjectHumanName}}, the health status will never
refer to the cluster state, only to a single instance.
responses:
'200':
content:
application/json:
schema:
type: object
properties:
status:
description: Always "ok".
type: string
description: {{.ProjectHumanName}} is ready to accept requests.
'503':
content:
application/json:
schema:
properties:
errors:
additionalProperties:
type: string
description: Errors contains a list of errors that caused the not ready status.
type: object
type: object
description: Ory Kratos is not yet ready to accept requests.
summary: Check HTTP Server and Database Status
tags: {{ .HealthPathTags | toJson }}
- op: replace
path: /paths/~1version
value:
get:
description: |-
This endpoint returns the version of {{.ProjectHumanName}}.
If the service supports TLS Edge Termination, this endpoint does not require the
`X-Forwarded-Proto` header to be set.
Be aware that if you are running multiple nodes of this service, the version will never
refer to the cluster state, only to a single instance.
operationId: getVersion
responses:
'200':
content:
application/json:
schema:
type: object
properties:
version:
description: The version of {{.ProjectHumanName}}.
type: string
description: Returns the {{.ProjectHumanName}} version.
summary: Return Running Software Version.
tags: {{ .HealthPathTags | toJson }}

View File

@@ -0,0 +1,12 @@
- op: replace
path: /info
value:
title: Ory Keto API
description: |
Documentation for all of Ory Keto's REST APIs. gRPC is documented separately.
version: >-
{{ getenv "CIRCLE_TAG" }}
license:
name: Apache 2.0
contact:
email: "hi@ory.sh"

View File

@@ -0,0 +1,7 @@
language: go
install:
- go get -d -v .
script:
- go build -v ./

View File

@@ -0,0 +1,221 @@
# Go API client for {{packageName}}
{{#appDescriptionWithNewLines}}
{{{appDescriptionWithNewLines}}}
{{/appDescriptionWithNewLines}}
## Overview
This API client was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using the [OpenAPI-spec](https://www.openapis.org/) from a remote server, you can easily generate an API client.
- API version: {{appVersion}}
- Package version: {{packageVersion}}
{{^hideGenerationTimestamp}}
- Build date: {{generatedDate}}
{{/hideGenerationTimestamp}}
- Build package: {{generatorClass}}
{{#infoUrl}}
For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}})
{{/infoUrl}}
## Installation
Install the following dependencies:
```shell
go get github.com/stretchr/testify/assert
go get golang.org/x/oauth2
go get golang.org/x/net/context
```
Put the package under your project folder and add the following in import:
```golang
import {{packageName}} "{{gitHost}}/{{gitUserId}}/{{gitRepoId}}{{#isGoSubmodule}}/{{packageName}}{{/isGoSubmodule}}"
```
To use a proxy, set the environment variable `HTTP_PROXY`:
```golang
os.Setenv("HTTP_PROXY", "http://proxy_name:proxy_port")
```
## Configuration of Server URL
Default configuration comes with `Servers` field that contains server objects as defined in the OpenAPI specification.
### Select Server Configuration
For using other server than the one defined on index 0 set context value `sw.ContextServerIndex` of type `int`.
```golang
ctx := context.WithValue(context.Background(), {{packageName}}.ContextServerIndex, 1)
```
### Templated Server URL
Templated server URL is formatted using default variables from configuration or from context value `sw.ContextServerVariables` of type `map[string]string`.
```golang
ctx := context.WithValue(context.Background(), {{packageName}}.ContextServerVariables, map[string]string{
"basePath": "v2",
})
```
Note, enum values are always validated and all unused variables are silently ignored.
### URLs Configuration per Operation
Each operation can use different server URL defined using `OperationServers` map in the `Configuration`.
An operation is uniquely identifield by `"{classname}Service.{nickname}"` string.
Similar rules for overriding default operation server index and variables applies by using `sw.ContextOperationServerIndices` and `sw.ContextOperationServerVariables` context maps.
```
ctx := context.WithValue(context.Background(), {{packageName}}.ContextOperationServerIndices, map[string]int{
"{classname}Service.{nickname}": 2,
})
ctx = context.WithValue(context.Background(), {{packageName}}.ContextOperationServerVariables, map[string]map[string]string{
"{classname}Service.{nickname}": {
"port": "8443",
},
})
```
## Documentation for API Endpoints
All URIs are relative to *{{basePath}}*
Class | Method | HTTP request | Description
------------ | ------------- | ------------- | -------------
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | [**{{operationId}}**]({{apiDocPath}}{{classname}}.md#{{operationIdLowerCase}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{summary}}{{/summary}}
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
## Documentation For Models
{{#models}}{{#model}} - [{{{classname}}}]({{modelDocPath}}{{{classname}}}.md)
{{/model}}{{/models}}
## Documentation For Authorization
{{^authMethods}} Endpoints do not require authorization.
{{/authMethods}}{{#authMethods}}{{#last}} Authentication schemes defined for the API:{{/last}}{{/authMethods}}
{{#authMethods}}
### {{{name}}}
{{#isApiKey}}
- **Type**: API key
- **API key parameter name**: {{{keyParamName}}}
- **Location**: {{#isKeyInQuery}}URL query string{{/isKeyInQuery}}{{#isKeyInHeader}}HTTP header{{/isKeyInHeader}}
Note, each API key must be added to a map of `map[string]APIKey` where the key is: {{keyParamName}} and passed in as the auth context for each request.
{{/isApiKey}}
{{#isBasic}}
{{#isBasicBearer}}
- **Type**: HTTP Bearer token authentication
Example
```golang
auth := context.WithValue(context.Background(), sw.ContextAccessToken, "BEARER_TOKEN_STRING")
r, err := client.Service.Operation(auth, args)
```
{{/isBasicBearer}}
{{#isBasicBasic}}
- **Type**: HTTP basic authentication
Example
```golang
auth := context.WithValue(context.Background(), sw.ContextBasicAuth, sw.BasicAuth{
UserName: "username",
Password: "password",
})
r, err := client.Service.Operation(auth, args)
```
{{/isBasicBasic}}
{{#isHttpSignature}}
- **Type**: HTTP signature authentication
Example
```golang
authConfig := client.HttpSignatureAuth{
KeyId: "my-key-id",
PrivateKeyPath: "rsa.pem",
Passphrase: "my-passphrase",
SigningScheme: sw.HttpSigningSchemeHs2019,
SignedHeaders: []string{
sw.HttpSignatureParameterRequestTarget, // The special (request-target) parameter expresses the HTTP request target.
sw.HttpSignatureParameterCreated, // Time when request was signed, formatted as a Unix timestamp integer value.
"Host", // The Host request header specifies the domain name of the server, and optionally the TCP port number.
"Date", // The date and time at which the message was originated.
"Content-Type", // The Media type of the body of the request.
"Digest", // A cryptographic digest of the request body.
},
SigningAlgorithm: sw.HttpSigningAlgorithmRsaPSS,
SignatureMaxValidity: 5 * time.Minute,
}
var authCtx context.Context
var err error
if authCtx, err = authConfig.ContextWithValue(context.Background()); err != nil {
// Process error
}
r, err = client.Service.Operation(auth, args)
```
{{/isHttpSignature}}
{{/isBasic}}
{{#isOAuth}}
- **Type**: OAuth
- **Flow**: {{{flow}}}
- **Authorization URL**: {{{authorizationUrl}}}
- **Scopes**: {{^scopes}}N/A{{/scopes}}
{{#scopes}} - **{{{scope}}}**: {{{description}}}
{{/scopes}}
Example
```golang
auth := context.WithValue(context.Background(), sw.ContextAccessToken, "ACCESSTOKENSTRING")
r, err := client.Service.Operation(auth, args)
```
Or via OAuth2 module to automatically refresh tokens and perform user authentication.
```golang
import "golang.org/x/oauth2"
/* Perform OAuth2 round trip request and obtain a token */
tokenSource := oauth2cfg.TokenSource(createContext(httpClient), &token)
auth := context.WithValue(oauth2.NoContext, sw.ContextOAuth2, tokenSource)
r, err := client.Service.Operation(auth, args)
```
{{/isOAuth}}
{{/authMethods}}
## Documentation for Utility Methods
Due to the fact that model structure members are all pointers, this package contains
a number of utility functions to easily obtain pointers to values of basic types.
Each of these functions takes a value of the given basic type and returns a pointer to it:
* `PtrBool`
* `PtrInt`
* `PtrInt32`
* `PtrInt64`
* `PtrFloat`
* `PtrFloat32`
* `PtrFloat64`
* `PtrString`
* `PtrTime`
## Author
{{#apiInfo}}{{#apis}}{{#-last}}{{infoEmail}}
{{/-last}}{{/apis}}{{/apiInfo}}

View File

@@ -0,0 +1,377 @@
{{>partial_header}}
package {{packageName}}
{{#operations}}
import (
"bytes"
"context"
"io"
"net/http"
"net/url"
{{#imports}} "{{import}}"
{{/imports}}
)
// Linger please
var (
_ context.Context
)
{{#generateInterfaces}}
type {{classname}} interface {
{{#operation}}
/*
* {{operationId}}{{#summary}} {{{.}}}{{/summary}}{{^summary}} Method for {{operationId}}{{/summary}}
{{#notes}}
* {{{unescapedNotes}}}
{{/notes}}
* @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().{{#pathParams}}
* @param {{paramName}}{{#description}} {{{.}}}{{/description}}{{/pathParams}}
* @return {{#structPrefix}}{{&classname}}{{/structPrefix}}Api{{operationId}}Request
*/
{{{nickname}}}(ctx context.Context{{#pathParams}}, {{paramName}} {{{dataType}}}{{/pathParams}}) {{#structPrefix}}{{&classname}}{{/structPrefix}}Api{{operationId}}Request
/*
* {{nickname}}Execute executes the request{{#returnType}}
* @return {{{.}}}{{/returnType}}
*/
{{nickname}}Execute(r {{#structPrefix}}{{&classname}}{{/structPrefix}}Api{{operationId}}Request) ({{#returnType}}{{^isArray}}{{^returnTypeIsPrimitive}}*{{/returnTypeIsPrimitive}}{{/isArray}}{{{.}}}, {{/returnType}}*http.Response, error)
{{/operation}}
}
{{/generateInterfaces}}
// {{classname}}Service {{classname}} service
type {{classname}}Service service
{{#operation}}
type {{#structPrefix}}{{&classname}}{{/structPrefix}}Api{{operationId}}Request struct {
ctx context.Context{{#generateInterfaces}}
ApiService {{classname}}
{{/generateInterfaces}}{{^generateInterfaces}}
ApiService *{{classname}}Service
{{/generateInterfaces}}
{{#allParams}}
{{paramName}} {{^isPathParam}}*{{/isPathParam}}{{{dataType}}}
{{/allParams}}
}
{{#allParams}}{{^isPathParam}}
func (r {{#structPrefix}}{{&classname}}{{/structPrefix}}Api{{operationId}}Request) {{vendorExtensions.x-export-param-name}}({{paramName}} {{{dataType}}}) {{#structPrefix}}{{&classname}}{{/structPrefix}}Api{{operationId}}Request {
r.{{paramName}} = &{{paramName}}
return r
}{{/isPathParam}}{{/allParams}}
func (r {{#structPrefix}}{{&classname}}{{/structPrefix}}Api{{operationId}}Request) Execute() ({{#returnType}}{{^isArray}}{{^returnTypeIsPrimitive}}*{{/returnTypeIsPrimitive}}{{/isArray}}{{{.}}}, {{/returnType}}*http.Response, error) {
return r.ApiService.{{nickname}}Execute(r)
}
/*
* {{operationId}}{{#summary}} {{{.}}}{{/summary}}{{^summary}} Method for {{operationId}}{{/summary}}
{{#notes}}
* {{{unescapedNotes}}}
{{/notes}}
* @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().{{#pathParams}}
* @param {{paramName}}{{#description}} {{{.}}}{{/description}}{{/pathParams}}
* @return {{#structPrefix}}{{&classname}}{{/structPrefix}}Api{{operationId}}Request
*/
func (a *{{{classname}}}Service) {{{nickname}}}(ctx context.Context{{#pathParams}}, {{paramName}} {{{dataType}}}{{/pathParams}}) {{#structPrefix}}{{&classname}}{{/structPrefix}}Api{{operationId}}Request {
return {{#structPrefix}}{{&classname}}{{/structPrefix}}Api{{operationId}}Request{
ApiService: a,
ctx: ctx,{{#pathParams}}
{{paramName}}: {{paramName}},{{/pathParams}}
}
}
/*
* Execute executes the request{{#returnType}}
* @return {{{.}}}{{/returnType}}
*/
func (a *{{{classname}}}Service) {{nickname}}Execute(r {{#structPrefix}}{{&classname}}{{/structPrefix}}Api{{operationId}}Request) ({{#returnType}}{{^isArray}}{{^returnTypeIsPrimitive}}*{{/returnTypeIsPrimitive}}{{/isArray}}{{{.}}}, {{/returnType}}*http.Response, error) {
var (
localVarHTTPMethod = http.Method{{httpMethod}}
localVarPostBody interface{}
localVarFormFileName string
localVarFileName string
localVarFileBytes []byte
{{#returnType}}
localVarReturnValue {{^isArray}}{{^returnTypeIsPrimitive}}*{{/returnTypeIsPrimitive}}{{/isArray}}{{{.}}}
{{/returnType}}
)
localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "{{{classname}}}Service.{{{nickname}}}")
if err != nil {
return {{#returnType}}localVarReturnValue, {{/returnType}}nil, &GenericOpenAPIError{error: err.Error()}
}
localVarPath := localBasePath + "{{{path}}}"{{#pathParams}}
localVarPath = strings.Replace(localVarPath, "{"+"{{baseName}}"+"}", url.PathEscape(parameterToString(r.{{paramName}}, "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}")), -1){{/pathParams}}
localVarHeaderParams := make(map[string]string)
localVarQueryParams := url.Values{}
localVarFormParams := url.Values{}
{{#allParams}}
{{#required}}
{{^isPathParam}}
if r.{{paramName}} == nil {
return {{#returnType}}localVarReturnValue, {{/returnType}}nil, reportError("{{paramName}} is required and must be specified")
}
{{/isPathParam}}
{{#minItems}}
if len({{^isPathParam}}*{{/isPathParam}}r.{{paramName}}) < {{minItems}} {
return {{#returnType}}localVarReturnValue, {{/returnType}}nil, reportError("{{paramName}} must have at least {{minItems}} elements")
}
{{/minItems}}
{{#maxItems}}
if len({{^isPathParam}}*{{/isPathParam}}r.{{paramName}}) > {{maxItems}} {
return {{#returnType}}localVarReturnValue, {{/returnType}}nil, reportError("{{paramName}} must have less than {{maxItems}} elements")
}
{{/maxItems}}
{{#minLength}}
if strlen({{^isPathParam}}*{{/isPathParam}}r.{{paramName}}) < {{minLength}} {
return {{#returnType}}localVarReturnValue, {{/returnType}}nil, reportError("{{paramName}} must have at least {{minLength}} elements")
}
{{/minLength}}
{{#maxLength}}
if strlen({{^isPathParam}}*{{/isPathParam}}r.{{paramName}}) > {{maxLength}} {
return {{#returnType}}localVarReturnValue, {{/returnType}}nil, reportError("{{paramName}} must have less than {{maxLength}} elements")
}
{{/maxLength}}
{{#minimum}}
{{#isString}}
{{paramName}}Txt, err := atoi({{^isPathParam}}*{{/isPathParam}}r.{{paramName}})
if {{paramName}}Txt < {{minimum}} {
{{/isString}}
{{^isString}}
if {{^isPathParam}}*{{/isPathParam}}r.{{paramName}} < {{minimum}} {
{{/isString}}
return {{#returnType}}localVarReturnValue, {{/returnType}}nil, reportError("{{paramName}} must be greater than {{minimum}}")
}
{{/minimum}}
{{#maximum}}
{{#isString}}
{{paramName}}Txt, err := atoi({{^isPathParam}}*{{/isPathParam}}r.{{paramName}})
if {{paramName}}Txt > {{maximum}} {
{{/isString}}
{{^isString}}
if {{^isPathParam}}*{{/isPathParam}}r.{{paramName}} > {{maximum}} {
{{/isString}}
return {{#returnType}}localVarReturnValue, {{/returnType}}nil, reportError("{{paramName}} must be less than {{maximum}}")
}
{{/maximum}}
{{/required}}
{{/allParams}}
{{#queryParams}}
{{#required}}
{{#isCollectionFormatMulti}}
{
t := *r.{{paramName}}
if reflect.TypeOf(t).Kind() == reflect.Slice {
s := reflect.ValueOf(t)
for i := 0; i < s.Len(); i++ {
localVarQueryParams.Add("{{baseName}}", parameterToString(s.Index(i), "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}"))
}
} else {
localVarQueryParams.Add("{{baseName}}", parameterToString(t, "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}"))
}
}
{{/isCollectionFormatMulti}}
{{^isCollectionFormatMulti}}
localVarQueryParams.Add("{{baseName}}", parameterToString(*r.{{paramName}}, "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}"))
{{/isCollectionFormatMulti}}
{{/required}}
{{^required}}
if r.{{paramName}} != nil {
{{#isCollectionFormatMulti}}
t := *r.{{paramName}}
if reflect.TypeOf(t).Kind() == reflect.Slice {
s := reflect.ValueOf(t)
for i := 0; i < s.Len(); i++ {
localVarQueryParams.Add("{{baseName}}", parameterToString(s.Index(i), "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}"))
}
} else {
localVarQueryParams.Add("{{baseName}}", parameterToString(t, "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}"))
}
{{/isCollectionFormatMulti}}
{{^isCollectionFormatMulti}}
localVarQueryParams.Add("{{baseName}}", parameterToString(*r.{{paramName}}, "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}"))
{{/isCollectionFormatMulti}}
}
{{/required}}
{{/queryParams}}
// to determine the Content-Type header
{{=<% %>=}}
localVarHTTPContentTypes := []string{<%#consumes%>"<%&mediaType%>"<%^-last%>, <%/-last%><%/consumes%>}
<%={{ }}=%>
// set Content-Type header
localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
if localVarHTTPContentType != "" {
localVarHeaderParams["Content-Type"] = localVarHTTPContentType
}
// to determine the Accept header
{{=<% %>=}}
localVarHTTPHeaderAccepts := []string{<%#produces%>"<%&mediaType%>"<%^-last%>, <%/-last%><%/produces%>}
<%={{ }}=%>
// set Accept header
localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
if localVarHTTPHeaderAccept != "" {
localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
}
{{#headerParams}}
{{#required}}
localVarHeaderParams["{{baseName}}"] = parameterToString(*r.{{paramName}}, "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}")
{{/required}}
{{^required}}
if r.{{paramName}} != nil {
localVarHeaderParams["{{baseName}}"] = parameterToString(*r.{{paramName}}, "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}")
}
{{/required}}
{{/headerParams}}
{{#formParams}}
{{#isFile}}
localVarFormFileName = "{{baseName}}"
{{#required}}
localVarFile := *r.{{paramName}}
{{/required}}
{{^required}}
var localVarFile {{dataType}}
if r.{{paramName}} != nil {
localVarFile = *r.{{paramName}}
}
{{/required}}
if localVarFile != nil {
fbs, _ := io.ReadAll(localVarFile)
localVarFileBytes = fbs
localVarFileName = localVarFile.Name()
localVarFile.Close()
}
{{/isFile}}
{{^isFile}}
{{#required}}
localVarFormParams.Add("{{baseName}}", parameterToString(*r.{{paramName}}, "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}"))
{{/required}}
{{^required}}
{{#isModel}}
if r.{{paramName}} != nil {
paramJson, err := parameterToJson(*r.{{paramName}})
if err != nil {
return {{#returnType}}localVarReturnValue, {{/returnType}}nil, err
}
localVarFormParams.Add("{{baseName}}", paramJson)
}
{{/isModel}}
{{^isModel}}
if r.{{paramName}} != nil {
localVarFormParams.Add("{{baseName}}", parameterToString(*r.{{paramName}}, "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}"))
}
{{/isModel}}
{{/required}}
{{/isFile}}
{{/formParams}}
{{#bodyParams}}
// body params
localVarPostBody = r.{{paramName}}
{{/bodyParams}}
{{#authMethods}}
{{#isApiKey}}
{{^isKeyInCookie}}
if r.ctx != nil {
// API Key Authentication
if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok {
{{#vendorExtensions.x-auth-id-alias}}
if apiKey, ok := auth["{{.}}"]; ok {
var key string
if prefix, ok := auth["{{name}}"]; ok && prefix.Prefix != "" {
key = prefix.Prefix + " " + apiKey.Key
} else {
key = apiKey.Key
}
{{/vendorExtensions.x-auth-id-alias}}
{{^vendorExtensions.x-auth-id-alias}}
if apiKey, ok := auth["{{name}}"]; ok {
var key string
if apiKey.Prefix != "" {
key = apiKey.Prefix + " " + apiKey.Key
} else {
key = apiKey.Key
}
{{/vendorExtensions.x-auth-id-alias}}
{{#isKeyInHeader}}
localVarHeaderParams["{{keyParamName}}"] = key
{{/isKeyInHeader}}
{{#isKeyInQuery}}
localVarQueryParams.Add("{{keyParamName}}", key)
{{/isKeyInQuery}}
}
}
}
{{/isKeyInCookie}}
{{/isApiKey}}
{{/authMethods}}
req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes)
if err != nil {
return {{#returnType}}localVarReturnValue, {{/returnType}}nil, err
}
localVarHTTPResponse, err := a.client.callAPI(req)
if err != nil || localVarHTTPResponse == nil {
return {{#returnType}}localVarReturnValue, {{/returnType}}localVarHTTPResponse, err
}
localVarBody, err := io.ReadAll(localVarHTTPResponse.Body)
localVarHTTPResponse.Body.Close()
localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))
if err != nil {
return {{#returnType}}localVarReturnValue, {{/returnType}}localVarHTTPResponse, err
}
if localVarHTTPResponse.StatusCode >= 300 {
newErr := &GenericOpenAPIError{
body: localVarBody,
error: localVarHTTPResponse.Status,
}
{{#responses}}
{{#dataType}}
{{^is1xx}}
{{^is2xx}}
{{^wildcard}}
if localVarHTTPResponse.StatusCode == {{{code}}} {
{{/wildcard}}
var v {{{dataType}}}
err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
if err != nil {
newErr.error = err.Error()
return {{#returnType}}localVarReturnValue, {{/returnType}}localVarHTTPResponse, newErr
}
newErr.model = v
{{^-last}}
return {{#returnType}}localVarReturnValue, {{/returnType}}localVarHTTPResponse, newErr
{{/-last}}
{{^wildcard}}
}
{{/wildcard}}
{{/is2xx}}
{{/is1xx}}
{{/dataType}}
{{/responses}}
return {{#returnType}}localVarReturnValue, {{/returnType}}localVarHTTPResponse, newErr
}
{{#returnType}}
err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
if err != nil {
newErr := &GenericOpenAPIError{
body: localVarBody,
error: err.Error(),
}
return {{#returnType}}localVarReturnValue, {{/returnType}}localVarHTTPResponse, newErr
}
{{/returnType}}
return {{#returnType}}localVarReturnValue, {{/returnType}}localVarHTTPResponse, nil
}
{{/operation}}
{{/operations}}

View File

@@ -0,0 +1,92 @@
# {{invokerPackage}}\{{classname}}{{#description}}
{{description}}{{/description}}
All URIs are relative to *{{basePath}}*
Method | HTTP request | Description
------------- | ------------- | -------------
{{#operations}}{{#operation}}[**{{operationId}}**]({{classname}}.md#{{operationId}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{summary}}{{/summary}}
{{/operation}}{{/operations}}
{{#operations}}
{{#operation}}
## {{{operationId}}}
> {{#returnType}}{{{.}}} {{/returnType}}{{{operationId}}}(ctx{{#pathParams}}, {{paramName}}{{/pathParams}}){{#allParams}}{{^isPathParam}}.{{vendorExtensions.x-export-param-name}}({{paramName}}){{/isPathParam}}{{/allParams}}.Execute()
{{{summary}}}{{#notes}}
{{{unespacedNotes}}}{{/notes}}
### Example
```go
package main
import (
"context"
"fmt"
"os"
{{#vendorExtensions.x-go-import}}
{{{vendorExtensions.x-go-import}}}
{{/vendorExtensions.x-go-import}}
{{goImportAlias}} "./openapi"
)
func main() {
{{#allParams}}
{{paramName}} := {{{vendorExtensions.x-go-example}}} // {{{dataType}}} | {{{description}}}{{^required}} (optional){{/required}}{{#defaultValue}} (default to {{{.}}}){{/defaultValue}}
{{/allParams}}
configuration := {{goImportAlias}}.NewConfiguration()
apiClient := {{goImportAlias}}.NewAPIClient(configuration)
resp, r, err := apiClient.{{classname}}.{{operationId}}(context.Background(){{#pathParams}}, {{paramName}}{{/pathParams}}){{#allParams}}{{^isPathParam}}.{{vendorExtensions.x-export-param-name}}({{paramName}}){{/isPathParam}}{{/allParams}}.Execute()
if err != nil {
fmt.Fprintf(os.Stderr, "Error when calling `{{classname}}.{{operationId}}``: %v\n", err)
fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r)
}
{{#returnType}}
// response from `{{operationId}}`: {{{.}}}
fmt.Fprintf(os.Stdout, "Response from `{{classname}}.{{operationId}}`: %v\n", resp)
{{/returnType}}
}
```
### Path Parameters
{{^allParams}}This endpoint does not need any parameter.{{/allParams}}{{#pathParams}}{{#-last}}
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc.{{/-last}}{{/pathParams}}{{#pathParams}}
**{{paramName}}** | {{^isPrimitiveType}}{{^isFile}}[{{/isFile}}{{/isPrimitiveType}}**{{dataType}}**{{^isPrimitiveType}}{{^isFile}}]({{baseType}}.md){{/isFile}}{{/isPrimitiveType}} | {{description}} | {{#defaultValue}}[default to {{defaultValue}}]{{/defaultValue}}{{/pathParams}}
### Other Parameters
Other parameters are passed through a pointer to a api{{{nickname}}}Request struct via the builder pattern
{{#allParams}}{{#-last}}
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------{{/-last}}{{/allParams}}{{#allParams}}
{{^isPathParam}} **{{paramName}}** | {{#isContainer}}{{#isArray}}{{#items}}{{^isPrimitiveType}}{{^isFile}}[{{/isFile}}{{/isPrimitiveType}}**[]{{dataType}}**{{^isPrimitiveType}}{{^isFile}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isFile}}{{/isPrimitiveType}}{{/items}}{{/isArray}}{{#isMap}}{{#items}}{{^isPrimitiveType}}{{^isFile}}[{{/isFile}}{{/isPrimitiveType}}**map[string]{{dataType}}**{{^isPrimitiveType}}{{^isFile}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isFile}}{{/isPrimitiveType}}{{/items}}{{/isMap}}{{/isContainer}}{{^isContainer}}{{^isPrimitiveType}}{{^isFile}}[{{/isFile}}{{/isPrimitiveType}}**{{dataType}}**{{^isPrimitiveType}}{{^isFile}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isFile}}{{/isPrimitiveType}}{{/isContainer}} | {{description}} | {{#defaultValue}}[default to {{defaultValue}}]{{/defaultValue}}{{/isPathParam}}{{/allParams}}
### Return type
{{#returnType}}{{#returnTypeIsPrimitive}}**{{{returnType}}}**{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}[**{{{returnType}}}**]({{returnBaseType}}.md){{/returnTypeIsPrimitive}}{{/returnType}}{{^returnType}} (empty response body){{/returnType}}
### Authorization
{{^authMethods}}No authorization required{{/authMethods}}{{#authMethods}}[{{{name}}}](../README.md#{{{name}}}){{^-last}}, {{/-last}}{{/authMethods}}
### HTTP request headers
- **Content-Type**: {{#consumes}}{{{mediaType}}}{{^-last}}, {{/-last}}{{/consumes}}{{^consumes}}Not defined{{/consumes}}
- **Accept**: {{#produces}}{{{mediaType}}}{{^-last}}, {{/-last}}{{/produces}}{{^produces}}Not defined{{/produces}}
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints)
[[Back to Model list]](../README.md#documentation-for-models)
[[Back to README]](../README.md)
{{/operation}}
{{/operations}}

View File

@@ -0,0 +1,583 @@
{{>partial_header}}
package {{packageName}}
import (
"bytes"
"context"
"encoding/json"
"encoding/xml"
"errors"
"fmt"
"io"
"log"
"mime/multipart"
"net/http"
"net/http/httputil"
"net/url"
"os"
"path/filepath"
"reflect"
"regexp"
"strconv"
"strings"
"time"
"unicode/utf8"
"golang.org/x/oauth2"
{{#withAWSV4Signature}}
awsv4 "github.com/aws/aws-sdk-go/aws/signer/v4"
awscredentials "github.com/aws/aws-sdk-go/aws/credentials"
{{/withAWSV4Signature}}
)
var (
jsonCheck = regexp.MustCompile(`(?i:(?:application|text)/(?:vnd\.[^;]+\+)?json)`)
xmlCheck = regexp.MustCompile(`(?i:(?:application|text)/xml)`)
)
// APIClient manages communication with the {{appName}} API v{{version}}
// In most cases there should be only one, shared, APIClient.
type APIClient struct {
cfg *Configuration
common service // Reuse a single struct instead of allocating one for each service on the heap.
// API Services
{{#apiInfo}}
{{#apis}}
{{#operations}}
{{#generateInterfaces}}
{{classname}} {{classname}}
{{/generateInterfaces}}
{{^generateInterfaces}}
{{classname}} *{{classname}}Service
{{/generateInterfaces}}
{{/operations}}
{{/apis}}
{{/apiInfo}}
}
type service struct {
client *APIClient
}
// NewAPIClient creates a new API client. Requires a userAgent string describing your application.
// optionally a custom http.Client to allow for advanced features such as caching.
func NewAPIClient(cfg *Configuration) *APIClient {
if cfg.HTTPClient == nil {
cfg.HTTPClient = http.DefaultClient
}
c := &APIClient{}
c.cfg = cfg
c.common.client = c
{{#apiInfo}}
// API Services
{{#apis}}
{{#operations}}
c.{{classname}} = (*{{classname}}Service)(&c.common)
{{/operations}}
{{/apis}}
{{/apiInfo}}
return c
}
func atoi(in string) (int, error) {
return strconv.Atoi(in)
}
// selectHeaderContentType select a content type from the available list.
func selectHeaderContentType(contentTypes []string) string {
if len(contentTypes) == 0 {
return ""
}
if contains(contentTypes, "application/json") {
return "application/json"
}
return contentTypes[0] // use the first content type specified in 'consumes'
}
// selectHeaderAccept join all accept types and return
func selectHeaderAccept(accepts []string) string {
if len(accepts) == 0 {
return ""
}
if contains(accepts, "application/json") {
return "application/json"
}
return strings.Join(accepts, ",")
}
// contains is a case insenstive match, finding needle in a haystack
func contains(haystack []string, needle string) bool {
for _, a := range haystack {
if strings.ToLower(a) == strings.ToLower(needle) {
return true
}
}
return false
}
// Verify optional parameters are of the correct type.
func typeCheckParameter(obj interface{}, expected string, name string) error {
// Make sure there is an object.
if obj == nil {
return nil
}
// Check the type is as expected.
if reflect.TypeOf(obj).String() != expected {
return fmt.Errorf("Expected %s to be of type %s but received %s.", name, expected, reflect.TypeOf(obj).String())
}
return nil
}
// parameterToString convert interface{} parameters to string, using a delimiter if format is provided.
func parameterToString(obj interface{}, collectionFormat string) string {
var delimiter string
switch collectionFormat {
case "pipes":
delimiter = "|"
case "ssv":
delimiter = " "
case "tsv":
delimiter = "\t"
case "csv":
delimiter = ","
}
if reflect.TypeOf(obj).Kind() == reflect.Slice {
return strings.Trim(strings.Replace(fmt.Sprint(obj), " ", delimiter, -1), "[]")
} else if t, ok := obj.(time.Time); ok {
return t.Format(time.RFC3339)
}
return fmt.Sprintf("%v", obj)
}
// helper for converting interface{} parameters to json strings
func parameterToJson(obj interface{}) (string, error) {
jsonBuf, err := json.Marshal(obj)
if err != nil {
return "", err
}
return string(jsonBuf), err
}
// callAPI do the request.
func (c *APIClient) callAPI(request *http.Request) (*http.Response, error) {
if c.cfg.Debug {
dump, err := httputil.DumpRequestOut(request, true)
if err != nil {
return nil, err
}
log.Printf("\n%s\n", string(dump))
}
resp, err := c.cfg.HTTPClient.Do(request)
if err != nil {
return resp, err
}
if c.cfg.Debug {
dump, err := httputil.DumpResponse(resp, true)
if err != nil {
return resp, err
}
log.Printf("\n%s\n", string(dump))
}
return resp, err
}
// Allow modification of underlying config for alternate implementations and testing
// Caution: modifying the configuration while live can cause data races and potentially unwanted behavior
func (c *APIClient) GetConfig() *Configuration {
return c.cfg
}
// prepareRequest build the request
func (c *APIClient) prepareRequest(
ctx context.Context,
path string, method string,
postBody interface{},
headerParams map[string]string,
queryParams url.Values,
formParams url.Values,
formFileName string,
fileName string,
fileBytes []byte) (localVarRequest *http.Request, err error) {
var body *bytes.Buffer
// Detect postBody type and post.
if postBody != nil {
contentType := headerParams["Content-Type"]
if contentType == "" {
contentType = detectContentType(postBody)
headerParams["Content-Type"] = contentType
}
body, err = setBody(postBody, contentType)
if err != nil {
return nil, err
}
}
// add form parameters and file if available.
if strings.HasPrefix(headerParams["Content-Type"], "multipart/form-data") && len(formParams) > 0 || (len(fileBytes) > 0 && fileName != "") {
if body != nil {
return nil, errors.New("Cannot specify postBody and multipart form at the same time.")
}
body = &bytes.Buffer{}
w := multipart.NewWriter(body)
for k, v := range formParams {
for _, iv := range v {
if strings.HasPrefix(k, "@") { // file
err = addFile(w, k[1:], iv)
if err != nil {
return nil, err
}
} else { // form value
w.WriteField(k, iv)
}
}
}
if len(fileBytes) > 0 && fileName != "" {
w.Boundary()
//_, fileNm := filepath.Split(fileName)
part, err := w.CreateFormFile(formFileName, filepath.Base(fileName))
if err != nil {
return nil, err
}
_, err = part.Write(fileBytes)
if err != nil {
return nil, err
}
}
// Set the Boundary in the Content-Type
headerParams["Content-Type"] = w.FormDataContentType()
// Set Content-Length
headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len())
w.Close()
}
if strings.HasPrefix(headerParams["Content-Type"], "application/x-www-form-urlencoded") && len(formParams) > 0 {
if body != nil {
return nil, errors.New("Cannot specify postBody and x-www-form-urlencoded form at the same time.")
}
body = &bytes.Buffer{}
body.WriteString(formParams.Encode())
// Set Content-Length
headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len())
}
// Setup path and query parameters
url, err := url.Parse(path)
if err != nil {
return nil, err
}
// Override request host, if applicable
if c.cfg.Host != "" {
url.Host = c.cfg.Host
}
// Override request scheme, if applicable
if c.cfg.Scheme != "" {
url.Scheme = c.cfg.Scheme
}
// Adding Query Param
query := url.Query()
for k, v := range queryParams {
for _, iv := range v {
query.Add(k, iv)
}
}
// Encode the parameters.
url.RawQuery = query.Encode()
// Generate a new request
if body != nil {
localVarRequest, err = http.NewRequest(method, url.String(), body)
} else {
localVarRequest, err = http.NewRequest(method, url.String(), nil)
}
if err != nil {
return nil, err
}
// add header parameters, if any
if len(headerParams) > 0 {
headers := http.Header{}
for h, v := range headerParams {
headers.Set(h, v)
}
localVarRequest.Header = headers
}
// Add the user agent to the request.
localVarRequest.Header.Add("User-Agent", c.cfg.UserAgent)
if ctx != nil {
// add context to the request
localVarRequest = localVarRequest.WithContext(ctx)
// Walk through any authentication.
// OAuth2 authentication
if tok, ok := ctx.Value(ContextOAuth2).(oauth2.TokenSource); ok {
// We were able to grab an oauth2 token from the context
var latestToken *oauth2.Token
if latestToken, err = tok.Token(); err != nil {
return nil, err
}
latestToken.SetAuthHeader(localVarRequest)
}
// Basic HTTP Authentication
if auth, ok := ctx.Value(ContextBasicAuth).(BasicAuth); ok {
localVarRequest.SetBasicAuth(auth.UserName, auth.Password)
}
// AccessToken Authentication
if auth, ok := ctx.Value(ContextAccessToken).(string); ok {
localVarRequest.Header.Add("Authorization", "Bearer "+auth)
}
{{#withAWSV4Signature}}
// AWS Signature v4 Authentication
if auth, ok := ctx.Value(ContextAWSv4).(AWSv4); ok {
creds := awscredentials.NewStaticCredentials(auth.AccessKey, auth.SecretKey, "")
signer := awsv4.NewSigner(creds)
var reader *strings.Reader
if body == nil {
reader = strings.NewReader("")
} else {
reader = strings.NewReader(body.String())
}
timestamp := time.Now()
_, err := signer.Sign(localVarRequest, reader, "oapi", "eu-west-2", timestamp)
if err != nil {
return nil, err
}
}
{{/withAWSV4Signature}}
}
for header, value := range c.cfg.DefaultHeader {
localVarRequest.Header.Add(header, value)
}
{{#hasHttpSignatureMethods}}
if ctx != nil {
// HTTP Signature Authentication. All request headers must be set (including default headers)
// because the headers may be included in the signature.
if auth, ok := ctx.Value(ContextHttpSignatureAuth).(HttpSignatureAuth); ok {
err = SignRequest(ctx, localVarRequest, auth)
if err != nil {
return nil, err
}
}
}
{{/hasHttpSignatureMethods}}
return localVarRequest, nil
}
func (c *APIClient) decode(v interface{}, b []byte, contentType string) (err error) {
if len(b) == 0 {
return nil
}
if s, ok := v.(*string); ok {
*s = string(b)
return nil
}
if xmlCheck.MatchString(contentType) {
if err = xml.Unmarshal(b, v); err != nil {
return err
}
return nil
}
if jsonCheck.MatchString(contentType) {
if actualObj, ok := v.(interface{GetActualInstance() interface{}}); ok { // oneOf, anyOf schemas
if unmarshalObj, ok := actualObj.(interface{UnmarshalJSON([]byte) error}); ok { // make sure it has UnmarshalJSON defined
if err = unmarshalObj.UnmarshalJSON(b); err!= nil {
return err
}
} else {
return errors.New("Unknown type with GetActualInstance but no unmarshalObj.UnmarshalJSON defined")
}
} else if err = json.Unmarshal(b, v); err != nil { // simple model
return err
}
return nil
}
return errors.New("undefined response type")
}
// Add a file to the multipart request
func addFile(w *multipart.Writer, fieldName, path string) error {
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
part, err := w.CreateFormFile(fieldName, filepath.Base(path))
if err != nil {
return err
}
_, err = io.Copy(part, file)
return err
}
// Prevent trying to import "fmt"
func reportError(format string, a ...interface{}) error {
return fmt.Errorf(format, a...)
}
// Prevent trying to import "bytes"
func newStrictDecoder(data []byte) *json.Decoder {
dec := json.NewDecoder(bytes.NewBuffer(data))
dec.DisallowUnknownFields()
return dec
}
// Set request body from an interface{}
func setBody(body interface{}, contentType string) (bodyBuf *bytes.Buffer, err error) {
if bodyBuf == nil {
bodyBuf = &bytes.Buffer{}
}
if reader, ok := body.(io.Reader); ok {
_, err = bodyBuf.ReadFrom(reader)
} else if b, ok := body.([]byte); ok {
_, err = bodyBuf.Write(b)
} else if s, ok := body.(string); ok {
_, err = bodyBuf.WriteString(s)
} else if s, ok := body.(*string); ok {
_, err = bodyBuf.WriteString(*s)
} else if jsonCheck.MatchString(contentType) {
err = json.NewEncoder(bodyBuf).Encode(body)
} else if xmlCheck.MatchString(contentType) {
err = xml.NewEncoder(bodyBuf).Encode(body)
}
if err != nil {
return nil, err
}
if bodyBuf.Len() == 0 {
err = fmt.Errorf("Invalid body type %s\n", contentType)
return nil, err
}
return bodyBuf, nil
}
// detectContentType method is used to figure out `Request.Body` content type for request header
func detectContentType(body interface{}) string {
contentType := "text/plain; charset=utf-8"
kind := reflect.TypeOf(body).Kind()
switch kind {
case reflect.Struct, reflect.Map, reflect.Ptr:
contentType = "application/json; charset=utf-8"
case reflect.String:
contentType = "text/plain; charset=utf-8"
default:
if b, ok := body.([]byte); ok {
contentType = http.DetectContentType(b)
} else if kind == reflect.Slice {
contentType = "application/json; charset=utf-8"
}
}
return contentType
}
// Ripped from https://github.com/gregjones/httpcache/blob/master/httpcache.go
type cacheControl map[string]string
func parseCacheControl(headers http.Header) cacheControl {
cc := cacheControl{}
ccHeader := headers.Get("Cache-Control")
for _, part := range strings.Split(ccHeader, ",") {
part = strings.Trim(part, " ")
if part == "" {
continue
}
if strings.ContainsRune(part, '=') {
keyval := strings.Split(part, "=")
cc[strings.Trim(keyval[0], " ")] = strings.Trim(keyval[1], ",")
} else {
cc[part] = ""
}
}
return cc
}
// CacheExpires helper function to determine remaining time before repeating a request.
func CacheExpires(r *http.Response) time.Time {
// Figure out when the cache expires.
var expires time.Time
now, err := time.Parse(time.RFC1123, r.Header.Get("date"))
if err != nil {
return time.Now()
}
respCacheControl := parseCacheControl(r.Header)
if maxAge, ok := respCacheControl["max-age"]; ok {
lifetime, err := time.ParseDuration(maxAge + "s")
if err != nil {
expires = now
} else {
expires = now.Add(lifetime)
}
} else {
expiresHeader := r.Header.Get("Expires")
if expiresHeader != "" {
expires, err = time.Parse(time.RFC1123, expiresHeader)
if err != nil {
expires = now
}
}
}
return expires
}
func strlen(s string) int {
return utf8.RuneCountInString(s)
}
// GenericOpenAPIError Provides access to the body, error and model on returned errors.
type GenericOpenAPIError struct {
body []byte
error string
model interface{}
}
// Error returns non-empty string if there was an error.
func (e GenericOpenAPIError) Error() string {
return e.error
}
// Body returns the raw bytes of the response
func (e GenericOpenAPIError) Body() []byte {
return e.body
}
// Model returns the unpacked model of the error
func (e GenericOpenAPIError) Model() interface{} {
return e.model
}

View File

@@ -0,0 +1,303 @@
{{>partial_header}}
package {{packageName}}
import (
"context"
"fmt"
"net/http"
"strings"
)
// contextKeys are used to identify the type of value in the context.
// Since these are string, it is possible to get a short description of the
// context key for logging and debugging using key.String().
type contextKey string
func (c contextKey) String() string {
return "auth " + string(c)
}
var (
// ContextOAuth2 takes an oauth2.TokenSource as authentication for the request.
ContextOAuth2 = contextKey("token")
// ContextBasicAuth takes BasicAuth as authentication for the request.
ContextBasicAuth = contextKey("basic")
// ContextAccessToken takes a string oauth2 access token as authentication for the request.
ContextAccessToken = contextKey("accesstoken")
// ContextAPIKeys takes a string apikey as authentication for the request
ContextAPIKeys = contextKey("apiKeys")
{{#withAWSV4Signature}}
// ContextAWSv4 takes an Access Key and a Secret Key for signing AWS Signature v4
ContextAWSv4 = contextKey("awsv4")
{{/withAWSV4Signature}}
// ContextHttpSignatureAuth takes HttpSignatureAuth as authentication for the request.
ContextHttpSignatureAuth = contextKey("httpsignature")
// ContextServerIndex uses a server configuration from the index.
ContextServerIndex = contextKey("serverIndex")
// ContextOperationServerIndices uses a server configuration from the index mapping.
ContextOperationServerIndices = contextKey("serverOperationIndices")
// ContextServerVariables overrides a server configuration variables.
ContextServerVariables = contextKey("serverVariables")
// ContextOperationServerVariables overrides a server configuration variables using operation specific values.
ContextOperationServerVariables = contextKey("serverOperationVariables")
)
// BasicAuth provides basic http authentication to a request passed via context using ContextBasicAuth
type BasicAuth struct {
UserName string `json:"userName,omitempty"`
Password string `json:"password,omitempty"`
}
// APIKey provides API key based authentication to a request passed via context using ContextAPIKey
type APIKey struct {
Key string
Prefix string
}
{{#withAWSV4Signature}}
// AWSv4 provides AWS Signature to a request passed via context using ContextAWSv4
// https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html
type AWSv4 struct {
AccessKey string
SecretKey string
}
{{/withAWSV4Signature}}
// ServerVariable stores the information about a server variable
type ServerVariable struct {
Description string
DefaultValue string
EnumValues []string
}
// ServerConfiguration stores the information about a server
type ServerConfiguration struct {
URL string
Description string
Variables map[string]ServerVariable
}
// ServerConfigurations stores multiple ServerConfiguration items
type ServerConfigurations []ServerConfiguration
// Configuration stores the configuration of the API client
type Configuration struct {
Host string `json:"host,omitempty"`
Scheme string `json:"scheme,omitempty"`
DefaultHeader map[string]string `json:"defaultHeader,omitempty"`
UserAgent string `json:"userAgent,omitempty"`
Debug bool `json:"debug,omitempty"`
Servers ServerConfigurations
OperationServers map[string]ServerConfigurations
HTTPClient *http.Client
}
// NewConfiguration returns a new Configuration object
func NewConfiguration() *Configuration {
cfg := &Configuration{
DefaultHeader: make(map[string]string),
UserAgent: "{{#httpUserAgent}}{{{.}}}{{/httpUserAgent}}{{^httpUserAgent}}OpenAPI-Generator/{{{packageVersion}}}/go{{/httpUserAgent}}",
Debug: false,
{{#servers}}
{{#-first}}
Servers: ServerConfigurations{
{{/-first}}
{
URL: "{{{url}}}",
Description: "{{{description}}}{{^description}}No description provided{{/description}}",
{{#variables}}
{{#-first}}
Variables: map[string]ServerVariable{
{{/-first}}
"{{{name}}}": ServerVariable{
Description: "{{{description}}}{{^description}}No description provided{{/description}}",
DefaultValue: "{{{defaultValue}}}",
{{#enumValues}}
{{#-first}}
EnumValues: []string{
{{/-first}}
"{{{.}}}",
{{#-last}}
},
{{/-last}}
{{/enumValues}}
},
{{#-last}}
},
{{/-last}}
{{/variables}}
},
{{#-last}}
},
{{/-last}}
{{/servers}}
{{#apiInfo}}
OperationServers: map[string]ServerConfigurations{
{{#apis}}
{{#operations}}
{{#operation}}
{{#servers}}
{{#-first}}
"{{{classname}}}Service.{{{nickname}}}": {
{{/-first}}
{
URL: "{{{url}}}",
Description: "{{{description}}}{{^description}}No description provided{{/description}}",
{{#variables}}
{{#-first}}
Variables: map[string]ServerVariable{
{{/-first}}
"{{{name}}}": ServerVariable{
Description: "{{{description}}}{{^description}}No description provided{{/description}}",
DefaultValue: "{{{defaultValue}}}",
{{#enumValues}}
{{#-first}}
EnumValues: []string{
{{/-first}}
"{{{.}}}",
{{#-last}}
},
{{/-last}}
{{/enumValues}}
},
{{#-last}}
},
{{/-last}}
{{/variables}}
},
{{#-last}}
},
{{/-last}}
{{/servers}}
{{/operation}}
{{/operations}}
{{/apis}}
},
{{/apiInfo}}
}
return cfg
}
// AddDefaultHeader adds a new HTTP header to the default header in the request
func (c *Configuration) AddDefaultHeader(key string, value string) {
c.DefaultHeader[key] = value
}
// URL formats template on a index using given variables
func (sc ServerConfigurations) URL(index int, variables map[string]string) (string, error) {
if index < 0 || len(sc) <= index {
return "", fmt.Errorf("Index %v out of range %v", index, len(sc)-1)
}
server := sc[index]
url := server.URL
// go through variables and replace placeholders
for name, variable := range server.Variables {
if value, ok := variables[name]; ok {
found := bool(len(variable.EnumValues) == 0)
for _, enumValue := range variable.EnumValues {
if value == enumValue {
found = true
}
}
if !found {
return "", fmt.Errorf("The variable %s in the server URL has invalid value %v. Must be %v", name, value, variable.EnumValues)
}
url = strings.Replace(url, "{"+name+"}", value, -1)
} else {
url = strings.Replace(url, "{"+name+"}", variable.DefaultValue, -1)
}
}
return url, nil
}
// ServerURL returns URL based on server settings
func (c *Configuration) ServerURL(index int, variables map[string]string) (string, error) {
return c.Servers.URL(index, variables)
}
func getServerIndex(ctx context.Context) (int, error) {
si := ctx.Value(ContextServerIndex)
if si != nil {
if index, ok := si.(int); ok {
return index, nil
}
return 0, reportError("Invalid type %T should be int", si)
}
return 0, nil
}
func getServerOperationIndex(ctx context.Context, endpoint string) (int, error) {
osi := ctx.Value(ContextOperationServerIndices)
if osi != nil {
if operationIndices, ok := osi.(map[string]int); !ok {
return 0, reportError("Invalid type %T should be map[string]int", osi)
} else {
index, ok := operationIndices[endpoint]
if ok {
return index, nil
}
}
}
return getServerIndex(ctx)
}
func getServerVariables(ctx context.Context) (map[string]string, error) {
sv := ctx.Value(ContextServerVariables)
if sv != nil {
if variables, ok := sv.(map[string]string); ok {
return variables, nil
}
return nil, reportError("ctx value of ContextServerVariables has invalid type %T should be map[string]string", sv)
}
return nil, nil
}
func getServerOperationVariables(ctx context.Context, endpoint string) (map[string]string, error) {
osv := ctx.Value(ContextOperationServerVariables)
if osv != nil {
if operationVariables, ok := osv.(map[string]map[string]string); !ok {
return nil, reportError("ctx value of ContextOperationServerVariables has invalid type %T should be map[string]map[string]string", osv)
} else {
variables, ok := operationVariables[endpoint]
if ok {
return variables, nil
}
}
}
return getServerVariables(ctx)
}
// ServerURLWithContext returns a new server URL given an endpoint
func (c *Configuration) ServerURLWithContext(ctx context.Context, endpoint string) (string, error) {
sc, ok := c.OperationServers[endpoint]
if !ok {
sc = c.Servers
}
if ctx == nil {
return sc.URL(0, nil)
}
index, err := getServerOperationIndex(ctx, endpoint)
if err != nil {
return "", err
}
variables, err := getServerOperationVariables(ctx, endpoint)
if err != nil {
return "", err
}
return sc.URL(index, variables)
}

View File

@@ -0,0 +1,58 @@
#!/bin/sh
# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
#
# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update" "gitlab.com"
git_user_id=$1
git_repo_id=$2
release_note=$3
git_host=$4
if [ "$git_host" = "" ]; then
git_host="{{{gitHost}}}"
echo "[INFO] No command line input provided. Set \$git_host to $git_host"
fi
if [ "$git_user_id" = "" ]; then
git_user_id="{{{gitUserId}}}"
echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
fi
if [ "$git_repo_id" = "" ]; then
git_repo_id="{{{gitRepoId}}}"
echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id"
fi
if [ "$release_note" = "" ]; then
release_note="{{{releaseNote}}}"
echo "[INFO] No command line input provided. Set \$release_note to $release_note"
fi
# Initialize the local directory as a Git repository
git init
# Adds the files in the local repository and stages them for commit.
git add .
# Commits the tracked changes and prepares them to be pushed to a remote repository.
git commit -m "$release_note"
# Sets the new remote
git_remote=`git remote`
if [ "$git_remote" = "" ]; then # git remote not defined
if [ "$GIT_TOKEN" = "" ]; then
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment."
git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git
else
git remote add origin https://${git_user_id}:${GIT_TOKEN}@${git_host}/${git_user_id}/${git_repo_id}.git
fi
fi
git pull origin master
# Pushes (Forces) the changes in the local repository up to the remote repository
echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git"
git push origin master 2>&1 | grep -v 'To https'

View File

@@ -0,0 +1,24 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.test
*.prof

View File

@@ -0,0 +1,20 @@
{{>partial_header}}
package {{packageName}}
{{#models}}
import (
"encoding/json"
{{#imports}}
"{{import}}"
{{/imports}}
)
{{#model}}
{{#isEnum}}
{{>model_enum}}
{{/isEnum}}
{{^isEnum}}
{{#oneOf}}{{#-first}}{{>model_oneof}}{{/-first}}{{/oneOf}}{{^oneOf}}{{#anyOf}}{{#-first}}{{>model_anyof}}{{/-first}}{{/anyOf}}{{^anyOf}}{{>model_simple}}{{/anyOf}}{{/oneOf}}
{{/isEnum}}
{{/model}}
{{/models}}

View File

@@ -0,0 +1,76 @@
// {{classname}}{{#description}} {{{description}}}{{/description}}{{^description}} struct for {{{classname}}}{{/description}}
type {{classname}} struct {
{{#anyOf}}
{{{.}}} *{{{.}}}
{{/anyOf}}
}
// Unmarshal JSON data into any of the pointers in the struct
func (dst *{{classname}}) UnmarshalJSON(data []byte) error {
var err error
{{#isNullable}}
// this object is nullable so check if the payload is null or empty string
if string(data) == "" || string(data) == "{}" {
return nil
}
{{/isNullable}}
{{#discriminator}}
{{#mappedModels}}
{{#-first}}
// use discriminator value to speed up the lookup
var jsonDict map[string]interface{}
err := json.Unmarshal(data, &jsonDict)
if err != nil {
return fmt.Errorf("Failed to unmarshal JSON into map for the discrimintor lookup.")
}
{{/-first}}
// check if the discriminator value is '{{{mappingName}}}'
if jsonDict["{{{propertyBaseName}}}"] == "{{{mappingName}}}" {
// try to unmarshal JSON data into {{{modelName}}}
err = json.Unmarshal(data, &dst.{{{modelName}}});
if err == nil {
json{{{modelName}}}, _ := json.Marshal(dst.{{{modelName}}})
if string(json{{{modelName}}}) == "{}" { // empty struct
dst.{{{modelName}}} = nil
} else {
return nil // data stored in dst.{{{modelName}}}, return on the first match
}
} else {
dst.{{{modelName}}} = nil
}
}
{{/mappedModels}}
{{/discriminator}}
{{#anyOf}}
// try to unmarshal JSON data into {{{.}}}
err = json.Unmarshal(data, &dst.{{{.}}});
if err == nil {
json{{{.}}}, _ := json.Marshal(dst.{{{.}}})
if string(json{{{.}}}) == "{}" { // empty struct
dst.{{{.}}} = nil
} else {
return nil // data stored in dst.{{{.}}}, return on the first match
}
} else {
dst.{{{.}}} = nil
}
{{/anyOf}}
return fmt.Errorf("Data failed to match schemas in anyOf({{classname}})")
}
// Marshal data from the first non-nil pointers in the struct to JSON
func (src *{{classname}}) MarshalJSON() ([]byte, error) {
{{#anyOf}}
if src.{{{.}}} != nil {
return json.Marshal(&src.{{{.}}})
}
{{/anyOf}}
return nil, nil // no data in anyOf schemas
}
{{>nullable_model}}

View File

@@ -0,0 +1,97 @@
{{#models}}{{#model}}# {{classname}}
{{^isEnum}}
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
{{#vendorExtensions.x-is-one-of-interface}}
**{{classname}}Interface** | **interface { {{#discriminator}}{{propertyGetter}}() {{propertyType}}{{/discriminator}} }** | An interface that can hold any of the proper implementing types |
{{/vendorExtensions.x-is-one-of-interface}}
{{^vendorExtensions.x-is-one-of-interface}}
{{#vars}}**{{name}}** | {{^required}}Pointer to {{/required}}{{#isContainer}}{{#isArray}}{{#items}}{{^isPrimitiveType}}{{^isFile}}[{{/isFile}}{{/isPrimitiveType}}**[]{{dataType}}**{{^isPrimitiveType}}{{^isFile}}]({{dataType}}.md){{/isFile}}{{/isPrimitiveType}}{{/items}}{{/isArray}}{{#isMap}}{{#items}}{{^isPrimitiveType}}{{^isFile}}[{{/isFile}}{{/isPrimitiveType}}**map[string]{{dataType}}**{{^isPrimitiveType}}{{^isFile}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isFile}}{{/isPrimitiveType}}{{/items}}{{/isMap}}{{/isContainer}}{{^isContainer}}{{^isPrimitiveType}}{{^isFile}}{{^isDateTime}}[{{/isDateTime}}{{/isFile}}{{/isPrimitiveType}}**{{dataType}}**{{^isPrimitiveType}}{{^isFile}}{{^isDateTime}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isDateTime}}{{/isFile}}{{/isPrimitiveType}}{{/isContainer}} | {{description}} | {{^required}}[optional] {{/required}}{{#isReadOnly}}[readonly] {{/isReadOnly}}{{#defaultValue}}[default to {{{.}}}]{{/defaultValue}}
{{/vars}}
{{/vendorExtensions.x-is-one-of-interface}}
## Methods
{{^vendorExtensions.x-is-one-of-interface}}
### New{{classname}}
`func New{{classname}}({{#vars}}{{#required}}{{nameInCamelCase}} {{dataType}}, {{/required}}{{/vars}}) *{{classname}}`
New{{classname}} instantiates a new {{classname}} object
This constructor will assign default values to properties that have it defined,
and makes sure properties required by API are set, but the set of arguments
will change when the set of required properties is changed
### New{{classname}}WithDefaults
`func New{{classname}}WithDefaults() *{{classname}}`
New{{classname}}WithDefaults instantiates a new {{classname}} object
This constructor will only assign default values to properties that have it defined,
but it doesn't guarantee that properties required by API are set
{{#vars}}
### Get{{name}}
`func (o *{{classname}}) Get{{name}}() {{vendorExtensions.x-go-base-type}}`
Get{{name}} returns the {{name}} field if non-nil, zero value otherwise.
### Get{{name}}Ok
`func (o *{{classname}}) Get{{name}}Ok() (*{{vendorExtensions.x-go-base-type}}, bool)`
Get{{name}}Ok returns a tuple with the {{name}} field if it's non-nil, zero value otherwise
and a boolean to check if the value has been set.
### Set{{name}}
`func (o *{{classname}}) Set{{name}}(v {{vendorExtensions.x-go-base-type}})`
Set{{name}} sets {{name}} field to given value.
{{^required}}
### Has{{name}}
`func (o *{{classname}}) Has{{name}}() bool`
Has{{name}} returns a boolean if a field has been set.
{{/required}}
{{#isNullable}}
### Set{{name}}Nil
`func (o *{{classname}}) Set{{name}}Nil(b bool)`
Set{{name}}Nil sets the value for {{name}} to be an explicit nil
### Unset{{name}}
`func (o *{{classname}}) Unset{{name}}()`
Unset{{name}} ensures that no value is present for {{name}}, not even an explicit nil
{{/isNullable}}
{{/vars}}
{{#vendorExtensions.x-implements}}
### As{{{.}}}
`func (s *{{classname}}) As{{{.}}}() {{{.}}}`
Convenience method to wrap this instance of {{classname}} in {{{.}}}
{{/vendorExtensions.x-implements}}
{{/vendorExtensions.x-is-one-of-interface}}
{{/isEnum}}
{{#isEnum}}
## Enum
{{#allowableValues}}{{#enumVars}}
* `{{name}}` (value: `{{{value}}}`)
{{/enumVars}}{{/allowableValues}}
{{/isEnum}}
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
{{/model}}{{/models}}

View File

@@ -0,0 +1,71 @@
// {{{classname}}} {{#description}}{{{.}}}{{/description}}{{^description}}the model '{{{classname}}}'{{/description}}
type {{{classname}}} {{^format}}{{dataType}}{{/format}}{{#format}}{{{format}}}{{/format}}
// List of {{{name}}}
const (
{{#allowableValues}}
{{#enumVars}}
{{^-first}}
{{/-first}}
{{#enumClassPrefix}}{{{classname.toUpperCase}}}_{{/enumClassPrefix}}{{name}} {{{classname}}} = {{{value}}}
{{/enumVars}}
{{/allowableValues}}
)
func (v *{{{classname}}}) UnmarshalJSON(src []byte) error {
var value {{^format}}{{dataType}}{{/format}}{{#format}}{{{format}}}{{/format}}
err := json.Unmarshal(src, &value)
if err != nil {
return err
}
enumTypeValue := {{{classname}}}(value)
for _, existing := range []{{classname}}{ {{#allowableValues}}{{#enumVars}}{{{value}}}, {{/enumVars}} {{/allowableValues}} } {
if existing == enumTypeValue {
*v = enumTypeValue
return nil
}
}
return fmt.Errorf("%+v is not a valid {{classname}}", value)
}
// Ptr returns reference to {{{name}}} value
func (v {{{classname}}}) Ptr() *{{{classname}}} {
return &v
}
type Nullable{{{classname}}} struct {
value *{{{classname}}}
isSet bool
}
func (v Nullable{{classname}}) Get() *{{classname}} {
return v.value
}
func (v *Nullable{{classname}}) Set(val *{{classname}}) {
v.value = val
v.isSet = true
}
func (v Nullable{{classname}}) IsSet() bool {
return v.isSet
}
func (v *Nullable{{classname}}) Unset() {
v.value = nil
v.isSet = false
}
func NewNullable{{classname}}(val *{{classname}}) *Nullable{{classname}} {
return &Nullable{{classname}}{value: val, isSet: true}
}
func (v Nullable{{{classname}}}) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *Nullable{{{classname}}}) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}

View File

@@ -0,0 +1,114 @@
// {{classname}} - {{#description}}{{{description}}}{{/description}}{{^description}}struct for {{{classname}}}{{/description}}
type {{classname}} struct {
{{#oneOf}}
{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}} *{{{.}}}
{{/oneOf}}
}
{{#oneOf}}
// {{{.}}}As{{classname}} is a convenience function that returns {{{.}}} wrapped in {{classname}}
func {{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}}As{{classname}}(v *{{{.}}}) {{classname}} {
return {{classname}}{
{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}}: v,
}
}
{{/oneOf}}
// Unmarshal JSON data into one of the pointers in the struct
func (dst *{{classname}}) UnmarshalJSON(data []byte) error {
var err error
{{#isNullable}}
// this object is nullable so check if the payload is null or empty string
if string(data) == "" || string(data) == "{}" {
return nil
}
{{/isNullable}}
{{#useOneOfDiscriminatorLookup}}
{{#discriminator}}
{{#mappedModels}}
{{#-first}}
// use discriminator value to speed up the lookup
var jsonDict map[string]interface{}
err = newStrictDecoder(data).Decode(&jsonDict)
if err != nil {
return fmt.Errorf("Failed to unmarshal JSON into map for the discrimintor lookup.")
}
{{/-first}}
// check if the discriminator value is '{{{mappingName}}}'
if jsonDict["{{{propertyBaseName}}}"] == "{{{mappingName}}}" {
// try to unmarshal JSON data into {{{modelName}}}
err = json.Unmarshal(data, &dst.{{{modelName}}})
if err == nil {
return nil // data stored in dst.{{{modelName}}}, return on the first match
} else {
dst.{{{modelName}}} = nil
return fmt.Errorf("Failed to unmarshal {{classname}} as {{{modelName}}}: %s", err.Error())
}
}
{{/mappedModels}}
{{/discriminator}}
return nil
{{/useOneOfDiscriminatorLookup}}
{{^useOneOfDiscriminatorLookup}}
match := 0
{{#oneOf}}
// try to unmarshal data into {{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}}
err = newStrictDecoder(data).Decode(&dst.{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}})
if err == nil {
json{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}}, _ := json.Marshal(dst.{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}})
if string(json{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}}) == "{}" { // empty struct
dst.{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}} = nil
} else {
match++
}
} else {
dst.{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}} = nil
}
{{/oneOf}}
if match > 1 { // more than 1 match
// reset to nil
{{#oneOf}}
dst.{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}} = nil
{{/oneOf}}
return fmt.Errorf("Data matches more than one schema in oneOf({{classname}})")
} else if match == 1 {
return nil // exactly one match
} else { // no match
return fmt.Errorf("Data failed to match schemas in oneOf({{classname}})")
}
{{/useOneOfDiscriminatorLookup}}
}
// Marshal data from the first non-nil pointers in the struct to JSON
func (src {{classname}}) MarshalJSON() ([]byte, error) {
{{#oneOf}}
if src.{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}} != nil {
return json.Marshal(&src.{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}})
}
{{/oneOf}}
return nil, nil // no data in oneOf schemas
}
// Get the actual instance
func (obj *{{classname}}) GetActualInstance() (interface{}) {
if obj == nil {
return nil
}
{{#oneOf}}
if obj.{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}} != nil {
return obj.{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}}
}
{{/oneOf}}
// all schemas are nil
return nil
}
{{>nullable_model}}

View File

@@ -0,0 +1,391 @@
// {{classname}}{{#description}} {{{description}}}{{/description}}{{^description}} struct for {{{classname}}}{{/description}}
type {{classname}} struct {
{{#parent}}
{{^isMap}}
{{^isArray}}
{{{parent}}}
{{/isArray}}
{{/isMap}}
{{#isArray}}
Items {{{parent}}}
{{/isArray}}
{{/parent}}
{{#vars}}
{{^-first}}
{{/-first}}
{{#description}}
// {{{description}}}
{{/description}}
{{name}} {{^required}}{{^isNullable}}{{^isArray}}{{^isFreeFormObject}}*{{/isFreeFormObject}}{{/isArray}}{{/isNullable}}{{/required}}{{{dataType}}} `json:"{{baseName}}{{^required}},omitempty{{/required}}"{{#withXml}} xml:"{{baseName}}{{#isXmlAttribute}},attr{{/isXmlAttribute}}"{{/withXml}}{{#vendorExtensions.x-go-custom-tag}} {{{.}}}{{/vendorExtensions.x-go-custom-tag}}`
{{/vars}}
{{#isAdditionalPropertiesTrue}}
AdditionalProperties map[string]interface{}
{{/isAdditionalPropertiesTrue}}
}
{{#isAdditionalPropertiesTrue}}
type _{{{classname}}} {{{classname}}}
{{/isAdditionalPropertiesTrue}}
// New{{classname}} instantiates a new {{classname}} object
// This constructor will assign default values to properties that have it defined,
// and makes sure properties required by API are set, but the set of arguments
// will change when the set of required properties is changed
func New{{classname}}({{#vars}}{{#required}}{{nameInCamelCase}} {{dataType}}, {{/required}}{{/vars}}) *{{classname}} {
this := {{classname}}{}
{{#vars}}
{{#required}}
this.{{name}} = {{nameInCamelCase}}
{{/required}}
{{^required}}
{{#defaultValue}}
{{^vendorExtensions.x-golang-is-container}}
{{#isNullable}}
var {{nameInCamelCase}} {{{datatypeWithEnum}}} = {{{.}}}
this.{{name}} = *New{{{dataType}}}(&{{nameInCamelCase}})
{{/isNullable}}
{{^isNullable}}
var {{nameInCamelCase}} {{{dataType}}} = {{{.}}}
this.{{name}} = &{{nameInCamelCase}}
{{/isNullable}}
{{/vendorExtensions.x-golang-is-container}}
{{/defaultValue}}
{{/required}}
{{/vars}}
return &this
}
// New{{classname}}WithDefaults instantiates a new {{classname}} object
// This constructor will only assign default values to properties that have it defined,
// but it doesn't guarantee that properties required by API are set
func New{{classname}}WithDefaults() *{{classname}} {
this := {{classname}}{}
{{#vars}}
{{#defaultValue}}
{{^vendorExtensions.x-golang-is-container}}
{{#isNullable}}
{{!we use datatypeWithEnum here, since it will represent the non-nullable name of the datatype, e.g. int64 for NullableInt64}}
var {{nameInCamelCase}} {{{datatypeWithEnum}}} = {{{.}}}
this.{{name}} = *New{{{dataType}}}(&{{nameInCamelCase}})
{{/isNullable}}
{{^isNullable}}
var {{nameInCamelCase}} {{{dataType}}} = {{{.}}}
this.{{name}} = {{^required}}&{{/required}}{{nameInCamelCase}}
{{/isNullable}}
{{/vendorExtensions.x-golang-is-container}}
{{/defaultValue}}
{{/vars}}
return &this
}
{{#vars}}
{{#required}}
// Get{{name}} returns the {{name}} field value
{{#isNullable}}
// If the value is explicit nil, the zero value for {{vendorExtensions.x-go-base-type}} will be returned
{{/isNullable}}
func (o *{{classname}}) Get{{name}}() {{vendorExtensions.x-go-base-type}} {
if o == nil {{#isNullable}}{{^vendorExtensions.x-golang-is-container}}|| o.{{name}}.Get() == nil{{/vendorExtensions.x-golang-is-container}}{{/isNullable}} {
var ret {{vendorExtensions.x-go-base-type}}
return ret
}
{{#isNullable}}
{{#vendorExtensions.x-golang-is-container}}
return o.{{name}}
{{/vendorExtensions.x-golang-is-container}}
{{^vendorExtensions.x-golang-is-container}}
return *o.{{name}}.Get()
{{/vendorExtensions.x-golang-is-container}}
{{/isNullable}}
{{^isNullable}}
return o.{{name}}
{{/isNullable}}
}
// Get{{name}}Ok returns a tuple with the {{name}} field value
// and a boolean to check if the value has been set.
{{#isNullable}}
// NOTE: If the value is an explicit nil, `nil, true` will be returned
{{/isNullable}}
func (o *{{classname}}) Get{{name}}Ok() ({{^isArray}}{{^isFreeFormObject}}*{{/isFreeFormObject}}{{/isArray}}{{vendorExtensions.x-go-base-type}}, bool) {
if o == nil {{#isNullable}}{{#vendorExtensions.x-golang-is-container}}|| o.{{name}} == nil{{/vendorExtensions.x-golang-is-container}}{{/isNullable}} {
return nil, false
}
{{#isNullable}}
{{#vendorExtensions.x-golang-is-container}}
return {{^isArray}}{{^isFreeFormObject}}&{{/isFreeFormObject}}{{/isArray}}o.{{name}}, true
{{/vendorExtensions.x-golang-is-container}}
{{^vendorExtensions.x-golang-is-container}}
return o.{{name}}.Get(), o.{{name}}.IsSet()
{{/vendorExtensions.x-golang-is-container}}
{{/isNullable}}
{{^isNullable}}
return {{^isArray}}{{^isFreeFormObject}}&{{/isFreeFormObject}}{{/isArray}}o.{{name}}, true
{{/isNullable}}
}
// Set{{name}} sets field value
func (o *{{classname}}) Set{{name}}(v {{vendorExtensions.x-go-base-type}}) {
{{#isNullable}}
{{#vendorExtensions.x-golang-is-container}}
o.{{name}} = v
{{/vendorExtensions.x-golang-is-container}}
{{^vendorExtensions.x-golang-is-container}}
o.{{name}}.Set(&v)
{{/vendorExtensions.x-golang-is-container}}
{{/isNullable}}
{{^isNullable}}
o.{{name}} = v
{{/isNullable}}
}
{{/required}}
{{^required}}
// Get{{name}} returns the {{name}} field value if set, zero value otherwise{{#isNullable}} (both if not set or set to explicit null){{/isNullable}}.
func (o *{{classname}}) Get{{name}}() {{vendorExtensions.x-go-base-type}} {
if o == nil {{^isNullable}}|| o.{{name}} == nil{{/isNullable}}{{#isNullable}}{{^vendorExtensions.x-golang-is-container}}|| o.{{name}}.Get() == nil{{/vendorExtensions.x-golang-is-container}}{{/isNullable}} {
var ret {{vendorExtensions.x-go-base-type}}
return ret
}
{{#isNullable}}
{{#vendorExtensions.x-golang-is-container}}
return o.{{name}}
{{/vendorExtensions.x-golang-is-container}}
{{^vendorExtensions.x-golang-is-container}}
return *o.{{name}}.Get()
{{/vendorExtensions.x-golang-is-container}}
{{/isNullable}}
{{^isNullable}}
return {{^isArray}}{{^isFreeFormObject}}*{{/isFreeFormObject}}{{/isArray}}o.{{name}}
{{/isNullable}}
}
// Get{{name}}Ok returns a tuple with the {{name}} field value if set, nil otherwise
// and a boolean to check if the value has been set.
{{#isNullable}}
// NOTE: If the value is an explicit nil, `nil, true` will be returned
{{/isNullable}}
func (o *{{classname}}) Get{{name}}Ok() ({{^isArray}}{{^isFreeFormObject}}*{{/isFreeFormObject}}{{/isArray}}{{vendorExtensions.x-go-base-type}}, bool) {
if o == nil {{^isNullable}}|| o.{{name}} == nil{{/isNullable}}{{#isNullable}}{{#vendorExtensions.x-golang-is-container}}|| o.{{name}} == nil{{/vendorExtensions.x-golang-is-container}}{{/isNullable}} {
return nil, false
}
{{#isNullable}}
{{#vendorExtensions.x-golang-is-container}}
return {{^isArray}}{{^isFreeFormObject}}&{{/isFreeFormObject}}{{/isArray}}o.{{name}}, true
{{/vendorExtensions.x-golang-is-container}}
{{^vendorExtensions.x-golang-is-container}}
return o.{{name}}.Get(), o.{{name}}.IsSet()
{{/vendorExtensions.x-golang-is-container}}
{{/isNullable}}
{{^isNullable}}
return o.{{name}}, true
{{/isNullable}}
}
// Has{{name}} returns a boolean if a field has been set.
func (o *{{classname}}) Has{{name}}() bool {
if o != nil && {{^isNullable}}o.{{name}} != nil{{/isNullable}}{{#isNullable}}{{#vendorExtensions.x-golang-is-container}}o.{{name}} != nil{{/vendorExtensions.x-golang-is-container}}{{^vendorExtensions.x-golang-is-container}}o.{{name}}.IsSet(){{/vendorExtensions.x-golang-is-container}}{{/isNullable}} {
return true
}
return false
}
// Set{{name}} gets a reference to the given {{dataType}} and assigns it to the {{name}} field.
func (o *{{classname}}) Set{{name}}(v {{vendorExtensions.x-go-base-type}}) {
{{#isNullable}}
{{#vendorExtensions.x-golang-is-container}}
o.{{name}} = v
{{/vendorExtensions.x-golang-is-container}}
{{^vendorExtensions.x-golang-is-container}}
o.{{name}}.Set({{^isArray}}{{^isFreeFormObject}}&{{/isFreeFormObject}}{{/isArray}}v)
{{/vendorExtensions.x-golang-is-container}}
{{/isNullable}}
{{^isNullable}}
o.{{name}} = {{^isArray}}{{^isFreeFormObject}}&{{/isFreeFormObject}}{{/isArray}}v
{{/isNullable}}
}
{{#isNullable}}
{{^vendorExtensions.x-golang-is-container}}
// Set{{name}}Nil sets the value for {{name}} to be an explicit nil
func (o *{{classname}}) Set{{name}}Nil() {
o.{{name}}.Set(nil)
}
// Unset{{name}} ensures that no value is present for {{name}}, not even an explicit nil
func (o *{{classname}}) Unset{{name}}() {
o.{{name}}.Unset()
}
{{/vendorExtensions.x-golang-is-container}}
{{/isNullable}}
{{/required}}
{{/vars}}
func (o {{classname}}) MarshalJSON() ([]byte, error) {
toSerialize := {{#isArray}}make([]interface{}, len(o.Items)){{/isArray}}{{^isArray}}map[string]interface{}{}{{/isArray}}
{{#parent}}
{{^isMap}}
{{^isArray}}
serialized{{parent}}, err{{parent}} := json.Marshal(o.{{parent}})
if err{{parent}} != nil {
return []byte{}, err{{parent}}
}
err{{parent}} = json.Unmarshal([]byte(serialized{{parent}}), &toSerialize)
if err{{parent}} != nil {
return []byte{}, err{{parent}}
}
{{/isArray}}
{{/isMap}}
{{#isArray}}
for i, item := range o.Items {
toSerialize[i] = item
}
{{/isArray}}
{{/parent}}
{{#vars}}
{{! if argument is nullable, only serialize it if it is set}}
{{#isNullable}}
{{#vendorExtensions.x-golang-is-container}}
{{! support for container fields is not ideal at this point because of lack of Nullable* types}}
if o.{{name}} != nil {
toSerialize["{{baseName}}"] = o.{{name}}
}
{{/vendorExtensions.x-golang-is-container}}
{{^vendorExtensions.x-golang-is-container}}
if {{#required}}true{{/required}}{{^required}}o.{{name}}.IsSet(){{/required}} {
toSerialize["{{baseName}}"] = o.{{name}}.Get()
}
{{/vendorExtensions.x-golang-is-container}}
{{/isNullable}}
{{! if argument is not nullable, don't set it if it is nil}}
{{^isNullable}}
if {{#required}}true{{/required}}{{^required}}o.{{name}} != nil{{/required}} {
toSerialize["{{baseName}}"] = o.{{name}}
}
{{/isNullable}}
{{/vars}}
{{#isAdditionalPropertiesTrue}}
for key, value := range o.AdditionalProperties {
toSerialize[key] = value
}
{{/isAdditionalPropertiesTrue}}
return json.Marshal(toSerialize)
}
{{#isAdditionalPropertiesTrue}}
func (o *{{{classname}}}) UnmarshalJSON(bytes []byte) (err error) {
{{#parent}}
{{^isMap}}
type {{classname}}WithoutEmbeddedStruct struct {
{{#vars}}
{{^-first}}
{{/-first}}
{{#description}}
// {{{description}}}
{{/description}}
{{name}} {{^required}}{{^isNullable}}*{{/isNullable}}{{/required}}{{{dataType}}} `json:"{{baseName}}{{^required}},omitempty{{/required}}"{{#withXml}} xml:"{{baseName}}{{#isXmlAttribute}},attr{{/isXmlAttribute}}"{{/withXml}}{{#vendorExtensions.x-go-custom-tag}} {{{.}}}{{/vendorExtensions.x-go-custom-tag}}`
{{/vars}}
}
var{{{classname}}}WithoutEmbeddedStruct := {{{classname}}}WithoutEmbeddedStruct{}
err = json.Unmarshal(bytes, &var{{{classname}}}WithoutEmbeddedStruct)
if err == nil {
var{{{classname}}} := _{{{classname}}}{}
{{#vars}}
var{{{classname}}}.{{{name}}} = var{{{classname}}}WithoutEmbeddedStruct.{{{name}}}
{{/vars}}
*o = {{{classname}}}(var{{{classname}}})
} else {
return err
}
var{{{classname}}} := _{{{classname}}}{}
err = json.Unmarshal(bytes, &var{{{classname}}})
if err == nil {
o.{{{parent}}} = var{{{classname}}}.{{{parent}}}
} else {
return err
}
additionalProperties := make(map[string]interface{})
if err = json.Unmarshal(bytes, &additionalProperties); err == nil {
{{#vars}}
delete(additionalProperties, "{{{baseName}}}")
{{/vars}}
// remove fields from embedded structs
reflect{{{parent}}} := reflect.ValueOf(o.{{{parent}}})
for i := 0; i < reflect{{{parent}}}.Type().NumField(); i++ {
t := reflect{{{parent}}}.Type().Field(i)
if jsonTag := t.Tag.Get("json"); jsonTag != "" {
fieldName := ""
if commaIdx := strings.Index(jsonTag, ","); commaIdx > 0 {
fieldName = jsonTag[:commaIdx]
} else {
fieldName = jsonTag
}
if fieldName != "AdditionalProperties" {
delete(additionalProperties, fieldName)
}
}
}
o.AdditionalProperties = additionalProperties
}
return err
{{/isMap}}
{{#isMap}}
var{{{classname}}} := _{{{classname}}}{}
if err = json.Unmarshal(bytes, &var{{{classname}}}); err == nil {
*o = {{{classname}}}(var{{{classname}}})
}
additionalProperties := make(map[string]interface{})
if err = json.Unmarshal(bytes, &additionalProperties); err == nil {
{{#vars}}
delete(additionalProperties, "{{{baseName}}}")
{{/vars}}
o.AdditionalProperties = additionalProperties
}
return err
{{/isMap}}
{{/parent}}
{{^parent}}
var{{{classname}}} := _{{{classname}}}{}
if err = json.Unmarshal(bytes, &var{{{classname}}}); err == nil {
*o = {{{classname}}}(var{{{classname}}})
}
additionalProperties := make(map[string]interface{})
if err = json.Unmarshal(bytes, &additionalProperties); err == nil {
{{#vars}}
delete(additionalProperties, "{{{baseName}}}")
{{/vars}}
o.AdditionalProperties = additionalProperties
}
return err
{{/parent}}
}
{{/isAdditionalPropertiesTrue}}
{{#isArray}}
func (o *{{{classname}}}) UnmarshalJSON(bytes []byte) (err error) {
return json.Unmarshal(bytes, &o.Items)
}
{{/isArray}}
{{>nullable_model}}

View File

@@ -0,0 +1,35 @@
type Nullable{{{classname}}} struct {
value {{^isArray}}{{^isFreeFormObject}}*{{/isFreeFormObject}}{{/isArray}}{{{classname}}}
isSet bool
}
func (v Nullable{{classname}}) Get() {{^isArray}}{{^isFreeFormObject}}*{{/isFreeFormObject}}{{/isArray}}{{classname}} {
return v.value
}
func (v *Nullable{{classname}}) Set(val {{^isArray}}{{^isFreeFormObject}}*{{/isFreeFormObject}}{{/isArray}}{{classname}}) {
v.value = val
v.isSet = true
}
func (v Nullable{{classname}}) IsSet() bool {
return v.isSet
}
func (v *Nullable{{classname}}) Unset() {
v.value = nil
v.isSet = false
}
func NewNullable{{classname}}(val {{^isArray}}{{^isFreeFormObject}}*{{/isFreeFormObject}}{{/isArray}}{{classname}}) *Nullable{{classname}} {
return &Nullable{{classname}}{value: val, isSet: true}
}
func (v Nullable{{{classname}}}) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *Nullable{{{classname}}}) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}

View File

@@ -0,0 +1 @@
{{{openapi-yaml}}}

View File

@@ -0,0 +1,18 @@
/*
{{#appName}}
* {{{appName}}}
*
{{/appName}}
{{#appDescription}}
* {{{appDescription}}}
*
{{/appDescription}}
{{#version}}
* API version: {{{version}}}
{{/version}}
{{#infoEmail}}
* Contact: {{{infoEmail}}}
{{/infoEmail}}
*/
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.

View File

@@ -0,0 +1,38 @@
{{>partial_header}}
package {{packageName}}
import (
"net/http"
)
// APIResponse stores the API response returned by the server.
type APIResponse struct {
*http.Response `json:"-"`
Message string `json:"message,omitempty"`
// Operation is the name of the OpenAPI operation.
Operation string `json:"operation,omitempty"`
// RequestURL is the request URL. This value is always available, even if the
// embedded *http.Response is nil.
RequestURL string `json:"url,omitempty"`
// Method is the HTTP method used for the request. This value is always
// available, even if the embedded *http.Response is nil.
Method string `json:"method,omitempty"`
// Payload holds the contents of the response body (which may be nil or empty).
// This is provided here as the raw response.Body() reader will have already
// been drained.
Payload []byte `json:"-"`
}
// NewAPIResponse returns a new APIResonse object.
func NewAPIResponse(r *http.Response) *APIResponse {
response := &APIResponse{Response: r}
return response
}
// NewAPIResponseWithError returns a new APIResponse object with the provided error message.
func NewAPIResponseWithError(errorMessage string) *APIResponse {
response := &APIResponse{Message: errorMessage}
return response
}

View File

@@ -0,0 +1,414 @@
{{>partial_header}}
package {{packageName}}
import (
"bytes"
"context"
"crypto"
"crypto/ecdsa"
"crypto/ed25519"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
"io"
"net/http"
"net/textproto"
"os"
"strings"
"time"
)
const (
// Constants for HTTP signature parameters.
// The '(request-target)' parameter concatenates the lowercased :method, an
// ASCII space, and the :path pseudo-headers.
HttpSignatureParameterRequestTarget string = "(request-target)"
// The '(created)' parameter expresses when the signature was
// created. The value MUST be a Unix timestamp integer value.
HttpSignatureParameterCreated string = "(created)"
// The '(expires)' parameter expresses when the signature ceases to
// be valid. The value MUST be a Unix timestamp integer value.
HttpSignatureParameterExpires string = "(expires)"
)
const (
// Constants for HTTP headers.
// The 'Host' header, as defined in RFC 2616, section 14.23.
HttpHeaderHost string = "Host"
// The 'Date' header.
HttpHeaderDate string = "Date"
// The digest header, as defined in RFC 3230, section 4.3.2.
HttpHeaderDigest string = "Digest"
// The HTTP Authorization header, as defined in RFC 7235, section 4.2.
HttpHeaderAuthorization string = "Authorization"
)
const (
// Specifies the Digital Signature Algorithm is derived from metadata
// associated with 'keyId'. Supported DSA algorithms are RSASSA-PKCS1-v1_5,
// RSASSA-PSS, and ECDSA.
// The hash is SHA-512.
// This is the default value.
HttpSigningSchemeHs2019 string = "hs2019"
// Use RSASSA-PKCS1-v1_5 with SHA-512 hash. Deprecated.
HttpSigningSchemeRsaSha512 string = "rsa-sha512"
// Use RSASSA-PKCS1-v1_5 with SHA-256 hash. Deprecated.
HttpSigningSchemeRsaSha256 string = "rsa-sha256"
// RFC 8017 section 7.2
// Calculate the message signature using RSASSA-PKCS1-V1_5-SIGN from RSA PKCS#1 v1.5.
// PKCSV1_5 is deterministic. The same message and key will produce an identical
// signature value each time.
HttpSigningAlgorithmRsaPKCS1v15 string = "RSASSA-PKCS1-v1_5"
// Calculate the message signature using probabilistic signature scheme RSASSA-PSS.
// PSS is randomized and will produce a different signature value each time.
HttpSigningAlgorithmRsaPSS string = "RSASSA-PSS"
)
var supportedSigningSchemes = map[string]bool{
HttpSigningSchemeHs2019: true,
HttpSigningSchemeRsaSha512: true,
HttpSigningSchemeRsaSha256: true,
}
// HttpSignatureAuth provides HTTP signature authentication to a request passed
// via context using ContextHttpSignatureAuth.
// An 'Authorization' header is calculated by creating a hash of select headers,
// and optionally the body of the HTTP request, then signing the hash value using
// a private key which is available to the client.
//
// SignedHeaders specifies the list of HTTP headers that are included when generating
// the message signature.
// The two special signature headers '(request-target)' and '(created)' SHOULD be
// included in SignedHeaders.
// The '(created)' header expresses when the signature was created.
// The '(request-target)' header is a concatenation of the lowercased :method, an
// ASCII space, and the :path pseudo-headers.
//
// For example, SignedHeaders can be set to:
// (request-target) (created) date host digest
//
// When SignedHeaders is not specified, the client defaults to a single value, '(created)',
// in the list of HTTP headers.
// When SignedHeaders contains the 'Digest' value, the client performs the following operations:
// 1. Calculate a digest of request body, as specified in RFC3230, section 4.3.2.
// 2. Set the 'Digest' header in the request body.
// 3. Include the 'Digest' header and value in the HTTP signature.
type HttpSignatureAuth struct {
KeyId string // A key identifier.
PrivateKeyPath string // The path to the private key.
Passphrase string // The passphrase to decrypt the private key, if the key is encrypted.
SigningScheme string // The signature scheme, when signing HTTP requests. Supported value is 'hs2019'.
// The signature algorithm, when signing HTTP requests.
// Supported values are RSASSA-PKCS1-v1_5, RSASSA-PSS.
SigningAlgorithm string
SignedHeaders []string // A list of HTTP headers included when generating the signature for the message.
// SignatureMaxValidity specifies the maximum duration of the signature validity.
// The value is used to set the '(expires)' signature parameter in the HTTP request.
// '(expires)' is set to '(created)' plus the value of the SignatureMaxValidity field.
// To specify the '(expires)' signature parameter, set 'SignatureMaxValidity' and add '(expires)' to 'SignedHeaders'.
SignatureMaxValidity time.Duration
privateKey crypto.PrivateKey // The private key used to sign HTTP requests.
}
// ContextWithValue validates the HttpSignatureAuth configuration parameters and returns a context
// suitable for HTTP signature. An error is returned if the HttpSignatureAuth configuration parameters
// are invalid.
func (h *HttpSignatureAuth) ContextWithValue(ctx context.Context) (context.Context, error) {
if h.KeyId == "" {
return nil, fmt.Errorf("Key ID must be specified")
}
if h.PrivateKeyPath == "" {
return nil, fmt.Errorf("Private key path must be specified")
}
if _, ok := supportedSigningSchemes[h.SigningScheme]; !ok {
return nil, fmt.Errorf("Invalid signing scheme: '%v'", h.SigningScheme)
}
m := make(map[string]bool)
for _, h := range h.SignedHeaders {
if strings.ToLower(h) == strings.ToLower(HttpHeaderAuthorization) {
return nil, fmt.Errorf("Signed headers cannot include the 'Authorization' header")
}
m[h] = true
}
if len(m) != len(h.SignedHeaders) {
return nil, fmt.Errorf("List of signed headers cannot have duplicate names")
}
if h.SignatureMaxValidity < 0 {
return nil, fmt.Errorf("Signature max validity must be a positive value")
}
if err := h.loadPrivateKey(); err != nil {
return nil, err
}
return context.WithValue(ctx, ContextHttpSignatureAuth, *h), nil
}
// GetPublicKey returns the public key associated with this HTTP signature configuration.
func (h *HttpSignatureAuth) GetPublicKey() (crypto.PublicKey, error) {
if h.privateKey == nil {
if err := h.loadPrivateKey(); err != nil {
return nil, err
}
}
switch key := h.privateKey.(type) {
case *rsa.PrivateKey:
return key.Public(), nil
case *ecdsa.PrivateKey:
return key.Public(), nil
default:
// Do not change '%T' to anything else such as '%v'!
// The value of the private key must not be returned.
return nil, fmt.Errorf("Unsupported key: %T", h.privateKey)
}
}
// loadPrivateKey reads the private key from the file specified in the HttpSignatureAuth.
func (h *HttpSignatureAuth) loadPrivateKey() (err error) {
var file *os.File
file, err = os.Open(h.PrivateKeyPath)
if err != nil {
return fmt.Errorf("Cannot load private key '%s'. Error: %v", h.PrivateKeyPath, err)
}
defer func() {
err = file.Close()
}()
var priv []byte
priv, err = io.ReadAll(file)
if err != nil {
return err
}
pemBlock, _ := pem.Decode(priv)
if pemBlock == nil {
// No PEM data has been found.
return fmt.Errorf("File '%s' does not contain PEM data", h.PrivateKeyPath)
}
var privKey []byte
if x509.IsEncryptedPEMBlock(pemBlock) {
// The PEM data is encrypted.
privKey, err = x509.DecryptPEMBlock(pemBlock, []byte(h.Passphrase))
if err != nil {
// Failed to decrypt PEM block. Because of deficiencies in the encrypted-PEM format,
// it's not always possibleto detect an incorrect password.
return err
}
} else {
privKey = pemBlock.Bytes
}
switch pemBlock.Type {
case "RSA PRIVATE KEY":
if h.privateKey, err = x509.ParsePKCS1PrivateKey(privKey); err != nil {
return err
}
case "EC PRIVATE KEY", "PRIVATE KEY":
// https://tools.ietf.org/html/rfc5915 section 4.
if h.privateKey, err = x509.ParsePKCS8PrivateKey(privKey); err != nil {
return err
}
default:
return fmt.Errorf("Key '%s' is not supported", pemBlock.Type)
}
return nil
}
// SignRequest signs the request using HTTP signature.
// See https://datatracker.ietf.org/doc/draft-cavage-http-signatures/
//
// Do not add, remove or change headers that are included in the SignedHeaders
// after SignRequest has been invoked; this is because the header values are
// included in the signature. Any subsequent alteration will cause a signature
// verification failure.
// If there are multiple instances of the same header field, all
// header field values associated with the header field MUST be
// concatenated, separated by a ASCII comma and an ASCII space
// ', ', and used in the order in which they will appear in the
// transmitted HTTP message.
func SignRequest(
ctx context.Context,
r *http.Request,
auth HttpSignatureAuth) error {
if auth.privateKey == nil {
return fmt.Errorf("Private key is not set")
}
now := time.Now()
date := now.UTC().Format(http.TimeFormat)
// The 'created' field expresses when the signature was created.
// The value MUST be a Unix timestamp integer value. See 'HTTP signature' section 2.1.4.
created := now.Unix()
var h crypto.Hash
var err error
var prefix string
var expiresUnix float64
if auth.SignatureMaxValidity < 0 {
return fmt.Errorf("Signature validity must be a positive value")
}
if auth.SignatureMaxValidity > 0 {
e := now.Add(auth.SignatureMaxValidity)
expiresUnix = float64(e.Unix()) + float64(e.Nanosecond()) / float64(time.Second)
}
// Determine the cryptographic hash to be used for the signature and the body digest.
switch auth.SigningScheme {
case HttpSigningSchemeRsaSha512, HttpSigningSchemeHs2019:
h = crypto.SHA512
prefix = "SHA-512="
case HttpSigningSchemeRsaSha256:
// This is deprecated and should no longer be used.
h = crypto.SHA256
prefix = "SHA-256="
default:
return fmt.Errorf("Unsupported signature scheme: %v", auth.SigningScheme)
}
if !h.Available() {
return fmt.Errorf("Hash '%v' is not available", h)
}
// Build the "(request-target)" signature header.
var sb bytes.Buffer
fmt.Fprintf(&sb, "%s %s", strings.ToLower(r.Method), r.URL.EscapedPath())
if r.URL.RawQuery != "" {
// The ":path" pseudo-header field includes the path and query parts
// of the target URI (the "path-absolute" production and optionally a
// '?' character followed by the "query" production (see Sections 3.3
// and 3.4 of [RFC3986]
fmt.Fprintf(&sb, "?%s", r.URL.RawQuery)
}
requestTarget := sb.String()
sb.Reset()
// Build the string to be signed.
signedHeaders := auth.SignedHeaders
if len(signedHeaders) == 0 {
signedHeaders = []string{HttpSignatureParameterCreated}
}
// Validate the list of signed headers has no duplicates.
m := make(map[string]bool)
for _, h := range signedHeaders {
m[h] = true
}
if len(m) != len(signedHeaders) {
return fmt.Errorf("List of signed headers must not have any duplicates")
}
hasCreatedParameter := false
hasExpiresParameter := false
for i, header := range signedHeaders {
header = strings.ToLower(header)
var value string
switch header {
case strings.ToLower(HttpHeaderAuthorization):
return fmt.Errorf("Cannot include the 'Authorization' header as a signed header.")
case HttpSignatureParameterRequestTarget:
value = requestTarget
case HttpSignatureParameterCreated:
value = fmt.Sprintf("%d", created)
hasCreatedParameter = true
case HttpSignatureParameterExpires:
if auth.SignatureMaxValidity.Nanoseconds() == 0 {
return fmt.Errorf("Cannot set '(expires)' signature parameter. SignatureMaxValidity is not configured.")
}
value = fmt.Sprintf("%.3f", expiresUnix)
hasExpiresParameter = true
case "date":
value = date
r.Header.Set(HttpHeaderDate, date)
case "digest":
// Calculate the digest of the HTTP request body.
// Calculate body digest per RFC 3230 section 4.3.2
bodyHash := h.New()
if r.Body != nil {
// Make a copy of the body io.Reader so that we can read the body to calculate the hash,
// then one more time when marshaling the request.
var body io.Reader
body, err = r.GetBody()
if err != nil {
return err
}
if _, err = io.Copy(bodyHash, body); err != nil {
return err
}
}
d := bodyHash.Sum(nil)
value = prefix + base64.StdEncoding.EncodeToString(d)
r.Header.Set(HttpHeaderDigest, value)
case "host":
value = r.Host
r.Header.Set(HttpHeaderHost, r.Host)
default:
var ok bool
var v []string
canonicalHeader := textproto.CanonicalMIMEHeaderKey(header)
if v, ok = r.Header[canonicalHeader]; !ok {
// If a header specified in the headers parameter cannot be matched with
// a provided header in the message, the implementation MUST produce an error.
return fmt.Errorf("Header '%s' does not exist in the request", canonicalHeader)
}
// If there are multiple instances of the same header field, all
// header field values associated with the header field MUST be
// concatenated, separated by a ASCII comma and an ASCII space
// `, `, and used in the order in which they will appear in the
// transmitted HTTP message.
value = strings.Join(v, ", ")
}
if i > 0 {
fmt.Fprintf(&sb, "\n")
}
fmt.Fprintf(&sb, "%s: %s", header, value)
}
if expiresUnix != 0 && !hasExpiresParameter {
return fmt.Errorf("SignatureMaxValidity is specified, but '(expired)' parameter is not present")
}
msg := []byte(sb.String())
msgHash := h.New()
if _, err = msgHash.Write(msg); err != nil {
return err
}
d := msgHash.Sum(nil)
var signature []byte
switch key := auth.privateKey.(type) {
case *rsa.PrivateKey:
switch auth.SigningAlgorithm {
case HttpSigningAlgorithmRsaPKCS1v15:
signature, err = rsa.SignPKCS1v15(rand.Reader, key, h, d)
case "", HttpSigningAlgorithmRsaPSS:
signature, err = rsa.SignPSS(rand.Reader, key, h, d, nil)
default:
return fmt.Errorf("Unsupported signing algorithm: '%s'", auth.SigningAlgorithm)
}
case *ecdsa.PrivateKey:
signature, err = key.Sign(rand.Reader, d, h)
case ed25519.PrivateKey: // requires go 1.13
signature, err = key.Sign(rand.Reader, msg, crypto.Hash(0))
default:
return fmt.Errorf("Unsupported private key")
}
if err != nil {
return err
}
sb.Reset()
for i, header := range signedHeaders {
if i > 0 {
sb.WriteRune(' ')
}
sb.WriteString(strings.ToLower(header))
}
headers_list := sb.String()
sb.Reset()
fmt.Fprintf(&sb, `Signature keyId="%s",algorithm="%s",`, auth.KeyId, auth.SigningScheme)
if hasCreatedParameter {
fmt.Fprintf(&sb, "created=%d,", created)
}
if hasExpiresParameter {
fmt.Fprintf(&sb, "expires=%.3f,", expiresUnix)
}
fmt.Fprintf(&sb, `headers="%s",signature="%s"`, headers_list, base64.StdEncoding.EncodeToString(signature))
authStr := sb.String()
r.Header.Set(HttpHeaderAuthorization, authStr)
return nil
}

View File

@@ -0,0 +1,326 @@
{{>partial_header}}
package {{packageName}}
import (
"encoding/json"
"time"
)
// PtrBool is a helper routine that returns a pointer to given boolean value.
func PtrBool(v bool) *bool { return &v }
// PtrInt is a helper routine that returns a pointer to given integer value.
func PtrInt(v int) *int { return &v }
// PtrInt32 is a helper routine that returns a pointer to given integer value.
func PtrInt32(v int32) *int32 { return &v }
// PtrInt64 is a helper routine that returns a pointer to given integer value.
func PtrInt64(v int64) *int64 { return &v }
// PtrFloat32 is a helper routine that returns a pointer to given float value.
func PtrFloat32(v float32) *float32 { return &v }
// PtrFloat64 is a helper routine that returns a pointer to given float value.
func PtrFloat64(v float64) *float64 { return &v }
// PtrString is a helper routine that returns a pointer to given string value.
func PtrString(v string) *string { return &v }
// PtrTime is helper routine that returns a pointer to given Time value.
func PtrTime(v time.Time) *time.Time { return &v }
type NullableBool struct {
value *bool
isSet bool
}
func (v NullableBool) Get() *bool {
return v.value
}
func (v *NullableBool) Set(val *bool) {
v.value = val
v.isSet = true
}
func (v NullableBool) IsSet() bool {
return v.isSet
}
func (v *NullableBool) Unset() {
v.value = nil
v.isSet = false
}
func NewNullableBool(val *bool) *NullableBool {
return &NullableBool{value: val, isSet: true}
}
func (v NullableBool) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *NullableBool) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}
type NullableInt struct {
value *int
isSet bool
}
func (v NullableInt) Get() *int {
return v.value
}
func (v *NullableInt) Set(val *int) {
v.value = val
v.isSet = true
}
func (v NullableInt) IsSet() bool {
return v.isSet
}
func (v *NullableInt) Unset() {
v.value = nil
v.isSet = false
}
func NewNullableInt(val *int) *NullableInt {
return &NullableInt{value: val, isSet: true}
}
func (v NullableInt) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *NullableInt) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}
type NullableInt32 struct {
value *int32
isSet bool
}
func (v NullableInt32) Get() *int32 {
return v.value
}
func (v *NullableInt32) Set(val *int32) {
v.value = val
v.isSet = true
}
func (v NullableInt32) IsSet() bool {
return v.isSet
}
func (v *NullableInt32) Unset() {
v.value = nil
v.isSet = false
}
func NewNullableInt32(val *int32) *NullableInt32 {
return &NullableInt32{value: val, isSet: true}
}
func (v NullableInt32) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *NullableInt32) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}
type NullableInt64 struct {
value *int64
isSet bool
}
func (v NullableInt64) Get() *int64 {
return v.value
}
func (v *NullableInt64) Set(val *int64) {
v.value = val
v.isSet = true
}
func (v NullableInt64) IsSet() bool {
return v.isSet
}
func (v *NullableInt64) Unset() {
v.value = nil
v.isSet = false
}
func NewNullableInt64(val *int64) *NullableInt64 {
return &NullableInt64{value: val, isSet: true}
}
func (v NullableInt64) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *NullableInt64) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}
type NullableFloat32 struct {
value *float32
isSet bool
}
func (v NullableFloat32) Get() *float32 {
return v.value
}
func (v *NullableFloat32) Set(val *float32) {
v.value = val
v.isSet = true
}
func (v NullableFloat32) IsSet() bool {
return v.isSet
}
func (v *NullableFloat32) Unset() {
v.value = nil
v.isSet = false
}
func NewNullableFloat32(val *float32) *NullableFloat32 {
return &NullableFloat32{value: val, isSet: true}
}
func (v NullableFloat32) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *NullableFloat32) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}
type NullableFloat64 struct {
value *float64
isSet bool
}
func (v NullableFloat64) Get() *float64 {
return v.value
}
func (v *NullableFloat64) Set(val *float64) {
v.value = val
v.isSet = true
}
func (v NullableFloat64) IsSet() bool {
return v.isSet
}
func (v *NullableFloat64) Unset() {
v.value = nil
v.isSet = false
}
func NewNullableFloat64(val *float64) *NullableFloat64 {
return &NullableFloat64{value: val, isSet: true}
}
func (v NullableFloat64) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *NullableFloat64) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}
type NullableString struct {
value *string
isSet bool
}
func (v NullableString) Get() *string {
return v.value
}
func (v *NullableString) Set(val *string) {
v.value = val
v.isSet = true
}
func (v NullableString) IsSet() bool {
return v.isSet
}
func (v *NullableString) Unset() {
v.value = nil
v.isSet = false
}
func NewNullableString(val *string) *NullableString {
return &NullableString{value: val, isSet: true}
}
func (v NullableString) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *NullableString) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}
type NullableTime struct {
value *time.Time
isSet bool
}
func (v NullableTime) Get() *time.Time {
return v.value
}
func (v *NullableTime) Set(val *time.Time) {
v.value = val
v.isSet = true
}
func (v NullableTime) IsSet() bool {
return v.isSet
}
func (v *NullableTime) Unset() {
v.value = nil
v.isSet = false
}
func NewNullableTime(val *time.Time) *NullableTime {
return &NullableTime{value: val, isSet: true}
}
func (v NullableTime) MarshalJSON() ([]byte, error) {
return v.value.MarshalJSON()
}
func (v *NullableTime) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}