Skip to content

Commit 79cbdf0

Browse files
committed
Test for authorizer callbacks
1 parent f3287e8 commit 79cbdf0

File tree

2 files changed

+132
-2
lines changed

2 files changed

+132
-2
lines changed

lib/authorizer-callbacks.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ module.exports.authorizerCheckCallback = function(
7171
getCacheEntry,
7272
cacheEntryTtl
7373
) {
74+
const defaultCacheFunc = function(i, cb) { cb() };
7475
return function(req, res, next) {
7576
if (!authorizer) {
7677
return next();
@@ -94,7 +95,7 @@ module.exports.authorizerCheckCallback = function(
9495
}
9596

9697
const cacheKey = req.lambda.authorizer.event.authorizationToken;
97-
(getCacheEntry || function(i, cb) { cb() })(
98+
(getCacheEntry || defaultCacheFunc)(
9899
cacheKey,
99100
function(err, cachedAuthorization) {
100101
if (cachedAuthorization) {
@@ -104,7 +105,7 @@ module.exports.authorizerCheckCallback = function(
104105
req.lambda.authorizer.event,
105106
req.lambda.context,
106107
function(innerErr, awsAuthDocument) {
107-
(setCacheEntry || function(i, cb) { cb() })({
108+
(setCacheEntry || defaultCacheFunc)({
108109
key: cacheKey,
109110
value: awsAuthDocument,
110111
ttl: cacheEntryTtl || 300,

tests/authorizer-callbacks.test.js

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,139 @@ describe('authorizer-callbacks', () => {
106106
expect(res.sendStatus).to.not.have.been.calledWith(403);
107107
expect(next).to.have.callCount(1);
108108
});
109+
110+
it('should accept arn options', () => {
111+
const req = {
112+
method: 'get',
113+
path: '/test',
114+
headers: {
115+
auth: 'Bearer test',
116+
},
117+
};
118+
const opts = {
119+
regionId: 'test-region',
120+
accountId: 'test-account',
121+
apiId: 'test-app',
122+
};
123+
subject.authorizerValidationCallback(null, null, opts)(req, null, next);
124+
expect(req.lambda).to.eql({
125+
authorizer: {
126+
event: {
127+
type: 'TOKEN',
128+
authorizationToken: 'Bearer test',
129+
methodArn: 'arn:serverlessify:execute-api:test-region:test-account:test-app/GET/test'
130+
},
131+
},
132+
});
133+
});
109134
});
110135

111136
describe('authorizerCheckCallback', () => {
137+
const req = {
138+
lambda: {
139+
authorizer: {
140+
event: {
141+
authorizationToken: 'test token',
142+
},
143+
},
144+
context: 'test context',
145+
},
146+
};
147+
const res = {
148+
send: sinon.spy(),
149+
sendStatus: sinon.spy(),
150+
};
151+
res.status = sinon.stub().returns(res);
152+
const next = sinon.spy();
112153

154+
beforeEach(() => {
155+
next.reset();
156+
res.send.reset();
157+
res.status.reset();
158+
res.sendStatus.reset();
159+
});
160+
161+
it('should skip if no authorizer is specified', () => {
162+
subject.authorizerCheckCallback()(null, null, next);
163+
expect(next).to.have.callCount(1);
164+
});
165+
166+
it('should authorize if authorizer allow', () => {
167+
const doc = {
168+
policyDocument: {
169+
Statement: [{ Effect: 'Allow' }],
170+
},
171+
};
172+
const authorizer = sinon.spy((e, c, cb) => cb(null, doc));
173+
subject.authorizerCheckCallback(authorizer)(req, res, next);
174+
expect(authorizer).to.have.been.calledWithMatch(
175+
{
176+
authorizationToken: 'test token',
177+
},
178+
'test context'
179+
);
180+
expect(next).to.have.callCount(1);
181+
});
182+
183+
it('should not authorize if authorizer deny', () => {
184+
const doc = {
185+
policyDocument: {
186+
Statement: [{ Effect: 'Deny' }],
187+
},
188+
};
189+
const authorizer = sinon.spy((e, c, cb) => cb(null, doc));
190+
subject.authorizerCheckCallback(authorizer)(req, res, next);
191+
expect(res.sendStatus).to.have.been.calledWith(401);
192+
expect(next).to.have.callCount(0);
193+
});
194+
195+
it('should 500 if authorizer fails', () => {
196+
const authorizer = sinon.spy((e, c, cb) => cb('err'));
197+
subject.authorizerCheckCallback(authorizer)(req, res, next);
198+
expect(res.status).to.have.been.calledWith(500);
199+
expect(res.send).to.have.been.calledWith('err');
200+
expect(next).to.have.callCount(0);
201+
});
202+
203+
it('should get authorization from cache', () => {
204+
const doc = {
205+
policyDocument: {
206+
Statement: [{ Effect: 'Allow' }],
207+
},
208+
};
209+
const authorizer = sinon.spy((e, c, cb) => cb(null, 'nope'));
210+
const getCache = sinon.spy((i, cb) => cb(null, doc));
211+
subject.authorizerCheckCallback(authorizer, null, getCache)(req, res, next);
212+
expect(getCache).to.have.callCount(1);
213+
expect(authorizer).to.have.callCount(0);
214+
});
215+
216+
it('should save authorization to cache', () => {
217+
const doc = {
218+
policyDocument: {
219+
Statement: [{ Effect: 'Allow' }],
220+
},
221+
};
222+
const authorizer = sinon.spy((e, c, cb) => cb(null, doc));
223+
const setCache = sinon.spy((i, cb) => cb());
224+
subject.authorizerCheckCallback(authorizer, setCache)(req, res, next);
225+
expect(setCache).to.have.been.calledWithMatch(
226+
{
227+
key: 'test token',
228+
value: doc,
229+
ttl: 300,
230+
}
231+
);
232+
233+
subject.authorizerCheckCallback(authorizer, setCache, null, 123)(req, res, next);
234+
expect(setCache).to.have.been.calledWithMatch(
235+
{
236+
key: 'test token',
237+
value: doc,
238+
ttl: 123,
239+
}
240+
);
241+
});
113242
});
114243
});
115244

0 commit comments

Comments
 (0)