Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81146 views
1
// Load modules
2
3
var Http = require('http');
4
var Url = require('url');
5
var Code = require('code');
6
var Hawk = require('../lib');
7
var Hoek = require('hoek');
8
var Lab = require('lab');
9
10
11
// Declare internals
12
13
var internals = {};
14
15
16
// Test shortcuts
17
18
var lab = exports.lab = Lab.script();
19
var describe = lab.experiment;
20
var it = lab.test;
21
var expect = Code.expect;
22
23
24
describe('Hawk', function () {
25
26
describe('Uri', function () {
27
28
var credentialsFunc = function (id, callback) {
29
30
var credentials = {
31
id: id,
32
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
33
algorithm: 'sha256',
34
user: 'steve'
35
};
36
37
return callback(null, credentials);
38
};
39
40
it('should generate a bewit then successfully authenticate it', function (done) {
41
42
var req = {
43
method: 'GET',
44
url: '/resource/4?a=1&b=2',
45
host: 'example.com',
46
port: 80
47
};
48
49
credentialsFunc('123456', function (err, credentials) {
50
51
var bewit = Hawk.uri.getBewit('http://example.com/resource/4?a=1&b=2', { credentials: credentials, ttlSec: 60 * 60 * 24 * 365 * 100, ext: 'some-app-data' });
52
req.url += '&bewit=' + bewit;
53
54
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
55
56
expect(err).to.not.exist();
57
expect(credentials.user).to.equal('steve');
58
expect(attributes.ext).to.equal('some-app-data');
59
done();
60
});
61
});
62
});
63
64
it('should generate a bewit then successfully authenticate it (no ext)', function (done) {
65
66
var req = {
67
method: 'GET',
68
url: '/resource/4?a=1&b=2',
69
host: 'example.com',
70
port: 80
71
};
72
73
credentialsFunc('123456', function (err, credentials) {
74
75
var bewit = Hawk.uri.getBewit('http://example.com/resource/4?a=1&b=2', { credentials: credentials, ttlSec: 60 * 60 * 24 * 365 * 100 });
76
req.url += '&bewit=' + bewit;
77
78
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
79
80
expect(err).to.not.exist();
81
expect(credentials.user).to.equal('steve');
82
done();
83
});
84
});
85
});
86
87
it('should successfully authenticate a request (last param)', function (done) {
88
89
var req = {
90
method: 'GET',
91
url: '/resource/4?a=1&b=2&bewit=MTIzNDU2XDQ1MTE0ODQ2MjFcMzFjMmNkbUJFd1NJRVZDOVkva1NFb2c3d3YrdEVNWjZ3RXNmOGNHU2FXQT1cc29tZS1hcHAtZGF0YQ',
92
host: 'example.com',
93
port: 8080
94
};
95
96
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
97
98
expect(err).to.not.exist();
99
expect(credentials.user).to.equal('steve');
100
expect(attributes.ext).to.equal('some-app-data');
101
done();
102
});
103
});
104
105
it('should successfully authenticate a request (first param)', function (done) {
106
107
var req = {
108
method: 'GET',
109
url: '/resource/4?bewit=MTIzNDU2XDQ1MTE0ODQ2MjFcMzFjMmNkbUJFd1NJRVZDOVkva1NFb2c3d3YrdEVNWjZ3RXNmOGNHU2FXQT1cc29tZS1hcHAtZGF0YQ&a=1&b=2',
110
host: 'example.com',
111
port: 8080
112
};
113
114
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
115
116
expect(err).to.not.exist();
117
expect(credentials.user).to.equal('steve');
118
expect(attributes.ext).to.equal('some-app-data');
119
done();
120
});
121
});
122
123
it('should successfully authenticate a request (only param)', function (done) {
124
125
var req = {
126
method: 'GET',
127
url: '/resource/4?bewit=MTIzNDU2XDQ1MTE0ODQ2NDFcZm1CdkNWT3MvcElOTUUxSTIwbWhrejQ3UnBwTmo4Y1VrSHpQd3Q5OXJ1cz1cc29tZS1hcHAtZGF0YQ',
128
host: 'example.com',
129
port: 8080
130
};
131
132
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
133
134
expect(err).to.not.exist();
135
expect(credentials.user).to.equal('steve');
136
expect(attributes.ext).to.equal('some-app-data');
137
done();
138
});
139
});
140
141
it('should fail on multiple authentication', function (done) {
142
143
var req = {
144
method: 'GET',
145
url: '/resource/4?bewit=MTIzNDU2XDQ1MTE0ODQ2NDFcZm1CdkNWT3MvcElOTUUxSTIwbWhrejQ3UnBwTmo4Y1VrSHpQd3Q5OXJ1cz1cc29tZS1hcHAtZGF0YQ',
146
host: 'example.com',
147
port: 8080,
148
authorization: 'Basic asdasdasdasd'
149
};
150
151
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
152
153
expect(err).to.exist();
154
expect(err.output.payload.message).to.equal('Multiple authentications');
155
done();
156
});
157
});
158
159
it('should fail on method other than GET', function (done) {
160
161
credentialsFunc('123456', function (err, credentials) {
162
163
var req = {
164
method: 'POST',
165
url: '/resource/4?filter=a',
166
host: 'example.com',
167
port: 8080
168
};
169
170
var exp = Math.floor(Hawk.utils.now() / 1000) + 60;
171
var ext = 'some-app-data';
172
var mac = Hawk.crypto.calculateMac('bewit', credentials, {
173
timestamp: exp,
174
nonce: '',
175
method: req.method,
176
resource: req.url,
177
host: req.host,
178
port: req.port,
179
ext: ext
180
});
181
182
var bewit = credentials.id + '\\' + exp + '\\' + mac + '\\' + ext;
183
184
req.url += '&bewit=' + Hoek.base64urlEncode(bewit);
185
186
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
187
188
expect(err).to.exist();
189
expect(err.output.payload.message).to.equal('Invalid method');
190
done();
191
});
192
});
193
});
194
195
it('should fail on invalid host header', function (done) {
196
197
var req = {
198
method: 'GET',
199
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ',
200
headers: {
201
host: 'example.com:something'
202
}
203
};
204
205
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
206
207
expect(err).to.exist();
208
expect(err.output.payload.message).to.equal('Invalid Host header');
209
done();
210
});
211
});
212
213
it('should fail on empty bewit', function (done) {
214
215
var req = {
216
method: 'GET',
217
url: '/resource/4?bewit=',
218
host: 'example.com',
219
port: 8080
220
};
221
222
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
223
224
expect(err).to.exist();
225
expect(err.output.payload.message).to.equal('Empty bewit');
226
expect(err.isMissing).to.not.exist();
227
done();
228
});
229
});
230
231
it('should fail on invalid bewit', function (done) {
232
233
var req = {
234
method: 'GET',
235
url: '/resource/4?bewit=*',
236
host: 'example.com',
237
port: 8080
238
};
239
240
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
241
242
expect(err).to.exist();
243
expect(err.output.payload.message).to.equal('Invalid bewit encoding');
244
expect(err.isMissing).to.not.exist();
245
done();
246
});
247
});
248
249
it('should fail on missing bewit', function (done) {
250
251
var req = {
252
method: 'GET',
253
url: '/resource/4',
254
host: 'example.com',
255
port: 8080
256
};
257
258
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
259
260
expect(err).to.exist();
261
expect(err.output.payload.message).to.not.exist();
262
expect(err.isMissing).to.equal(true);
263
done();
264
});
265
});
266
267
it('should fail on invalid bewit structure', function (done) {
268
269
var req = {
270
method: 'GET',
271
url: '/resource/4?bewit=abc',
272
host: 'example.com',
273
port: 8080
274
};
275
276
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
277
278
expect(err).to.exist();
279
expect(err.output.payload.message).to.equal('Invalid bewit structure');
280
done();
281
});
282
});
283
284
it('should fail on empty bewit attribute', function (done) {
285
286
var req = {
287
method: 'GET',
288
url: '/resource/4?bewit=YVxcY1xk',
289
host: 'example.com',
290
port: 8080
291
};
292
293
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
294
295
expect(err).to.exist();
296
expect(err.output.payload.message).to.equal('Missing bewit attributes');
297
done();
298
});
299
});
300
301
it('should fail on missing bewit id attribute', function (done) {
302
303
var req = {
304
method: 'GET',
305
url: '/resource/4?bewit=XDQ1NTIxNDc2MjJcK0JFbFhQMXhuWjcvd1Nrbm1ldGhlZm5vUTNHVjZNSlFVRHk4NWpTZVJ4VT1cc29tZS1hcHAtZGF0YQ',
306
host: 'example.com',
307
port: 8080
308
};
309
310
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
311
312
expect(err).to.exist();
313
expect(err.output.payload.message).to.equal('Missing bewit attributes');
314
done();
315
});
316
});
317
318
it('should fail on expired access', function (done) {
319
320
var req = {
321
method: 'GET',
322
url: '/resource/4?a=1&b=2&bewit=MTIzNDU2XDEzNTY0MTg1ODNcWk1wZlMwWU5KNHV0WHpOMmRucTRydEk3NXNXTjFjeWVITTcrL0tNZFdVQT1cc29tZS1hcHAtZGF0YQ',
323
host: 'example.com',
324
port: 8080
325
};
326
327
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
328
329
expect(err).to.exist();
330
expect(err.output.payload.message).to.equal('Access expired');
331
done();
332
});
333
});
334
335
it('should fail on credentials function error', function (done) {
336
337
var req = {
338
method: 'GET',
339
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ',
340
host: 'example.com',
341
port: 8080
342
};
343
344
Hawk.uri.authenticate(req, function (id, callback) { callback(Hawk.error.badRequest('Boom')); }, {}, function (err, credentials, attributes) {
345
346
expect(err).to.exist();
347
expect(err.output.payload.message).to.equal('Boom');
348
done();
349
});
350
});
351
352
it('should fail on credentials function error with credentials', function (done) {
353
354
var req = {
355
method: 'GET',
356
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ',
357
host: 'example.com',
358
port: 8080
359
};
360
361
Hawk.uri.authenticate(req, function (id, callback) { callback(Hawk.error.badRequest('Boom'), { some: 'value' }); }, {}, function (err, credentials, attributes) {
362
363
expect(err).to.exist();
364
expect(err.output.payload.message).to.equal('Boom');
365
expect(credentials.some).to.equal('value');
366
done();
367
});
368
});
369
370
it('should fail on null credentials function response', function (done) {
371
372
var req = {
373
method: 'GET',
374
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ',
375
host: 'example.com',
376
port: 8080
377
};
378
379
Hawk.uri.authenticate(req, function (id, callback) { callback(null, null); }, {}, function (err, credentials, attributes) {
380
381
expect(err).to.exist();
382
expect(err.output.payload.message).to.equal('Unknown credentials');
383
done();
384
});
385
});
386
387
it('should fail on invalid credentials function response', function (done) {
388
389
var req = {
390
method: 'GET',
391
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ',
392
host: 'example.com',
393
port: 8080
394
};
395
396
Hawk.uri.authenticate(req, function (id, callback) { callback(null, {}); }, {}, function (err, credentials, attributes) {
397
398
expect(err).to.exist();
399
expect(err.message).to.equal('Invalid credentials');
400
done();
401
});
402
});
403
404
it('should fail on invalid credentials function response (unknown algorithm)', function (done) {
405
406
var req = {
407
method: 'GET',
408
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ',
409
host: 'example.com',
410
port: 8080
411
};
412
413
Hawk.uri.authenticate(req, function (id, callback) { callback(null, { key: 'xxx', algorithm: 'xxx' }); }, {}, function (err, credentials, attributes) {
414
415
expect(err).to.exist();
416
expect(err.message).to.equal('Unknown algorithm');
417
done();
418
});
419
});
420
421
it('should fail on expired access', function (done) {
422
423
var req = {
424
method: 'GET',
425
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ',
426
host: 'example.com',
427
port: 8080
428
};
429
430
Hawk.uri.authenticate(req, function (id, callback) { callback(null, { key: 'xxx', algorithm: 'sha256' }); }, {}, function (err, credentials, attributes) {
431
432
expect(err).to.exist();
433
expect(err.output.payload.message).to.equal('Bad mac');
434
done();
435
});
436
});
437
});
438
439
describe('#getBewit', function () {
440
441
it('returns a valid bewit value', function (done) {
442
443
var credentials = {
444
id: '123456',
445
key: '2983d45yun89q',
446
algorithm: 'sha256'
447
};
448
449
var bewit = Hawk.uri.getBewit('https://example.com/somewhere/over/the/rainbow', { credentials: credentials, ttlSec: 300, localtimeOffsetMsec: 1356420407232 - Hawk.utils.now(), ext: 'xandyandz' });
450
expect(bewit).to.equal('MTIzNDU2XDEzNTY0MjA3MDdca3NjeHdOUjJ0SnBQMVQxekRMTlBiQjVVaUtJVTl0T1NKWFRVZEc3WDloOD1ceGFuZHlhbmR6');
451
done();
452
});
453
454
it('returns a valid bewit value (explicit port)', function (done) {
455
456
var credentials = {
457
id: '123456',
458
key: '2983d45yun89q',
459
algorithm: 'sha256'
460
};
461
462
var bewit = Hawk.uri.getBewit('https://example.com:8080/somewhere/over/the/rainbow', { credentials: credentials, ttlSec: 300, localtimeOffsetMsec: 1356420407232 - Hawk.utils.now(), ext: 'xandyandz' });
463
expect(bewit).to.equal('MTIzNDU2XDEzNTY0MjA3MDdcaFpiSjNQMmNLRW80a3kwQzhqa1pBa1J5Q1p1ZWc0V1NOYnhWN3ZxM3hIVT1ceGFuZHlhbmR6');
464
done();
465
});
466
467
it('returns a valid bewit value (null ext)', function (done) {
468
469
var credentials = {
470
id: '123456',
471
key: '2983d45yun89q',
472
algorithm: 'sha256'
473
};
474
475
var bewit = Hawk.uri.getBewit('https://example.com/somewhere/over/the/rainbow', { credentials: credentials, ttlSec: 300, localtimeOffsetMsec: 1356420407232 - Hawk.utils.now(), ext: null });
476
expect(bewit).to.equal('MTIzNDU2XDEzNTY0MjA3MDdcSUdZbUxnSXFMckNlOEN4dktQczRKbFdJQStValdKSm91d2dBUmlWaENBZz1c');
477
done();
478
});
479
480
it('returns a valid bewit value (parsed uri)', function (done) {
481
482
var credentials = {
483
id: '123456',
484
key: '2983d45yun89q',
485
algorithm: 'sha256'
486
};
487
488
var bewit = Hawk.uri.getBewit(Url.parse('https://example.com/somewhere/over/the/rainbow'), { credentials: credentials, ttlSec: 300, localtimeOffsetMsec: 1356420407232 - Hawk.utils.now(), ext: 'xandyandz' });
489
expect(bewit).to.equal('MTIzNDU2XDEzNTY0MjA3MDdca3NjeHdOUjJ0SnBQMVQxekRMTlBiQjVVaUtJVTl0T1NKWFRVZEc3WDloOD1ceGFuZHlhbmR6');
490
done();
491
});
492
493
it('errors on invalid options', function (done) {
494
495
var credentials = {
496
id: '123456',
497
key: '2983d45yun89q',
498
algorithm: 'sha256'
499
};
500
501
var bewit = Hawk.uri.getBewit('https://example.com/somewhere/over/the/rainbow', 4);
502
expect(bewit).to.equal('');
503
done();
504
});
505
506
it('errors on missing uri', function (done) {
507
508
var credentials = {
509
id: '123456',
510
key: '2983d45yun89q',
511
algorithm: 'sha256'
512
};
513
514
var bewit = Hawk.uri.getBewit('', { credentials: credentials, ttlSec: 300, localtimeOffsetMsec: 1356420407232 - Hawk.utils.now(), ext: 'xandyandz' });
515
expect(bewit).to.equal('');
516
done();
517
});
518
519
it('errors on invalid uri', function (done) {
520
521
var credentials = {
522
id: '123456',
523
key: '2983d45yun89q',
524
algorithm: 'sha256'
525
};
526
527
var bewit = Hawk.uri.getBewit(5, { credentials: credentials, ttlSec: 300, localtimeOffsetMsec: 1356420407232 - Hawk.utils.now(), ext: 'xandyandz' });
528
expect(bewit).to.equal('');
529
done();
530
});
531
532
it('errors on invalid credentials (id)', function (done) {
533
534
var credentials = {
535
key: '2983d45yun89q',
536
algorithm: 'sha256'
537
};
538
539
var bewit = Hawk.uri.getBewit('https://example.com/somewhere/over/the/rainbow', { credentials: credentials, ttlSec: 3000, ext: 'xandyandz' });
540
expect(bewit).to.equal('');
541
done();
542
});
543
544
it('errors on missing credentials', function (done) {
545
546
var bewit = Hawk.uri.getBewit('https://example.com/somewhere/over/the/rainbow', { ttlSec: 3000, ext: 'xandyandz' });
547
expect(bewit).to.equal('');
548
done();
549
});
550
551
it('errors on invalid credentials (key)', function (done) {
552
553
var credentials = {
554
id: '123456',
555
algorithm: 'sha256'
556
};
557
558
var bewit = Hawk.uri.getBewit('https://example.com/somewhere/over/the/rainbow', { credentials: credentials, ttlSec: 3000, ext: 'xandyandz' });
559
expect(bewit).to.equal('');
560
done();
561
});
562
563
it('errors on invalid algorithm', function (done) {
564
565
var credentials = {
566
id: '123456',
567
key: '2983d45yun89q',
568
algorithm: 'hmac-sha-0'
569
};
570
571
var bewit = Hawk.uri.getBewit('https://example.com/somewhere/over/the/rainbow', { credentials: credentials, ttlSec: 300, ext: 'xandyandz' });
572
expect(bewit).to.equal('');
573
done();
574
});
575
576
it('errors on missing options', function (done) {
577
578
var credentials = {
579
id: '123456',
580
key: '2983d45yun89q',
581
algorithm: 'hmac-sha-0'
582
};
583
584
var bewit = Hawk.uri.getBewit('https://example.com/somewhere/over/the/rainbow');
585
expect(bewit).to.equal('');
586
done();
587
});
588
});
589
});
590
591
592