Skip to content

Commit 7733a55

Browse files
Allow only READONLY_USERNAME and READONLY_PASSWORD to be set for auth (#72)
This is useful for registries that are supposed to be just mirrors of upstream registries (using REGISTRIES_JSON).
1 parent 56f4d96 commit 7733a55

File tree

2 files changed

+30
-5
lines changed

2 files changed

+30
-5
lines changed

src/authentication-method.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,20 @@ import type { AuthenticatorCredentials } from "./user";
66
export async function authenticationMethodFromEnv(env: Env) {
77
if (env.JWT_REGISTRY_TOKENS_PUBLIC_KEY) {
88
return await newRegistryTokens(env.JWT_REGISTRY_TOKENS_PUBLIC_KEY);
9-
} else if (env.USERNAME && env.PASSWORD) {
10-
const credentials: AuthenticatorCredentials[] = [
11-
{ username: env.USERNAME, password: env.PASSWORD, capabilities: ["pull", "push"] }
12-
];
9+
} else if ((env.USERNAME && env.PASSWORD) || (env.READONLY_USERNAME && env.READONLY_PASSWORD)) {
10+
const credentials: AuthenticatorCredentials[] = [];
1311

12+
if (env.USERNAME && env.PASSWORD) {
13+
credentials.push({ username: env.USERNAME, password: env.PASSWORD, capabilities: ["pull", "push"] });
14+
}
1415
if (env.READONLY_USERNAME && env.READONLY_PASSWORD) {
1516
credentials.push({ username: env.READONLY_USERNAME, password: env.READONLY_PASSWORD, capabilities: ["pull"] });
1617
}
1718

1819
return new UserAuthenticator(credentials);
1920
}
2021

21-
console.error("Either env.JWT_REGISTRY_TOKENS_PUBLIC_KEY must be set or both env.USERNAME, env.PASSWORD must be set.");
22+
console.error("Either env.JWT_REGISTRY_TOKENS_PUBLIC_KEY must be set or both env.USERNAME, env.PASSWORD must be set or both env.READONLY_USERNAME, env.READONLY_PASSWORD must be set.");
2223

2324
// invalid configuration
2425
return undefined;

test/index.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,30 @@ describe("http client", () => {
466466

467467
expect("exists" in res && res.exists).toBe(false);
468468
});
469+
470+
test("test manifest exists with readonly", async () => {
471+
envBindings = { ...bindings };
472+
envBindings.JWT_REGISTRY_TOKENS_PUBLIC_KEY = "";
473+
envBindings.PASSWORD = "";
474+
envBindings.USERNAME = "";
475+
envBindings.READONLY_PASSWORD = "world";
476+
envBindings.READONLY_USERNAME = "hello";
477+
envBindings.REGISTRIES_JSON = undefined;
478+
global.fetch = async function (r: RequestInfo): Promise<Response> {
479+
return fetch(new Request(r));
480+
};
481+
const client = new RegistryHTTPClient(envBindings, {
482+
registry: "https://localhost",
483+
password_env: "PASSWORD",
484+
username: "hello",
485+
});
486+
const res = await client.manifestExists("namespace/hello", "latest");
487+
if ("response" in res) {
488+
expect(await res.response.json()).toEqual({ status: res.response.status });
489+
}
490+
491+
expect("exists" in res && res.exists).toBe(false);
492+
});
469493
});
470494

471495
describe("push and catalog", () => {

0 commit comments

Comments
 (0)