chat-ui-agent-demo / src /lib /server /agent /AgentPushAuth.spec.ts
Mike0021's picture
Deploy verified chat and coding agent UX (part 2)
fae625a verified
Raw History Blame Contribute Delete
5.36 kB
import { describe, expect, it, vi } from "vitest";
import {
parseServicePushRepos,
resolveAgentPushCredential,
type ResolveAgentPushCredentialOptions,
} from "./AgentPushAuth";
const target = {
repoId: "service-owner/new-agent-app",
repoType: "space" as const,
branch: "main",
create: true,
};
const configValues = {
AGENT_HF_TOKEN: "hf_service_secret",
HF_TOKEN: "hf_fallback_secret",
AGENT_SANDBOX_NAMESPACE: "service-owner",
AGENT_SERVICE_PUSH_REPOS: "",
};
const defaultConfigValue: NonNullable<ResolveAgentPushCredentialOptions["configValue"]> = (name) =>
configValues[name];
function options(
overrides: Partial<ResolveAgentPushCredentialOptions> = {}
): ResolveAgentPushCredentialOptions {
return {
workspace: { repo: { kind: "blank" } },
target,
configValue: defaultConfigValue,
resolveServiceOwner: vi.fn().mockResolvedValue("service-owner"),
...overrides,
};
}
describe("resolveAgentPushCredential", () => {
it("always prefers the signed-in user's OAuth token", async () => {
const resolveServiceOwner = vi.fn();
await expect(
resolveAgentPushCredential(
options({
userToken: "hf_user_token",
workspace: { repo: { kind: "hf", ref: "someone/existing", repoType: "space" } },
target: { ...target, repoId: "arbitrary-owner/existing", create: false },
resolveServiceOwner,
})
)
).resolves.toBe("hf_user_token");
expect(resolveServiceOwner).not.toHaveBeenCalled();
});
it("allows service-token creation only in the configured namespace", async () => {
await expect(resolveAgentPushCredential(options())).resolves.toBe("hf_service_secret");
await expect(
resolveAgentPushCredential(options({ target: { ...target, repoId: "attacker/new-app" } }))
).rejects.toMatchObject({ status: 403 });
});
it("never uses the service token to update a pre-existing or imported repository", async () => {
await expect(
resolveAgentPushCredential(
options({
workspace: {
repo: { kind: "hf", ref: "service-owner/important", repoType: "space" },
},
target: { ...target, repoId: "service-owner/important", create: false },
})
)
).rejects.toMatchObject({ status: 403 });
await expect(
resolveAgentPushCredential(options({ target: { ...target, create: false } }))
).rejects.toMatchObject({ status: 403 });
await expect(
resolveAgentPushCredential(
options({
workspace: { repo: { kind: "git", ref: "https://example.com/source.git" } },
target: { ...target, create: false },
configValue: (name) =>
name === "AGENT_SERVICE_PUSH_REPOS"
? "space:service-owner/new-agent-app"
: defaultConfigValue(name),
})
)
).rejects.toMatchObject({ status: 403 });
});
it("allows a delta update only for the exact current HF source and allowlist entry", async () => {
const allowlisted = options({
workspace: {
repo: { kind: "hf", ref: "service-owner/live-fixture", repoType: "space" },
},
target: { ...target, repoId: "service-owner/live-fixture", create: false },
configValue: (name) => {
if (name === "AGENT_SERVICE_PUSH_REPOS") {
return "model:service-owner/other, space:service-owner/live-fixture";
}
return defaultConfigValue(name);
},
});
await expect(resolveAgentPushCredential(allowlisted)).resolves.toBe("hf_service_secret");
await expect(
resolveAgentPushCredential({
...allowlisted,
target: { ...allowlisted.target, repoId: "service-owner/different" },
})
).rejects.toMatchObject({ status: 403 });
await expect(
resolveAgentPushCredential({
...allowlisted,
target: { ...allowlisted.target, repoType: "model" },
})
).rejects.toMatchObject({ status: 403 });
await expect(
resolveAgentPushCredential({
...allowlisted,
target: { ...allowlisted.target, create: true },
})
).rejects.toMatchObject({ status: 403 });
});
it("retains the namespace gate even for an exact allowlist entry", async () => {
await expect(
resolveAgentPushCredential(
options({
workspace: {
repo: { kind: "hf", ref: "other-owner/live-fixture", repoType: "space" },
},
target: { ...target, repoId: "other-owner/live-fixture", create: false },
configValue: (name) => {
if (name === "AGENT_SERVICE_PUSH_REPOS") {
return "space:other-owner/live-fixture";
}
return defaultConfigValue(name);
},
})
)
).rejects.toMatchObject({ status: 403 });
});
it("parses only exact typed repository entries", () => {
expect([
...parseServicePushRepos(" space:owner/app, model:owner/m, bad, SPACE:owner/nope "),
]).toEqual(["space:owner/app", "model:owner/m"]);
});
it("falls back to the authenticated service owner when no namespace is configured", async () => {
const resolveServiceOwner = vi.fn().mockResolvedValue("service-owner");
await expect(
resolveAgentPushCredential(
options({
configValue: (name) => (name === "AGENT_HF_TOKEN" ? "hf_service_secret" : ""),
resolveServiceOwner,
})
)
).resolves.toBe("hf_service_secret");
expect(resolveServiceOwner).toHaveBeenCalledWith("hf_service_secret");
});
it("requires either a user credential or configured service credential", async () => {
await expect(
resolveAgentPushCredential(options({ configValue: () => "" }))
).rejects.toMatchObject({ status: 401 });
});
});