@kattebak/openapi-generator-ts 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (290) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +189 -0
  3. package/dist/cli/commands/generate.d.ts +23 -0
  4. package/dist/cli/commands/generate.d.ts.map +1 -0
  5. package/dist/cli/commands/generate.js +116 -0
  6. package/dist/cli/commands/generate.js.map +1 -0
  7. package/dist/cli/commands/list.d.ts +2 -0
  8. package/dist/cli/commands/list.d.ts.map +1 -0
  9. package/dist/cli/commands/list.js +26 -0
  10. package/dist/cli/commands/list.js.map +1 -0
  11. package/dist/cli/commands/validate.d.ts +6 -0
  12. package/dist/cli/commands/validate.d.ts.map +1 -0
  13. package/dist/cli/commands/validate.js +80 -0
  14. package/dist/cli/commands/validate.js.map +1 -0
  15. package/dist/cli/convert-template.d.ts +31 -0
  16. package/dist/cli/convert-template.d.ts.map +1 -0
  17. package/dist/cli/convert-template.js +204 -0
  18. package/dist/cli/convert-template.js.map +1 -0
  19. package/dist/cli/convert-template.test.d.ts +2 -0
  20. package/dist/cli/convert-template.test.d.ts.map +1 -0
  21. package/dist/cli/convert-template.test.js +74 -0
  22. package/dist/cli/convert-template.test.js.map +1 -0
  23. package/dist/cli/index.d.ts +3 -0
  24. package/dist/cli/index.d.ts.map +1 -0
  25. package/dist/cli/index.js +246 -0
  26. package/dist/cli/index.js.map +1 -0
  27. package/dist/core/config.d.ts +252 -0
  28. package/dist/core/config.d.ts.map +1 -0
  29. package/dist/core/config.js +31 -0
  30. package/dist/core/config.js.map +1 -0
  31. package/dist/core/generator.d.ts +99 -0
  32. package/dist/core/generator.d.ts.map +1 -0
  33. package/dist/core/generator.js +492 -0
  34. package/dist/core/generator.js.map +1 -0
  35. package/dist/core/index.d.ts +4 -0
  36. package/dist/core/index.d.ts.map +1 -0
  37. package/dist/core/index.js +4 -0
  38. package/dist/core/index.js.map +1 -0
  39. package/dist/core/types.d.ts +47 -0
  40. package/dist/core/types.d.ts.map +1 -0
  41. package/dist/core/types.js +5 -0
  42. package/dist/core/types.js.map +1 -0
  43. package/dist/generators/generators.test.d.ts +6 -0
  44. package/dist/generators/generators.test.d.ts.map +1 -0
  45. package/dist/generators/generators.test.js +247 -0
  46. package/dist/generators/generators.test.js.map +1 -0
  47. package/dist/generators/go.d.ts +10 -0
  48. package/dist/generators/go.d.ts.map +1 -0
  49. package/dist/generators/go.js +327 -0
  50. package/dist/generators/go.js.map +1 -0
  51. package/dist/generators/index.d.ts +29 -0
  52. package/dist/generators/index.d.ts.map +1 -0
  53. package/dist/generators/index.js +58 -0
  54. package/dist/generators/index.js.map +1 -0
  55. package/dist/generators/php.d.ts +14 -0
  56. package/dist/generators/php.d.ts.map +1 -0
  57. package/dist/generators/php.js +241 -0
  58. package/dist/generators/php.js.map +1 -0
  59. package/dist/generators/python.d.ts +10 -0
  60. package/dist/generators/python.d.ts.map +1 -0
  61. package/dist/generators/python.js +273 -0
  62. package/dist/generators/python.js.map +1 -0
  63. package/dist/generators/typescript-fetch.d.ts +14 -0
  64. package/dist/generators/typescript-fetch.d.ts.map +1 -0
  65. package/dist/generators/typescript-fetch.js +217 -0
  66. package/dist/generators/typescript-fetch.js.map +1 -0
  67. package/dist/index.d.ts +14 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +16 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/models/codegen-model.d.ts +123 -0
  72. package/dist/models/codegen-model.d.ts.map +1 -0
  73. package/dist/models/codegen-model.js +64 -0
  74. package/dist/models/codegen-model.js.map +1 -0
  75. package/dist/models/codegen-model.test.d.ts +6 -0
  76. package/dist/models/codegen-model.test.d.ts.map +1 -0
  77. package/dist/models/codegen-model.test.js +143 -0
  78. package/dist/models/codegen-model.test.js.map +1 -0
  79. package/dist/models/codegen-operation.d.ts +95 -0
  80. package/dist/models/codegen-operation.d.ts.map +1 -0
  81. package/dist/models/codegen-operation.js +54 -0
  82. package/dist/models/codegen-operation.js.map +1 -0
  83. package/dist/models/codegen-parameter.d.ts +86 -0
  84. package/dist/models/codegen-parameter.d.ts.map +1 -0
  85. package/dist/models/codegen-parameter.js +47 -0
  86. package/dist/models/codegen-parameter.js.map +1 -0
  87. package/dist/models/codegen-property.d.ts +95 -0
  88. package/dist/models/codegen-property.d.ts.map +1 -0
  89. package/dist/models/codegen-property.js +47 -0
  90. package/dist/models/codegen-property.js.map +1 -0
  91. package/dist/models/codegen-response.d.ts +64 -0
  92. package/dist/models/codegen-response.d.ts.map +1 -0
  93. package/dist/models/codegen-response.js +42 -0
  94. package/dist/models/codegen-response.js.map +1 -0
  95. package/dist/models/codegen-security.d.ts +34 -0
  96. package/dist/models/codegen-security.d.ts.map +1 -0
  97. package/dist/models/codegen-security.js +18 -0
  98. package/dist/models/codegen-security.js.map +1 -0
  99. package/dist/models/index.d.ts +8 -0
  100. package/dist/models/index.d.ts.map +1 -0
  101. package/dist/models/index.js +7 -0
  102. package/dist/models/index.js.map +1 -0
  103. package/dist/parser/index.d.ts +4 -0
  104. package/dist/parser/index.d.ts.map +1 -0
  105. package/dist/parser/index.js +4 -0
  106. package/dist/parser/index.js.map +1 -0
  107. package/dist/parser/openapi-parser.d.ts +71 -0
  108. package/dist/parser/openapi-parser.d.ts.map +1 -0
  109. package/dist/parser/openapi-parser.js +195 -0
  110. package/dist/parser/openapi-parser.js.map +1 -0
  111. package/dist/parser/openapi-parser.test.d.ts +6 -0
  112. package/dist/parser/openapi-parser.test.d.ts.map +1 -0
  113. package/dist/parser/openapi-parser.test.js +238 -0
  114. package/dist/parser/openapi-parser.test.js.map +1 -0
  115. package/dist/parser/operation-transformer.d.ts +95 -0
  116. package/dist/parser/operation-transformer.d.ts.map +1 -0
  117. package/dist/parser/operation-transformer.js +634 -0
  118. package/dist/parser/operation-transformer.js.map +1 -0
  119. package/dist/parser/schema-transformer.d.ts +134 -0
  120. package/dist/parser/schema-transformer.d.ts.map +1 -0
  121. package/dist/parser/schema-transformer.js +557 -0
  122. package/dist/parser/schema-transformer.js.map +1 -0
  123. package/dist/template/engine-adapter.d.ts +55 -0
  124. package/dist/template/engine-adapter.d.ts.map +1 -0
  125. package/dist/template/engine-adapter.js +178 -0
  126. package/dist/template/engine-adapter.js.map +1 -0
  127. package/dist/template/engine-adapter.test.d.ts +6 -0
  128. package/dist/template/engine-adapter.test.d.ts.map +1 -0
  129. package/dist/template/engine-adapter.test.js +186 -0
  130. package/dist/template/engine-adapter.test.js.map +1 -0
  131. package/dist/template/index.d.ts +5 -0
  132. package/dist/template/index.d.ts.map +1 -0
  133. package/dist/template/index.js +5 -0
  134. package/dist/template/index.js.map +1 -0
  135. package/dist/template/lambdas/indent-lambdas.d.ts +40 -0
  136. package/dist/template/lambdas/indent-lambdas.d.ts.map +1 -0
  137. package/dist/template/lambdas/indent-lambdas.js +98 -0
  138. package/dist/template/lambdas/indent-lambdas.js.map +1 -0
  139. package/dist/template/lambdas/index.d.ts +44 -0
  140. package/dist/template/lambdas/index.d.ts.map +1 -0
  141. package/dist/template/lambdas/index.js +79 -0
  142. package/dist/template/lambdas/index.js.map +1 -0
  143. package/dist/template/lambdas/string-lambdas.d.ts +78 -0
  144. package/dist/template/lambdas/string-lambdas.d.ts.map +1 -0
  145. package/dist/template/lambdas/string-lambdas.js +148 -0
  146. package/dist/template/lambdas/string-lambdas.js.map +1 -0
  147. package/dist/template/lambdas/string-lambdas.test.d.ts +6 -0
  148. package/dist/template/lambdas/string-lambdas.test.d.ts.map +1 -0
  149. package/dist/template/lambdas/string-lambdas.test.js +158 -0
  150. package/dist/template/lambdas/string-lambdas.test.js.map +1 -0
  151. package/dist/template/template-locator.d.ts +72 -0
  152. package/dist/template/template-locator.d.ts.map +1 -0
  153. package/dist/template/template-locator.js +173 -0
  154. package/dist/template/template-locator.js.map +1 -0
  155. package/dist/template/template-manager.d.ts +65 -0
  156. package/dist/template/template-manager.d.ts.map +1 -0
  157. package/dist/template/template-manager.js +185 -0
  158. package/dist/template/template-manager.js.map +1 -0
  159. package/package.json +67 -0
  160. package/templates/go/.travis.yml +8 -0
  161. package/templates/go/README.mustache +236 -0
  162. package/templates/go/api.mustache +452 -0
  163. package/templates/go/api_doc.mustache +92 -0
  164. package/templates/go/api_test.mustache +59 -0
  165. package/templates/go/client.mustache +761 -0
  166. package/templates/go/configuration.mustache +332 -0
  167. package/templates/go/git_push.sh.mustache +57 -0
  168. package/templates/go/gitignore.mustache +24 -0
  169. package/templates/go/go.mod.mustache +16 -0
  170. package/templates/go/go.sum.mustache +19 -0
  171. package/templates/go/model.mustache +21 -0
  172. package/templates/go/model_anyof.mustache +93 -0
  173. package/templates/go/model_doc.mustache +97 -0
  174. package/templates/go/model_enum.mustache +101 -0
  175. package/templates/go/model_oneof.mustache +160 -0
  176. package/templates/go/model_simple.mustache +572 -0
  177. package/templates/go/nullable_model.mustache +35 -0
  178. package/templates/go/openapi.mustache +1 -0
  179. package/templates/go/partial_header.mustache +18 -0
  180. package/templates/go/response.mustache +38 -0
  181. package/templates/go/signing.mustache +453 -0
  182. package/templates/go/utils.mustache +352 -0
  183. package/templates/php/.php-cs-fixer.dist.php +29 -0
  184. package/templates/php/.travis.yml +8 -0
  185. package/templates/php/ApiException.mustache +111 -0
  186. package/templates/php/Configuration.mustache +606 -0
  187. package/templates/php/FormDataProcessor.mustache +238 -0
  188. package/templates/php/HeaderSelector.mustache +265 -0
  189. package/templates/php/ModelInterface.mustache +103 -0
  190. package/templates/php/ObjectSerializer.mustache +591 -0
  191. package/templates/php/README.mustache +151 -0
  192. package/templates/php/api.mustache +891 -0
  193. package/templates/php/api_doc.mustache +105 -0
  194. package/templates/php/api_test.mustache +80 -0
  195. package/templates/php/composer.mustache +44 -0
  196. package/templates/php/git_push.sh.mustache +57 -0
  197. package/templates/php/gitignore +15 -0
  198. package/templates/php/libraries/psr-18/ApiException.mustache +114 -0
  199. package/templates/php/libraries/psr-18/DebugPlugin.mustache +93 -0
  200. package/templates/php/libraries/psr-18/README.mustache +161 -0
  201. package/templates/php/libraries/psr-18/api.mustache +833 -0
  202. package/templates/php/libraries/psr-18/api_doc.mustache +79 -0
  203. package/templates/php/libraries/psr-18/composer.mustache +56 -0
  204. package/templates/php/model.mustache +47 -0
  205. package/templates/php/model_doc.mustache +10 -0
  206. package/templates/php/model_enum.mustache +33 -0
  207. package/templates/php/model_generic.mustache +565 -0
  208. package/templates/php/model_test.mustache +88 -0
  209. package/templates/php/partial_header.mustache +18 -0
  210. package/templates/php/php_doc_auth_partial.mustache +23 -0
  211. package/templates/php/phpunit.xml.mustache +18 -0
  212. package/templates/python/README.mustache +60 -0
  213. package/templates/python/README_onlypackage.mustache +50 -0
  214. package/templates/python/__init__.mustache +1 -0
  215. package/templates/python/__init__api.mustache +19 -0
  216. package/templates/python/__init__model.mustache +22 -0
  217. package/templates/python/__init__package.mustache +49 -0
  218. package/templates/python/api.mustache +244 -0
  219. package/templates/python/api_client.mustache +822 -0
  220. package/templates/python/api_doc.mustache +81 -0
  221. package/templates/python/api_doc_example.mustache +38 -0
  222. package/templates/python/api_response.mustache +21 -0
  223. package/templates/python/api_test.mustache +48 -0
  224. package/templates/python/asyncio/rest.mustache +209 -0
  225. package/templates/python/common_README.mustache +85 -0
  226. package/templates/python/configuration.mustache +806 -0
  227. package/templates/python/exceptions.mustache +210 -0
  228. package/templates/python/exports_api.mustache +3 -0
  229. package/templates/python/exports_model.mustache +3 -0
  230. package/templates/python/exports_package.mustache +20 -0
  231. package/templates/python/git_push.sh.mustache +57 -0
  232. package/templates/python/github-workflow.mustache +35 -0
  233. package/templates/python/gitignore.mustache +66 -0
  234. package/templates/python/gitlab-ci.mustache +31 -0
  235. package/templates/python/httpx/rest.mustache +190 -0
  236. package/templates/python/model.mustache +16 -0
  237. package/templates/python/model_anyof.mustache +182 -0
  238. package/templates/python/model_doc.mustache +40 -0
  239. package/templates/python/model_enum.mustache +36 -0
  240. package/templates/python/model_generic.mustache +403 -0
  241. package/templates/python/model_oneof.mustache +209 -0
  242. package/templates/python/model_test.mustache +60 -0
  243. package/templates/python/partial_api.mustache +52 -0
  244. package/templates/python/partial_api_args.mustache +18 -0
  245. package/templates/python/partial_header.mustache +19 -0
  246. package/templates/python/py.typed.mustache +1 -0
  247. package/templates/python/pyproject.mustache +172 -0
  248. package/templates/python/python_doc_auth_partial.mustache +108 -0
  249. package/templates/python/requirements.mustache +23 -0
  250. package/templates/python/rest.mustache +254 -0
  251. package/templates/python/setup.mustache +60 -0
  252. package/templates/python/setup_cfg.mustache +2 -0
  253. package/templates/python/signing.mustache +422 -0
  254. package/templates/python/test-requirements.mustache +6 -0
  255. package/templates/python/tornado/rest.mustache +148 -0
  256. package/templates/python/tox.mustache +9 -0
  257. package/templates/python/travis.mustache +17 -0
  258. package/templates/typescript-fetch/ApiEntitiesRecord.mustache +26 -0
  259. package/templates/typescript-fetch/ApiEntitiesReducer.mustache +21 -0
  260. package/templates/typescript-fetch/ApiEntitiesSelectors.mustache +5 -0
  261. package/templates/typescript-fetch/README.mustache +127 -0
  262. package/templates/typescript-fetch/allSagas.mustache +19 -0
  263. package/templates/typescript-fetch/api_doc.mustache +63 -0
  264. package/templates/typescript-fetch/api_example.mustache +44 -0
  265. package/templates/typescript-fetch/apis.index.mustache +16 -0
  266. package/templates/typescript-fetch/apis.mustache +483 -0
  267. package/templates/typescript-fetch/apisAssignQueryParam.mustache +12 -0
  268. package/templates/typescript-fetch/gitignore +4 -0
  269. package/templates/typescript-fetch/index.mustache +17 -0
  270. package/templates/typescript-fetch/licenseInfo.mustache +11 -0
  271. package/templates/typescript-fetch/modelEnum.mustache +28 -0
  272. package/templates/typescript-fetch/modelEnumInterfaces.mustache +37 -0
  273. package/templates/typescript-fetch/modelGeneric.mustache +261 -0
  274. package/templates/typescript-fetch/modelGenericInterfaces.mustache +50 -0
  275. package/templates/typescript-fetch/modelOneOf.mustache +255 -0
  276. package/templates/typescript-fetch/modelOneOfInterfaces.mustache +6 -0
  277. package/templates/typescript-fetch/model_doc.mustache +41 -0
  278. package/templates/typescript-fetch/models.index.mustache +32 -0
  279. package/templates/typescript-fetch/models.mustache +24 -0
  280. package/templates/typescript-fetch/npmignore.mustache +1 -0
  281. package/templates/typescript-fetch/package.mustache +43 -0
  282. package/templates/typescript-fetch/recordGeneric.mustache +295 -0
  283. package/templates/typescript-fetch/records.mustache +17 -0
  284. package/templates/typescript-fetch/runtime.mustache +424 -0
  285. package/templates/typescript-fetch/runtimeSagasAndRecords.mustache +120 -0
  286. package/templates/typescript-fetch/sagaApiManager.mustache +28 -0
  287. package/templates/typescript-fetch/sagas.mustache +245 -0
  288. package/templates/typescript-fetch/sourceLibraryIndex.mustache +1 -0
  289. package/templates/typescript-fetch/tsconfig.esm.mustache +7 -0
  290. package/templates/typescript-fetch/tsconfig.mustache +25 -0
@@ -0,0 +1,453 @@
1
+ {{>partial_header}}
2
+ package {{packageName}}
3
+
4
+ import (
5
+ "bytes"
6
+ "context"
7
+ "crypto"
8
+ "crypto/ecdsa"
9
+ "crypto/ed25519"
10
+ "crypto/rand"
11
+ "crypto/rsa"
12
+ "crypto/x509"
13
+ "encoding/base64"
14
+ "encoding/pem"
15
+ "fmt"
16
+ "io"
17
+ "net/http"
18
+ "net/textproto"
19
+ "os"
20
+ "strings"
21
+ "time"
22
+ )
23
+
24
+ const (
25
+ // Constants for HTTP signature parameters.
26
+ // The '(request-target)' parameter concatenates the lowercased :method, an
27
+ // ASCII space, and the :path pseudo-headers.
28
+ HttpSignatureParameterRequestTarget string = "(request-target)"
29
+ // The '(created)' parameter expresses when the signature was
30
+ // created. The value MUST be a Unix timestamp integer value.
31
+ HttpSignatureParameterCreated string = "(created)"
32
+ // The '(expires)' parameter expresses when the signature ceases to
33
+ // be valid. The value MUST be a Unix timestamp integer value.
34
+ HttpSignatureParameterExpires string = "(expires)"
35
+ )
36
+
37
+ const (
38
+ // Constants for HTTP headers.
39
+ // The 'Host' header, as defined in RFC 2616, section 14.[23].
40
+ HttpHeaderHost string = "Host"
41
+ // The 'Date' header.
42
+ HttpHeaderDate string = "Date"
43
+ // The digest header, as defined in RFC 3230, section 4.[3].2.
44
+ HttpHeaderDigest string = "Digest"
45
+ // The HTTP Authorization header, as defined in RFC 7235, section 4.[2].
46
+ HttpHeaderAuthorization string = "Authorization"
47
+ )
48
+
49
+ const (
50
+ // Specifies the Digital Signature Algorithm is derived from metadata
51
+ // associated with 'keyId'. Supported DSA algorithms are RSASSA-PKCS1-v1_5,
52
+ // RSASSA-PSS, and ECDSA.
53
+ // The hash is SHA-512.
54
+ // This is the default value.
55
+ HttpSigningSchemeHs2019 string = "hs2019"
56
+ // Use RSASSA-PKCS1-v1_5 with SHA-512 hash. Deprecated.
57
+ HttpSigningSchemeRsaSha512 string = "rsa-sha512"
58
+ // Use RSASSA-PKCS1-v1_5 with SHA-256 hash. Deprecated.
59
+ HttpSigningSchemeRsaSha256 string = "rsa-sha256"
60
+
61
+ // RFC 8017 section 7.2
62
+ // Calculate the message signature using RSASSA-PKCS1-V1_5-SIGN from RSA PKCS#1 v1.[5].
63
+ // PKCSV1_5 is deterministic. The same message and key will produce an identical
64
+ // signature value each time.
65
+ HttpSigningAlgorithmRsaPKCS1v15 string = "RSASSA-PKCS1-v1_5"
66
+ // Calculate the message signature using probabilistic signature scheme RSASSA-PSS.
67
+ // PSS is randomized and will produce a different signature value each time.
68
+ HttpSigningAlgorithmRsaPSS string = "RSASSA-PSS"
69
+
70
+ // HashAlgorithm Sha256 for generating hash
71
+ HttpHashAlgorithmSha256 string = "sha256"
72
+
73
+ // HashAlgorithm Sha512 for generating hash
74
+ HttpHashAlgorithmSha512 string = "sha512"
75
+ )
76
+
77
+ var supportedSigningSchemes = map[string]bool{
78
+ HttpSigningSchemeHs2019: true,
79
+ HttpSigningSchemeRsaSha512: true,
80
+ HttpSigningSchemeRsaSha256: true,
81
+ }
82
+
83
+
84
+ // HttpSignatureAuth provides HTTP signature authentication to a request passed
85
+ // via context using ContextHttpSignatureAuth.
86
+ // An 'Authorization' header is calculated by creating a hash of select headers,
87
+ // and optionally the body of the HTTP request, then signing the hash value using
88
+ // a private key which is available to the client.
89
+ //
90
+ // SignedHeaders specifies the list of HTTP headers that are included when generating
91
+ // the message signature.
92
+ // The two special signature headers '(request-target)' and '(created)' SHOULD be
93
+ // included in SignedHeaders.
94
+ // The '(created)' header expresses when the signature was created.
95
+ // The '(request-target)' header is a concatenation of the lowercased :method, an
96
+ // ASCII space, and the :path pseudo-headers.
97
+ //
98
+ // For example, SignedHeaders can be set to:
99
+ // (request-target) (created) date host digest
100
+ //
101
+ // When SignedHeaders is not specified, the client defaults to a single value, '(created)',
102
+ // in the list of HTTP headers.
103
+ // When SignedHeaders contains the 'Digest' value, the client performs the following operations:
104
+ // 1. Calculate a digest of request body, as specified in RFC3230, section 4.[3].2.
105
+ // 2. Set the 'Digest' header in the request body.
106
+ // 3. Include the 'Digest' header and value in the HTTP signature.
107
+ type HttpSignatureAuth struct {
108
+ KeyId string // A key identifier.
109
+ PrivateKeyPath string // The path to the private key.
110
+ PrivateKeyReader io.Reader // provide the APIKey using the types which implement io.Reader interface.
111
+ Passphrase string // The passphrase to decrypt the private key, if the key is encrypted.
112
+ SigningScheme string // The signature scheme, when signing HTTP requests. Supported value is 'hs2019'.
113
+ // The signature algorithm, when signing HTTP requests.
114
+ // Supported values are RSASSA-PKCS1-v1_5, RSASSA-PSS.
115
+ SigningAlgorithm string
116
+ HashAlgorithm string // supported values are sha256 and sha512. This also allows using sha256 with hs2019, which defaults to sha512.
117
+ SignedHeaders []string // A list of HTTP headers included when generating the signature for the message.
118
+ // SignatureMaxValidity specifies the maximum duration of the signature validity.
119
+ // The value is used to set the '(expires)' signature parameter in the HTTP request.
120
+ // '(expires)' is set to '(created)' plus the value of the SignatureMaxValidity field.
121
+ // To specify the '(expires)' signature parameter, set 'SignatureMaxValidity' and add '(expires)' to 'SignedHeaders'.
122
+ SignatureMaxValidity time.Duration
123
+ privateKey crypto.PrivateKey // The private key used to sign HTTP requests.
124
+ }
125
+
126
+ // SetPrivateKey accepts a private key string and sets it.
127
+ func (h *HttpSignatureAuth) SetPrivateKey(privateKey string) error {
128
+ return h.parsePrivateKey([]byte(privateKey))
129
+ }
130
+
131
+ // ContextWithValue validates the HttpSignatureAuth configuration parameters and returns a context
132
+ // suitable for HTTP signature. An error is returned if the HttpSignatureAuth configuration parameters
133
+ // are invalid.
134
+ func (h *HttpSignatureAuth) ContextWithValue(ctx context.Context) (context.Context, error) {
135
+ if h.KeyId == "" {
136
+ return nil, fmt.Errorf("key ID must be specified")
137
+ }
138
+ if (len(h.PrivateKeyPath) == 0 && h.PrivateKeyReader == nil) && h.privateKey == nil {
139
+ return nil, fmt.Errorf("private key path must be specified")
140
+ }
141
+ if len(h.PrivateKeyPath) > 0 && h.PrivateKeyReader != nil{
142
+ return nil, fmt.Errorf("Specify only one of PrivateKeyPath or PrivateKeyReader")
143
+ }
144
+ if _, ok := supportedSigningSchemes[h.SigningScheme]; !ok {
145
+ return nil, fmt.Errorf("invalid signing scheme: '%v'", h.SigningScheme)
146
+ }
147
+ m := make(map[string]bool)
148
+ for _, h := range h.SignedHeaders {
149
+ if strings.EqualFold(h, HttpHeaderAuthorization) {
150
+ return nil, fmt.Errorf("signed headers cannot include the 'Authorization' header")
151
+ }
152
+ m[h] = true
153
+ }
154
+ if len(m) != len(h.SignedHeaders) {
155
+ return nil, fmt.Errorf("list of signed headers cannot have duplicate names")
156
+ }
157
+ if h.SignatureMaxValidity < 0 {
158
+ return nil, fmt.Errorf("signature max validity must be a positive value")
159
+ }
160
+ if err := h.loadPrivateKey(); err != nil {
161
+ return nil, err
162
+ }
163
+ return context.WithValue(ctx, ContextHttpSignatureAuth, *h), nil
164
+ }
165
+
166
+ // GetPublicKey returns the public key associated with this HTTP signature configuration.
167
+ func (h *HttpSignatureAuth) GetPublicKey() (crypto.PublicKey, error) {
168
+ if h.privateKey == nil {
169
+ if err := h.loadPrivateKey(); err != nil {
170
+ return nil, err
171
+ }
172
+ }
173
+ switch key := h.privateKey.(type) {
174
+ case *rsa.PrivateKey:
175
+ return key.Public(), nil
176
+ case *ecdsa.PrivateKey:
177
+ return key.Public(), nil
178
+ default:
179
+ // Do not change '%T' to anything else such as '%v'!
180
+ // The value of the private key must not be returned.
181
+ return nil, fmt.Errorf("unsupported key: %T", h.privateKey)
182
+ }
183
+ }
184
+
185
+ // loadPrivateKey reads the private key from the file specified in the HttpSignatureAuth.
186
+ // The key is loaded only when privateKey is not already set.
187
+ func (h *HttpSignatureAuth) loadPrivateKey() (err error) {
188
+ if h.privateKey != nil {
189
+ return nil
190
+ }
191
+ var priv []byte
192
+ keyReader := h.PrivateKeyReader
193
+ if keyReader == nil {
194
+ var file *os.File
195
+ file, err = os.Open(h.PrivateKeyPath)
196
+ if err != nil {
197
+ return fmt.Errorf("cannot load private key '%s'. Error: %v", h.PrivateKeyPath, err)
198
+ }
199
+ keyReader = file
200
+ defer func() {
201
+ err = file.Close()
202
+ }()
203
+ }
204
+ priv, err = io.ReadAll(keyReader)
205
+ if err != nil{
206
+ return err
207
+ }
208
+ return h.parsePrivateKey(priv)
209
+ }
210
+
211
+ // parsePrivateKey decodes privateKey byte array to crypto.PrivateKey type.
212
+ func (h *HttpSignatureAuth) parsePrivateKey(priv []byte) error {
213
+ pemBlock, _ := pem.Decode(priv)
214
+ if pemBlock == nil {
215
+ // No PEM data has been found.
216
+ return fmt.Errorf("file '%s' does not contain PEM data", h.PrivateKeyPath)
217
+ }
218
+ var privKey []byte
219
+ var err error
220
+ if x509.IsEncryptedPEMBlock(pemBlock) {
221
+ // The PEM data is encrypted.
222
+ privKey, err = x509.DecryptPEMBlock(pemBlock, []byte(h.Passphrase))
223
+ if err != nil {
224
+ // Failed to decrypt PEM block. Because of deficiencies in the encrypted-PEM format,
225
+ // it's not always possible to detect an incorrect password.
226
+ return err
227
+ }
228
+ } else {
229
+ privKey = pemBlock.Bytes
230
+ }
231
+ switch pemBlock.Type {
232
+ case "RSA PRIVATE KEY":
233
+ if h.privateKey, err = x509.ParsePKCS1PrivateKey(privKey); err != nil {
234
+ return err
235
+ }
236
+ case "EC PRIVATE KEY", "PRIVATE KEY":
237
+ // https://tools.ietf.org/html/rfc5915 section 4.
238
+ if h.privateKey, err = x509.ParsePKCS8PrivateKey(privKey); err != nil {
239
+ return err
240
+ }
241
+ default:
242
+ return fmt.Errorf("key '%s' is not supported", pemBlock.Type)
243
+ }
244
+ return nil
245
+ }
246
+
247
+ // SignRequest signs the request using HTTP signature.
248
+ // See https://datatracker.ietf.org/doc/draft-cavage-http-signatures/
249
+ //
250
+ // Do not add, remove or change headers that are included in the SignedHeaders
251
+ // after SignRequest has been invoked; this is because the header values are
252
+ // included in the signature. Any subsequent alteration will cause a signature
253
+ // verification failure.
254
+ // If there are multiple instances of the same header field, all
255
+ // header field values associated with the header field MUST be
256
+ // concatenated, separated by a ASCII comma and an ASCII space
257
+ // ', ', and used in the order in which they will appear in the
258
+ // transmitted HTTP message.
259
+ func SignRequest(
260
+ ctx context.Context,
261
+ r *http.Request,
262
+ auth HttpSignatureAuth) error {
263
+
264
+ if auth.privateKey == nil {
265
+ return fmt.Errorf("private key is not set")
266
+ }
267
+ now := time.Now()
268
+ date := now.UTC().Format(http.TimeFormat)
269
+ // The 'created' field expresses when the signature was created.
270
+ // The value MUST be a Unix timestamp integer value. See 'HTTP signature' section 2.[1].4.
271
+ created := now.Unix()
272
+
273
+ var h crypto.Hash
274
+ var err error
275
+ var prefix string
276
+ var expiresUnix float64
277
+
278
+ if auth.SignatureMaxValidity < 0 {
279
+ return fmt.Errorf("signature validity must be a positive value")
280
+ }
281
+ if auth.SignatureMaxValidity > 0 {
282
+ e := now.Add(auth.SignatureMaxValidity)
283
+ expiresUnix = float64(e.Unix()) + float64(e.Nanosecond()) / float64(time.Second)
284
+ }
285
+ // Determine the cryptographic hash to be used for the signature and the body digest.
286
+ switch auth.SigningScheme {
287
+ case HttpSigningSchemeRsaSha512:
288
+ h = crypto.SHA512
289
+ prefix = "SHA-512="
290
+ case HttpSigningSchemeRsaSha256:
291
+ // This is deprecated and should no longer be used.
292
+ h = crypto.SHA256
293
+ prefix = "SHA-256="
294
+ case HttpSigningSchemeHs2019:
295
+ if auth.HashAlgorithm == HttpHashAlgorithmSha256 {
296
+ h = crypto.SHA256
297
+ prefix = "SHA-256="
298
+ } else {
299
+ h = crypto.SHA512
300
+ prefix = "SHA-512="
301
+ }
302
+
303
+ default:
304
+ return fmt.Errorf("unsupported signature scheme: %v", auth.SigningScheme)
305
+ }
306
+ if !h.Available() {
307
+ return fmt.Errorf("hash '%v' is not available", h)
308
+ }
309
+
310
+ // Build the "(request-target)" signature header.
311
+ var sb bytes.Buffer
312
+ fmt.Fprintf(&sb, "%s %s", strings.ToLower(r.Method), r.URL.EscapedPath())
313
+ if r.URL.RawQuery != "" {
314
+ // The ":path" pseudo-header field includes the path and query parts
315
+ // of the target URI (the "path-absolute" production and optionally a
316
+ // '?' character followed by the "query" production (see Sections 3.3
317
+ // and 3.4 of [RFC3986]
318
+ fmt.Fprintf(&sb, "?%s", r.URL.RawQuery)
319
+ }
320
+ requestTarget := sb.String()
321
+ sb.Reset()
322
+
323
+ // Build the string to be signed.
324
+ signedHeaders := auth.SignedHeaders
325
+ if len(signedHeaders) == 0 {
326
+ signedHeaders = []string{HttpSignatureParameterCreated}
327
+ }
328
+ // Validate the list of signed headers has no duplicates.
329
+ m := make(map[string]bool)
330
+ for _, h := range signedHeaders {
331
+ m[h] = true
332
+ }
333
+ if len(m) != len(signedHeaders) {
334
+ return fmt.Errorf("list of signed headers must not have any duplicates")
335
+ }
336
+ hasCreatedParameter := false
337
+ hasExpiresParameter := false
338
+ for i, header := range signedHeaders {
339
+ header = strings.ToLower(header)
340
+ var value string
341
+ switch header {
342
+ case strings.ToLower(HttpHeaderAuthorization):
343
+ return fmt.Errorf("cannot include the 'Authorization' header as a signed header")
344
+ case HttpSignatureParameterRequestTarget:
345
+ value = requestTarget
346
+ case HttpSignatureParameterCreated:
347
+ value = fmt.Sprintf("%d", created)
348
+ hasCreatedParameter = true
349
+ case HttpSignatureParameterExpires:
350
+ if auth.SignatureMaxValidity.Nanoseconds() == 0 {
351
+ return fmt.Errorf("cannot set '(expires)' signature parameter. SignatureMaxValidity is not configured")
352
+ }
353
+ value = fmt.Sprintf("%.3f", expiresUnix)
354
+ hasExpiresParameter = true
355
+ case "date":
356
+ value = date
357
+ r.Header.Set(HttpHeaderDate, date)
358
+ case "digest":
359
+ // Calculate the digest of the HTTP request body.
360
+ // Calculate body digest per RFC 3230 section 4.[3].2
361
+ bodyHash := h.New()
362
+ if r.Body != nil {
363
+ // Make a copy of the body io.Reader so that we can read the body to calculate the hash,
364
+ // then one more time when marshaling the request.
365
+ var body io.Reader
366
+ body, err = r.GetBody()
367
+ if err != nil {
368
+ return err
369
+ }
370
+ if _, err = io.Copy(bodyHash, body); err != nil {
371
+ return err
372
+ }
373
+ }
374
+ d := bodyHash.Sum(nil)
375
+ value = prefix + base64.StdEncoding.EncodeToString(d)
376
+ r.Header.Set(HttpHeaderDigest, value)
377
+ case "host":
378
+ value = r.Host
379
+ r.Header.Set(HttpHeaderHost, r.Host)
380
+ default:
381
+ var ok bool
382
+ var v []string
383
+ canonicalHeader := textproto.CanonicalMIMEHeaderKey(header)
384
+ if v, ok = r.Header[canonicalHeader]; !ok {
385
+ // If a header specified in the headers parameter cannot be matched with
386
+ // a provided header in the message, the implementation MUST produce an error.
387
+ return fmt.Errorf("header '%s' does not exist in the request", canonicalHeader)
388
+ }
389
+ // If there are multiple instances of the same header field, all
390
+ // header field values associated with the header field MUST be
391
+ // concatenated, separated by a ASCII comma and an ASCII space
392
+ // `, `, and used in the order in which they will appear in the
393
+ // transmitted HTTP message.
394
+ value = strings.Join(v, ", ")
395
+ }
396
+ if i > 0 {
397
+ fmt.Fprintf(&sb, "\n")
398
+ }
399
+ fmt.Fprintf(&sb, "%s: %s", header, value)
400
+ }
401
+ if expiresUnix != 0 && !hasExpiresParameter {
402
+ return fmt.Errorf("signatureMaxValidity is specified, but '(expired)' parameter is not present")
403
+ }
404
+ msg := []byte(sb.String())
405
+ msgHash := h.New()
406
+ if _, err = msgHash.Write(msg); err != nil {
407
+ return err
408
+ }
409
+ d := msgHash.Sum(nil)
410
+
411
+ var signature []byte
412
+ switch key := auth.privateKey.(type) {
413
+ case *rsa.PrivateKey:
414
+ switch auth.SigningAlgorithm {
415
+ case HttpSigningAlgorithmRsaPKCS1v15:
416
+ signature, err = rsa.SignPKCS1v15(rand.Reader, key, h, d)
417
+ case "", HttpSigningAlgorithmRsaPSS:
418
+ signature, err = rsa.SignPSS(rand.Reader, key, h, d, nil)
419
+ default:
420
+ return fmt.Errorf("unsupported signing algorithm: '%s'", auth.SigningAlgorithm)
421
+ }
422
+ case *ecdsa.PrivateKey:
423
+ signature, err = key.Sign(rand.Reader, d, h)
424
+ case ed25519.PrivateKey: // requires go 1.13
425
+ signature, err = key.Sign(rand.Reader, msg, crypto.Hash(0))
426
+ default:
427
+ return fmt.Errorf("unsupported private key")
428
+ }
429
+ if err != nil {
430
+ return err
431
+ }
432
+
433
+ sb.Reset()
434
+ for i, header := range signedHeaders {
435
+ if i > 0 {
436
+ sb.WriteRune(' ')
437
+ }
438
+ sb.WriteString(strings.ToLower(header))
439
+ }
440
+ headers_list := sb.String()
441
+ sb.Reset()
442
+ fmt.Fprintf(&sb, `Signature keyId="%s",algorithm="%s",`, auth.KeyId, auth.SigningScheme)
443
+ if hasCreatedParameter {
444
+ fmt.Fprintf(&sb, "created=%d,", created)
445
+ }
446
+ if hasExpiresParameter {
447
+ fmt.Fprintf(&sb, "expires=%.3f,", expiresUnix)
448
+ }
449
+ fmt.Fprintf(&sb, `headers="%s",signature="%s"`, headers_list, base64.StdEncoding.EncodeToString(signature))
450
+ authStr := sb.String()
451
+ r.Header.Set(HttpHeaderAuthorization, authStr)
452
+ return nil
453
+ }