synapse 2.205.0__py311-none-any.whl → 2.206.0__py311-none-any.whl

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.

Potentially problematic release.


This version of synapse might be problematic. Click here for more details.

@@ -1,4 +1,5 @@
1
1
  import ssl
2
+ import http
2
3
 
3
4
  import aiohttp
4
5
  import aiohttp.client_exceptions as a_exc
@@ -6,6 +7,7 @@ import aiohttp.client_exceptions as a_exc
6
7
  import synapse.common as s_common
7
8
  import synapse.tools.backup as s_backup
8
9
 
10
+ import synapse.exc as s_exc
9
11
  import synapse.lib.coro as s_coro
10
12
  import synapse.lib.json as s_json
11
13
  import synapse.lib.link as s_link
@@ -39,14 +41,14 @@ class HttpApiTest(s_tests.SynTest):
39
41
  async with self.getHttpSess(auth=('root', 'secret'), port=port) as sess:
40
42
 
41
43
  async with sess.get(url) as resp:
42
- self.eq(resp.status, 200)
44
+ self.eq(resp.status, http.HTTPStatus.OK)
43
45
  retn = await resp.json()
44
46
  self.eq(retn.get('status'), 'ok')
45
47
  self.eq(retn.get('result'), {'data': 'everything is awesome!'})
46
48
 
47
49
  async with self.getHttpSess(auth=('user', '12345'), port=port) as sess:
48
50
  async with sess.get(url) as resp:
49
- self.eq(resp.status, 403)
51
+ self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
50
52
  retn = await resp.json()
51
53
  self.eq(retn.get('status'), 'err')
52
54
  self.eq(retn.get('code'), 'AuthDeny')
@@ -54,7 +56,7 @@ class HttpApiTest(s_tests.SynTest):
54
56
  await user.addRule((True, ('syn:test',)))
55
57
 
56
58
  async with sess.get(url) as resp:
57
- self.eq(resp.status, 200)
59
+ self.eq(resp.status, http.HTTPStatus.OK)
58
60
  retn = await resp.json()
59
61
  self.eq(retn.get('status'), 'ok')
60
62
  self.eq(retn.get('result'), {'data': 'everything is awesome!'})
@@ -62,7 +64,7 @@ class HttpApiTest(s_tests.SynTest):
62
64
  async with aiohttp.ClientSession() as sess:
63
65
  burl = f'https://newp:newp@localhost:{port}/api/tests/test_reqauth'
64
66
  async with sess.get(burl, ssl=False) as resp:
65
- self.eq(resp.status, 401)
67
+ self.eq(resp.status, http.HTTPStatus.UNAUTHORIZED)
66
68
  retn = await resp.json()
67
69
  self.eq(retn.get('status'), 'err')
68
70
 
@@ -80,48 +82,57 @@ class HttpApiTest(s_tests.SynTest):
80
82
  async with self.getHttpSess(auth=('root', 'secret'), port=port) as sess:
81
83
 
82
84
  async with sess.get(f'https://localhost:{port}/api/v1/auth/users') as resp:
85
+ self.eq(resp.status, http.HTTPStatus.OK)
83
86
  item = await resp.json()
84
87
  users = item.get('result')
85
88
  self.isin('newb', [u.get('name') for u in users])
86
89
 
87
90
  info = {'archived': True}
88
91
  async with sess.post(f'https://localhost:{port}/api/v1/auth/user/{newb.iden}', json=info) as resp:
92
+ self.eq(resp.status, http.HTTPStatus.OK)
89
93
  retn = await resp.json()
90
94
  self.eq('ok', retn.get('status'))
91
95
 
92
96
  self.true(newb.isLocked())
93
97
 
94
98
  async with sess.get(f'https://localhost:{port}/api/v1/auth/users') as resp:
99
+ self.eq(resp.status, http.HTTPStatus.OK)
95
100
  item = await resp.json()
96
101
  users = item.get('result')
97
102
  self.notin('newb', [u.get('name') for u in users])
98
103
 
99
104
  async with sess.get(f'https://localhost:{port}/api/v1/auth/users?archived=asdf') as resp:
105
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
100
106
  item = await resp.json()
101
107
  self.eq('err', item.get('status'))
102
108
  self.eq('BadHttpParam', item.get('code'))
103
109
 
104
110
  async with sess.get(f'https://localhost:{port}/api/v1/auth/users?archived=99') as resp:
111
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
105
112
  item = await resp.json()
106
113
  self.eq('err', item.get('status'))
107
114
  self.eq('BadHttpParam', item.get('code'))
108
115
 
109
116
  async with sess.get(f'https://localhost:{port}/api/v1/auth/users?archived=0') as resp:
117
+ self.eq(resp.status, http.HTTPStatus.OK)
110
118
  item = await resp.json()
111
119
  users = item.get('result')
112
120
  self.notin('newb', [u.get('name') for u in users])
113
121
 
114
122
  async with sess.get(f'https://localhost:{port}/api/v1/auth/users?archived=1') as resp:
123
+ self.eq(resp.status, http.HTTPStatus.OK)
115
124
  item = await resp.json()
116
125
  users = item.get('result')
117
126
  self.isin('newb', [u.get('name') for u in users])
118
127
 
119
128
  info = {'archived': False}
120
129
  async with sess.post(f'https://localhost:{port}/api/v1/auth/user/{newb.iden}', json=info) as resp:
130
+ self.eq(resp.status, http.HTTPStatus.OK)
121
131
  retn = await resp.json()
122
132
  self.eq('ok', retn.get('status'))
123
133
 
124
134
  async with sess.get(f'https://localhost:{port}/api/v1/auth/users') as resp:
135
+ self.eq(resp.status, http.HTTPStatus.OK)
125
136
  item = await resp.json()
126
137
  users = item.get('result')
127
138
  self.isin('newb', [u.get('name') for u in users])
@@ -146,6 +157,7 @@ class HttpApiTest(s_tests.SynTest):
146
157
 
147
158
  info = {'name': 'bobs'}
148
159
  async with sess.post(f'https://localhost:{port}/api/v1/auth/delrole', json=info) as resp:
160
+ self.eq(resp.status, http.HTTPStatus.UNAUTHORIZED)
149
161
  item = await resp.json()
150
162
  self.eq('err', item.get('status'))
151
163
  self.eq('NotAuthenticated', item.get('code'))
@@ -154,6 +166,7 @@ class HttpApiTest(s_tests.SynTest):
154
166
 
155
167
  info = {'name': 'bobs'}
156
168
  async with sess.post(f'https://localhost:{port}/api/v1/auth/delrole', json=info) as resp:
169
+ self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
157
170
  item = await resp.json()
158
171
  self.eq('err', item.get('status'))
159
172
  self.eq('AuthDeny', item.get('code'))
@@ -162,17 +175,20 @@ class HttpApiTest(s_tests.SynTest):
162
175
 
163
176
  info = {}
164
177
  async with sess.post(f'https://localhost:{port}/api/v1/auth/delrole', json=info) as resp:
178
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
165
179
  item = await resp.json()
166
180
  self.eq('err', item.get('status'))
167
181
  self.eq('MissingField', item.get('code'))
168
182
 
169
183
  async with sess.post(f'https://localhost:{port}/api/v1/auth/delrole', data=b'asdf') as resp:
184
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
170
185
  item = await resp.json()
171
186
  self.eq('err', item.get('status'))
172
187
  self.eq('SchemaViolation', item.get('code'))
173
188
 
174
189
  info = {'name': 'newp'}
175
190
  async with sess.post(f'https://localhost:{port}/api/v1/auth/delrole', json=info) as resp:
191
+ self.eq(resp.status, http.HTTPStatus.NOT_FOUND)
176
192
  item = await resp.json()
177
193
  self.eq('err', item.get('status'))
178
194
  self.eq('NoSuchRole', item.get('code'))
@@ -180,6 +196,7 @@ class HttpApiTest(s_tests.SynTest):
180
196
  self.len(2, newb.getRoles())
181
197
  info = {'name': 'bobs'}
182
198
  async with sess.post(f'https://localhost:{port}/api/v1/auth/delrole', json=info) as resp:
199
+ self.eq(resp.status, http.HTTPStatus.OK)
183
200
  item = await resp.json()
184
201
  self.eq('ok', item.get('status'))
185
202
 
@@ -201,17 +218,20 @@ class HttpApiTest(s_tests.SynTest):
201
218
  url = f'https://localhost:{port}/api/v1/auth/password/{newb.iden}'
202
219
  # Admin can change the newb password
203
220
  async with sess.post(url, json={'passwd': 'words'}) as resp:
221
+ self.eq(resp.status, http.HTTPStatus.OK)
204
222
  item = await resp.json()
205
223
  self.eq(item.get('status'), 'ok')
206
224
 
207
225
  # must have content
208
226
  async with sess.post(url) as resp:
227
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
209
228
  item = await resp.json()
210
229
  self.eq(item.get('status'), 'err')
211
230
  self.isin('Invalid JSON content.', (item.get('mesg')))
212
231
 
213
232
  # password must be valid
214
233
  async with sess.post(url, json={'passwd': ''}) as resp:
234
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
215
235
  item = await resp.json()
216
236
  self.eq(item.get('status'), 'err')
217
237
  self.eq(item.get('code'), 'BadArg')
@@ -219,6 +239,7 @@ class HttpApiTest(s_tests.SynTest):
219
239
  url = f'https://localhost:{port}/api/v1/auth/password/1234'
220
240
  # User iden must be valid
221
241
  async with sess.post(url, json={'passwd': 'words'}) as resp:
242
+ self.eq(resp.status, http.HTTPStatus.NOT_FOUND)
222
243
  item = await resp.json()
223
244
  self.isin('User does not exist', (item.get('mesg')))
224
245
 
@@ -226,12 +247,14 @@ class HttpApiTest(s_tests.SynTest):
226
247
  # newb can change their own password
227
248
  url = f'https://localhost:{port}/api/v1/auth/password/{newb.iden}'
228
249
  async with sess.post(url, json={'passwd': 'newb'}) as resp:
250
+ self.eq(resp.status, http.HTTPStatus.OK)
229
251
  item = await resp.json()
230
252
  self.eq(item.get('status'), 'ok')
231
253
 
232
254
  # non-admin newb cannot change someone elses password
233
255
  url = f'https://localhost:{port}/api/v1/auth/password/{root.iden}'
234
256
  async with sess.post(url, json={'passwd': 'newb'}) as resp:
257
+ self.eq(resp.status, http.HTTPStatus.OK)
235
258
  item = await resp.json()
236
259
  self.eq(item.get('status'), 'ok')
237
260
 
@@ -250,6 +273,7 @@ class HttpApiTest(s_tests.SynTest):
250
273
  info = {'name': 'visi', 'passwd': 'secret', 'admin': True}
251
274
  # Make the first user as root
252
275
  async with sess.post(f'https://root:root@localhost:{port}/api/v1/auth/adduser', json=info) as resp:
276
+ self.eq(resp.status, http.HTTPStatus.OK)
253
277
  item = await resp.json()
254
278
  self.nn(item.get('result').get('iden'))
255
279
  visiiden = item['result']['iden']
@@ -257,17 +281,20 @@ class HttpApiTest(s_tests.SynTest):
257
281
  info = {'name': 'noob', 'passwd': 'nooblet', 'email': 'nobody@nowhere.com'}
258
282
  # The visi user is an admin, so reuse it
259
283
  async with sess.post(f'https://visi:secret@localhost:{port}/api/v1/auth/adduser', json=info) as resp:
284
+ self.eq(resp.status, http.HTTPStatus.OK)
260
285
  item = await resp.json()
261
286
  self.nn(item.get('result').get('iden'))
262
287
  self.eq('nobody@nowhere.com', item['result']['email'])
263
288
  noobiden = item['result']['iden']
264
289
 
265
290
  async with sess.get(f'https://visi:secret@localhost:{port}/api/v1/auth/user/{noobiden}') as resp:
291
+ self.eq(resp.status, http.HTTPStatus.OK)
266
292
  item = await resp.json()
267
293
  self.eq(noobiden, item['result']['iden'])
268
294
 
269
295
  info = {'name': 'visi', 'passwd': 'secret', 'admin': True}
270
296
  async with sess.post(f'https://visi:secret@localhost:{port}/api/v1/auth/adduser', json=info) as resp:
297
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
271
298
  item = await resp.json()
272
299
  self.eq('err', item.get('status'))
273
300
  self.eq('DupUser', item.get('code'))
@@ -278,61 +305,73 @@ class HttpApiTest(s_tests.SynTest):
278
305
  [False, ('baz',)]
279
306
  ]}
280
307
  async with sess.post(f'https://visi:secret@localhost:{port}/api/v1/auth/addrole', json=info) as resp:
308
+ self.eq(resp.status, http.HTTPStatus.OK)
281
309
  item = await resp.json()
282
310
  self.nn(item.get('result').get('iden'))
283
311
  self.eq(item.get('result').get('rules'), ((True, ('foo', 'bar')), (False, ('baz',))))
284
312
  analystiden = item['result']['iden']
285
313
 
286
314
  async with sess.get(f'https://visi:secret@localhost:{port}/api/v1/auth/role/{analystiden}') as resp:
315
+ self.eq(resp.status, http.HTTPStatus.OK)
287
316
  item = await resp.json()
288
317
  self.nn(item.get('result').get('iden'), analystiden)
289
318
 
290
319
  info = {'name': 'analysts'}
291
320
  async with sess.post(f'https://visi:secret@localhost:{port}/api/v1/auth/addrole', json=info) as resp:
321
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
292
322
  item = await resp.json()
293
323
  self.eq('err', item.get('status'))
294
324
  self.eq('DupRole', item.get('code'))
295
325
 
296
326
  async with sess.get(f'https://visi:secret@localhost:{port}/api/v1/auth/user/newp') as resp:
327
+ self.eq(resp.status, http.HTTPStatus.NOT_FOUND)
297
328
  item = await resp.json()
298
329
  self.eq('NoSuchUser', item.get('code'))
299
330
 
300
331
  async with sess.get(f'https://visi:secret@localhost:{port}/api/v1/auth/role/newp') as resp:
332
+ self.eq(resp.status, http.HTTPStatus.NOT_FOUND)
301
333
  item = await resp.json()
302
334
  self.eq('NoSuchRole', item.get('code'))
303
335
 
304
336
  async with sess.get(f'https://visi:secret@localhost:{port}/api/v1/auth/users') as resp:
337
+ self.eq(resp.status, http.HTTPStatus.OK)
305
338
  item = await resp.json()
306
339
  users = item.get('result')
307
340
  self.isin('visi', [u.get('name') for u in users])
308
341
 
309
342
  async with sess.get(f'https://visi:secret@localhost:{port}/api/v1/auth/roles') as resp:
343
+ self.eq(resp.status, http.HTTPStatus.OK)
310
344
  item = await resp.json()
311
345
  roles = item.get('result')
312
346
  self.isin('analysts', [r.get('name') for r in roles])
313
347
 
314
348
  info = {'user': 'blah', 'role': 'blah'}
315
349
  async with sess.post(f'https://visi:secret@localhost:{port}/api/v1/auth/grant', json=info) as resp:
350
+ self.eq(resp.status, http.HTTPStatus.NOT_FOUND)
316
351
  item = await resp.json()
317
352
  self.eq('NoSuchUser', item.get('code'))
318
353
 
319
354
  info = {'user': visiiden, 'role': 'blah'}
320
355
  async with sess.post(f'https://visi:secret@localhost:{port}/api/v1/auth/grant', json=info) as resp:
356
+ self.eq(resp.status, http.HTTPStatus.NOT_FOUND)
321
357
  item = await resp.json()
322
358
  self.eq('NoSuchRole', item.get('code'))
323
359
 
324
360
  info = {'user': 'blah', 'role': 'blah'}
325
361
  async with sess.post(f'https://visi:secret@localhost:{port}/api/v1/auth/revoke', json=info) as resp:
362
+ self.eq(resp.status, http.HTTPStatus.NOT_FOUND)
326
363
  item = await resp.json()
327
364
  self.eq('NoSuchUser', item.get('code'))
328
365
 
329
366
  info = {'user': visiiden, 'role': 'blah'}
330
367
  async with sess.post(f'https://visi:secret@localhost:{port}/api/v1/auth/revoke', json=info) as resp:
368
+ self.eq(resp.status, http.HTTPStatus.NOT_FOUND)
331
369
  item = await resp.json()
332
370
  self.eq('NoSuchRole', item.get('code'))
333
371
 
334
372
  info = {'user': visiiden, 'role': analystiden}
335
373
  async with sess.post(f'https://visi:secret@localhost:{port}/api/v1/auth/grant', json=info) as resp:
374
+ self.eq(resp.status, http.HTTPStatus.OK)
336
375
  item = await resp.json()
337
376
  self.eq('ok', item.get('status'))
338
377
  roles = item['result']['roles']
@@ -341,6 +380,7 @@ class HttpApiTest(s_tests.SynTest):
341
380
 
342
381
  info = {'user': visiiden, 'role': analystiden}
343
382
  async with sess.post(f'https://visi:secret@localhost:{port}/api/v1/auth/revoke', json=info) as resp:
383
+ self.eq(resp.status, http.HTTPStatus.OK)
344
384
  item = await resp.json()
345
385
  self.eq('ok', item.get('status'))
346
386
  roles = item['result']['roles']
@@ -348,42 +388,60 @@ class HttpApiTest(s_tests.SynTest):
348
388
 
349
389
  # Sad path coverage
350
390
  async with sess.get(f'https://visi:newp@localhost:{port}/api/v1/auth/roles') as resp:
391
+ self.eq(resp.status, http.HTTPStatus.UNAUTHORIZED)
351
392
  item = await resp.json()
352
393
  self.eq('err', item.get('status'))
353
394
  self.eq('NotAuthenticated', item.get('code'))
354
395
 
355
396
  async with sess.get(f'https://visi:newp@localhost:{port}/api/v1/auth/user/{noobiden}') as resp:
397
+ self.eq(resp.status, http.HTTPStatus.UNAUTHORIZED)
356
398
  item = await resp.json()
357
399
  self.eq('err', item.get('status'))
358
400
  self.eq('NotAuthenticated', item.get('code'))
359
401
 
360
402
  async with sess.get(f'https://visi:newp@localhost:{port}/api/v1/auth/role/{analystiden}') as resp:
403
+ self.eq(resp.status, http.HTTPStatus.UNAUTHORIZED)
361
404
  item = await resp.json()
362
405
  self.eq('err', item.get('status'))
363
406
  self.eq('NotAuthenticated', item.get('code'))
364
407
 
365
408
  async with sess.get(f'https://visi:secret@localhost:{port}/api/v1/auth/user/{s_common.guid()}') as resp:
409
+ self.eq(resp.status, http.HTTPStatus.NOT_FOUND)
366
410
  item = await resp.json()
367
411
  self.eq('err', item.get('status'))
368
412
  self.eq('NoSuchUser', item.get('code'))
369
413
 
370
414
  async with sess.get(f'https://visi:secret@localhost:{port}/api/v1/auth/role/{s_common.guid()}') as resp:
415
+ self.eq(resp.status, http.HTTPStatus.NOT_FOUND)
371
416
  item = await resp.json()
372
417
  self.eq('err', item.get('status'))
373
418
  self.eq('NoSuchRole', item.get('code'))
374
419
 
375
420
  async with sess.post(f'https://visi:secret@localhost:{port}/api/v1/auth/role/{s_common.guid()}') as resp:
421
+ self.eq(resp.status, http.HTTPStatus.NOT_FOUND)
376
422
  item = await resp.json()
377
423
  self.eq('err', item.get('status'))
378
424
  self.eq('NoSuchRole', item.get('code'))
379
425
 
380
426
  # lets try out session based login
381
427
 
428
+ # Sad path tests
382
429
  async with self.getHttpSess() as sess:
430
+ async with sess.post(f'https://localhost:{port}/api/v1/login') as resp:
431
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
432
+ item = await resp.json()
433
+ self.eq('SchemaViolation', item.get('code'))
434
+ async with sess.post(f'https://localhost:{port}/api/v1/login', json=['newp',]) as resp:
435
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
436
+ item = await resp.json()
437
+ self.eq('SchemaViolation', item.get('code'))
383
438
 
384
- info = {'user': 'hehe'}
439
+ async with self.getHttpSess() as sess:
440
+
441
+ info = {'user': 'hehe', 'passwd': 'newp'}
385
442
  with self.getAsyncLoggerStream('synapse.lib.httpapi', 'No such user.') as stream:
386
443
  async with sess.post(f'https://localhost:{port}/api/v1/login', json=info) as resp:
444
+ self.eq(resp.status, http.HTTPStatus.NOT_FOUND)
387
445
  item = await resp.json()
388
446
  self.eq('AuthDeny', item.get('code'))
389
447
  self.true(await stream.wait(timeout=6))
@@ -393,6 +451,7 @@ class HttpApiTest(s_tests.SynTest):
393
451
  await core.setUserLocked(visiiden, True)
394
452
  with self.getAsyncLoggerStream('synapse.lib.httpapi', 'User is locked.') as stream:
395
453
  async with sess.post(f'https://localhost:{port}/api/v1/login', json=info) as resp:
454
+ self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
396
455
  item = await resp.json()
397
456
  self.eq('AuthDeny', item.get('code'))
398
457
  self.true(await stream.wait(timeout=6))
@@ -403,6 +462,7 @@ class HttpApiTest(s_tests.SynTest):
403
462
  info = {'user': 'visi', 'passwd': 'borked'}
404
463
  with self.getAsyncLoggerStream('synapse.lib.httpapi', 'Incorrect password.') as stream:
405
464
  async with sess.post(f'https://localhost:{port}/api/v1/login', json=info) as resp:
465
+ self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
406
466
  item = await resp.json()
407
467
  self.eq('AuthDeny', item.get('code'))
408
468
  self.true(await stream.wait(timeout=6))
@@ -410,16 +470,19 @@ class HttpApiTest(s_tests.SynTest):
410
470
  async with self.getHttpSess() as sess:
411
471
  info = {'user': 'visi', 'passwd': 'secret'}
412
472
  async with sess.post(f'https://localhost:{port}/api/v1/login', json=info) as resp:
473
+ self.eq(resp.status, http.HTTPStatus.OK)
413
474
  item = await resp.json()
414
475
  self.eq('ok', item.get('status'))
415
476
 
416
477
  # make sure session works
417
478
  async with sess.get(f'https://localhost:{port}/api/v1/auth/users') as resp:
479
+ self.eq(resp.status, http.HTTPStatus.OK)
418
480
  item = await resp.json()
419
481
  self.eq('ok', item.get('status'))
420
482
 
421
483
  # log out of said session
422
484
  async with sess.get(f'https://localhost:{port}/api/v1/logout') as resp:
485
+ self.eq(resp.status, http.HTTPStatus.OK)
423
486
  item = await resp.json()
424
487
  self.eq('ok', item.get('status'))
425
488
  newcookie = resp.headers.get('Set-Cookie')
@@ -428,11 +491,13 @@ class HttpApiTest(s_tests.SynTest):
428
491
  # session no longer works
429
492
  data = {'query': '[ inet:ipv4=1.2.3.4 ]'}
430
493
  async with sess.get(f'https://localhost:{port}/api/v1/storm/nodes', json=data) as resp:
494
+ self.eq(resp.status, http.HTTPStatus.UNAUTHORIZED)
431
495
  item = await resp.json()
432
496
  self.eq('err', item.get('status'))
433
497
  self.eq('NotAuthenticated', item.get('code'))
434
498
 
435
499
  async with sess.get(f'https://localhost:{port}/api/v1/auth/users') as resp:
500
+ self.eq(resp.status, http.HTTPStatus.UNAUTHORIZED)
436
501
  item = await resp.json()
437
502
  self.eq('err', item.get('status'))
438
503
  self.eq('NotAuthenticated', item.get('code'))
@@ -440,6 +505,7 @@ class HttpApiTest(s_tests.SynTest):
440
505
  async with self.getHttpSess() as sess:
441
506
 
442
507
  async with sess.post(f'https://localhost:{port}/api/v1/auth/adduser', json=info) as resp:
508
+ self.eq(resp.status, http.HTTPStatus.UNAUTHORIZED)
443
509
  item = await resp.json()
444
510
  self.eq('NotAuthenticated', item.get('code'))
445
511
 
@@ -448,11 +514,13 @@ class HttpApiTest(s_tests.SynTest):
448
514
  newpauth = aiohttp.BasicAuth('visi', 'newp')
449
515
 
450
516
  async with sess.get(f'https://localhost:{port}/api/v1/auth/users', auth=visiauth) as resp:
517
+ self.eq(resp.status, http.HTTPStatus.OK)
451
518
  item = await resp.json()
452
519
  self.eq('ok', item.get('status'))
453
520
 
454
521
  with self.getAsyncLoggerStream('synapse.lib.httpapi', 'No such user.') as stream:
455
522
  async with sess.get(f'https://localhost:{port}/api/v1/auth/users', auth=heheauth) as resp:
523
+ self.eq(resp.status, http.HTTPStatus.UNAUTHORIZED)
456
524
  item = await resp.json()
457
525
  self.eq('NotAuthenticated', item.get('code'))
458
526
  self.true(await stream.wait(timeout=12))
@@ -460,6 +528,7 @@ class HttpApiTest(s_tests.SynTest):
460
528
  await core.setUserLocked(visiiden, True)
461
529
  with self.getAsyncLoggerStream('synapse.lib.httpapi', 'User is locked.') as stream:
462
530
  async with sess.get(f'https://localhost:{port}/api/v1/auth/users', auth=visiauth) as resp:
531
+ self.eq(resp.status, http.HTTPStatus.UNAUTHORIZED)
463
532
  item = await resp.json()
464
533
  self.eq('NotAuthenticated', item.get('code'))
465
534
  self.true(await stream.wait(timeout=12))
@@ -467,17 +536,20 @@ class HttpApiTest(s_tests.SynTest):
467
536
 
468
537
  with self.getAsyncLoggerStream('synapse.lib.httpapi', 'Incorrect password.') as stream:
469
538
  async with sess.get(f'https://localhost:{port}/api/v1/auth/users', auth=newpauth) as resp:
539
+ self.eq(resp.status, http.HTTPStatus.UNAUTHORIZED)
470
540
  item = await resp.json()
471
541
  self.eq('NotAuthenticated', item.get('code'))
472
542
  self.true(await stream.wait(timeout=12))
473
543
 
474
544
  headers = {'Authorization': 'yermom'}
475
545
  async with sess.get(f'https://localhost:{port}/api/v1/auth/users', headers=headers) as resp:
546
+ self.eq(resp.status, http.HTTPStatus.UNAUTHORIZED)
476
547
  item = await resp.json()
477
548
  self.eq('NotAuthenticated', item.get('code'))
478
549
 
479
550
  headers = {'Authorization': 'Basic zzzz'}
480
551
  async with sess.get(f'https://localhost:{port}/api/v1/auth/users', headers=headers) as resp:
552
+ self.eq(resp.status, http.HTTPStatus.UNAUTHORIZED)
481
553
  item = await resp.json()
482
554
  self.eq('NotAuthenticated', item.get('code'))
483
555
 
@@ -493,6 +565,7 @@ class HttpApiTest(s_tests.SynTest):
493
565
  origin = 'https://localhost:1/web/site'
494
566
  headers = {'origin': origin}
495
567
  async with sess.get(f'https://localhost:{port}/api/v1/auth/users', headers=headers) as resp:
568
+ self.eq(resp.status, http.HTTPStatus.OK)
496
569
  retn = await resp.json()
497
570
  self.eq(origin, resp.headers.get('Access-Control-Allow-Origin'))
498
571
  self.eq('ok', retn.get('status'))
@@ -502,20 +575,23 @@ class HttpApiTest(s_tests.SynTest):
502
575
  headers = {'origin': origin}
503
576
  async with sess.options(f'https://localhost:{port}/api/v1/auth/users', headers=headers) as resp:
504
577
  self.eq(origin, resp.headers.get('Access-Control-Allow-Origin'))
505
- self.eq(204, resp.status)
578
+ self.eq(resp.status, http.HTTPStatus.NO_CONTENT)
506
579
 
507
580
  # use the authenticated session to do stuff...
508
581
  async with sess.get(f'https://localhost:{port}/api/v1/auth/users') as resp:
582
+ self.eq(resp.status, http.HTTPStatus.OK)
509
583
  retn = await resp.json()
510
584
  self.eq('ok', retn.get('status'))
511
585
 
512
586
  info = {'rules': ()}
513
587
  async with sess.post(f'https://localhost:{port}/api/v1/auth/user/{visiiden}', json=info) as resp:
588
+ self.eq(resp.status, http.HTTPStatus.OK)
514
589
  retn = await resp.json()
515
590
  self.eq('ok', retn.get('status'))
516
591
 
517
592
  info = {'locked': True, 'name': 'derpderp', 'email': 'noob@derp.com'}
518
593
  async with sess.post(f'https://localhost:{port}/api/v1/auth/user/{noobiden}', json=info) as resp:
594
+ self.eq(resp.status, http.HTTPStatus.OK)
519
595
  retn = await resp.json()
520
596
  self.eq('ok', retn.get('status'))
521
597
  self.eq(True, retn['result']['locked'])
@@ -531,6 +607,7 @@ class HttpApiTest(s_tests.SynTest):
531
607
 
532
608
  info = {'locked': False}
533
609
  async with sess.post(f'https://localhost:{port}/api/v1/auth/user/{noobiden}', json=info) as resp:
610
+ self.eq(resp.status, http.HTTPStatus.OK)
534
611
  retn = await resp.json()
535
612
  self.eq('ok', retn.get('status'))
536
613
  self.false(retn['result']['locked'])
@@ -539,48 +616,59 @@ class HttpApiTest(s_tests.SynTest):
539
616
 
540
617
  info = {'rules': ()}
541
618
  async with sess.post(f'https://localhost:{port}/api/v1/auth/role/{analystiden}', json=info) as resp:
619
+ self.eq(resp.status, http.HTTPStatus.OK)
542
620
  retn = await resp.json()
543
621
  self.eq('ok', retn.get('status'))
544
622
 
545
623
  async with sess.post(f'https://localhost:{port}/api/v1/auth/adduser', json={}) as resp:
624
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
546
625
  item = await resp.json()
547
626
  self.eq('MissingField', item.get('code'))
548
627
 
549
628
  async with sess.post(f'https://localhost:{port}/api/v1/auth/addrole', json={}) as resp:
629
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
550
630
  item = await resp.json()
551
631
  self.eq('MissingField', item.get('code'))
552
632
 
553
633
  async with sess.post(f'https://localhost:{port}/api/v1/auth/adduser', data=b'asdf') as resp:
634
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
554
635
  item = await resp.json()
555
636
  self.eq('SchemaViolation', item.get('code'))
556
637
 
557
638
  async with sess.post(f'https://localhost:{port}/api/v1/auth/addrole', data=b'asdf') as resp:
639
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
558
640
  item = await resp.json()
559
641
  self.eq('SchemaViolation', item.get('code'))
560
642
 
561
643
  async with sess.post(f'https://localhost:{port}/api/v1/auth/grant', data=b'asdf') as resp:
644
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
562
645
  item = await resp.json()
563
646
  self.eq('SchemaViolation', item.get('code'))
564
647
 
565
648
  async with sess.post(f'https://localhost:{port}/api/v1/auth/revoke', data=b'asdf') as resp:
649
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
566
650
  item = await resp.json()
567
651
  self.eq('SchemaViolation', item.get('code'))
568
652
 
569
653
  async with sess.post(f'https://localhost:{port}/api/v1/auth/user/{visiiden}', data=b'asdf') as resp:
654
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
570
655
  item = await resp.json()
571
656
  self.eq('SchemaViolation', item.get('code'))
572
657
 
573
658
  async with sess.post(f'https://localhost:{port}/api/v1/auth/role/{analystiden}', data=b'asdf') as resp:
659
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
574
660
  item = await resp.json()
575
661
  self.eq('SchemaViolation', item.get('code'))
576
662
 
577
663
  async with sess.get(f'https://localhost:{port}/api/v1/storm/nodes', data=b'asdf') as resp:
664
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
578
665
  item = await resp.json()
579
666
  self.eq('SchemaViolation', item.get('code'))
580
667
 
581
668
  rules = [(True, ('node', 'add',))]
582
669
  info = {'name': 'derpuser', 'passwd': 'derpuser', 'rules': rules}
583
670
  async with sess.post(f'https://localhost:{port}/api/v1/auth/adduser', json=info) as resp:
671
+ self.eq(resp.status, http.HTTPStatus.OK)
584
672
  retn = await resp.json()
585
673
  self.eq('ok', retn.get('status'))
586
674
  user = retn.get('result')
@@ -591,6 +679,7 @@ class HttpApiTest(s_tests.SynTest):
591
679
 
592
680
  info = {'admin': True}
593
681
  async with sess.post(f'https://localhost:{port}/api/v1/auth/user/{derpiden}', json=info) as resp:
682
+ self.eq(resp.status, http.HTTPStatus.OK)
594
683
  retn = await resp.json()
595
684
  self.eq('ok', retn.get('status'))
596
685
  user = retn.get('result')
@@ -598,48 +687,63 @@ class HttpApiTest(s_tests.SynTest):
598
687
 
599
688
  info = {'admin': False}
600
689
  async with sess.post(f'https://localhost:{port}/api/v1/auth/user/{derpiden}', json=info) as resp:
690
+ self.eq(resp.status, http.HTTPStatus.OK)
601
691
  retn = await resp.json()
602
692
  self.eq('ok', retn.get('status'))
603
693
  user = retn.get('result')
604
694
  self.false(user.get('admin'))
605
695
 
696
+ async with sess.post(f'https://localhost:{port}/api/v1/auth/user/{s_common.guid()}', json=info) as resp:
697
+ self.eq(resp.status, http.HTTPStatus.NOT_FOUND)
698
+ retn = await resp.json()
699
+ self.eq('err', retn.get('status'))
700
+ self.eq('NoSuchUser', retn.get('code'))
701
+
606
702
  # test some auth but not admin paths
607
703
  async with self.getHttpSess() as sess:
608
704
 
609
705
  async with sess.post(f'https://localhost:{port}/api/v1/login', data=b'asdf') as resp:
706
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
610
707
  retn = await resp.json()
611
708
  self.eq('SchemaViolation', retn.get('code'))
612
709
 
613
710
  async with sess.post(f'https://localhost:{port}/api/v1/login',
614
711
  json={'user': 'derpuser', 'passwd': 'derpuser'}) as resp:
712
+ self.eq(resp.status, http.HTTPStatus.OK)
615
713
  retn = await resp.json()
616
714
  self.eq('ok', retn.get('status'))
617
715
  self.eq('derpuser', retn['result']['name'])
618
716
 
619
717
  info = {'admin': True}
620
718
  async with sess.post(f'https://localhost:{port}/api/v1/auth/user/{derpiden}', json=info) as resp:
719
+ self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
621
720
  retn = await resp.json()
622
721
  self.eq('AuthDeny', retn.get('code'))
623
722
 
624
723
  info = {'rules': ()}
625
724
  async with sess.post(f'https://localhost:{port}/api/v1/auth/role/{analystiden}', json=info) as resp:
725
+ self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
626
726
  retn = await resp.json()
627
727
  self.eq('AuthDeny', retn.get('code'))
628
728
 
629
729
  async with sess.post(f'https://localhost:{port}/api/v1/auth/grant', json={}) as resp:
730
+ self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
630
731
  retn = await resp.json()
631
732
  self.eq('AuthDeny', retn.get('code'))
632
733
 
633
734
  async with sess.post(f'https://localhost:{port}/api/v1/auth/revoke', json={}) as resp:
735
+ self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
634
736
  retn = await resp.json()
635
737
  self.eq('AuthDeny', retn.get('code'))
636
738
 
637
739
  async with sess.post(f'https://localhost:{port}/api/v1/auth/adduser', json={}) as resp:
740
+ self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
638
741
  retn = await resp.json()
639
742
  self.eq('AuthDeny', retn.get('code'))
640
743
 
641
744
  async with sess.post(f'https://localhost:{port}/api/v1/auth/addrole', json={}) as resp:
642
745
  retn = await resp.json()
746
+ self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
643
747
  self.eq('AuthDeny', retn.get('code'))
644
748
 
645
749
  async def test_http_impersonate(self):
@@ -649,6 +753,7 @@ class HttpApiTest(s_tests.SynTest):
649
753
  host, port = await core.addHttpsPort(0, host='127.0.0.1')
650
754
 
651
755
  visi = await core.auth.addUser('visi')
756
+ newpuser = s_common.guid()
652
757
 
653
758
  await visi.setPasswd('secret')
654
759
  await visi.addRule((True, ('impersonate',)))
@@ -665,6 +770,7 @@ class HttpApiTest(s_tests.SynTest):
665
770
 
666
771
  podes = []
667
772
  async with sess.get(f'https://localhost:{port}/api/v1/storm/nodes', json=data) as resp:
773
+ self.eq(resp.status, http.HTTPStatus.OK)
668
774
 
669
775
  async for byts, x in resp.content.iter_chunks():
670
776
 
@@ -675,11 +781,19 @@ class HttpApiTest(s_tests.SynTest):
675
781
 
676
782
  self.eq(podes[0][0], ('inet:ipv4', 0x01020304))
677
783
 
784
+ # NoSuchUser precondition failure
785
+ data = {'query': '.created', 'opts': {'user': newpuser}}
786
+ async with sess.get(f'https://localhost:{port}/api/v1/storm/nodes', json=data) as resp:
787
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
788
+ data = await resp.json()
789
+ self.eq(data, {'status': 'err', 'code': 'NoSuchUser',
790
+ 'mesg': f'No user found with iden: {newpuser}'})
791
+
678
792
  msgs = []
679
793
  data = {'query': '[ inet:ipv4=5.5.5.5 ]', 'opts': opts}
680
794
 
681
795
  async with sess.get(f'https://localhost:{port}/api/v1/storm', json=data) as resp:
682
-
796
+ self.eq(resp.status, http.HTTPStatus.OK)
683
797
  async for byts, x in resp.content.iter_chunks():
684
798
 
685
799
  if not byts:
@@ -689,6 +803,14 @@ class HttpApiTest(s_tests.SynTest):
689
803
  podes = [m[1] for m in msgs if m[0] == 'node']
690
804
  self.eq(podes[0][0], ('inet:ipv4', 0x05050505))
691
805
 
806
+ # NoSuchUser precondition failure
807
+ opts['user'] = newpuser
808
+ async with sess.get(f'https://localhost:{port}/api/v1/storm', json=data) as resp:
809
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
810
+ data = await resp.json()
811
+ self.eq(data, {'status': 'err', 'code': 'NoSuchUser',
812
+ 'mesg': f'No user found with iden: {newpuser}'})
813
+
692
814
  async def test_http_coreinfo(self):
693
815
  async with self.getTestCore() as core:
694
816
 
@@ -703,11 +825,13 @@ class HttpApiTest(s_tests.SynTest):
703
825
 
704
826
  async with sess.post(f'https://localhost:{port}/api/v1/login',
705
827
  json={'user': 'visi', 'passwd': 'secret'}) as resp:
828
+ self.eq(resp.status, http.HTTPStatus.OK)
706
829
  retn = await resp.json()
707
830
  self.eq('ok', retn.get('status'))
708
831
  self.eq('visi', retn['result']['name'])
709
832
 
710
833
  async with sess.get(f'https://localhost:{port}/api/v1/core/info') as resp:
834
+ self.eq(resp.status, http.HTTPStatus.OK)
711
835
  retn = await resp.json()
712
836
  self.eq('ok', retn.get('status'))
713
837
  coreinfo = retn.get('result')
@@ -724,6 +848,7 @@ class HttpApiTest(s_tests.SynTest):
724
848
  conn = aiohttp.TCPConnector(ssl=False)
725
849
  async with aiohttp.ClientSession(connector=conn) as sess:
726
850
  async with sess.get(f'https://visi:newp@localhost:{port}/api/v1/core/info') as resp:
851
+ self.eq(resp.status, http.HTTPStatus.UNAUTHORIZED)
727
852
  retn = await resp.json()
728
853
  self.eq('err', retn.get('status'))
729
854
 
@@ -762,6 +887,7 @@ class HttpApiTest(s_tests.SynTest):
762
887
  # Norm via GET
763
888
  body = {'prop': 'inet:ipv4', 'value': '1.2.3.4'}
764
889
  async with sess.get(f'https://localhost:{port}/api/v1/model/norm', json=body) as resp:
890
+ self.eq(resp.status, http.HTTPStatus.OK)
765
891
  retn = await resp.json()
766
892
  self.eq('ok', retn.get('status'))
767
893
  self.eq(0x01020304, retn['result']['norm'])
@@ -769,16 +895,25 @@ class HttpApiTest(s_tests.SynTest):
769
895
 
770
896
  body = {'prop': 'fake:prop', 'value': '1.2.3.4'}
771
897
  async with sess.get(f'https://localhost:{port}/api/v1/model/norm', json=body) as resp:
898
+ self.eq(resp.status, http.HTTPStatus.NOT_FOUND)
772
899
  retn = await resp.json()
773
900
  self.eq('NoSuchProp', retn.get('code'))
774
901
 
902
+ body = {'prop': 'test:int', 'value': 'newp'}
903
+ async with sess.get(f'https://localhost:{port}/api/v1/model/norm', json=body) as resp:
904
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
905
+ retn = await resp.json()
906
+ self.eq('BadTypeValu', retn.get('code'))
907
+
775
908
  body = {'value': '1.2.3.4'}
776
909
  async with sess.get(f'https://localhost:{port}/api/v1/model/norm', json=body) as resp:
910
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
777
911
  retn = await resp.json()
778
912
  self.eq('MissingField', retn.get('code'))
779
913
 
780
914
  body = {'prop': 'test:comp', 'value': '3^foobar', 'typeopts': {'sepr': '^'}}
781
915
  async with sess.get(f'https://localhost:{port}/api/v1/model/norm', json=body) as resp:
916
+ self.eq(resp.status, http.HTTPStatus.OK)
782
917
  retn = await resp.json()
783
918
  self.eq('ok', retn.get('status'))
784
919
  self.eq([3, 'foobar'], retn['result']['norm'])
@@ -786,6 +921,7 @@ class HttpApiTest(s_tests.SynTest):
786
921
  # Norm via POST
787
922
  body = {'prop': 'inet:ipv4', 'value': '1.2.3.4'}
788
923
  async with sess.post(f'https://localhost:{port}/api/v1/model/norm', json=body) as resp:
924
+ self.eq(resp.status, http.HTTPStatus.OK)
789
925
  retn = await resp.json()
790
926
  self.eq('ok', retn.get('status'))
791
927
  self.eq(0x01020304, retn['result']['norm'])
@@ -796,11 +932,13 @@ class HttpApiTest(s_tests.SynTest):
796
932
  async with aiohttp.ClientSession(connector=conn) as sess:
797
933
  async with sess.get(f'https://visi:newp@localhost:{port}/api/v1/model') as resp:
798
934
  retn = await resp.json()
935
+ self.eq(resp.status, http.HTTPStatus.UNAUTHORIZED)
799
936
  self.eq('err', retn.get('status'))
800
937
 
801
938
  body = {'prop': 'inet:ipv4', 'value': '1.2.3.4'}
802
939
  async with sess.get(f'https://visi:newp@localhost:{port}/api/v1/model/norm', json=body) as resp:
803
940
  retn = await resp.json()
941
+ self.eq(resp.status, http.HTTPStatus.UNAUTHORIZED)
804
942
  self.eq('err', retn.get('status'))
805
943
 
806
944
  async def test_http_beholder(self):
@@ -1289,7 +1427,9 @@ class HttpApiTest(s_tests.SynTest):
1289
1427
 
1290
1428
  async with self.getHttpSess(port=port) as sess:
1291
1429
  resp = await sess.post(f'https://localhost:{port}/api/v1/storm')
1292
- self.eq(401, resp.status)
1430
+ self.eq(resp.status, http.HTTPStatus.UNAUTHORIZED)
1431
+ item = await resp.json()
1432
+ self.eq('NotAuthenticated', item.get('code'))
1293
1433
 
1294
1434
  async with self.getHttpSess() as sess:
1295
1435
 
@@ -1300,15 +1440,20 @@ class HttpApiTest(s_tests.SynTest):
1300
1440
 
1301
1441
  body = {'query': 'inet:ipv4', 'opts': {'user': core.auth.rootuser.iden}}
1302
1442
  async with sess.get(f'https://localhost:{port}/api/v1/storm', json=body) as resp:
1303
- self.eq(resp.status, 403)
1443
+ self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
1444
+ item = await resp.json()
1445
+ self.eq('AuthDeny', item.get('code'))
1304
1446
 
1305
1447
  body = {'query': 'inet:ipv4', 'opts': {'user': core.auth.rootuser.iden}}
1306
1448
  async with sess.get(f'https://localhost:{port}/api/v1/storm/nodes', json=body) as resp:
1307
- self.eq(resp.status, 403)
1449
+ self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
1450
+ item = await resp.json()
1451
+ self.eq('AuthDeny', item.get('code'))
1308
1452
 
1309
1453
  await visi.setAdmin(True)
1310
1454
 
1311
1455
  async with sess.get(f'https://localhost:{port}/api/v1/storm', data=b'asdf') as resp:
1456
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
1312
1457
  item = await resp.json()
1313
1458
  self.eq('SchemaViolation', item.get('code'))
1314
1459
 
@@ -1316,7 +1461,7 @@ class HttpApiTest(s_tests.SynTest):
1316
1461
  body = {'query': '[ inet:ipv4=1.2.3.4 ]'}
1317
1462
 
1318
1463
  async with sess.get(f'https://localhost:{port}/api/v1/storm', json=body) as resp:
1319
-
1464
+ self.eq(resp.status, http.HTTPStatus.OK)
1320
1465
  async for byts, x in resp.content.iter_chunks():
1321
1466
 
1322
1467
  if not byts:
@@ -1331,7 +1476,7 @@ class HttpApiTest(s_tests.SynTest):
1331
1476
  self.eq(0x01020304, node[0][1])
1332
1477
 
1333
1478
  async with sess.post(f'https://localhost:{port}/api/v1/storm', json=body) as resp:
1334
-
1479
+ self.eq(resp.status, http.HTTPStatus.OK)
1335
1480
  async for byts, x in resp.content.iter_chunks():
1336
1481
 
1337
1482
  if not byts:
@@ -1348,7 +1493,7 @@ class HttpApiTest(s_tests.SynTest):
1348
1493
  body = {'query': '[ inet:ipv4=1.2.3.4 ]'}
1349
1494
 
1350
1495
  async with sess.get(f'https://localhost:{port}/api/v1/storm/nodes', json=body) as resp:
1351
-
1496
+ self.eq(resp.status, http.HTTPStatus.OK)
1352
1497
  async for byts, x in resp.content.iter_chunks():
1353
1498
 
1354
1499
  if not byts:
@@ -1359,7 +1504,7 @@ class HttpApiTest(s_tests.SynTest):
1359
1504
  self.eq(0x01020304, node[0][1])
1360
1505
 
1361
1506
  async with sess.post(f'https://localhost:{port}/api/v1/storm/nodes', json=body) as resp:
1362
-
1507
+ self.eq(resp.status, http.HTTPStatus.OK)
1363
1508
  async for byts, x in resp.content.iter_chunks():
1364
1509
 
1365
1510
  if not byts:
@@ -1372,6 +1517,7 @@ class HttpApiTest(s_tests.SynTest):
1372
1517
  body['stream'] = 'jsonlines'
1373
1518
 
1374
1519
  async with sess.get(f'https://localhost:{port}/api/v1/storm/nodes', json=body) as resp:
1520
+ self.eq(resp.status, http.HTTPStatus.OK)
1375
1521
  bufr = b''
1376
1522
  async for byts, x in resp.content.iter_chunks():
1377
1523
 
@@ -1393,7 +1539,7 @@ class HttpApiTest(s_tests.SynTest):
1393
1539
  self.eq(0x01020304, node[0][1])
1394
1540
 
1395
1541
  async with sess.post(f'https://localhost:{port}/api/v1/storm', json=body) as resp:
1396
-
1542
+ self.eq(resp.status, http.HTTPStatus.OK)
1397
1543
  bufr = b''
1398
1544
  async for byts, x in resp.content.iter_chunks():
1399
1545
 
@@ -1421,7 +1567,7 @@ class HttpApiTest(s_tests.SynTest):
1421
1567
  body = {'query': '.created | sleep 10'}
1422
1568
  task = None
1423
1569
  async with sess.get(f'https://localhost:{port}/api/v1/storm', json=body) as resp:
1424
-
1570
+ self.eq(resp.status, http.HTTPStatus.OK)
1425
1571
  async for byts, x in resp.content.iter_chunks():
1426
1572
 
1427
1573
  if not byts:
@@ -1439,7 +1585,7 @@ class HttpApiTest(s_tests.SynTest):
1439
1585
 
1440
1586
  task = None
1441
1587
  async with sess.get(f'https://localhost:{port}/api/v1/storm/nodes', json=body) as resp:
1442
-
1588
+ self.eq(resp.status, http.HTTPStatus.OK)
1443
1589
  async for byts, x in resp.content.iter_chunks():
1444
1590
 
1445
1591
  if not byts:
@@ -1454,6 +1600,21 @@ class HttpApiTest(s_tests.SynTest):
1454
1600
  self.true(await task.waitfini(6))
1455
1601
  self.len(0, core.boss.tasks)
1456
1602
 
1603
+ fork = await core.callStorm('return($lib.view.get().fork().iden)')
1604
+ lowuser = await core.auth.addUser('lowuser')
1605
+
1606
+ async with sess.get(f'https://localhost:{port}/api/v1/storm/nodes',
1607
+ json={'query': '.created', 'opts': {'view': s_common.guid()}}) as resp:
1608
+ self.eq(resp.status, http.HTTPStatus.NOT_FOUND)
1609
+
1610
+ async with sess.get(f'https://localhost:{port}/api/v1/storm',
1611
+ json={'query': '.created', 'opts': {'view': s_common.guid()}}) as resp:
1612
+ self.eq(resp.status, http.HTTPStatus.NOT_FOUND)
1613
+
1614
+ async with sess.get(f'https://localhost:{port}/api/v1/storm',
1615
+ json={'query': '.created', 'opts': {'user': lowuser.iden, 'view': fork}}) as resp:
1616
+ self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
1617
+
1457
1618
  # check reqvalidstorm with various queries
1458
1619
  tvs = (
1459
1620
  ('test:str=test', {}, 'ok'),
@@ -1467,13 +1628,17 @@ class HttpApiTest(s_tests.SynTest):
1467
1628
  for (query, opts, rcode) in tvs:
1468
1629
  body = {'query': query, 'opts': opts}
1469
1630
  async with sess.post(url, json=body) as resp:
1470
- if resp.status == 200:
1471
- data = await resp.json()
1472
- self.eq(data.get('status'), rcode)
1631
+ if rcode == 'ok':
1632
+ self.eq(resp.status, http.HTTPStatus.OK)
1633
+ else:
1634
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
1635
+ data = await resp.json()
1636
+ self.eq(data.get('status'), rcode)
1473
1637
  # Sad path
1474
1638
  async with aiohttp.client.ClientSession() as bad_sess:
1475
1639
  async with bad_sess.post(url, ssl=False) as resp:
1476
1640
  data = await resp.json()
1641
+ self.eq(resp.status, http.HTTPStatus.UNAUTHORIZED)
1477
1642
  self.eq(data.get('status'), 'err')
1478
1643
  self.eq(data.get('code'), 'NotAuthenticated')
1479
1644
 
@@ -1526,6 +1691,7 @@ class HttpApiTest(s_tests.SynTest):
1526
1691
 
1527
1692
  url = f'https://localhost:{port}/api/v1/active'
1528
1693
  async with sess.get(url) as resp:
1694
+ self.eq(resp.status, http.HTTPStatus.OK)
1529
1695
  self.none(resp.headers.get('server'))
1530
1696
  self.eq('wootwoot!', resp.headers.get('x-hehe-haha'))
1531
1697
  result = await resp.json()
@@ -1538,6 +1704,7 @@ class HttpApiTest(s_tests.SynTest):
1538
1704
  url = f'https://localhost:{port}/api/v1/healthcheck'
1539
1705
  async with self.getHttpSess(auth=('root', 'secret'), port=port) as sess:
1540
1706
  async with sess.get(url) as resp:
1707
+ self.eq(resp.status, http.HTTPStatus.OK)
1541
1708
  result = await resp.json()
1542
1709
  self.eq(result.get('status'), 'ok')
1543
1710
  snfo = result.get('result')
@@ -1548,10 +1715,12 @@ class HttpApiTest(s_tests.SynTest):
1548
1715
  await user.setPasswd('beep')
1549
1716
  async with self.getHttpSess(auth=('user', 'beep'), port=port) as sess:
1550
1717
  async with sess.get(url) as resp:
1718
+ self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
1551
1719
  result = await resp.json()
1552
1720
  self.eq(result.get('status'), 'err')
1553
1721
  await user.addRule((True, ('health',)))
1554
1722
  async with sess.get(url) as resp:
1723
+ self.eq(resp.status, http.HTTPStatus.OK)
1555
1724
  result = await resp.json()
1556
1725
  self.eq(result.get('status'), 'ok')
1557
1726
 
@@ -1594,42 +1763,52 @@ class HttpApiTest(s_tests.SynTest):
1594
1763
  async with self.getHttpSess(auth=('root', 'secret'), port=port) as sess:
1595
1764
 
1596
1765
  resp = await sess.post(f'https://localhost:{port}/api/v1/storm/vars/set')
1766
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
1597
1767
  self.eq('SchemaViolation', (await resp.json())['code'])
1598
1768
 
1599
1769
  resp = await sess.get(f'https://localhost:{port}/api/v1/storm/vars/get')
1770
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
1600
1771
  self.eq('SchemaViolation', (await resp.json())['code'])
1601
1772
 
1602
1773
  resp = await sess.post(f'https://localhost:{port}/api/v1/storm/vars/pop')
1774
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
1603
1775
  self.eq('SchemaViolation', (await resp.json())['code'])
1604
1776
 
1605
1777
  body = {'name': 'hehe'}
1606
1778
  resp = await sess.post(f'https://localhost:{port}/api/v1/storm/vars/set', json=body)
1779
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
1607
1780
  self.eq('BadArg', (await resp.json())['code'])
1608
1781
 
1609
1782
  body = {'name': 'hehe', 'value': 'haha'}
1610
1783
  resp = await sess.post(f'https://localhost:{port}/api/v1/storm/vars/set', json=body)
1784
+ self.eq(resp.status, http.HTTPStatus.OK)
1611
1785
  self.eq({'status': 'ok', 'result': True}, await resp.json())
1612
1786
 
1613
1787
  body = {'name': 'hehe', 'default': 'lolz'}
1614
1788
  resp = await sess.get(f'https://localhost:{port}/api/v1/storm/vars/get', json=body)
1789
+ self.eq(resp.status, http.HTTPStatus.OK)
1615
1790
  self.eq({'status': 'ok', 'result': 'haha'}, await resp.json())
1616
1791
 
1617
1792
  body = {'name': 'hehe', 'default': 'lolz'}
1618
1793
  resp = await sess.post(f'https://localhost:{port}/api/v1/storm/vars/pop', json=body)
1794
+ self.eq(resp.status, http.HTTPStatus.OK)
1619
1795
  self.eq({'status': 'ok', 'result': 'haha'}, await resp.json())
1620
1796
 
1621
1797
  async with self.getHttpSess(auth=('visi', 'secret'), port=port) as sess:
1622
1798
 
1623
1799
  body = {'name': 'hehe', 'value': 'haha'}
1624
1800
  resp = await sess.post(f'https://localhost:{port}/api/v1/storm/vars/set', json=body)
1801
+ self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
1625
1802
  self.eq('AuthDeny', (await resp.json())['code'])
1626
1803
 
1627
1804
  body = {'name': 'hehe', 'default': 'lolz'}
1628
1805
  resp = await sess.get(f'https://localhost:{port}/api/v1/storm/vars/get', json=body)
1806
+ self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
1629
1807
  self.eq('AuthDeny', (await resp.json())['code'])
1630
1808
 
1631
1809
  body = {'name': 'hehe', 'default': 'lolz'}
1632
1810
  resp = await sess.post(f'https://localhost:{port}/api/v1/storm/vars/pop', json=body)
1811
+ self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
1633
1812
  self.eq('AuthDeny', (await resp.json())['code'])
1634
1813
 
1635
1814
  async def test_http_feed(self):
@@ -1651,24 +1830,29 @@ class HttpApiTest(s_tests.SynTest):
1651
1830
 
1652
1831
  async with self.getHttpSess(auth=('root', 'secret'), port=port) as sess:
1653
1832
  resp = await sess.post(f'https://localhost:{port}/api/v1/feed')
1833
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
1654
1834
  self.eq('SchemaViolation', (await resp.json())['code'])
1655
1835
 
1656
1836
  body = {'view': 'asdf'}
1657
1837
  resp = await sess.post(f'https://localhost:{port}/api/v1/feed', json=body)
1838
+ self.eq(resp.status, http.HTTPStatus.NOT_FOUND)
1658
1839
  self.eq('NoSuchView', (await resp.json())['code'])
1659
1840
 
1660
1841
  body = {'name': 'asdf'}
1661
1842
  resp = await sess.post(f'https://localhost:{port}/api/v1/feed', json=body)
1843
+ self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
1662
1844
  self.eq('NoSuchFunc', (await resp.json())['code'])
1663
1845
 
1664
1846
  body = {'items': [(('inet:ipv4', 0x05050505), {'tags': {'hehe': (None, None)}})]}
1665
1847
  resp = await sess.post(f'https://localhost:{port}/api/v1/feed', json=body)
1848
+ self.eq(resp.status, http.HTTPStatus.OK)
1666
1849
  self.eq('ok', (await resp.json())['status'])
1667
1850
  self.len(1, await core.nodes('inet:ipv4=5.5.5.5 +#hehe'))
1668
1851
 
1669
1852
  async with self.getHttpSess(auth=('visi', 'secret'), port=port) as sess:
1670
1853
  body = {'items': [(('inet:ipv4', 0x01020304), {})]}
1671
1854
  resp = await sess.post(f'https://localhost:{port}/api/v1/feed', json=body)
1855
+ self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
1672
1856
  self.eq('AuthDeny', (await resp.json())['code'])
1673
1857
  self.len(0, await core.nodes('inet:ipv4=1.2.3.4'))
1674
1858
 
@@ -1753,7 +1937,7 @@ class HttpApiTest(s_tests.SynTest):
1753
1937
  item = await resp.json()
1754
1938
  self.nn(item.get('result').get('iden'))
1755
1939
  visiiden = item['result']['iden']
1756
- self.eq(resp.status, 200)
1940
+ self.eq(resp.status, http.HTTPStatus.OK)
1757
1941
  self.true(await stream.wait(6))
1758
1942
 
1759
1943
  mesg = get_mesg(stream)
@@ -1770,7 +1954,7 @@ class HttpApiTest(s_tests.SynTest):
1770
1954
  # No auth provided
1771
1955
  with self.getStructuredAsyncLoggerStream(logname, 'api/v1/active') as stream:
1772
1956
  async with sess.get(f'https://root:root@localhost:{port}/api/v1/active', skip_auto_headers=['User-Agent']) as resp:
1773
- self.eq(resp.status, 200)
1957
+ self.eq(resp.status, http.HTTPStatus.OK)
1774
1958
  self.true(await stream.wait(6))
1775
1959
 
1776
1960
  mesg = get_mesg(stream)
@@ -1787,7 +1971,7 @@ class HttpApiTest(s_tests.SynTest):
1787
1971
  # api/v1/login populates the data
1788
1972
  with self.getStructuredAsyncLoggerStream(logname, 'api/v1/login') as stream:
1789
1973
  async with sess.post(f'https://localhost:{port}/api/v1/login', json={'user': 'visi', 'passwd': 'secret'}) as resp:
1790
- self.eq(resp.status, 200)
1974
+ self.eq(resp.status, http.HTTPStatus.OK)
1791
1975
  self.true(await stream.wait(6))
1792
1976
 
1793
1977
  mesg = get_mesg(stream)
@@ -1798,7 +1982,7 @@ class HttpApiTest(s_tests.SynTest):
1798
1982
  # session cookie loging populates the data upon reuse
1799
1983
  with self.getStructuredAsyncLoggerStream(logname, 'api/v1/auth/users') as stream:
1800
1984
  async with sess.get(f'https://localhost:{port}/api/v1/auth/users') as resp:
1801
- self.eq(resp.status, 200)
1985
+ self.eq(resp.status, http.HTTPStatus.OK)
1802
1986
  self.true(await stream.wait(6))
1803
1987
 
1804
1988
  mesg = get_mesg(stream)
@@ -1827,7 +2011,7 @@ class HttpApiTest(s_tests.SynTest):
1827
2011
  json=info, headers={'X-Forwarded-For': '1.2.3.4'}) as resp:
1828
2012
  item = await resp.json()
1829
2013
  self.nn(item.get('result').get('iden'))
1830
- self.eq(resp.status, 200)
2014
+ self.eq(resp.status, http.HTTPStatus.OK)
1831
2015
  self.true(await stream.wait(6))
1832
2016
 
1833
2017
  mesg = get_mesg(stream)
@@ -1845,7 +2029,7 @@ class HttpApiTest(s_tests.SynTest):
1845
2029
  json=info, headers={'X-Real-Ip': '8.8.8.8'}) as resp:
1846
2030
  item = await resp.json()
1847
2031
  self.nn(item.get('result').get('iden'))
1848
- self.eq(resp.status, 200)
2032
+ self.eq(resp.status, http.HTTPStatus.OK)
1849
2033
  self.true(await stream.wait(6))
1850
2034
 
1851
2035
  mesg = get_mesg(stream)
@@ -1930,15 +2114,18 @@ class HttpApiTest(s_tests.SynTest):
1930
2114
  return
1931
2115
 
1932
2116
  throw = bool(int(self.request.headers.get('throw', 0)))
2117
+ code = int(self.request.headers.get('code', 200))
1933
2118
 
1934
2119
  if throw:
1935
2120
  vals = {'hehe': 'haha', 'omg': {'hehe', 'haha'}}
2121
+ code = None
1936
2122
  else:
1937
2123
  vals = {'now': s_common.now(), 'lastip': self.request.connection.context.remote_ip}
1938
2124
 
1939
2125
  await self._web_sess.update(vals)
1940
2126
 
1941
- self.sendRestRetn({'iden': s_common.ehex(self._web_sess.iden), 'info': self._web_sess.info})
2127
+ self.sendRestRetn({'iden': s_common.ehex(self._web_sess.iden), 'info': self._web_sess.info},
2128
+ status_code=code)
1942
2129
  return
1943
2130
 
1944
2131
  async with self.getTestCore() as core:
@@ -1958,7 +2145,7 @@ class HttpApiTest(s_tests.SynTest):
1958
2145
  self.eq('ok', item.get('status'))
1959
2146
 
1960
2147
  async with sess.get(url) as resp:
1961
- self.eq(resp.status, 200)
2148
+ self.eq(resp.status, http.HTTPStatus.OK)
1962
2149
  data = await resp.json()
1963
2150
  result = data.get('result')
1964
2151
  iden = s_common.uhex(result.get('iden'))
@@ -1972,11 +2159,15 @@ class HttpApiTest(s_tests.SynTest):
1972
2159
  self.eq(cell_sess.info, result.get('info'))
1973
2160
 
1974
2161
  async with sess.get(url, headers={'throw': '1'}) as resp:
1975
- self.eq(resp.status, 500)
2162
+ self.eq(resp.status, http.HTTPStatus.INTERNAL_SERVER_ERROR)
1976
2163
 
1977
2164
  # No change with the bad data
1978
2165
  self.eq(cell_sess.info, result.get('info'))
1979
2166
 
2167
+ # Coverage for sendRestRetn status_code
2168
+ async with sess.get(url, headers={'code': '418'}) as resp:
2169
+ self.eq(resp.status, http.HTTPStatus.IM_A_TEAPOT)
2170
+
1980
2171
  async def test_http_locked_admin(self):
1981
2172
  async with self.getTestCore() as core:
1982
2173
 
@@ -1989,10 +2180,10 @@ class HttpApiTest(s_tests.SynTest):
1989
2180
 
1990
2181
  async with self.getHttpSess() as sess:
1991
2182
  resp = await sess.post(f'{root}/api/v1/login', json={'user': 'visi', 'passwd': 'secret123'})
1992
- self.eq(resp.status, 200)
2183
+ self.eq(resp.status, http.HTTPStatus.OK)
1993
2184
 
1994
2185
  resp = await sess.get(f'{root}/api/v1/auth/users')
1995
- self.eq(resp.status, 200)
2186
+ self.eq(resp.status, http.HTTPStatus.OK)
1996
2187
 
1997
2188
  data = {'query': '[ inet:ipv4=1.2.3.4 ]', 'opts': {'user': visi.iden}}
1998
2189
  async with sess.get(f'{root}/api/v1/storm/call', json=data) as resp:
@@ -2005,16 +2196,17 @@ class HttpApiTest(s_tests.SynTest):
2005
2196
  self.true(await stream.wait(timeout=2))
2006
2197
 
2007
2198
  resp = await sess.get(f'{root}/api/v1/auth/users')
2008
- self.eq(resp.status, 401)
2199
+ self.eq(resp.status, http.HTTPStatus.UNAUTHORIZED)
2009
2200
 
2010
2201
  data = {'query': '[ inet:ipv4=5.6.7.8 ]', 'opts': {'user': visi.iden}}
2011
2202
  async with sess.get(f'{root}/api/v1/storm/call', json=data) as resp:
2012
2203
  item = await resp.json()
2204
+ self.eq(resp.status, http.HTTPStatus.UNAUTHORIZED)
2013
2205
  self.eq('err', item.get('status'))
2014
2206
  self.eq('NotAuthenticated', item.get('code'))
2015
2207
 
2016
2208
  resp = await sess.post(f'{root}/api/v1/login', json={'user': 'visi', 'passwd': 'secret123'})
2017
- self.eq(resp.status, 200)
2209
+ self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
2018
2210
  retn = await resp.json()
2019
2211
  self.eq(retn.get('status'), 'err')
2020
2212
  self.eq(retn.get('code'), 'AuthDeny')