Inject secrets into the services (#3652)
This is a reworking of #3410 based on some feedback @calebcartwright left on that PR. The goals of injecting the secrets are threefold: 1. Simplify testing 2. Be consistent with all of the other config (which is injected) 3. Encapsulate the sensitive auth-related code in one place so it can be studied and tested thoroughly - Rather than add more code to BaseService to handle authorization logic, it delegates that to an AuthHelper class. - When the server starts, it fetches the credentials from `config` and injects them into `BaseService.register()` which passes them to `invoke()`. - In `invoke()` the service's auth configuration is checked (`static get auth()`, much like `static get route()`). - If the auth config is present, an AuthHelper instance is created and attached to the new instance. - Then within the service, the password, basic auth config, or bearer authentication can be accessed via e.g. `this.authHelper.basicAuth` and passed to `this._requestJson()` and friends. - Everything is being done very explicitly, so it should be very clear where and how the configured secrets are being used. - Testing different configurations of services can now be done by injecting the config into `invoke()` in `.spec` files instead of mocking global state in the service tests as was done before. See the new Jira spec files for a good example of this. Ref #3393
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
'use strict'
|
||||
|
||||
const Joi = require('@hapi/joi')
|
||||
const serverSecrets = require('../../lib/server-secrets')
|
||||
const { optionalUrl } = require('../validators')
|
||||
const { isDependencyMap } = require('../package-json-helpers')
|
||||
const { BaseJsonService, InvalidResponse, NotFound } = require('..')
|
||||
@@ -38,6 +37,10 @@ const queryParamSchema = Joi.object({
|
||||
// Abstract class for NPM badges which display data about the latest version
|
||||
// of a package.
|
||||
module.exports = class NpmBase extends BaseJsonService {
|
||||
static get auth() {
|
||||
return { passKey: 'npm_token' }
|
||||
}
|
||||
|
||||
static buildRoute(base, { withTag } = {}) {
|
||||
if (withTag) {
|
||||
return {
|
||||
@@ -74,15 +77,16 @@ module.exports = class NpmBase extends BaseJsonService {
|
||||
}
|
||||
|
||||
async _requestJson(data) {
|
||||
// Use a custom Accept header because of this bug:
|
||||
// <https://github.com/npm/npmjs.org/issues/163>
|
||||
const headers = { Accept: '*/*' }
|
||||
if (serverSecrets.npm_token) {
|
||||
headers.Authorization = `Bearer ${serverSecrets.npm_token}`
|
||||
}
|
||||
return super._requestJson({
|
||||
...data,
|
||||
options: { headers },
|
||||
options: {
|
||||
headers: {
|
||||
// Use a custom Accept header because of this bug:
|
||||
// <https://github.com/npm/npmjs.org/issues/163>
|
||||
Accept: '*/*',
|
||||
...this.authHelper.bearerAuthHeader,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user