mirror of
https://github.com/docker/login-action.git
synced 2026-10-23 16:57:17 +00:00
Merge pull request #1088 from crazy-max/fix-scoped-registry-url
use registry hosts for scoped credentials
This commit is contained in:
@@ -3,7 +3,7 @@ import * as path from 'path';
|
||||
|
||||
import {Buildx} from '@docker/actions-toolkit/lib/buildx/buildx.js';
|
||||
|
||||
import {getAuthList, getInputs} from '../src/context.js';
|
||||
import {getAuthList, getInputs, scopeToConfigDir} from '../src/context.js';
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
@@ -188,3 +188,23 @@ test.each([
|
||||
});
|
||||
expect(auth.ecr).toBe(expected);
|
||||
});
|
||||
|
||||
// prettier-ignore
|
||||
test.each([
|
||||
['ghcr.io', 'ghcr.io'],
|
||||
['ghcr.io/', 'ghcr.io'],
|
||||
['https://ghcr.io', 'ghcr.io'],
|
||||
['https://ghcr.io/', 'ghcr.io'],
|
||||
['https://ghcr.io/v2/', 'ghcr.io'],
|
||||
['http://localhost:5000', 'localhost:5000'],
|
||||
['http://localhost:80', 'localhost:80'],
|
||||
['https://ghcr.io:443', 'ghcr.io:443'],
|
||||
['https://012345678910.dkr.ecr.eu-west-3.amazonaws.com', '012345678910.dkr.ecr.eu-west-3.amazonaws.com'],
|
||||
['https://docker.io', 'registry-1.docker.io']
|
||||
])('scopeToConfigDir uses the registry host for %s', (registry, host) => {
|
||||
expect(scopeToConfigDir(registry, 'myorg/myimage@push')).toBe(path.join(Buildx.configDir, 'config', host, 'myorg', 'myimage') + '@push');
|
||||
});
|
||||
|
||||
test('scopeToConfigDir rejects a URL whose host escapes the config directory', () => {
|
||||
expect(() => scopeToConfigDir('https://../', '@push')).toThrow(/Invalid registry/);
|
||||
});
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import {afterEach, expect, test, vi} from 'vitest';
|
||||
import * as path from 'path';
|
||||
|
||||
import {Buildx} from '@docker/actions-toolkit/lib/buildx/buildx.js';
|
||||
import {Docker} from '@docker/actions-toolkit/lib/docker/docker.js';
|
||||
|
||||
import {login, loginStandard, logout} from '../src/docker.js';
|
||||
import * as aws from '../src/aws.js';
|
||||
import {getAuthList} from '../src/context.js';
|
||||
import {login, loginECR, loginStandard, logout} from '../src/docker.js';
|
||||
import * as dockerhub from '../src/dockerhub.js';
|
||||
|
||||
afterEach(() => {
|
||||
@@ -92,3 +96,29 @@ test('logout calls exec', async () => {
|
||||
ignoreReturnCode: true
|
||||
});
|
||||
});
|
||||
|
||||
test('loginECR and logout use the config dir of the registry host', async () => {
|
||||
const execSpy = vi.spyOn(Docker, 'getExecOutput').mockResolvedValue({
|
||||
exitCode: 0,
|
||||
stdout: '',
|
||||
stderr: ''
|
||||
});
|
||||
const registry = '012345678910.dkr.ecr.eu-west-3.amazonaws.com';
|
||||
vi.spyOn(aws, 'getRegistriesData').mockResolvedValue([
|
||||
{
|
||||
registry: `https://${registry}`,
|
||||
username: 'AWS',
|
||||
password: 'world'
|
||||
}
|
||||
]);
|
||||
|
||||
const scope = 'myapp@push';
|
||||
const [auth] = getAuthList({registry, username: 'CAFEBABE', password: 'DEADBEEF', scope, ecr: 'auto', logout: true, registryAuth: ''});
|
||||
await loginECR(auth.registry, auth.username, auth.password, auth.scope);
|
||||
await logout(auth.registry, auth.configDir);
|
||||
|
||||
const expectedConfigDir = path.join(Buildx.configDir, 'config', registry, 'myapp@push');
|
||||
expect(execSpy).toHaveBeenCalledTimes(2);
|
||||
expect(execSpy.mock.calls[0][1]?.env?.DOCKER_CONFIG).toBe(expectedConfigDir);
|
||||
expect(execSpy.mock.calls[1][1]?.env?.DOCKER_CONFIG).toBe(expectedConfigDir);
|
||||
});
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+3
-3
File diff suppressed because one or more lines are too long
+4
-1
@@ -77,8 +77,11 @@ export function scopeToConfigDir(registry: string, scope?: string): string {
|
||||
if (scopeDisabled() || !scope || scope === '') {
|
||||
return '';
|
||||
}
|
||||
const schemeEnd = registry.indexOf('://');
|
||||
// A neutral scheme preserves explicit ports, including HTTP(S) default ports.
|
||||
const registryHost = schemeEnd === -1 ? registry : new URL(`registry://${registry.slice(schemeEnd + 3)}`).host;
|
||||
const configRoot = path.resolve(Buildx.configDir, 'config');
|
||||
const registryDir = path.resolve(configRoot, registry === 'docker.io' ? 'registry-1.docker.io' : registry);
|
||||
const registryDir = path.resolve(configRoot, registryHost === 'docker.io' ? 'registry-1.docker.io' : registryHost);
|
||||
if (!isChildPath(configRoot, registryDir)) {
|
||||
throw new Error(`Invalid registry '${registry}': resolved config path escapes the Buildx config directory`);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user