source: trip-planner-front/node_modules/needle/test/auth_digest_spec.js@ 6a80231

Last change on this file since 6a80231 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 6.2 KB
Line 
1var needle = require('../'),
2 auth = require('../lib/auth'),
3 sinon = require('sinon'),
4 should = require('should'),
5 http = require('http'),
6 helpers = require('./helpers');
7
8var createHash = require('crypto').createHash;
9
10function md5(string) {
11 return createHash('md5').update(string).digest('hex');
12}
13
14function parse_header(header) {
15 var challenge = {},
16 matches = header.match(/([a-z0-9_-]+)="?([a-z0-9=\/\.@\s-\+]+)"?/gi);
17
18 for (var i = 0, l = matches.length; i < l; i++) {
19 var parts = matches[i].split('='),
20 key = parts.shift(),
21 val = parts.join('=').replace(/^"/, '').replace(/"$/, '');
22
23 challenge[key] = val;
24 }
25
26 return challenge;
27}
28
29describe('auth_digest', function() {
30 describe('With qop (RFC 2617)', function() {
31 it('should generate a proper header', function() {
32 // from https://tools.ietf.org/html/rfc2617
33 var performDigest = function() {
34 var header = 'Digest realm="testrealm@host.com", qop="auth,auth-int", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", opaque="5ccc069c403ebaf9f0171e9517f40e41"';
35 var user = 'Mufasa';
36 var pass = 'Circle Of Life';
37 var method = 'get';
38 var path = '/dir/index.html';
39
40 var updatedHeader = auth.digest(header, user, pass, method, path);
41 var parsedUpdatedHeader = parse_header(updatedHeader);
42
43 var ha1 = md5(user + ':' + parsedUpdatedHeader.realm + ':' + pass);
44 var ha2 = md5(method.toUpperCase() + ':' + path);
45 var expectedResponse = md5([
46 ha1,
47 parsedUpdatedHeader.nonce,
48 parsedUpdatedHeader.nc,
49 parsedUpdatedHeader.cnonce,
50 parsedUpdatedHeader.qop,
51 ha2
52 ].join(':'));
53
54 return {
55 header: updatedHeader,
56 parsed: parsedUpdatedHeader,
57 expectedResponse: expectedResponse,
58 }
59 }
60
61 const result = performDigest();
62
63 (result.header).should
64 .match(/qop="auth"/)
65 .match(/uri="\/dir\/index.html"/)
66 .match(/opaque="5ccc069c403ebaf9f0171e9517f40e41"/)
67 .match(/realm="testrealm@host\.com"/)
68 .match(/response=/)
69 .match(/nc=/)
70 .match(/nonce=/)
71 .match(/cnonce=/);
72
73 (result.parsed.response).should.be.eql(result.expectedResponse);
74 });
75 });
76
77 describe('With plus character in nonce header', function() {
78 it('should generate a proper header', function() {
79 // from https://tools.ietf.org/html/rfc2617
80 var performDigest = function() {
81 var header = 'Digest realm="testrealm@host.com", qop="auth,auth-int", nonce="dcd98b7102dd2f0e8b11d0f6+00bfb0c093", opaque="5ccc069c403ebaf9f0171e9517f40e41"';
82 var user = 'Mufasa';
83 var pass = 'Circle Of Life';
84 var method = 'get';
85 var path = '/dir/index.html';
86
87 var updatedHeader = auth.digest(header, user, pass, method, path);
88 var parsedUpdatedHeader = parse_header(updatedHeader);
89
90 var ha1 = md5(user + ':' + parsedUpdatedHeader.realm + ':' + pass);
91 var ha2 = md5(method.toUpperCase() + ':' + path);
92 var expectedResponse = md5([
93 ha1,
94 parsedUpdatedHeader.nonce,
95 parsedUpdatedHeader.nc,
96 parsedUpdatedHeader.cnonce,
97 parsedUpdatedHeader.qop,
98 ha2
99 ].join(':'));
100
101 return {
102 header: updatedHeader,
103 parsed: parsedUpdatedHeader,
104 expectedResponse: expectedResponse,
105 }
106 }
107
108 const result = performDigest();
109
110 (result.header).should
111 .match(/nonce="dcd98b7102dd2f0e8b11d0f6\+00bfb0c093"/)
112 });
113 });
114
115 describe('With brackets in realm header', function() {
116 it('should generate a proper header', function() {
117 // from https://tools.ietf.org/html/rfc2617
118 var performDigest = function() {
119 var header = 'Digest qop="auth", realm="IP Camera(76475)", nonce="4e4449794d575269597a706b5a575935595441324d673d3d", stale="FALSE", Basic realm="IP Camera(76475)"';
120 var user = 'Mufasa';
121 var pass = 'Circle Of Life';
122 var method = 'get';
123 var path = '/dir/index.html';
124
125 var updatedHeader = auth.digest(header, user, pass, method, path);
126 var parsedUpdatedHeader = parse_header(updatedHeader);
127
128 var ha1 = md5(user + ':' + parsedUpdatedHeader.realm + ':' + pass);
129 var ha2 = md5(method.toUpperCase() + ':' + path);
130 var expectedResponse = md5([
131 ha1,
132 parsedUpdatedHeader.nonce,
133 parsedUpdatedHeader.nc,
134 parsedUpdatedHeader.cnonce,
135 parsedUpdatedHeader.qop,
136 ha2
137 ].join(':'));
138
139 return {
140 header: updatedHeader,
141 parsed: parsedUpdatedHeader,
142 expectedResponse: expectedResponse,
143 }
144 }
145
146 const result = performDigest();
147
148 (result.header).should
149 .match(/realm="IP Camera\(76475\)"/)
150 });
151 });
152
153 describe('Without qop (RFC 2617)', function() {
154 it('should generate a proper header', function() {
155 // from https://tools.ietf.org/html/rfc2069
156 var performDigest = function() {
157 var header = 'Digest realm="testrealm@host.com", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", opaque="5ccc069c403ebaf9f0171e9517f40e41"';
158 var user = 'Mufasa';
159 var pass = 'Circle Of Life';
160 var method = 'get';
161 var path = '/dir/index.html';
162
163 var updatedHeader = auth.digest(header, user, pass, method, path);
164 var parsedUpdatedHeader = parse_header(updatedHeader);
165
166 var ha1 = md5(user + ':' + parsedUpdatedHeader.realm + ':' + pass);
167 var ha2 = md5(method.toUpperCase() + ':' + path);
168 var expectedResponse = md5([ha1, parsedUpdatedHeader.nonce, ha2].join(':'));
169
170 return {
171 header: updatedHeader,
172 parsed: parsedUpdatedHeader,
173 expectedResponse: expectedResponse,
174 }
175 }
176
177 const result = performDigest();
178
179 (result.header).should
180 .not.match(/qop=/)
181 .match(/uri="\/dir\/index.html"/)
182 .match(/opaque="5ccc069c403ebaf9f0171e9517f40e41"/)
183 .match(/realm="testrealm@host\.com"/)
184 .match(/response=/)
185 .not.match(/nc=/)
186 .match(/nonce=/)
187 .not.match(/cnonce=/);
188
189 (result.parsed.response).should.be.eql(result.expectedResponse);
190 });
191 });
192})
Note: See TracBrowser for help on using the repository browser.