Skip to content

Commit

Permalink
Do not return auth config when registry names partially match
Browse files Browse the repository at this point in the history
  • Loading branch information
cristianrgreco committed Mar 7, 2023
1 parent 36b6c5b commit 726057c
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 13 deletions.
3 changes: 2 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
clearMocks: true,
resetMocks: true,
restoreMocks: true,
};
17 changes: 15 additions & 2 deletions src/registry-auth-locator/auths.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ describe("Auths", () => {
describe("getAuthConfig", () => {
it("should return undefined when auths is undefined", async () => {
const dockerConfig: DockerConfig = {};
expect(await locator.getAuthConfig("registry-name", dockerConfig)).toBe(undefined);
expect(await locator.getAuthConfig("registry-name", dockerConfig)).toBeUndefined();
});

it("should return undefined when auths does not contain registry name", async () => {
const dockerConfig: DockerConfig = { auths: {} };
expect(await locator.getAuthConfig("registry-name", dockerConfig)).toBe(undefined);
expect(await locator.getAuthConfig("registry-name", dockerConfig)).toBeUndefined();
});

it("should return credentials from username and password", async () => {
Expand All @@ -35,6 +35,19 @@ describe("Auths", () => {
expect(await locator.getAuthConfig("https://registry.example.com", dockerConfig)).toEqual(authConfig);
});

it("should not return credentials for registry which is a partial match", async () => {
const dockerConfig: DockerConfig = {
auths: {
"https://registry.example.com": {
email: "user@example.com",
username: "user",
password: "pass",
},
},
};
expect(await locator.getAuthConfig("registry.example.co", dockerConfig)).toBeUndefined();
});

it("should return credentials from encoded auth", async () => {
const dockerConfig: DockerConfig = {
auths: {
Expand Down
3 changes: 2 additions & 1 deletion src/registry-auth-locator/auths.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Auth, DockerConfig } from "./types";
import { RegistryAuthLocator } from "./registry-auth-locator";
import { AuthConfig } from "../docker/types";
import { registryMatches } from "./registry-matches";

export class Auths implements RegistryAuthLocator {
public getName(): string {
Expand Down Expand Up @@ -40,7 +41,7 @@ export class Auths implements RegistryAuthLocator {
const authEntries = dockerConfig.auths ?? {};

for (const key in authEntries) {
if (key === registry || key.includes(`://${registry}`)) {
if (registryMatches(key, registry)) {
return authEntries[key];
}
}
Expand Down
12 changes: 4 additions & 8 deletions src/registry-auth-locator/credential-provider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,18 @@ describe("CredentialProvider", () => {
});
});

it("should return auth config when registry is a substring of registry in credentials", async () => {
mockExecReturns(JSON.stringify({ "registry.example.com": "username" }));
it("should not return auth config for registry which is a partial match", async () => {
mockExecReturns(JSON.stringify({ "https://registry.example.com": "username" }));
mockSpawnReturns(
0,
JSON.stringify({
ServerURL: "registry.example.com",
ServerURL: "https://registry.example.com",
Username: "username",
Secret: "secret",
})
);

expect(await credentialProvider.getAuthConfig("registry", dockerConfig)).toEqual({
registryAddress: "registry.example.com",
username: "username",
password: "secret",
});
expect(await credentialProvider.getAuthConfig("https://registry.example.co", dockerConfig)).toBeUndefined();
});

it("should return undefined when no auth config found for registry", async () => {
Expand Down
3 changes: 2 additions & 1 deletion src/registry-auth-locator/credential-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { log } from "../logger";
import { exec, spawn } from "child_process";
import { RegistryAuthLocator } from "./registry-auth-locator";
import { AuthConfig } from "../docker/types";
import { registryMatches } from "./registry-matches";

export abstract class CredentialProvider implements RegistryAuthLocator {
abstract getName(): string;
Expand All @@ -19,7 +20,7 @@ export abstract class CredentialProvider implements RegistryAuthLocator {
log.debug(`Executing Docker credential provider: ${programName}`);

const credentials = await this.listCredentials(programName);
if (!Object.keys(credentials).some((credential) => credential.includes(registry))) {
if (!Object.keys(credentials).some((aRegistry) => registryMatches(aRegistry, registry))) {
log.debug(`No credential found for registry: "${registry}"`);
return undefined;
}
Expand Down
15 changes: 15 additions & 0 deletions src/registry-auth-locator/registry-matches.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { registryMatches } from "./registry-matches";

describe("registryMatches", () => {
it("should return true when registries are equal", () => {
expect(registryMatches("https://registry.example.com", "https://registry.example.com")).toBe(true);
});

it("should return true when registries are equal without protocol", () => {
expect(registryMatches("https://registry.example.com", "registry.example.com")).toBe(true);
});

it("should return false when registries do not match", () => {
expect(registryMatches("https://registry.example.com", "registry.example.co")).toBe(false);
});
});
2 changes: 2 additions & 0 deletions src/registry-auth-locator/registry-matches.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const registryMatches = (authConfigRegistry: string, requestedRegistry: string): boolean =>
authConfigRegistry == requestedRegistry || authConfigRegistry.endsWith("://" + requestedRegistry);

0 comments on commit 726057c

Please sign in to comment.