From c13db4d55a8cf25c109dfcbb88a2d7828b791147 Mon Sep 17 00:00:00 2001 From: Justin Wind Date: Fri, 31 Dec 2021 12:08:37 -0800 Subject: [PATCH] fixed apiRequiredLocal method --- lib/authenticator.js | 24 +++++++++++++++++++----- test/lib/authenticator.js | 29 +++++++++++++++++++++++++---- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/lib/authenticator.js b/lib/authenticator.js index efa3d84..1cff210 100644 --- a/lib/authenticator.js +++ b/lib/authenticator.js @@ -338,7 +338,8 @@ class Authenticator { /** * Require auth for an API endpoint. - * Check for valid local identifier in session, or Authentication header. + * Check for valid local identifier in Authorization header; optionally + * fall back to session cookie if no header provided. * Prompts for Basic auth if not valid. * @param {http.ClientRequest} req * @param {http.ServerResponse} res @@ -346,12 +347,25 @@ class Authenticator { * @param {Boolean} sessionAlsoValid */ async apiRequiredLocal(req, res, ctx, sessionAlsoValid = true) { - const validSession = sessionAlsoValid && this.sessionCheck(req, res, ctx, undefined, false, false); + const _scope = _fileScope('apiRequiredLocal'); + this.logger.debug(_scope, 'called', { ctx, sessionAlsoValid }); + + // If a Authorization header was provided, never consider session as a fallback. const authorizationHeader = req.getHeader(Enum.Header.Authorization); - const validAuthorization = authorizationHeader && this.isValidAuthorization(authorizationHeader, ctx); - if (validSession || validAuthorization) { - return true; + if (authorizationHeader) { + if (await this.isValidAuthorization(authorizationHeader, ctx)) { + this.logger.debug(_scope, 'valid authorization', { ctx, sessionAlsoValid }); + return true; + } + } else { + if (sessionAlsoValid + && await this.sessionCheck(req, res, ctx, undefined, false, false)) { + this.logger.debug(_scope, 'valid session', { ctx, sessionAlsoValid }); + return true; + } } + + this.logger.debug(_scope, 'invalid authorization', { ctx, sessionAlsoValid }); this.requestBasic(res); } diff --git a/test/lib/authenticator.js b/test/lib/authenticator.js index 3ab6fb3..067d0ca 100644 --- a/test/lib/authenticator.js +++ b/test/lib/authenticator.js @@ -407,7 +407,7 @@ describe('Authenticator', function () { }); // sessionCheck describe('apiRequiredLocal', function () { - let req, res, ctx; + let req, res; beforeEach(function () { ctx = {}; req = { @@ -423,18 +423,39 @@ describe('Authenticator', function () { sinon.stub(authenticator, 'sessionCheck').resolves(false); sinon.stub(authenticator, 'isValidAuthorization').resolves(true); const result = await authenticator.apiRequiredLocal(req, res, ctx); - assert(authenticator.sessionCheck.called); + assert.strictEqual(result, true); assert(authenticator.isValidAuthorization.called); + assert(!authenticator.sessionCheck.called); + }); + it('covers invalid basic auth', async function () { + req.getHeader.returns('Basic Zm9vOmJhcg=='); + sinon.stub(authenticator, 'sessionCheck').resolves(false); + sinon.stub(authenticator, 'isValidAuthorization').resolves(false); + try { + await authenticator.apiRequiredLocal(req, res, ctx); + assert.fail(noExpectedException); + } catch (e) { + assert.strictEqual(e.statusCode, 401); + assert(!authenticator.sessionCheck.called); + assert(authenticator.isValidAuthorization.called); + } + }); + it('covers missing basic auth, valid session', async function () { + req.getHeader.returns(); + sinon.stub(authenticator, 'sessionCheck').resolves(true); + sinon.stub(authenticator, 'isValidAuthorization').resolves(false); + const result = await authenticator.apiRequiredLocal(req, res, ctx); assert.strictEqual(result, true); + assert(!authenticator.isValidAuthorization.called); + assert(authenticator.sessionCheck.called); }); - it('requests basic auth when missing, ignores session', async function () { + it('covers missing basic auth, ignores session', async function () { req.getHeader.returns(); sinon.stub(authenticator, 'isValidAuthorization').resolves(true); try { await authenticator.apiRequiredLocal(req, res, ctx, false); assert.fail(noExpectedException); } catch (e) { - console.log(e); assert.strictEqual(e.statusCode, 401); assert(!authenticator.sessionCheck.called); assert(!authenticator.isValidAuthorization.called); -- 2.45.2