@toa.io/extensions.exposition 0.20.0-dev.9 → 0.21.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.
- package/components/context.toa.yaml +15 -0
- package/components/identity.bans/manifest.toa.yaml +18 -0
- package/components/identity.basic/events/principal.js +9 -0
- package/components/identity.basic/manifest.toa.yaml +50 -0
- package/components/identity.basic/source/authenticate.ts +29 -0
- package/components/identity.basic/source/create.ts +19 -0
- package/components/identity.basic/source/transit.ts +64 -0
- package/components/identity.basic/source/types.ts +42 -0
- package/components/identity.basic/tsconfig.json +9 -0
- package/components/identity.roles/manifest.toa.yaml +31 -0
- package/components/identity.roles/source/list.ts +7 -0
- package/components/identity.roles/source/principal.ts +20 -0
- package/components/identity.roles/tsconfig.json +9 -0
- package/components/identity.tokens/manifest.toa.yaml +39 -0
- package/components/identity.tokens/receivers/identity.bans.updated.js +3 -0
- package/components/identity.tokens/source/authenticate.test.ts +56 -0
- package/components/identity.tokens/source/authenticate.ts +38 -0
- package/components/identity.tokens/source/decrypt.test.ts +59 -0
- package/components/identity.tokens/source/decrypt.ts +25 -0
- package/components/identity.tokens/source/encrypt.test.ts +35 -0
- package/components/identity.tokens/source/encrypt.ts +25 -0
- package/components/identity.tokens/source/revoke.ts +5 -0
- package/components/identity.tokens/source/types.ts +48 -0
- package/components/identity.tokens/tsconfig.json +9 -0
- package/cucumber.js +9 -0
- package/documentation/.assets/ia3-dark.jpg +0 -0
- package/documentation/.assets/ia3-light.jpg +0 -0
- package/documentation/.assets/overview-dark.jpg +0 -0
- package/documentation/.assets/overview-light.jpg +0 -0
- package/documentation/.assets/role-scopes-dark.jpg +0 -0
- package/documentation/.assets/role-scopes-light.jpg +0 -0
- package/documentation/.assets/rtd-dark.jpg +0 -0
- package/documentation/.assets/rtd-light.jpg +0 -0
- package/documentation/access.md +256 -0
- package/documentation/components.md +276 -0
- package/documentation/identity.md +156 -0
- package/documentation/notes/sse.md +71 -0
- package/documentation/protocol.md +18 -0
- package/documentation/query.md +226 -0
- package/documentation/tree.md +169 -0
- package/features/access.feature +448 -0
- package/features/annotation.feature +30 -0
- package/features/body.feature +45 -0
- package/features/directives.feature +56 -0
- package/features/dynamic.feature +99 -0
- package/features/errors.feature +193 -0
- package/features/identity.basic.feature +276 -0
- package/features/identity.feature +61 -0
- package/features/identity.roles.feature +51 -0
- package/features/identity.tokens.feature +119 -0
- package/features/queries.feature +214 -0
- package/features/routes.feature +49 -0
- package/features/steps/Common.ts +10 -0
- package/features/steps/Components.ts +43 -0
- package/features/steps/Database.ts +58 -0
- package/features/steps/Gateway.ts +113 -0
- package/features/steps/HTTP.ts +71 -0
- package/features/steps/Parameters.ts +12 -0
- package/features/steps/Workspace.ts +40 -0
- package/features/steps/components/echo/manifest.toa.yaml +9 -0
- package/features/steps/components/echo/operations/affect.js +7 -0
- package/features/steps/components/echo/operations/compute.js +7 -0
- package/features/steps/components/greeter/manifest.toa.yaml +5 -0
- package/features/steps/components/greeter/operations/greet.js +7 -0
- package/features/steps/components/pots/manifest.toa.yaml +20 -0
- package/features/steps/components/sequences/manifest.toa.yaml +10 -0
- package/features/steps/components/sequences/operations/numbers.js +7 -0
- package/features/steps/components/sequences/operations/tokens.js +16 -0
- package/features/steps/components/users/manifest.toa.yaml +11 -0
- package/features/steps/tsconfig.json +9 -0
- package/features/streams.feature +26 -0
- package/package.json +34 -17
- package/readme.md +183 -0
- package/schemas/annotation.cos.yaml +5 -0
- package/schemas/directive.cos.yaml +3 -0
- package/schemas/method.cos.yaml +8 -0
- package/schemas/node.cos.yaml +5 -0
- package/schemas/query.cos.yaml +17 -0
- package/schemas/querystring.cos.yaml +5 -0
- package/schemas/range.cos.yaml +2 -0
- package/schemas/route.cos.yaml +2 -0
- package/source/Annotation.ts +7 -0
- package/source/Branch.ts +8 -0
- package/source/Composition.ts +57 -0
- package/source/Context.ts +6 -0
- package/source/Directive.test.ts +91 -0
- package/source/Directive.ts +120 -0
- package/source/Endpoint.ts +59 -0
- package/source/Factory.ts +51 -0
- package/source/Gateway.ts +93 -0
- package/source/HTTP/Server.fixtures.ts +45 -0
- package/source/HTTP/Server.test.ts +221 -0
- package/source/HTTP/Server.ts +135 -0
- package/source/HTTP/exceptions.ts +77 -0
- package/source/HTTP/formats/index.ts +19 -0
- package/source/HTTP/formats/json.ts +13 -0
- package/source/HTTP/formats/msgpack.ts +10 -0
- package/source/HTTP/formats/text.ts +9 -0
- package/source/HTTP/formats/yaml.ts +14 -0
- package/source/HTTP/index.ts +3 -0
- package/source/HTTP/messages.test.ts +116 -0
- package/source/HTTP/messages.ts +89 -0
- package/source/Mapping.ts +51 -0
- package/source/Query.test.ts +37 -0
- package/source/Query.ts +105 -0
- package/source/RTD/Context.ts +16 -0
- package/source/RTD/Directives.ts +9 -0
- package/source/RTD/Endpoint.ts +11 -0
- package/source/RTD/Match.ts +16 -0
- package/source/RTD/Method.ts +24 -0
- package/source/RTD/Node.ts +85 -0
- package/source/RTD/Route.ts +59 -0
- package/source/RTD/Tree.ts +54 -0
- package/source/RTD/factory.ts +47 -0
- package/source/RTD/index.ts +8 -0
- package/source/RTD/segment.test.ts +32 -0
- package/source/RTD/segment.ts +25 -0
- package/source/RTD/syntax/index.ts +2 -0
- package/source/RTD/syntax/parse.test.ts +188 -0
- package/source/RTD/syntax/parse.ts +153 -0
- package/source/RTD/syntax/types.ts +48 -0
- package/source/Remotes.test.ts +42 -0
- package/source/Remotes.ts +22 -0
- package/source/Tenant.ts +38 -0
- package/source/deployment.ts +49 -0
- package/source/directives/auth/Anonymous.ts +14 -0
- package/source/directives/auth/Echo.ts +12 -0
- package/source/directives/auth/Family.ts +145 -0
- package/source/directives/auth/Id.ts +19 -0
- package/source/directives/auth/Incept.ts +42 -0
- package/source/directives/auth/Role.test.ts +62 -0
- package/source/directives/auth/Role.ts +56 -0
- package/source/directives/auth/Rule.ts +28 -0
- package/source/directives/auth/Scheme.ts +26 -0
- package/source/directives/auth/index.ts +3 -0
- package/source/directives/auth/schemes.ts +8 -0
- package/source/directives/auth/split.ts +15 -0
- package/source/directives/auth/types.ts +37 -0
- package/source/directives/dev/Family.ts +36 -0
- package/source/directives/dev/Stub.ts +14 -0
- package/source/directives/dev/Throw.ts +14 -0
- package/source/directives/dev/index.ts +3 -0
- package/source/directives/dev/types.ts +5 -0
- package/source/directives/index.ts +5 -0
- package/source/discovery.ts +1 -0
- package/source/exceptions.ts +17 -0
- package/source/index.test.ts +9 -0
- package/source/index.ts +6 -0
- package/source/manifest.test.ts +59 -0
- package/source/manifest.ts +48 -0
- package/source/root.ts +38 -0
- package/source/schemas.ts +9 -0
- package/tsconfig.json +12 -0
- package/src/.manifest/index.js +0 -7
- package/src/.manifest/normalize.js +0 -58
- package/src/.manifest/schema.yaml +0 -71
- package/src/.manifest/validate.js +0 -17
- package/src/constants.js +0 -3
- package/src/deployment.js +0 -23
- package/src/exposition.js +0 -68
- package/src/factory.js +0 -76
- package/src/index.js +0 -9
- package/src/manifest.js +0 -12
- package/src/query/criteria.js +0 -55
- package/src/query/enum.js +0 -35
- package/src/query/index.js +0 -17
- package/src/query/query.js +0 -60
- package/src/query/range.js +0 -28
- package/src/query/sort.js +0 -19
- package/src/remote.js +0 -88
- package/src/server.js +0 -83
- package/src/tenant.js +0 -29
- package/src/translate/etag.js +0 -14
- package/src/translate/index.js +0 -7
- package/src/translate/request.js +0 -68
- package/src/translate/response.js +0 -62
- package/src/tree.js +0 -109
- package/test/manifest.normalize.fixtures.js +0 -37
- package/test/manifest.normalize.test.js +0 -37
- package/test/manifest.validate.test.js +0 -40
- package/test/query.range.test.js +0 -18
- package/test/tree.fixtures.js +0 -21
- package/test/tree.test.js +0 -44
- package/types/annotations.d.ts +0 -10
- package/types/declarations.d.ts +0 -31
- package/types/exposition.d.ts +0 -13
- package/types/http.d.ts +0 -13
- package/types/query.d.ts +0 -16
- package/types/remote.d.ts +0 -19
- package/types/server.d.ts +0 -13
- package/types/tree.d.ts +0 -33
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
Feature: Access authorization
|
|
2
|
+
|
|
3
|
+
Background:
|
|
4
|
+
Given the `identity.basic` database contains:
|
|
5
|
+
# developer:secret
|
|
6
|
+
# user:12345
|
|
7
|
+
| _id | username | password |
|
|
8
|
+
| efe3a65ebbee47ed95a73edd911ea328 | developer | $2b$10$ZRSKkgZoGnrcTNA5w5eCcu3pxDzdTduhteVYXcp56AaNcilNkwJ.O |
|
|
9
|
+
| e8e4f9c2a68d419b861403d71fabc915 | user | $2b$10$Frszmrmsz9iwSXzBbRRMKeDVKsNxozkrLNSsN.SnVC.KPxLtQr/bK |
|
|
10
|
+
And the `identity.bans` database is empty
|
|
11
|
+
|
|
12
|
+
Scenario: Deny by default
|
|
13
|
+
Given the annotation:
|
|
14
|
+
"""yaml
|
|
15
|
+
/:
|
|
16
|
+
GET:
|
|
17
|
+
dev:stub:
|
|
18
|
+
access: granted!
|
|
19
|
+
"""
|
|
20
|
+
When the following request is received:
|
|
21
|
+
"""
|
|
22
|
+
GET / HTTP/1.1
|
|
23
|
+
"""
|
|
24
|
+
Then the following reply is sent:
|
|
25
|
+
"""
|
|
26
|
+
401 Unauthorized
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
Scenario: Allow anonymous access
|
|
30
|
+
Given the annotation:
|
|
31
|
+
"""yaml
|
|
32
|
+
/:
|
|
33
|
+
auth:anonymous: true
|
|
34
|
+
GET:
|
|
35
|
+
dev:stub:
|
|
36
|
+
access: granted!
|
|
37
|
+
"""
|
|
38
|
+
When the following request is received:
|
|
39
|
+
"""
|
|
40
|
+
GET / HTTP/1.1
|
|
41
|
+
"""
|
|
42
|
+
Then the following reply is sent:
|
|
43
|
+
"""
|
|
44
|
+
200 OK
|
|
45
|
+
content-type: application/yaml
|
|
46
|
+
|
|
47
|
+
access: granted!
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
Scenario: Deny access with credentials to a resource with anonymous access
|
|
51
|
+
Given the annotation:
|
|
52
|
+
"""yaml
|
|
53
|
+
/:
|
|
54
|
+
auth:anonymous: true
|
|
55
|
+
GET:
|
|
56
|
+
dev:stub:
|
|
57
|
+
access: granted!
|
|
58
|
+
"""
|
|
59
|
+
When the following request is received:
|
|
60
|
+
"""
|
|
61
|
+
GET / HTTP/1.1
|
|
62
|
+
authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
|
|
63
|
+
"""
|
|
64
|
+
Then the following reply is sent:
|
|
65
|
+
"""
|
|
66
|
+
403 Forbidden
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
Scenario: Using `auth:id` directive
|
|
70
|
+
Given the annotation:
|
|
71
|
+
"""yaml
|
|
72
|
+
/:
|
|
73
|
+
/:id:
|
|
74
|
+
auth:id: id
|
|
75
|
+
GET:
|
|
76
|
+
dev:stub:
|
|
77
|
+
access: granted!
|
|
78
|
+
"""
|
|
79
|
+
When the following request is received:
|
|
80
|
+
"""
|
|
81
|
+
GET /efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
|
|
82
|
+
authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
|
|
83
|
+
accept: application/yaml
|
|
84
|
+
"""
|
|
85
|
+
Then the following reply is sent:
|
|
86
|
+
"""
|
|
87
|
+
200 OK
|
|
88
|
+
content-type: application/yaml
|
|
89
|
+
|
|
90
|
+
access: granted!
|
|
91
|
+
"""
|
|
92
|
+
When the following request is received:
|
|
93
|
+
"""
|
|
94
|
+
GET /efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
|
|
95
|
+
authorization: Basic dXNlcjoxMjM0NQ==
|
|
96
|
+
accept: application/yaml
|
|
97
|
+
"""
|
|
98
|
+
Then the following reply is sent:
|
|
99
|
+
"""
|
|
100
|
+
403 Forbidden
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
Scenario: Using `auth:role` directive
|
|
104
|
+
Given the `identity.roles` database contains:
|
|
105
|
+
| _id | identity | role |
|
|
106
|
+
| 775a648d054e4ce1a65f8f17e5b51803 | efe3a65ebbee47ed95a73edd911ea328 | developer |
|
|
107
|
+
| 1d95bd2c764142818f6ece5e084015b5 | efe3a65ebbee47ed95a73edd911ea328 | user |
|
|
108
|
+
And the annotation:
|
|
109
|
+
"""yaml
|
|
110
|
+
/:
|
|
111
|
+
auth:role: developer
|
|
112
|
+
GET:
|
|
113
|
+
dev:stub:
|
|
114
|
+
access: granted!
|
|
115
|
+
"""
|
|
116
|
+
When the following request is received:
|
|
117
|
+
# identity with `developer` and `user` roles
|
|
118
|
+
"""
|
|
119
|
+
GET / HTTP/1.1
|
|
120
|
+
authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
|
|
121
|
+
accept: application/yaml
|
|
122
|
+
"""
|
|
123
|
+
Then the following reply is sent:
|
|
124
|
+
"""
|
|
125
|
+
200 OK
|
|
126
|
+
content-type: application/yaml
|
|
127
|
+
|
|
128
|
+
access: granted!
|
|
129
|
+
"""
|
|
130
|
+
When the following request is received:
|
|
131
|
+
# identity with no roles
|
|
132
|
+
"""
|
|
133
|
+
GET / HTTP/1.1
|
|
134
|
+
authorization: Basic dXNlcjoxMjM0NQ==
|
|
135
|
+
"""
|
|
136
|
+
Then the following reply is sent:
|
|
137
|
+
"""
|
|
138
|
+
403 Forbidden
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
Scenario: Using `auth:role` directive with scope matching
|
|
142
|
+
Given the `identity.roles` database contains:
|
|
143
|
+
| _id | identity | role |
|
|
144
|
+
| 775a648d054e4ce1a65f8f17e5b51803 | efe3a65ebbee47ed95a73edd911ea328 | developer:rust |
|
|
145
|
+
And the annotation:
|
|
146
|
+
"""yaml
|
|
147
|
+
/:
|
|
148
|
+
/:
|
|
149
|
+
auth:role: developer:rust:junior # role scope matches
|
|
150
|
+
/nested:
|
|
151
|
+
GET:
|
|
152
|
+
dev:stub: good!
|
|
153
|
+
/javascript:
|
|
154
|
+
auth:role: developer:javascript # role scope does not match
|
|
155
|
+
GET:
|
|
156
|
+
dev:stub: no good!
|
|
157
|
+
"""
|
|
158
|
+
When the following request is received:
|
|
159
|
+
"""
|
|
160
|
+
GET /nested/ HTTP/1.1
|
|
161
|
+
authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
|
|
162
|
+
accept: text/plain
|
|
163
|
+
"""
|
|
164
|
+
Then the following reply is sent:
|
|
165
|
+
"""
|
|
166
|
+
200 OK
|
|
167
|
+
content-type: text/plain
|
|
168
|
+
|
|
169
|
+
good!
|
|
170
|
+
"""
|
|
171
|
+
When the following request is received:
|
|
172
|
+
"""
|
|
173
|
+
GET /javascript/ HTTP/1.1
|
|
174
|
+
authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
|
|
175
|
+
"""
|
|
176
|
+
Then the following reply is sent:
|
|
177
|
+
"""
|
|
178
|
+
403 Forbidden
|
|
179
|
+
"""
|
|
180
|
+
|
|
181
|
+
Scenario: Allow by `auth:role` matching one of the roles
|
|
182
|
+
Given the `identity.roles` database contains:
|
|
183
|
+
| _id | identity | role |
|
|
184
|
+
| 775a648d054e4ce1a65f8f17e5b51803 | efe3a65ebbee47ed95a73edd911ea328 | developer |
|
|
185
|
+
And the annotation:
|
|
186
|
+
"""yaml
|
|
187
|
+
/:
|
|
188
|
+
role:
|
|
189
|
+
- developer
|
|
190
|
+
- admin
|
|
191
|
+
GET:
|
|
192
|
+
dev:stub:
|
|
193
|
+
access: granted!
|
|
194
|
+
"""
|
|
195
|
+
When the following request is received:
|
|
196
|
+
# identity with `developer` and `user` roles
|
|
197
|
+
"""
|
|
198
|
+
GET / HTTP/1.1
|
|
199
|
+
authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
|
|
200
|
+
accept: application/yaml
|
|
201
|
+
"""
|
|
202
|
+
Then the following reply is sent:
|
|
203
|
+
"""
|
|
204
|
+
200 OK
|
|
205
|
+
content-type: application/yaml
|
|
206
|
+
|
|
207
|
+
access: granted!
|
|
208
|
+
"""
|
|
209
|
+
|
|
210
|
+
Scenario: Using `auth:rule` directive
|
|
211
|
+
Given the `identity.roles` database contains:
|
|
212
|
+
| _id | identity | role |
|
|
213
|
+
| 775a648d054e4ce1a65f8f17e5b51803 | efe3a65ebbee47ed95a73edd911ea328 | developer:rust |
|
|
214
|
+
And the annotation:
|
|
215
|
+
"""yaml
|
|
216
|
+
/:
|
|
217
|
+
/rust/:id:
|
|
218
|
+
auth:rule:
|
|
219
|
+
id: id
|
|
220
|
+
role: developer:rust
|
|
221
|
+
GET:
|
|
222
|
+
dev:stub:
|
|
223
|
+
access: granted!
|
|
224
|
+
/javascript/:id:
|
|
225
|
+
rule:
|
|
226
|
+
id: id
|
|
227
|
+
role: developer:javascript
|
|
228
|
+
GET:
|
|
229
|
+
dev:stub:
|
|
230
|
+
access: granted!
|
|
231
|
+
"""
|
|
232
|
+
When the following request is received:
|
|
233
|
+
"""
|
|
234
|
+
GET /rust/efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
|
|
235
|
+
authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
|
|
236
|
+
accept: application/yaml
|
|
237
|
+
"""
|
|
238
|
+
Then the following reply is sent:
|
|
239
|
+
"""
|
|
240
|
+
200 OK
|
|
241
|
+
content-type: application/yaml
|
|
242
|
+
|
|
243
|
+
access: granted!
|
|
244
|
+
"""
|
|
245
|
+
When the following request is received:
|
|
246
|
+
"""
|
|
247
|
+
GET /javascript/efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
|
|
248
|
+
authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
|
|
249
|
+
"""
|
|
250
|
+
Then the following reply is sent:
|
|
251
|
+
"""
|
|
252
|
+
403 Forbidden
|
|
253
|
+
"""
|
|
254
|
+
|
|
255
|
+
Scenario: Token authentication scheme
|
|
256
|
+
Given the annotation:
|
|
257
|
+
"""yaml
|
|
258
|
+
/:
|
|
259
|
+
/:id:
|
|
260
|
+
auth:id: id
|
|
261
|
+
GET:
|
|
262
|
+
dev:stub:
|
|
263
|
+
access: granted!
|
|
264
|
+
"""
|
|
265
|
+
When the following request is received:
|
|
266
|
+
"""
|
|
267
|
+
GET /efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
|
|
268
|
+
authorization: Token v3.local.9oEtVJkfRw4cOJ8M4DxuVuAN29dGT26XMYyPAoXtwrkdkiJVSVj46sMNAOdlxwKGszJZV_ReOL26dxDVlsQ7QAIuRhRPlvsHYNOhcD-LApoAXV0S3IK16EMoEv7tE9z70FCLC3WoIW9RIQ8PR3uZhAdhSgBilsVOpWrk4XtnfCIlVwhYMKu79a66oZZhV2Q7Kl3nfYsf84-6rAL_1H0MsqCDUHVXuIg
|
|
269
|
+
accept: application/yaml
|
|
270
|
+
"""
|
|
271
|
+
Then the following reply is sent:
|
|
272
|
+
"""
|
|
273
|
+
200 OK
|
|
274
|
+
content-type: application/yaml
|
|
275
|
+
|
|
276
|
+
access: granted!
|
|
277
|
+
"""
|
|
278
|
+
And the reply does not contain:
|
|
279
|
+
"""
|
|
280
|
+
authorization: Token
|
|
281
|
+
"""
|
|
282
|
+
When the following request is received:
|
|
283
|
+
"""
|
|
284
|
+
GET /efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
|
|
285
|
+
authorization: Token v3.local.cjlxn4IJ9hI92KuksguzDx7_kYxgDFFGFnfNchf0cWnmos34dqX2XpTAUBd-LqgqfuH-lVGfNvjBUkw5JtHRBiIAVaPHF3Ncc0eafwgH2DPme9pndZL92fWryGnJ-sMHA28Q6UcXsIfhgd2JZ0n-585SBhwlosC3gKTcVHK7XNljeaTen4jZPw8uY-pdbsm6dDq3aKMzl8K78_BTTfiNPG2cI_aNuHw
|
|
286
|
+
accept: application/yaml
|
|
287
|
+
"""
|
|
288
|
+
Then the following reply is sent:
|
|
289
|
+
"""
|
|
290
|
+
403 Forbidden
|
|
291
|
+
"""
|
|
292
|
+
|
|
293
|
+
Scenario: Using token with roles
|
|
294
|
+
Given the annotation:
|
|
295
|
+
"""yaml
|
|
296
|
+
/:
|
|
297
|
+
auth:role: developer
|
|
298
|
+
GET:
|
|
299
|
+
dev:stub:
|
|
300
|
+
access: granted!
|
|
301
|
+
"""
|
|
302
|
+
And the `identity.roles` database contains:
|
|
303
|
+
| _id | identity | role |
|
|
304
|
+
| 775a648d054e4ce1a65f8f17e5b51803 | efe3a65ebbee47ed95a73edd911ea328 | developer |
|
|
305
|
+
When the following request is received:
|
|
306
|
+
"""
|
|
307
|
+
GET / HTTP/1.1
|
|
308
|
+
authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
|
|
309
|
+
accept: application/yaml
|
|
310
|
+
"""
|
|
311
|
+
Then the following reply is sent:
|
|
312
|
+
"""
|
|
313
|
+
200 OK
|
|
314
|
+
content-type: application/yaml
|
|
315
|
+
authorization: Token ${{ token }}
|
|
316
|
+
|
|
317
|
+
access: granted!
|
|
318
|
+
"""
|
|
319
|
+
When the following request is received:
|
|
320
|
+
"""
|
|
321
|
+
GET / HTTP/1.1
|
|
322
|
+
authorization: Token ${{ token }}
|
|
323
|
+
accept: application/yaml
|
|
324
|
+
"""
|
|
325
|
+
Then the following reply is sent:
|
|
326
|
+
"""
|
|
327
|
+
200 OK
|
|
328
|
+
content-type: application/yaml
|
|
329
|
+
|
|
330
|
+
access: granted!
|
|
331
|
+
"""
|
|
332
|
+
|
|
333
|
+
Scenario: Using `auth:scheme` directive
|
|
334
|
+
Given the annotation:
|
|
335
|
+
"""yaml
|
|
336
|
+
/:
|
|
337
|
+
/:id:
|
|
338
|
+
auth:scheme: basic
|
|
339
|
+
auth:id: id
|
|
340
|
+
GET:
|
|
341
|
+
dev:stub:
|
|
342
|
+
access: granted!
|
|
343
|
+
"""
|
|
344
|
+
When the following request is received:
|
|
345
|
+
"""
|
|
346
|
+
GET /efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
|
|
347
|
+
authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
|
|
348
|
+
accept: application/yaml
|
|
349
|
+
"""
|
|
350
|
+
Then the following reply is sent:
|
|
351
|
+
"""
|
|
352
|
+
200 OK
|
|
353
|
+
content-type: application/yaml
|
|
354
|
+
|
|
355
|
+
access: granted!
|
|
356
|
+
"""
|
|
357
|
+
When the following request is received:
|
|
358
|
+
"""
|
|
359
|
+
GET /efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
|
|
360
|
+
authorization: Token v3.local.9oEtVJkfRw4cOJ8M4DxuVuAN29dGT26XMYyPAoXtwrkdkiJVSVj46sMNAOdlxwKGszJZV_ReOL26dxDVlsQ7QAIuRhRPlvsHYNOhcD-LApoAXV0S3IK16EMoEv7tE9z70FCLC3WoIW9RIQ8PR3uZhAdhSgBilsVOpWrk4XtnfCIlVwhYMKu79a66oZZhV2Q7Kl3nfYsf84-6rAL_1H0MsqCDUHVXuIg
|
|
361
|
+
accept: text/plain
|
|
362
|
+
"""
|
|
363
|
+
Then the following reply is sent:
|
|
364
|
+
"""
|
|
365
|
+
403 Forbidden
|
|
366
|
+
|
|
367
|
+
Basic authentication scheme is required to access this resource.
|
|
368
|
+
"""
|
|
369
|
+
|
|
370
|
+
Scenario: Adding a role without required permissions
|
|
371
|
+
|
|
372
|
+
Trunk directives should not be applied to the Identity management resources.
|
|
373
|
+
|
|
374
|
+
Given the annotation:
|
|
375
|
+
"""yaml
|
|
376
|
+
anonymous: true
|
|
377
|
+
"""
|
|
378
|
+
When the following request is received:
|
|
379
|
+
"""
|
|
380
|
+
POST /identity/roles/efe3a65ebbee47ed95a73edd911ea328/ HTTP/1.1
|
|
381
|
+
content-type: application/yaml
|
|
382
|
+
|
|
383
|
+
role: developer
|
|
384
|
+
"""
|
|
385
|
+
Then the following reply is sent:
|
|
386
|
+
"""
|
|
387
|
+
401 Unauthorized
|
|
388
|
+
"""
|
|
389
|
+
|
|
390
|
+
Scenario: Banning an Identity
|
|
391
|
+
Given the `identity.roles` database contains:
|
|
392
|
+
| _id | identity | role |
|
|
393
|
+
| 775a648d054e4ce1a65f8f17e5b51803 | efe3a65ebbee47ed95a73edd911ea328 | system |
|
|
394
|
+
And the annotation:
|
|
395
|
+
"""yaml
|
|
396
|
+
/:
|
|
397
|
+
/:id:
|
|
398
|
+
auth:id: id
|
|
399
|
+
GET:
|
|
400
|
+
dev:stub:
|
|
401
|
+
access: granted!
|
|
402
|
+
"""
|
|
403
|
+
And the `identity.tokens` configuration:
|
|
404
|
+
"""yaml
|
|
405
|
+
refresh: 1
|
|
406
|
+
"""
|
|
407
|
+
When the following request is received:
|
|
408
|
+
"""
|
|
409
|
+
GET /e8e4f9c2a68d419b861403d71fabc915/ HTTP/1.1
|
|
410
|
+
authorization: Basic dXNlcjoxMjM0NQ==
|
|
411
|
+
"""
|
|
412
|
+
Then the following reply is sent:
|
|
413
|
+
"""
|
|
414
|
+
200 OK
|
|
415
|
+
authorization: Token ${{ token }}
|
|
416
|
+
"""
|
|
417
|
+
When the following request is received:
|
|
418
|
+
"""
|
|
419
|
+
PUT /identity/bans/e8e4f9c2a68d419b861403d71fabc915/ HTTP/1.1
|
|
420
|
+
authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
|
|
421
|
+
content-type: application/yaml
|
|
422
|
+
|
|
423
|
+
banned: true
|
|
424
|
+
"""
|
|
425
|
+
Then the following reply is sent:
|
|
426
|
+
"""
|
|
427
|
+
204 No Content
|
|
428
|
+
"""
|
|
429
|
+
# accessing a resource with a banned Identity
|
|
430
|
+
When the following request is received:
|
|
431
|
+
"""
|
|
432
|
+
GET /e8e4f9c2a68d419b861403d71fabc915/ HTTP/1.1
|
|
433
|
+
authorization: Basic dXNlcjoxMjM0NQ==
|
|
434
|
+
"""
|
|
435
|
+
Then the following reply is sent:
|
|
436
|
+
"""
|
|
437
|
+
401 Unauthorized
|
|
438
|
+
"""
|
|
439
|
+
Then after 1 second
|
|
440
|
+
When the following request is received:
|
|
441
|
+
"""
|
|
442
|
+
GET /e8e4f9c2a68d419b861403d71fabc915/ HTTP/1.1
|
|
443
|
+
authorization: Token ${{ token }}
|
|
444
|
+
"""
|
|
445
|
+
Then the following reply is sent:
|
|
446
|
+
"""
|
|
447
|
+
401 Unauthorized
|
|
448
|
+
"""
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
Feature: Annotation
|
|
2
|
+
|
|
3
|
+
Scenario: Simple annotation
|
|
4
|
+
Given the annotation:
|
|
5
|
+
"""yaml
|
|
6
|
+
/:
|
|
7
|
+
anonymous: true
|
|
8
|
+
/foo:
|
|
9
|
+
GET:
|
|
10
|
+
query: {}
|
|
11
|
+
endpoint: pots.enumerate
|
|
12
|
+
"""
|
|
13
|
+
And the `pots` is running
|
|
14
|
+
And the `pots` database contains:
|
|
15
|
+
| _id | title | volume |
|
|
16
|
+
| 4c4759e6f9c74da989d64511df42d6f4 | First pot | 100 |
|
|
17
|
+
When the following request is received:
|
|
18
|
+
"""
|
|
19
|
+
GET /foo/ HTTP/1.1
|
|
20
|
+
accept: application/yaml
|
|
21
|
+
"""
|
|
22
|
+
Then the following reply is sent:
|
|
23
|
+
"""
|
|
24
|
+
200 OK
|
|
25
|
+
content-type: application/yaml
|
|
26
|
+
|
|
27
|
+
- id: 4c4759e6f9c74da989d64511df42d6f4
|
|
28
|
+
title: First pot
|
|
29
|
+
volume: 100
|
|
30
|
+
"""
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
Feature: Request body
|
|
2
|
+
|
|
3
|
+
Scenario: Creating an entity
|
|
4
|
+
Given the `pots` is running with the following manifest:
|
|
5
|
+
"""yaml
|
|
6
|
+
exposition:
|
|
7
|
+
/:
|
|
8
|
+
POST: transit
|
|
9
|
+
"""
|
|
10
|
+
When the following request is received:
|
|
11
|
+
"""
|
|
12
|
+
POST /pots/ HTTP/1.1
|
|
13
|
+
content-type: application/yaml
|
|
14
|
+
|
|
15
|
+
title: Hello
|
|
16
|
+
volume: 1.5
|
|
17
|
+
"""
|
|
18
|
+
Then the following reply is sent:
|
|
19
|
+
"""
|
|
20
|
+
201 Created
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
Scenario Outline: Path segment as input for <operation>
|
|
24
|
+
Given the `echo` is running with the following manifest:
|
|
25
|
+
"""yaml
|
|
26
|
+
exposition:
|
|
27
|
+
/:name:
|
|
28
|
+
GET: <operation>
|
|
29
|
+
"""
|
|
30
|
+
When the following request is received:
|
|
31
|
+
"""
|
|
32
|
+
GET /echo/world/ HTTP/1.1
|
|
33
|
+
accept: text/plain
|
|
34
|
+
"""
|
|
35
|
+
Then the following reply is sent:
|
|
36
|
+
"""
|
|
37
|
+
200 OK
|
|
38
|
+
content-type: text/plain
|
|
39
|
+
|
|
40
|
+
Hello world
|
|
41
|
+
"""
|
|
42
|
+
Examples:
|
|
43
|
+
| operation |
|
|
44
|
+
| compute |
|
|
45
|
+
| affect |
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
Feature: Directives
|
|
2
|
+
|
|
3
|
+
Scenario: Basic directive
|
|
4
|
+
Given the annotation:
|
|
5
|
+
"""yaml
|
|
6
|
+
/:
|
|
7
|
+
anonymous: true
|
|
8
|
+
GET:
|
|
9
|
+
dev:stub:
|
|
10
|
+
hello: world
|
|
11
|
+
"""
|
|
12
|
+
When the following request is received:
|
|
13
|
+
"""
|
|
14
|
+
GET / HTTP/1.1
|
|
15
|
+
accept: application/json
|
|
16
|
+
"""
|
|
17
|
+
Then the following reply is sent:
|
|
18
|
+
"""
|
|
19
|
+
200 OK
|
|
20
|
+
content-type: application/json
|
|
21
|
+
|
|
22
|
+
{"hello":"world"}
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
Scenario: Nested routes
|
|
26
|
+
Given the annotation:
|
|
27
|
+
"""yaml
|
|
28
|
+
/:
|
|
29
|
+
anonymous: true
|
|
30
|
+
dev:stub:
|
|
31
|
+
hello: again
|
|
32
|
+
GET: {}
|
|
33
|
+
/pots:
|
|
34
|
+
GET: {}
|
|
35
|
+
"""
|
|
36
|
+
When the following request is received:
|
|
37
|
+
"""
|
|
38
|
+
GET /pots/ HTTP/1.1
|
|
39
|
+
accept: application/yaml
|
|
40
|
+
"""
|
|
41
|
+
Then the following reply is sent:
|
|
42
|
+
"""
|
|
43
|
+
200 OK
|
|
44
|
+
content-type: application/yaml
|
|
45
|
+
|
|
46
|
+
hello: again
|
|
47
|
+
"""
|
|
48
|
+
When the following request is received:
|
|
49
|
+
"""
|
|
50
|
+
GET /pots/non-existent/ HTTP/1.1
|
|
51
|
+
accept: application/yaml
|
|
52
|
+
"""
|
|
53
|
+
Then the following reply is sent:
|
|
54
|
+
"""
|
|
55
|
+
404 Not Found
|
|
56
|
+
"""
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
Feature: Dynamic tree updates
|
|
2
|
+
|
|
3
|
+
Background:
|
|
4
|
+
Given the `pots` database contains:
|
|
5
|
+
| _id | title | volume | temperature |
|
|
6
|
+
| 4c4759e6f9c74da989d64511df42d6f4 | First pot | 100 | 80 |
|
|
7
|
+
|
|
8
|
+
Scenario: Updating routes
|
|
9
|
+
Given the Gateway is running
|
|
10
|
+
And the `pots` is running with the following manifest:
|
|
11
|
+
"""yaml
|
|
12
|
+
exposition:
|
|
13
|
+
/:
|
|
14
|
+
isolated: true
|
|
15
|
+
GET: enumerate
|
|
16
|
+
"""
|
|
17
|
+
When the following request is received:
|
|
18
|
+
"""
|
|
19
|
+
GET /pots/ HTTP/1.1
|
|
20
|
+
"""
|
|
21
|
+
Then the following reply is sent:
|
|
22
|
+
"""
|
|
23
|
+
401 Unauthorized
|
|
24
|
+
"""
|
|
25
|
+
Then the `pots` is stopped
|
|
26
|
+
Then the `pots` is running with the following manifest:
|
|
27
|
+
"""yaml
|
|
28
|
+
exposition:
|
|
29
|
+
/:
|
|
30
|
+
GET: enumerate
|
|
31
|
+
"""
|
|
32
|
+
When the following request is received:
|
|
33
|
+
"""
|
|
34
|
+
GET /pots/ HTTP/1.1
|
|
35
|
+
accept: application/yaml
|
|
36
|
+
"""
|
|
37
|
+
Then the following reply is sent:
|
|
38
|
+
"""
|
|
39
|
+
200 OK
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
Scenario: Updating routes with conflict
|
|
43
|
+
And the `pots` is running with the following manifest:
|
|
44
|
+
"""yaml
|
|
45
|
+
exposition:
|
|
46
|
+
/:id:
|
|
47
|
+
GET: observe
|
|
48
|
+
"""
|
|
49
|
+
Then the `pots` is stopped
|
|
50
|
+
Then the `pots` is running with the following manifest:
|
|
51
|
+
"""yaml
|
|
52
|
+
exposition:
|
|
53
|
+
/:id:
|
|
54
|
+
GET: observe
|
|
55
|
+
/big:
|
|
56
|
+
GET:
|
|
57
|
+
endpoint: enumerate
|
|
58
|
+
query:
|
|
59
|
+
criteria: volume>200
|
|
60
|
+
"""
|
|
61
|
+
When the following request is received:
|
|
62
|
+
"""
|
|
63
|
+
GET /pots/big/ HTTP/1.1
|
|
64
|
+
accept: application/yaml
|
|
65
|
+
"""
|
|
66
|
+
Then the following reply is sent:
|
|
67
|
+
"""
|
|
68
|
+
200 OK
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
Scenario: Updating method mapping
|
|
72
|
+
Given the `pots` is running with the following manifest:
|
|
73
|
+
"""yaml
|
|
74
|
+
exposition:
|
|
75
|
+
/big:
|
|
76
|
+
GET:
|
|
77
|
+
endpoint: enumerate
|
|
78
|
+
query:
|
|
79
|
+
criteria: volume>200 # closed
|
|
80
|
+
"""
|
|
81
|
+
Then the `pots` is stopped
|
|
82
|
+
Then the `pots` is running with the following manifest:
|
|
83
|
+
"""yaml
|
|
84
|
+
exposition:
|
|
85
|
+
/big:
|
|
86
|
+
GET:
|
|
87
|
+
endpoint: enumerate
|
|
88
|
+
query:
|
|
89
|
+
criteria: volume>200; # open
|
|
90
|
+
"""
|
|
91
|
+
When the following request is received:
|
|
92
|
+
"""
|
|
93
|
+
GET /pots/big/?criteria=temperature>50 HTTP/1.1
|
|
94
|
+
accept: application/yaml
|
|
95
|
+
"""
|
|
96
|
+
Then the following reply is sent:
|
|
97
|
+
"""
|
|
98
|
+
200 OK
|
|
99
|
+
"""
|