@toa.io/extensions.exposition 0.8.3-dev.9 → 0.20.0-alpha.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 (363) hide show
  1. package/components/context.toa.yaml +15 -0
  2. package/components/identity.bans/manifest.toa.yaml +18 -0
  3. package/components/identity.basic/events/principal.js +9 -0
  4. package/components/identity.basic/manifest.toa.yaml +50 -0
  5. package/components/identity.basic/source/authenticate.ts +29 -0
  6. package/components/identity.basic/source/create.ts +19 -0
  7. package/components/identity.basic/source/transit.ts +64 -0
  8. package/components/identity.basic/source/types.ts +42 -0
  9. package/components/identity.basic/tsconfig.json +9 -0
  10. package/components/identity.roles/manifest.toa.yaml +31 -0
  11. package/components/identity.roles/source/list.ts +7 -0
  12. package/components/identity.roles/source/principal.ts +20 -0
  13. package/components/identity.roles/tsconfig.json +9 -0
  14. package/components/identity.tokens/manifest.toa.yaml +39 -0
  15. package/components/identity.tokens/receivers/identity.bans.updated.js +3 -0
  16. package/components/identity.tokens/source/authenticate.test.ts +56 -0
  17. package/components/identity.tokens/source/authenticate.ts +38 -0
  18. package/components/identity.tokens/source/decrypt.test.ts +59 -0
  19. package/components/identity.tokens/source/decrypt.ts +25 -0
  20. package/components/identity.tokens/source/encrypt.test.ts +35 -0
  21. package/components/identity.tokens/source/encrypt.ts +25 -0
  22. package/components/identity.tokens/source/revoke.ts +5 -0
  23. package/components/identity.tokens/source/types.ts +48 -0
  24. package/components/identity.tokens/tsconfig.json +9 -0
  25. package/cucumber.js +9 -0
  26. package/documentation/.assets/ia3-dark.jpg +0 -0
  27. package/documentation/.assets/ia3-light.jpg +0 -0
  28. package/documentation/.assets/overview-dark.jpg +0 -0
  29. package/documentation/.assets/overview-light.jpg +0 -0
  30. package/documentation/.assets/role-scopes-dark.jpg +0 -0
  31. package/documentation/.assets/role-scopes-light.jpg +0 -0
  32. package/documentation/.assets/rtd-dark.jpg +0 -0
  33. package/documentation/.assets/rtd-light.jpg +0 -0
  34. package/documentation/access.md +256 -0
  35. package/documentation/components.md +276 -0
  36. package/documentation/identity.md +156 -0
  37. package/documentation/protocol.md +15 -0
  38. package/documentation/query.md +226 -0
  39. package/documentation/tree.md +169 -0
  40. package/features/access.feature +442 -0
  41. package/features/annotation.feature +28 -0
  42. package/features/body.feature +21 -0
  43. package/features/directives.feature +56 -0
  44. package/features/dynamic.feature +89 -0
  45. package/features/errors.feature +208 -0
  46. package/features/identity.basic.feature +235 -0
  47. package/features/identity.feature +61 -0
  48. package/features/identity.roles.feature +51 -0
  49. package/features/identity.tokens.feature +116 -0
  50. package/features/queries.feature +214 -0
  51. package/features/routes.feature +49 -0
  52. package/features/steps/Common.ts +10 -0
  53. package/features/steps/Components.ts +43 -0
  54. package/features/steps/Database.ts +58 -0
  55. package/features/steps/Gateway.ts +105 -0
  56. package/features/steps/HTTP.ts +71 -0
  57. package/features/steps/Parameters.ts +12 -0
  58. package/features/steps/Workspace.ts +40 -0
  59. package/features/steps/components/greeter/manifest.toa.yaml +9 -0
  60. package/features/steps/components/greeter/operations/greet.js +7 -0
  61. package/features/steps/components/pots/manifest.toa.yaml +20 -0
  62. package/features/steps/components/users/manifest.toa.yaml +11 -0
  63. package/features/steps/tsconfig.json +9 -0
  64. package/package.json +31 -17
  65. package/readme.md +181 -0
  66. package/schemas/annotation.cos.yaml +4 -0
  67. package/schemas/directive.cos.yaml +3 -0
  68. package/schemas/method.cos.yaml +9 -0
  69. package/schemas/node.cos.yaml +5 -0
  70. package/schemas/query.cos.yaml +16 -0
  71. package/schemas/querystring.cos.yaml +5 -0
  72. package/schemas/range.cos.yaml +2 -0
  73. package/schemas/route.cos.yaml +2 -0
  74. package/source/Annotation.ts +6 -0
  75. package/source/Branch.ts +8 -0
  76. package/source/Composition.ts +58 -0
  77. package/source/Context.ts +6 -0
  78. package/source/Directive.test.ts +91 -0
  79. package/source/Directive.ts +120 -0
  80. package/source/Endpoint.ts +57 -0
  81. package/source/Factory.ts +53 -0
  82. package/source/Gateway.ts +93 -0
  83. package/source/HTTP/Server.fixtures.ts +45 -0
  84. package/source/HTTP/Server.test.ts +221 -0
  85. package/source/HTTP/Server.ts +135 -0
  86. package/source/HTTP/exceptions.ts +77 -0
  87. package/source/HTTP/formats/index.ts +19 -0
  88. package/source/HTTP/formats/json.ts +13 -0
  89. package/source/HTTP/formats/msgpack.ts +10 -0
  90. package/source/HTTP/formats/text.ts +9 -0
  91. package/source/HTTP/formats/yaml.ts +14 -0
  92. package/source/HTTP/index.ts +3 -0
  93. package/source/HTTP/messages.test.ts +116 -0
  94. package/source/HTTP/messages.ts +77 -0
  95. package/source/Mapping.ts +48 -0
  96. package/source/Query.test.ts +37 -0
  97. package/source/Query.ts +105 -0
  98. package/source/RTD/Context.ts +16 -0
  99. package/source/RTD/Directives.ts +9 -0
  100. package/source/RTD/Endpoint.ts +11 -0
  101. package/source/RTD/Match.ts +16 -0
  102. package/source/RTD/Method.ts +24 -0
  103. package/source/RTD/Node.ts +85 -0
  104. package/source/RTD/Route.ts +58 -0
  105. package/source/RTD/Tree.ts +57 -0
  106. package/source/RTD/factory.ts +47 -0
  107. package/source/RTD/index.ts +8 -0
  108. package/source/RTD/segment.test.ts +32 -0
  109. package/source/RTD/segment.ts +25 -0
  110. package/source/RTD/syntax/index.ts +2 -0
  111. package/source/RTD/syntax/parse.test.ts +188 -0
  112. package/source/RTD/syntax/parse.ts +153 -0
  113. package/source/RTD/syntax/types.ts +48 -0
  114. package/source/Remotes.test.ts +41 -0
  115. package/source/Remotes.ts +20 -0
  116. package/source/Tenant.ts +38 -0
  117. package/source/deployment.ts +42 -0
  118. package/source/directives/auth/Anonymous.ts +14 -0
  119. package/source/directives/auth/Echo.ts +12 -0
  120. package/source/directives/auth/Family.ts +145 -0
  121. package/source/directives/auth/Id.ts +19 -0
  122. package/source/directives/auth/Incept.ts +42 -0
  123. package/source/directives/auth/Role.test.ts +62 -0
  124. package/source/directives/auth/Role.ts +56 -0
  125. package/source/directives/auth/Rule.ts +28 -0
  126. package/source/directives/auth/Scheme.ts +26 -0
  127. package/source/directives/auth/index.ts +3 -0
  128. package/source/directives/auth/schemes.ts +8 -0
  129. package/source/directives/auth/split.ts +15 -0
  130. package/source/directives/auth/types.ts +37 -0
  131. package/source/directives/dev/Family.ts +34 -0
  132. package/source/directives/dev/Stub.ts +14 -0
  133. package/source/directives/dev/index.ts +3 -0
  134. package/source/directives/dev/types.ts +5 -0
  135. package/source/directives/index.ts +5 -0
  136. package/source/discovery.ts +1 -0
  137. package/source/exceptions.ts +17 -0
  138. package/source/index.test.ts +9 -0
  139. package/source/index.ts +6 -0
  140. package/source/manifest.test.ts +57 -0
  141. package/source/manifest.ts +35 -0
  142. package/source/root.ts +38 -0
  143. package/source/schemas.ts +9 -0
  144. package/transpiled/Annotation.d.ts +6 -0
  145. package/transpiled/Annotation.js +3 -0
  146. package/transpiled/Annotation.js.map +1 -0
  147. package/transpiled/Branch.d.ts +7 -0
  148. package/transpiled/Branch.js +3 -0
  149. package/transpiled/Branch.js.map +1 -0
  150. package/transpiled/Composition.d.ts +14 -0
  151. package/transpiled/Composition.js +43 -0
  152. package/transpiled/Composition.js.map +1 -0
  153. package/transpiled/Context.d.ts +5 -0
  154. package/transpiled/Context.js +3 -0
  155. package/transpiled/Context.js.map +1 -0
  156. package/transpiled/Directive.d.ts +32 -0
  157. package/transpiled/Directive.js +76 -0
  158. package/transpiled/Directive.js.map +1 -0
  159. package/transpiled/Endpoint.d.ts +20 -0
  160. package/transpiled/Endpoint.js +44 -0
  161. package/transpiled/Endpoint.js.map +1 -0
  162. package/transpiled/Factory.d.ts +11 -0
  163. package/transpiled/Factory.js +67 -0
  164. package/transpiled/Factory.js.map +1 -0
  165. package/transpiled/Gateway.d.ts +19 -0
  166. package/transpiled/Gateway.js +90 -0
  167. package/transpiled/Gateway.js.map +1 -0
  168. package/transpiled/HTTP/Server.d.ts +22 -0
  169. package/transpiled/HTTP/Server.fixtures.d.ts +12 -0
  170. package/transpiled/HTTP/Server.fixtures.js +36 -0
  171. package/transpiled/HTTP/Server.fixtures.js.map +1 -0
  172. package/transpiled/HTTP/Server.js +111 -0
  173. package/transpiled/HTTP/Server.js.map +1 -0
  174. package/transpiled/HTTP/exceptions.d.ts +39 -0
  175. package/transpiled/HTTP/exceptions.js +78 -0
  176. package/transpiled/HTTP/exceptions.js.map +1 -0
  177. package/transpiled/HTTP/formats/index.d.ts +8 -0
  178. package/transpiled/HTTP/formats/index.js +38 -0
  179. package/transpiled/HTTP/formats/index.js.map +1 -0
  180. package/transpiled/HTTP/formats/json.d.ts +4 -0
  181. package/transpiled/HTTP/formats/json.js +15 -0
  182. package/transpiled/HTTP/formats/json.js.map +1 -0
  183. package/transpiled/HTTP/formats/msgpack.d.ts +4 -0
  184. package/transpiled/HTTP/formats/msgpack.js +36 -0
  185. package/transpiled/HTTP/formats/msgpack.js.map +1 -0
  186. package/transpiled/HTTP/formats/text.d.ts +4 -0
  187. package/transpiled/HTTP/formats/text.js +13 -0
  188. package/transpiled/HTTP/formats/text.js.map +1 -0
  189. package/transpiled/HTTP/formats/yaml.d.ts +4 -0
  190. package/transpiled/HTTP/formats/yaml.js +39 -0
  191. package/transpiled/HTTP/formats/yaml.js.map +1 -0
  192. package/transpiled/HTTP/index.d.ts +3 -0
  193. package/transpiled/HTTP/index.js +20 -0
  194. package/transpiled/HTTP/index.js.map +1 -0
  195. package/transpiled/HTTP/messages.d.ts +27 -0
  196. package/transpiled/HTTP/messages.js +49 -0
  197. package/transpiled/HTTP/messages.js.map +1 -0
  198. package/transpiled/Mapping.d.ts +8 -0
  199. package/transpiled/Mapping.js +35 -0
  200. package/transpiled/Mapping.js.map +1 -0
  201. package/transpiled/Query.d.ts +13 -0
  202. package/transpiled/Query.js +107 -0
  203. package/transpiled/Query.js.map +1 -0
  204. package/transpiled/RTD/Context.d.ts +11 -0
  205. package/transpiled/RTD/Context.js +3 -0
  206. package/transpiled/RTD/Context.js.map +1 -0
  207. package/transpiled/RTD/Directives.d.ts +7 -0
  208. package/transpiled/RTD/Directives.js +3 -0
  209. package/transpiled/RTD/Directives.js.map +1 -0
  210. package/transpiled/RTD/Endpoint.d.ts +9 -0
  211. package/transpiled/RTD/Endpoint.js +3 -0
  212. package/transpiled/RTD/Endpoint.js.map +1 -0
  213. package/transpiled/RTD/Match.d.ts +11 -0
  214. package/transpiled/RTD/Match.js +3 -0
  215. package/transpiled/RTD/Match.js.map +1 -0
  216. package/transpiled/RTD/Method.d.ts +9 -0
  217. package/transpiled/RTD/Method.js +16 -0
  218. package/transpiled/RTD/Method.js.map +1 -0
  219. package/transpiled/RTD/Node.d.ts +21 -0
  220. package/transpiled/RTD/Node.js +61 -0
  221. package/transpiled/RTD/Node.js.map +1 -0
  222. package/transpiled/RTD/Route.d.ts +14 -0
  223. package/transpiled/RTD/Route.js +48 -0
  224. package/transpiled/RTD/Route.js.map +1 -0
  225. package/transpiled/RTD/Tree.d.ts +14 -0
  226. package/transpiled/RTD/Tree.js +45 -0
  227. package/transpiled/RTD/Tree.js.map +1 -0
  228. package/transpiled/RTD/factory.d.ts +6 -0
  229. package/transpiled/RTD/factory.js +36 -0
  230. package/transpiled/RTD/factory.js.map +1 -0
  231. package/transpiled/RTD/index.d.ts +8 -0
  232. package/transpiled/RTD/index.js +38 -0
  233. package/transpiled/RTD/index.js.map +1 -0
  234. package/transpiled/RTD/segment.d.ts +8 -0
  235. package/transpiled/RTD/segment.js +23 -0
  236. package/transpiled/RTD/segment.js.map +1 -0
  237. package/transpiled/RTD/syntax/index.d.ts +2 -0
  238. package/transpiled/RTD/syntax/index.js +19 -0
  239. package/transpiled/RTD/syntax/index.js.map +1 -0
  240. package/transpiled/RTD/syntax/parse.d.ts +4 -0
  241. package/transpiled/RTD/syntax/parse.js +128 -0
  242. package/transpiled/RTD/syntax/parse.js.map +1 -0
  243. package/transpiled/RTD/syntax/types.d.ts +41 -0
  244. package/transpiled/RTD/syntax/types.js +5 -0
  245. package/transpiled/RTD/syntax/types.js.map +1 -0
  246. package/transpiled/Remotes.d.ts +7 -0
  247. package/transpiled/Remotes.js +19 -0
  248. package/transpiled/Remotes.js.map +1 -0
  249. package/transpiled/Tenant.d.ts +12 -0
  250. package/transpiled/Tenant.js +30 -0
  251. package/transpiled/Tenant.js.map +1 -0
  252. package/transpiled/deployment.d.ts +3 -0
  253. package/transpiled/deployment.js +61 -0
  254. package/transpiled/deployment.js.map +1 -0
  255. package/transpiled/directives/auth/Anonymous.d.ts +6 -0
  256. package/transpiled/directives/auth/Anonymous.js +17 -0
  257. package/transpiled/directives/auth/Anonymous.js.map +1 -0
  258. package/transpiled/directives/auth/Echo.d.ts +6 -0
  259. package/transpiled/directives/auth/Echo.js +13 -0
  260. package/transpiled/directives/auth/Echo.js.map +1 -0
  261. package/transpiled/directives/auth/Family.d.ts +20 -0
  262. package/transpiled/directives/auth/Family.js +125 -0
  263. package/transpiled/directives/auth/Family.js.map +1 -0
  264. package/transpiled/directives/auth/Id.d.ts +7 -0
  265. package/transpiled/directives/auth/Id.js +17 -0
  266. package/transpiled/directives/auth/Id.js.map +1 -0
  267. package/transpiled/directives/auth/Incept.d.ts +10 -0
  268. package/transpiled/directives/auth/Incept.js +59 -0
  269. package/transpiled/directives/auth/Incept.js.map +1 -0
  270. package/transpiled/directives/auth/Role.d.ts +11 -0
  271. package/transpiled/directives/auth/Role.js +44 -0
  272. package/transpiled/directives/auth/Role.js.map +1 -0
  273. package/transpiled/directives/auth/Rule.d.ts +9 -0
  274. package/transpiled/directives/auth/Rule.js +22 -0
  275. package/transpiled/directives/auth/Rule.js.map +1 -0
  276. package/transpiled/directives/auth/Scheme.d.ts +7 -0
  277. package/transpiled/directives/auth/Scheme.js +47 -0
  278. package/transpiled/directives/auth/Scheme.js.map +1 -0
  279. package/transpiled/directives/auth/index.d.ts +2 -0
  280. package/transpiled/directives/auth/index.js +7 -0
  281. package/transpiled/directives/auth/index.js.map +1 -0
  282. package/transpiled/directives/auth/schemes.d.ts +3 -0
  283. package/transpiled/directives/auth/schemes.js +9 -0
  284. package/transpiled/directives/auth/schemes.js.map +1 -0
  285. package/transpiled/directives/auth/split.d.ts +2 -0
  286. package/transpiled/directives/auth/split.js +38 -0
  287. package/transpiled/directives/auth/split.js.map +1 -0
  288. package/transpiled/directives/auth/types.d.ts +31 -0
  289. package/transpiled/directives/auth/types.js +3 -0
  290. package/transpiled/directives/auth/types.js.map +1 -0
  291. package/transpiled/directives/dev/Family.d.ts +10 -0
  292. package/transpiled/directives/dev/Family.js +25 -0
  293. package/transpiled/directives/dev/Family.js.map +1 -0
  294. package/transpiled/directives/dev/Stub.d.ts +7 -0
  295. package/transpiled/directives/dev/Stub.js +14 -0
  296. package/transpiled/directives/dev/Stub.js.map +1 -0
  297. package/transpiled/directives/dev/index.d.ts +2 -0
  298. package/transpiled/directives/dev/index.js +7 -0
  299. package/transpiled/directives/dev/index.js.map +1 -0
  300. package/transpiled/directives/dev/types.d.ts +4 -0
  301. package/transpiled/directives/dev/types.js +3 -0
  302. package/transpiled/directives/dev/types.js.map +1 -0
  303. package/transpiled/directives/index.d.ts +2 -0
  304. package/transpiled/directives/index.js +10 -0
  305. package/transpiled/directives/index.js.map +1 -0
  306. package/transpiled/discovery.d.ts +1 -0
  307. package/transpiled/discovery.js +3 -0
  308. package/transpiled/discovery.js.map +1 -0
  309. package/transpiled/exceptions.d.ts +2 -0
  310. package/transpiled/exceptions.js +39 -0
  311. package/transpiled/exceptions.js.map +1 -0
  312. package/transpiled/index.d.ts +5 -0
  313. package/transpiled/index.js +12 -0
  314. package/transpiled/index.js.map +1 -0
  315. package/transpiled/manifest.d.ts +3 -0
  316. package/transpiled/manifest.js +30 -0
  317. package/transpiled/manifest.js.map +1 -0
  318. package/transpiled/root.d.ts +2 -0
  319. package/transpiled/root.js +39 -0
  320. package/transpiled/root.js.map +1 -0
  321. package/transpiled/schemas.d.ts +3 -0
  322. package/transpiled/schemas.js +14 -0
  323. package/transpiled/schemas.js.map +1 -0
  324. package/transpiled/tsconfig.tsbuildinfo +1 -0
  325. package/tsconfig.json +12 -0
  326. package/src/.manifest/index.js +0 -7
  327. package/src/.manifest/normalize.js +0 -58
  328. package/src/.manifest/schema.yaml +0 -69
  329. package/src/.manifest/validate.js +0 -17
  330. package/src/constants.js +0 -3
  331. package/src/deployment.js +0 -23
  332. package/src/exposition.js +0 -68
  333. package/src/factory.js +0 -76
  334. package/src/index.js +0 -9
  335. package/src/manifest.js +0 -12
  336. package/src/query/criteria.js +0 -55
  337. package/src/query/enum.js +0 -35
  338. package/src/query/index.js +0 -17
  339. package/src/query/query.js +0 -60
  340. package/src/query/range.js +0 -28
  341. package/src/query/sort.js +0 -19
  342. package/src/remote.js +0 -88
  343. package/src/server.js +0 -83
  344. package/src/tenant.js +0 -29
  345. package/src/translate/etag.js +0 -14
  346. package/src/translate/index.js +0 -7
  347. package/src/translate/request.js +0 -68
  348. package/src/translate/response.js +0 -62
  349. package/src/tree.js +0 -109
  350. package/test/manifest.normalize.fixtures.js +0 -37
  351. package/test/manifest.normalize.test.js +0 -37
  352. package/test/manifest.validate.test.js +0 -40
  353. package/test/query.range.test.js +0 -18
  354. package/test/tree.fixtures.js +0 -21
  355. package/test/tree.test.js +0 -44
  356. package/types/annotations.d.ts +0 -10
  357. package/types/declarations.d.ts +0 -31
  358. package/types/exposition.d.ts +0 -13
  359. package/types/http.d.ts +0 -13
  360. package/types/query.d.ts +0 -16
  361. package/types/remote.d.ts +0 -19
  362. package/types/server.d.ts +0 -13
  363. package/types/tree.d.ts +0 -33
@@ -0,0 +1,208 @@
1
+ Feature: Errors
2
+
3
+ Scenario Outline: Missing routes
4
+ Given the `greeter` is running with the following manifest:
5
+ """yaml
6
+ namespace: basic
7
+ """
8
+ When the following request is received:
9
+ """
10
+ GET <path> HTTP/1.1
11
+ accept: application/yaml
12
+ """
13
+ Then the following reply is sent:
14
+ """
15
+ 404 Not Found
16
+ """
17
+ Examples:
18
+ | path |
19
+ | /basic/greeter/non-existent-segment/ |
20
+ | /basic/non-existent-component/ |
21
+ | /non-existent-namespace/ |
22
+
23
+ Scenario: Missing trailing slash
24
+ Given the `greeter` is running with the following manifest:
25
+ """yaml
26
+ namespace: basic
27
+ """
28
+ When the following request is received:
29
+ """
30
+ GET /basic/greeter HTTP/1.1
31
+ accept: application/json
32
+ """
33
+ Then the following reply is sent:
34
+ """
35
+ 404 Not Found
36
+ content-type: application/json
37
+
38
+ "Trailing slash is required."
39
+ """
40
+
41
+ Scenario: Missing method
42
+ Given the `greeter` is running
43
+ When the following request is received:
44
+ """
45
+ PATCH /greeter/ HTTP/1.1
46
+ accept: application/yaml
47
+ """
48
+ Then the following reply is sent:
49
+ """http
50
+ 405 Method Not Allowed
51
+ """
52
+
53
+ Scenario: Unsupported method
54
+ When the following request is received:
55
+ """
56
+ COPY /basic/greeter/ HTTP/1.1
57
+ accept: application/yaml
58
+ """
59
+ Then the following reply is sent:
60
+ """http
61
+ 501 Not Implemented
62
+ """
63
+
64
+ Scenario: Request body does not match input schema
65
+ Given the `pots` is running with the following manifest:
66
+ """yaml
67
+ exposition:
68
+ /:
69
+ POST: transit
70
+ """
71
+ When the following request is received:
72
+ """
73
+ POST /pots/ HTTP/1.1
74
+ accept: application/yaml
75
+ content-type: application/yaml
76
+
77
+ foo: Hello
78
+ bar: 1.5
79
+ """
80
+ Then the following reply is sent:
81
+ """
82
+ 400 Bad Request
83
+ content-type: application/yaml
84
+
85
+ must have required property 'title'
86
+ """
87
+
88
+ Scenario: Query limit out of range
89
+ Given the `pots` is running with the following manifest:
90
+ """yaml
91
+ exposition:
92
+ /:
93
+ GET: enumerate
94
+ """
95
+ When the following request is received:
96
+ """
97
+ GET /pots/?limit=1001 HTTP/1.1
98
+ accept: text/plain
99
+ """
100
+ Then the following reply is sent:
101
+ """
102
+ 400 Bad Request
103
+ content-type: text/plain
104
+
105
+ Query limit must be between 1 and 1000 inclusive.
106
+ """
107
+
108
+ Scenario: Closed query criteria
109
+ Given the `pots` is running with the following manifest:
110
+ """yaml
111
+ exposition:
112
+ /hot:
113
+ GET:
114
+ endpoint: enumerate
115
+ query:
116
+ criteria: temerature>60
117
+ """
118
+ When the following request is received:
119
+ """
120
+ GET /pots/hot/?criteria=volume>500 HTTP/1.1
121
+ accept: text/plain
122
+ """
123
+ Then the following reply is sent:
124
+ """
125
+ 400 Bad Request
126
+ content-type: text/plain
127
+
128
+ Query criteria is closed.
129
+ """
130
+
131
+ Scenario: Additional query parameters
132
+ Given the `pots` is running with the following manifest:
133
+ """yaml
134
+ exposition:
135
+ /:
136
+ GET:
137
+ endpoint: enumerate
138
+ """
139
+ When the following request is received:
140
+ """
141
+ GET /pots/?foo=bar HTTP/1.1
142
+ accept: text/plain
143
+ """
144
+ Then the following reply is sent:
145
+ """
146
+ 400 Bad Request
147
+ content-type: text/plain
148
+
149
+ Query must NOT have additional properties
150
+ """
151
+
152
+ Scenario: Malformed authorization header
153
+ Given the annotation:
154
+ """yaml
155
+ /:
156
+ GET: {}
157
+ """
158
+ When the following request is received:
159
+ """
160
+ GET / HTTP/1.1
161
+ authorization: Basic
162
+ accept: text/plain
163
+ """
164
+ Then the following reply is sent:
165
+ """
166
+ 401 Unauthorized
167
+
168
+ Malformed authorization header.
169
+ """
170
+
171
+ Scenario: Creating an Identity using inception with existing credentials
172
+ Given the `identity.basic` database is empty
173
+ And the `users` is running with the following manifest:
174
+ """yaml
175
+ exposition:
176
+ /:
177
+ anonymous: true
178
+ POST:
179
+ incept: id
180
+ endpoint: transit
181
+ """
182
+ When the following request is received:
183
+ # identity inception
184
+ """
185
+ POST /users/ HTTP/1.1
186
+ authorization: Basic dXNlcjpwYXNzMTIzNA==
187
+ accept: application/yaml
188
+ content-type: application/yaml
189
+
190
+ name: Bill Smith
191
+ """
192
+ Then the following reply is sent:
193
+ """
194
+ 201 Created
195
+ """
196
+ And the following request is received:
197
+ # same credentials
198
+ """
199
+ POST /users/ HTTP/1.1
200
+ authorization: Basic dXNlcjpwYXNzMTIzNA==
201
+ content-type: text/plain
202
+
203
+ name: Mary Louis
204
+ """
205
+ Then the following reply is sent:
206
+ """
207
+ 403 Forbidden
208
+ """
@@ -0,0 +1,235 @@
1
+ Feature: Basic authentication
2
+
3
+ Background:
4
+ Given the `identity.basic` database is empty
5
+
6
+ Scenario: Creating new Identity with basic credentials
7
+ When the following request is received:
8
+ """
9
+ POST /identity/basic/ HTTP/1.1
10
+ content-type: application/yaml
11
+
12
+ username: developer
13
+ password: secret#1234
14
+ """
15
+ Then the following reply is sent:
16
+ """
17
+ 201 Created
18
+ """
19
+
20
+ Scenario: Creating new Identity using inception
21
+ Given the `users` is running with the following manifest:
22
+ """yaml
23
+ exposition:
24
+ /:
25
+ anonymous: true # checking compatibility with anonymous access
26
+ POST:
27
+ incept: id
28
+ endpoint: transit
29
+ /:id: # credential testing route
30
+ id: id
31
+ GET: observe
32
+ """
33
+ When the following request is received:
34
+ """
35
+ POST /users/ HTTP/1.1
36
+ authorization: Basic dXNlcjpwYXNzMTIzNA==
37
+ accept: application/yaml
38
+ content-type: application/yaml
39
+
40
+ name: Bill Smith
41
+ """
42
+ Then the following reply is sent:
43
+ """
44
+ 201 Created
45
+ authorization: Token ${{ token }}
46
+
47
+ id: ${{ id }}
48
+ """
49
+ When the following request is received:
50
+ # basic credentials have been created
51
+ """
52
+ GET /users/${{ id }}/ HTTP/1.1
53
+ authorization: Basic dXNlcjpwYXNzMTIzNA==
54
+ """
55
+ Then the following reply is sent:
56
+ """
57
+ 200 OK
58
+ """
59
+ When the following request is received:
60
+ # valid token has been issued
61
+ """
62
+ GET /users/${{ id }}/ HTTP/1.1
63
+ authorization: Token ${{ token }}
64
+ """
65
+ Then the following reply is sent:
66
+ """
67
+ 200 OK
68
+ """
69
+
70
+ Scenario: Changing the password
71
+ Given the annotation:
72
+ """
73
+ /:id:
74
+ id: id
75
+ GET:
76
+ dev:stub:
77
+ access: granted!
78
+ """
79
+ And the `identity.basic` database contains:
80
+ | _id | _version | username | password |
81
+ | efe3a65ebbee47ed95a73edd911ea328 | 1 | developer | $2b$10$ZRSKkgZoGnrcTNA5w5eCcu3pxDzdTduhteVYXcp56AaNcilNkwJ.O |
82
+ When the following request is received:
83
+ """
84
+ PATCH /identity/basic/efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
85
+ authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
86
+ accept: application/yaml
87
+ content-type: application/yaml
88
+
89
+ password: new-secret
90
+ """
91
+ Then the following reply is sent:
92
+ """
93
+ 200 OK
94
+ """
95
+ When the following request is received:
96
+ # old password
97
+ """
98
+ GET /efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
99
+ authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
100
+ """
101
+ Then the following reply is sent:
102
+ """
103
+ 401 Unauthorized
104
+ """
105
+ When the following request is received:
106
+ # new password
107
+ """
108
+ GET /efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
109
+ authorization: Basic ZGV2ZWxvcGVyOm5ldy1zZWNyZXQ=
110
+ """
111
+ Then the following reply is sent:
112
+ """
113
+ 200 OK
114
+ """
115
+
116
+ Scenario Outline: <problem> not meeting the requirements
117
+ When the following request is received:
118
+ """
119
+ POST /identity/basic/ HTTP/1.1
120
+ accept: application/yaml
121
+ content-type: application/yaml
122
+
123
+ username: <username>
124
+ password: <password>
125
+ """
126
+ Then the following reply is sent:
127
+ """
128
+ 409 Conflict
129
+
130
+ code: <code>
131
+ message: <problem> is not meeting the requirements.
132
+ """
133
+ Examples:
134
+ | username | password | problem | code |
135
+ | with whitespace | secret#1234 | Username | INVALID_USERNAME |
136
+ | root | short | Password | INVALID_PASSWORD |
137
+
138
+ Scenario Outline: Given <property> is not meeting one of requirements
139
+ Given the `identity.basic` configuration:
140
+ """yaml
141
+ <property>:
142
+ - ^\S{1,16}$
143
+ - ^[^A]{1,16}$ # should not contain 'A'
144
+ """
145
+ And the `identity.basic` database contains:
146
+ | _id | _version | username | password |
147
+ | efe3a65ebbee47ed95a73edd911ea328 | 1 | developer | $2b$10$ZRSKkgZoGnrcTNA5w5eCcu3pxDzdTduhteVYXcp56AaNcilNkwJ.O |
148
+ When the following request is received:
149
+ """
150
+ PATCH /identity/basic/efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
151
+ authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
152
+ accept: application/yaml
153
+ content-type: application/yaml
154
+
155
+ <property>: hasAinside
156
+ """
157
+ Then the following reply is sent:
158
+ """
159
+ 409 Conflict
160
+ """
161
+ Examples:
162
+ | property |
163
+ | username |
164
+ | password |
165
+
166
+ Scenario: Granting a `system` role to a Principal
167
+ Given the `identity.basic` configuration:
168
+ """yaml
169
+ principal: root
170
+ """
171
+ And the annotation:
172
+ """yaml
173
+ /:
174
+ GET:
175
+ auth:role: system:stub
176
+ dev:stub:
177
+ access: granted!
178
+ """
179
+ When the following request is received:
180
+ """
181
+ POST /identity/basic/ HTTP/1.1
182
+ content-type: application/yaml
183
+
184
+ username: root
185
+ password: secret#1234
186
+ """
187
+ Then the following reply is sent:
188
+ """
189
+ 201 Created
190
+
191
+ id: ${{ id }}
192
+ """
193
+ # role granting is eventual
194
+ Then after 0.1 seconds
195
+ When the following request is received:
196
+ """
197
+ GET /identity/roles/${{ id }}/ HTTP/1.1
198
+ authorization: Basic cm9vdDpzZWNyZXQjMTIzNA==
199
+ accept: application/yaml
200
+ """
201
+ Then the following reply is sent:
202
+ """
203
+ 200 OK
204
+ authorization: Token ${{ token }}
205
+
206
+ - system
207
+ """
208
+ When the following request is received:
209
+ """
210
+ GET / HTTP/1.1
211
+ authorization: Token ${{ token }}
212
+ accept: application/yaml
213
+ """
214
+ Then the following reply is sent:
215
+ """
216
+ 200 OK
217
+
218
+ access: granted!
219
+ """
220
+ # Principal username cannot be changed
221
+ When the following request is received:
222
+ """
223
+ PATCH /identity/basic/${{ id }}/ HTTP/1.1
224
+ authorization: Token ${{ token }}
225
+ content-type: application/yaml
226
+
227
+ username: admin
228
+ """
229
+ Then the following reply is sent:
230
+ """
231
+ 409 Conflict
232
+
233
+ code: PRINCIPAL_LOCKED
234
+ message: Principal username cannot be changed.
235
+ """
@@ -0,0 +1,61 @@
1
+ Feature: Identity resource
2
+
3
+ Scenario: Requesting own Identity
4
+ Given the `identity.basic` database contains:
5
+ | _id | username | password |
6
+ | efe3a65ebbee47ed95a73edd911ea328 | developer | $2b$10$ZRSKkgZoGnrcTNA5w5eCcu3pxDzdTduhteVYXcp56AaNcilNkwJ.O |
7
+ And the `identity.roles` database contains:
8
+ | _id | identity | role |
9
+ | 9c4702490ff84f2a9e1b1da2ab64bdd4 | efe3a65ebbee47ed95a73edd911ea328 | developer |
10
+ | 88ec8e348a5c48aaa2d25faa904cd9ff | efe3a65ebbee47ed95a73edd911ea328 | system:identity |
11
+ When the following request is received:
12
+ """
13
+ GET /identity/ HTTP/1.1
14
+ authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
15
+ accept: application/yaml
16
+ """
17
+ Then the following reply is sent:
18
+ """
19
+ 200 OK
20
+ authorization: Token ${{ token }}
21
+
22
+ id: efe3a65ebbee47ed95a73edd911ea328
23
+ roles:
24
+ - developer
25
+ - system:identity
26
+ """
27
+ When the following request is received:
28
+ """
29
+ GET /identity/ HTTP/1.1
30
+ authorization: Token ${{ token }}
31
+ accept: application/yaml
32
+ """
33
+ Then the following reply is sent:
34
+ """
35
+ 200 OK
36
+
37
+ id: efe3a65ebbee47ed95a73edd911ea328
38
+ roles:
39
+ - developer
40
+ - system:identity
41
+ """
42
+
43
+ Scenario: Requesting Identity with non-existent credentials
44
+ Given the `identity.basic` database is empty
45
+ When the following request is received:
46
+ """
47
+ GET /identity/ HTTP/1.1
48
+ authorization: Basic dXNlcjpwYXNzMTIzNA==
49
+ """
50
+ Then the following reply is sent:
51
+ """
52
+ 401 Unauthorized
53
+ """
54
+ When the following request is received:
55
+ """
56
+ GET /identity/ HTTP/1.1
57
+ """
58
+ Then the following reply is sent:
59
+ """
60
+ 401 Unauthorized
61
+ """
@@ -0,0 +1,51 @@
1
+ Feature: Roles management
2
+
3
+ Scenario: Adding a role to an Identity
4
+ Given the `identity.basic` database contains:
5
+ | _id | username | password |
6
+ | 72cf9b0ab0ac4ab2b8036e4e940ddcae | root | $2b$10$Qq/qnyyU5wjrbDXyWok14OnqAZv/z.pLhz.UddatjI6eHU/rFof4i |
7
+ | 4344518184ad44228baffce7a44fd0b1 | user | $2b$10$JoiAQUS7tzobDAFIDBWhWeEIJv933dQetyjRzSmfQGaJE5ZlJbmYy |
8
+ And the `identity.roles` database contains:
9
+ | _id | identity | role |
10
+ | 9c4702490ff84f2a9e1b1da2ab64bdd4 | 72cf9b0ab0ac4ab2b8036e4e940ddcae | system:identity:roles |
11
+ And the annotation:
12
+ """yaml
13
+ /:
14
+ auth:role: test
15
+ GET:
16
+ dev:stub:
17
+ access: granted!
18
+ """
19
+ When the following request is received:
20
+ # user doesn't have the required role
21
+ """
22
+ GET / HTTP/1.1
23
+ authorization: Basic dXNlcjpwYXNz
24
+ """
25
+ Then the following reply is sent:
26
+ """
27
+ 403 Forbidden
28
+ """
29
+ When the following request is received:
30
+ # root adds a role to a user
31
+ """
32
+ POST /identity/roles/4344518184ad44228baffce7a44fd0b1/ HTTP/1.1
33
+ authorization: Basic cm9vdDpzZWNyZXQ=
34
+ content-type: application/yaml
35
+
36
+ role: test
37
+ """
38
+ Then the following reply is sent:
39
+ """
40
+ 201 Created
41
+ """
42
+ When the following request is received:
43
+ # user now have the role
44
+ """
45
+ GET / HTTP/1.1
46
+ authorization: Basic dXNlcjpwYXNz
47
+ """
48
+ Then the following reply is sent:
49
+ """
50
+ 200 OK
51
+ """
@@ -0,0 +1,116 @@
1
+ Feature: Tokens lifecycle
2
+
3
+ Scenario: Switching to Token authentication scheme
4
+ Given the `identity.basic` database contains:
5
+ | _id | username | password |
6
+ | efe3a65ebbee47ed95a73edd911ea328 | developer | $2b$10$ZRSKkgZoGnrcTNA5w5eCcu3pxDzdTduhteVYXcp56AaNcilNkwJ.O |
7
+ And the `greeter` is running with the following manifest:
8
+ """yaml
9
+ exposition:
10
+ /:id:
11
+ auth:id: id
12
+ GET: greet
13
+ """
14
+ When the following request is received:
15
+ """
16
+ GET /greeter/efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
17
+ authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
18
+ accept: text/plain
19
+ """
20
+ Then the following reply is sent:
21
+ """
22
+ 200 OK
23
+ content-type: text/plain
24
+ authorization: Token ${{ token }}
25
+
26
+ Hello
27
+ """
28
+
29
+ Scenario: Refreshing stale token
30
+ Given the `identity.tokens` configuration:
31
+ """yaml
32
+ refresh: 1
33
+ """
34
+ And the `greeter` is running with the following manifest:
35
+ """yaml
36
+ exposition:
37
+ /:id:
38
+ auth:id: id
39
+ GET: greet
40
+ """
41
+ When the following request is received:
42
+ """
43
+ GET /greeter/efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
44
+ authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
45
+ accept: text/plain
46
+ """
47
+ Then the following reply is sent:
48
+ """
49
+ 200 OK
50
+ authorization: Token ${{ token }}
51
+
52
+ Hello
53
+ """
54
+ Then after 1 second
55
+ When the following request is received:
56
+ """
57
+ GET /greeter/efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
58
+ authorization: Token ${{ token }}
59
+ accept: text/plain
60
+ """
61
+ Then the following reply is sent:
62
+ """
63
+ 200 OK
64
+ authorization: Token
65
+
66
+ Hello
67
+ """
68
+
69
+ Scenario: Token revocation on password change
70
+ Given the annotation:
71
+ """yaml
72
+ /:id:
73
+ id: id
74
+ GET:
75
+ dev:stub:
76
+ access: granted!
77
+ """
78
+ And the `identity.tokens` configuration:
79
+ """yaml
80
+ refresh: 0.1
81
+ """
82
+ And the `identity.basic` database contains:
83
+ | _id | _version | username | password |
84
+ | efe3a65ebbee47ed95a73edd911ea328 | 1 | developer | $2b$10$ZRSKkgZoGnrcTNA5w5eCcu3pxDzdTduhteVYXcp56AaNcilNkwJ.O |
85
+ When the following request is received:
86
+ """
87
+ GET /efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
88
+ authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
89
+ """
90
+ Then the following reply is sent:
91
+ """
92
+ 200 OK
93
+ authorization: Token ${{ token }}
94
+ """
95
+ When the following request is received:
96
+ """
97
+ PATCH /identity/basic/efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
98
+ authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
99
+ content-type: application/yaml
100
+
101
+ password: new-secret
102
+ """
103
+ Then the following reply is sent:
104
+ """
105
+ 200 OK
106
+ """
107
+ Then after 0.2 seconds
108
+ When the following request is received:
109
+ """
110
+ GET /efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
111
+ authorization: Token ${{ token }}
112
+ """
113
+ Then the following reply is sent:
114
+ """
115
+ 401 Unauthorized
116
+ """