feat(backend): enforce user-owned sessions

This commit is contained in:
User
2026-07-16 18:32:52 +02:00
parent 72db6b823d
commit 458eb13c89
15 changed files with 626 additions and 105 deletions
+29
View File
@@ -48,6 +48,35 @@ test("PUT /settings persists and GET reads it back", async () => {
}
});
test("settings are isolated by the authenticated repository principal", async () => {
const preferences = new Map<string, any>();
const runner = {
withPrincipal: (principal: any) => ({
preferencesGet: async () => preferences.get(principal.subject) ?? {},
preferencesSet: async (next: any) => { preferences.set(principal.subject, next); },
}),
};
const app = buildApp(loadConfig({ AUTH_MODE: "upstream", THT_HARNESS_DIR: "../harness" }), {
thtRunner: runner as any,
listModels: async () => [],
});
const headers = (subject: string) => ({
"x-thoth-principal-issuer": "portal",
"x-thoth-principal-subject": subject,
"x-thoth-is-admin": "0",
});
await app.inject({
method: "PUT", url: "/settings", headers: headers("alice"),
payload: { workspace: "psd", provider: "zai", model: "glm-5.2", thinking: "high" },
});
const alice = await app.inject({ method: "GET", url: "/settings", headers: headers("alice") });
const bob = await app.inject({ method: "GET", url: "/settings", headers: headers("bob") });
expect(alice.json()).toMatchObject({ workspace: "psd", thinking: "high" });
expect(bob.json()).not.toMatchObject({ workspace: "psd", thinking: "high" });
});
test("PUT /settings rejects an unknown model when a model list is available", async () => {
const { app, dir } = appWithTmpSettings({}, {
listModels: async () => [{ provider: "zai", id: "glm-5.2", name: "GLM 5.2", reasoning: true }],