diff --git a/lib/datasource/docker/index.js b/lib/datasource/docker/index.js index 5672436dc64a9071dae64e51f6406cf3781c6fe2..77877e4bfd37ac5ebe3a20831abd58f12ec48f5a 100644 --- a/lib/datasource/docker/index.js +++ b/lib/datasource/docker/index.js @@ -49,8 +49,6 @@ async function getAuthHeaders(registry, repository) { apiCheckResponse.headers['www-authenticate'] ); - // prettier-ignore - const authUrl = `${authenticateHeader.parms.realm}?service=${authenticateHeader.parms.service}&scope=repository:${repository}:pull`; const { host } = URL.parse(registry); const opts = hostRules.find({ platform: 'docker', host }, { json: true }); if (opts.username && opts.password) { @@ -59,6 +57,15 @@ async function getAuthHeaders(registry, repository) { ); opts.headers = { Authorization: `Basic ${auth}` }; } + + if (authenticateHeader.scheme.toUpperCase() === 'BASIC') { + logger.debug(`Using Basic auth for docker registry ${repository}`); + await got(apiCheckUrl, opts); + return opts.headers; + } + + // prettier-ignore + const authUrl = `${authenticateHeader.parms.realm}?service=${authenticateHeader.parms.service}&scope=repository:${repository}:pull`; logger.debug( `Obtaining docker registry token for ${repository} using url ${authUrl}` ); @@ -80,6 +87,14 @@ async function getAuthHeaders(registry, repository) { logger.debug({ err }); return null; } + if (err.statusCode === 403) { + logger.info( + { registry, dockerRepository: repository }, + 'Not allowed to access docker registry' + ); + logger.debug({ err }); + return null; + } if (err.statusCode === 429 && registry.endsWith('docker.io')) { logger.warn({ err }, 'docker registry failure: too many requests'); throw new Error('registry-failure'); diff --git a/test/datasource/docker.spec.js b/test/datasource/docker.spec.js index 4399136459f2dde176d888a0bff734121d8651be..05c5140caba77bdc4e7d22725d2f88e40a85674b 100644 --- a/test/datasource/docker.spec.js +++ b/test/datasource/docker.spec.js @@ -89,6 +89,36 @@ describe('api/docker', () => { 'sha256:b3d6068234f3a18ebeedd2dab81e67b6a192e81192a099df4112ecfc7c3be84f' ); }); + it('supports basic authentication', async () => { + got.mockReturnValueOnce({ + headers: { + 'www-authenticate': 'Basic realm="My Private Docker Registry Server"', + }, + }); + got.mockReturnValueOnce({ + statusCode: 200, + }); + got.mockReturnValueOnce({ + headers: { 'docker-content-digest': 'some-digest' }, + }); + const res = await docker.getDigest({ depName: 'some-dep' }, 'some-tag'); + expect(got.mock.calls[1][1].headers.Authorization).toBe( + 'Basic c29tZS11c2VybmFtZTpzb21lLXBhc3N3b3Jk' + ); + expect(res).toBe('some-digest'); + }); + it('returns null for 403 with basic authentication', async () => { + got.mockReturnValueOnce({ + headers: { + 'www-authenticate': 'Basic realm="My Private Docker Registry Server"', + }, + }); + got.mockReturnValueOnce({ + statusCode: 403, + }); + const res = await docker.getDigest({ depName: 'some-dep' }, 'some-tag'); + expect(res).toBeNull(); + }); it('continues without token, when no header is present', async () => { got.mockReturnValueOnce({ headers: {