1 | {beforeEach, describe, it} = global
|
2 | {expect} = require 'chai'
|
3 | sinon = require 'sinon'
|
4 |
|
5 | MeshbluAuthExpress = require '../src/meshblu-auth-express'
|
6 |
|
7 | describe 'MeshbluAuthExpress', ->
|
8 | describe '->getFromAnywhere', ->
|
9 | beforeEach ->
|
10 | @sut = new MeshbluAuthExpress
|
11 |
|
12 | describe '2nd to worst case (bearer token)', ->
|
13 | beforeEach ->
|
14 | @result = @sut.getFromAnywhere headers: {authorization: 'Bearer Z3JlZW5pc2gteWVsbG93OmJsdWUtYS1sb3QK'}
|
15 |
|
16 | it 'should return the auth', ->
|
17 | expect(@result).to.deep.equal uuid: 'greenish-yellow', token: 'blue-a-lot'
|
18 |
|
19 | describe 'worst case (invalid bearer token)', ->
|
20 | beforeEach ->
|
21 | @result = @sut.getFromAnywhere headers: {authorization: 'Bearer zpwaW5raXNoLBAD'}
|
22 |
|
23 | it 'should return null', ->
|
24 | expect(@result).to.be.null
|
25 |
|
26 | describe '->getFromBearerToken', ->
|
27 | beforeEach ->
|
28 | @sut = new MeshbluAuthExpress
|
29 |
|
30 | describe 'with a valid bearer token', ->
|
31 | beforeEach ->
|
32 | @result = @sut.getFromBearerToken headers: {authorization: 'Bearer Z3JlZW5pc2gteWVsbG93OmJsdWUtYS1sb3QK'}
|
33 |
|
34 | it 'should return the auth', ->
|
35 | expect(@result).to.deep.equal uuid: 'greenish-yellow', token: 'blue-a-lot'
|
36 |
|
37 | describe 'with a different valid bearer token', ->
|
38 | beforeEach ->
|
39 | @result = @sut.getFromBearerToken headers: {authorization: 'Bearer c3VwZXItcGluazpwaW5raXNoLXB1cnBsZWlzaAo='}
|
40 |
|
41 | it 'should return the auth', ->
|
42 | expect(@result).to.deep.equal uuid: 'super-pink', token: 'pinkish-purpleish'
|
43 |
|
44 | describe 'with an invalid bearer token', ->
|
45 | beforeEach ->
|
46 | @result = @sut.getFromBearerToken headers: {authorization: 'Bearer zpwaW5raXNoLBAD'}
|
47 |
|
48 | it 'should return null', ->
|
49 | expect(@result).to.be.null
|
50 |
|
51 | describe 'with an invalid header', ->
|
52 | beforeEach ->
|
53 | @result = @sut.getFromBearerToken {}
|
54 |
|
55 | it 'should return null', ->
|
56 | expect(@result).to.be.null
|
57 |
|
58 | describe 'with a different authorization scheme', ->
|
59 | beforeEach ->
|
60 | @result = @sut.getFromBearerToken headers: {authorization: 'Basic'}
|
61 |
|
62 | it 'should return null', ->
|
63 | expect(@result).to.not.exist
|
64 |
|
65 | describe '->getFromBasicAuth', ->
|
66 | beforeEach ->
|
67 | @sut = new MeshbluAuthExpress
|
68 |
|
69 | describe 'with a valid basic auth', ->
|
70 | beforeEach ->
|
71 | @result = @sut.getFromBasicAuth headers: {authorization: 'Basic Z3JlZW5pc2gteWVsbG93OmJsdWUtYS1sb3QK'}
|
72 |
|
73 | it 'should return the uuid and token', ->
|
74 | expect(@result).to.deep.equal uuid: 'greenish-yellow', token: 'blue-a-lot'
|
75 |
|
76 | describe 'with a different valid basic auth', ->
|
77 | beforeEach ->
|
78 | @result = @sut.getFromBasicAuth headers: {authorization: 'Basic c3VwZXItcGluazpwaW5raXNoLXB1cnBsZWlzaAo='}
|
79 |
|
80 | it 'should return the uuid and token', ->
|
81 | expect(@result).to.deep.equal uuid: 'super-pink', token: 'pinkish-purpleish'
|
82 |
|
83 | describe 'with a invalid basic auth', ->
|
84 | beforeEach ->
|
85 | @result = @sut.getFromBasicAuth headers: {authorization: 'Basic zpwaW5raXNoLBAD'}
|
86 |
|
87 | it 'should return null', ->
|
88 | expect(@result).to.be.null
|
89 |
|
90 | describe 'with a invalid header', ->
|
91 | beforeEach ->
|
92 | @result = @sut.getFromBasicAuth {}
|
93 |
|
94 | it 'should return null', ->
|
95 | expect(@result).to.be.null
|
96 |
|
97 | describe 'with a different authorization scheme', ->
|
98 | beforeEach ->
|
99 | @result = @sut.getFromBasicAuth headers: {authorization: 'Bearer c3VwZXItcGluazpwaW5raXNoLXB1cnBsZWlzaAo='}
|
100 |
|
101 | it 'should return null', ->
|
102 | expect(@result).to.be.null
|
103 |
|
104 | describe '->getFromCookies', ->
|
105 | beforeEach ->
|
106 | @sut = new MeshbluAuthExpress
|
107 |
|
108 | describe 'with a valid cookie', ->
|
109 | beforeEach ->
|
110 | @result = @sut.getFromCookies {
|
111 | cookies:
|
112 | meshblu_auth_uuid: 'greenish-yellow'
|
113 | meshblu_auth_token: 'blue-a-lot'
|
114 | }
|
115 |
|
116 | it 'should return the uuid and token', ->
|
117 | expect(@result).to.deep.equal uuid: 'greenish-yellow', token: 'blue-a-lot'
|
118 |
|
119 | describe 'with a valid bearer cookie', ->
|
120 | beforeEach ->
|
121 | bearer = Buffer('i-can-barely-stand:erik', 'utf8').toString('base64')
|
122 | @result = @sut.getFromCookies cookies: {meshblu_auth_bearer: bearer}
|
123 |
|
124 | it 'should return the uuid and token', ->
|
125 | expect(@result).to.deep.equal uuid: 'i-can-barely-stand', token: 'erik'
|
126 |
|
127 | describe 'with a different valid cookie', ->
|
128 | beforeEach ->
|
129 | @result = @sut.getFromCookies {
|
130 | cookies:
|
131 | meshblu_auth_uuid: 'super-pink'
|
132 | meshblu_auth_token: 'pinkish-purpleish'
|
133 | }
|
134 |
|
135 | it 'should return the uuid and token', ->
|
136 | expect(@result).to.deep.equal uuid: 'super-pink', token: 'pinkish-purpleish'
|
137 |
|
138 | describe 'with invalid cookies', ->
|
139 | beforeEach ->
|
140 | @result = @sut.getFromCookies cookies: {}
|
141 |
|
142 | it 'should return null', ->
|
143 | expect(@result).to.be.null
|
144 |
|
145 | describe 'with a invalid header', ->
|
146 | beforeEach ->
|
147 | @result = @sut.getFromCookies {}
|
148 |
|
149 | it 'should return null', ->
|
150 | expect(@result).to.be.null
|
151 |
|
152 | describe '->getFromSkynetHeaders', ->
|
153 | beforeEach ->
|
154 | @sut = new MeshbluAuthExpress
|
155 |
|
156 | describe 'with a valid auth', ->
|
157 | beforeEach ->
|
158 | @result = @sut.getFromXMeshbluHeaders {
|
159 | headers:
|
160 | 'X-Meshblu-UUID': 'greenish-yellow'
|
161 | 'X-Meshblu-Token': 'blue-a-lot'
|
162 | }
|
163 |
|
164 | it 'should return the uuid and token', ->
|
165 | expect(@result).to.deep.equal uuid: 'greenish-yellow', token: 'blue-a-lot'
|
166 |
|
167 | describe 'with a crazy case', ->
|
168 | beforeEach ->
|
169 | @result = @sut.getFromXMeshbluHeaders {
|
170 | headers:
|
171 | 'x-meshBLU-uuID': 'greenish-yellow'
|
172 | 'X-meshblu-token': 'blue-a-lot'
|
173 | }
|
174 |
|
175 | it 'should return the uuid and token', ->
|
176 | expect(@result).to.deep.equal uuid: 'greenish-yellow', token: 'blue-a-lot'
|
177 |
|
178 | describe '->getFromSkynetHeaders', ->
|
179 | beforeEach ->
|
180 | @sut = new MeshbluAuthExpress
|
181 |
|
182 | describe 'with a valid auth', ->
|
183 | beforeEach ->
|
184 | @result = @sut.getFromSkynetHeaders {
|
185 | headers:
|
186 | skynet_auth_uuid: 'greenish-yellow'
|
187 | skynet_auth_token: 'blue-a-lot'
|
188 | }
|
189 |
|
190 | it 'should return the uuid and token', ->
|
191 | expect(@result).to.deep.equal uuid: 'greenish-yellow', token: 'blue-a-lot'
|
192 |
|
193 | describe '->getFromHeaders', ->
|
194 | beforeEach ->
|
195 | @sut = new MeshbluAuthExpress
|
196 |
|
197 | describe 'with a valid basic auth', ->
|
198 | beforeEach ->
|
199 | @result = @sut.getFromHeaders {
|
200 | headers:
|
201 | meshblu_auth_uuid: 'greenish-yellow'
|
202 | meshblu_auth_token: 'blue-a-lot'
|
203 | }
|
204 |
|
205 | it 'should return the uuid and token', ->
|
206 | expect(@result).to.deep.equal uuid: 'greenish-yellow', token: 'blue-a-lot'
|
207 |
|
208 | describe 'with a different valid bearer token', ->
|
209 | beforeEach ->
|
210 | @result = @sut.getFromHeaders {
|
211 | headers:
|
212 | meshblu_auth_uuid: 'super-pink'
|
213 | meshblu_auth_token: 'pinkish-purpleish'
|
214 | }
|
215 |
|
216 | it 'should return the uuid and token', ->
|
217 | expect(@result).to.deep.equal uuid: 'super-pink', token: 'pinkish-purpleish'
|
218 |
|
219 | describe 'with invalid headers', ->
|
220 | beforeEach ->
|
221 | @result = @sut.getFromHeaders headers: {}
|
222 |
|
223 | it 'should return null', ->
|
224 | expect(@result).to.be.null
|
225 |
|
226 | describe 'with a invalid header', ->
|
227 | beforeEach ->
|
228 | @result = @sut.getFromHeaders {}
|
229 |
|
230 | it 'should set meshbluAuth on the request', ->
|
231 | expect(@result).to.be.null
|
232 |
|
233 | describe 'when instantiated with meshblu configuration', ->
|
234 | beforeEach ->
|
235 | @meshbluHttp =
|
236 | authenticate: sinon.stub()
|
237 | @MeshbluHttp = sinon.spy => @meshbluHttp
|
238 | dependencies = MeshbluHttp: @MeshbluHttp
|
239 | options =
|
240 | server: 'yellow-mellow'
|
241 | port: 'greeeeeeennn'
|
242 |
|
243 | @sut = new MeshbluAuthExpress options, dependencies
|
244 |
|
245 | describe 'when called with uuid and token', ->
|
246 | beforeEach ->
|
247 | @sut.authDeviceWithMeshblu 'blackened', 'bluened', (@error, @result) =>
|
248 |
|
249 | it 'should be instantiated', ->
|
250 | expect(@MeshbluHttp).to.be.calledWithNew
|
251 |
|
252 | it 'should be instantiated with the correct options', ->
|
253 | expect(@MeshbluHttp).to.be.calledWith {
|
254 | server: 'yellow-mellow'
|
255 | port: 'greeeeeeennn'
|
256 | uuid: 'blackened'
|
257 | token: 'bluened'
|
258 | }
|
259 |
|
260 | it 'should call meshbluHttp.device with correct url and options', ->
|
261 | expect(@meshbluHttp.authenticate).to.have.been.called
|
262 |
|
263 | describe 'when MeshbluHttp yields a device', ->
|
264 | beforeEach ->
|
265 | @meshbluHttp.authenticate.yield null, {uuid: 'blackened', foo: 'bar'}
|
266 |
|
267 | it 'should yields without an error', ->
|
268 | expect(@error).not.to.exist
|
269 |
|
270 | it 'should yield the credentials, bearerToken, server info', ->
|
271 | expect(@result).to.deep.equal {
|
272 | server: 'yellow-mellow'
|
273 | port: 'greeeeeeennn'
|
274 | uuid: 'blackened'
|
275 | token: 'bluened'
|
276 | bearerToken: new Buffer('blackened:bluened').toString 'base64'
|
277 | }
|
278 |
|
279 | describe 'when MeshbluHttp yields an error with no code', ->
|
280 | beforeEach ->
|
281 | @meshbluHttp.authenticate.yield new Error('Generic Error')
|
282 |
|
283 | it 'should yields with an error', ->
|
284 | expect(=> throw @error).to.throw 'Generic Error'
|
285 |
|
286 | describe 'when MeshbluHttp yields an error with a 401', ->
|
287 | beforeEach ->
|
288 | error = new Error('Unauthorized')
|
289 | error.code = 401
|
290 | @meshbluHttp.authenticate.yield error
|
291 |
|
292 | it 'should yield nulls', ->
|
293 | expect(@error).to.be.null
|
294 | expect(@result).to.be.null
|
295 |
|
296 | describe 'when MeshbluHttp yields an error with a 500', ->
|
297 | beforeEach ->
|
298 | error = new Error('Internal Server Error')
|
299 | error.code = 500
|
300 | @meshbluHttp.authenticate.yield error
|
301 |
|
302 | it 'should yields with an error', ->
|
303 | expect(=> throw @error).to.throw 'Internal Server Error'
|