import { Config } from "app/gen-server/entity/Config"; import { HomeDBManager } from "app/gen-server/lib/homedb/HomeDBManager"; import axios from "axios"; import * as chai from "chai"; import omit from "lodash/omit"; import { TestServer } from "test/gen-server/apiUtils"; import { configForUser } from "test/gen-server/testUtils"; import * as testUtils from "test/server/testUtils"; describe("InstallConfig", function () { const assert = chai.assert; let server: TestServer; let dbManager: HomeDBManager; let homeUrl: string; const chimpy = configForUser("Chimpy"); const kiwi = configForUser("Kiwi"); const support = configForUser("Support"); const anonymous = configForUser("Anonymous"); const chimpyEmail = "chimpy@getgrist.com"; let oldEnv: testUtils.EnvironmentSnapshot; testUtils.setTmpLogLevel("error"); before(async function () { oldEnv = new testUtils.EnvironmentSnapshot(); process.env.GRIST_DEFAULT_EMAIL = chimpyEmail; server = new TestServer(this); homeUrl = await server.start(["home"]); dbManager = server.dbManager; }); after(async function () { oldEnv.restore(); await server.stop(); }); describe("GET /api/install/configs/:key", async function () { let config: Config; before(async function () { await dbManager.connection.transaction(async (manager) => { config = new Config(); config.key = "audit_log_streaming_destinations"; config.value = [ { id: "4e9f3c26-d069-43f2-8388-1f0f906c0ca3", name: "splunk", url: "https://hec.example.com:8088/services/collector/event", token: "Splunk B5A79AAD-D822-46CC-80D1-819F80D7BFB0", }, ]; await manager.save(config); }); }); after(async function () { await dbManager.connection.transaction((manager) => manager.createQueryBuilder().delete().from(Config).execute() ); }); it("returns 200 on success", async function () { const resp = await axios.get( `${homeUrl}/api/install/configs/audit_log_streaming_destinations`, chimpy ); assert.equal(resp.status, 200); assert.deepEqual(resp.data, { id: 1, key: "audit_log_streaming_destinations", value: [ { id: "4e9f3c26-d069-43f2-8388-1f0f906c0ca3", name: "splunk", url: "https://hec.example.com:8088/services/collector/event", token: "Splunk B5A79AAD-D822-46CC-80D1-819F80D7BFB0", }, ], createdAt: config.createdAt.toISOString(), updatedAt: config.updatedAt.toISOString(), }); }); it("returns 400 if key is invalid", async function () { const resp = await axios.get( `${homeUrl}/api/install/configs/invalid`, chimpy ); assert.equal(resp.status, 400); assert.deepEqual(resp.data, { error: "Invalid config key", details: { userError: 'Error: value is not "audit_log_streaming_destinations"', }, }); }); it("returns 403 if user isn't an install admin", async function () { for (const user of [kiwi, anonymous]) { const resp = await axios.get( `${homeUrl}/api/install/configs/audit_log_streaming_destinations`, user ); assert.equal(resp.status, 403); assert.deepEqual(resp.data, { error: "Access denied" }); } const resp = await axios.get( `${homeUrl}/api/install/configs/audit_log_streaming_destinations`, support ); assert.equal(resp.status, 200); }); it("returns 404 if key doesn't exist", async function () { await dbManager.connection.transaction((manager) => manager.remove(config) ); const resp = await axios.get( `${homeUrl}/api/install/configs/audit_log_streaming_destinations`, chimpy ); assert.equal(resp.status, 404); assert.deepEqual(resp.data, { error: "config not found", }); }); }); describe("PUT /api/install/configs/:key", async function () { after(async function () { await dbManager.connection.transaction((manager) => manager.createQueryBuilder().delete().from(Config).execute() ); }); function testCreateOrUpdate({ status }: { status: 200 | 201 }) { return async function () { const resp1 = await axios.put( `${homeUrl}/api/install/configs/audit_log_streaming_destinations`, [ { id: "4e9f3c26-d069-43f2-8388-1f0f906c0ca3", name: "splunk", url: "https://hec.example.com:8088/services/collector/event", token: "Splunk B5A79AAD-D822-46CC-80D1-819F80D7BFB0", }, ], chimpy ); assert.equal(resp1.status, status); assert.deepEqual(omit(resp1.data, "createdAt", "updatedAt"), { id: 2, key: "audit_log_streaming_destinations", value: [ { id: "4e9f3c26-d069-43f2-8388-1f0f906c0ca3", name: "splunk", url: "https://hec.example.com:8088/services/collector/event", token: "Splunk B5A79AAD-D822-46CC-80D1-819F80D7BFB0", }, ], }); assert.hasAllKeys(resp1.data, [ "id", "key", "value", "createdAt", "updatedAt", ]); const resp2 = await axios.get( `${homeUrl}/api/install/configs/audit_log_streaming_destinations`, chimpy ); assert.equal(resp2.status, 200); assert.deepEqual(resp2.data, resp1.data); }; } it( "returns 201 if resource was created", testCreateOrUpdate({ status: 201 }) ); it( "returns 200 if resource was updated", testCreateOrUpdate({ status: 200 }) ); it("returns 400 if key invalid", async function () { const resp = await axios.put( `${homeUrl}/api/install/configs/invalid`, "invalid", chimpy ); assert.equal(resp.status, 400); assert.deepEqual(resp.data, { error: "Invalid config key", details: { userError: 'Error: value is not "audit_log_streaming_destinations"', }, }); }); it("returns 400 if body is invalid", async function () { let resp = await axios.put( `${homeUrl}/api/install/configs/audit_log_streaming_destinations`, "invalid", chimpy ); assert.equal(resp.status, 400); assert.deepEqual(resp.data, { error: "Invalid config value", details: { userError: "Error: value is not an array", }, }); resp = await axios.put( `${homeUrl}/api/install/configs/audit_log_streaming_destinations`, ["invalid"], chimpy ); assert.equal(resp.status, 400); assert.deepEqual(resp.data, { error: "Invalid config value", details: { userError: "Error: value[0] is not a AuditLogStreamingDestination; value[0] is not an object", }, }); }); it("returns 403 if user isn't an install admin", async function () { for (const user of [kiwi, anonymous]) { const resp = await axios.put( `${homeUrl}/api/install/configs/audit_log_streaming_destinations`, [ { id: "4e9f3c26-d069-43f2-8388-1f0f906c0ca3", name: "splunk", url: "https://hec.example.com:8088/services/collector/event", token: "Splunk B5A79AAD-D822-46CC-80D1-819F80D7BFB0", }, ], user ); assert.equal(resp.status, 403); assert.deepEqual(resp.data, { error: "Access denied" }); } const resp = await axios.put( `${homeUrl}/api/install/configs/audit_log_streaming_destinations`, [ { id: "4e9f3c26-d069-43f2-8388-1f0f906c0ca3", name: "splunk", url: "https://hec.example.com:8088/services/collector/event", token: "Splunk B5A79AAD-D822-46CC-80D1-819F80D7BFB0", }, ], support ); assert.equal(resp.status, 200); }); }); describe("DELETE /api/install/configs/:key", async function () { before(async function () { await dbManager.connection.transaction(async (manager) => { const config = new Config(); config.key = "audit_log_streaming_destinations"; config.value = [ { id: "4e9f3c26-d069-43f2-8388-1f0f906c0ca3", name: "splunk", url: "https://hec.example.com:8088/services/collector/event", token: "Splunk B5A79AAD-D822-46CC-80D1-819F80D7BFB0", }, ]; await manager.save(config); }); }); after(async function () { await dbManager.connection.transaction((manager) => manager.createQueryBuilder().delete().from(Config).execute() ); }); it("returns 200 on success", async function () { let resp = await axios.delete( `${homeUrl}/api/install/configs/audit_log_streaming_destinations`, chimpy ); assert.equal(resp.status, 200); assert.equal(resp.data, null); resp = await axios.get( `${homeUrl}/api/install/configs/audit_log_streaming_destinations`, chimpy ); assert.equal(resp.status, 404); assert.deepEqual(resp.data, { error: "config not found", }); }); it("returns 400 if key is invalid", async function () { const resp = await axios.delete( `${homeUrl}/api/install/configs/invalid`, chimpy ); assert.equal(resp.status, 400); assert.deepEqual(resp.data, { error: "Invalid config key", details: { userError: 'Error: value is not "audit_log_streaming_destinations"', }, }); }); it("returns 403 if user isn't an install admin", async function () { for (const user of [kiwi, anonymous]) { const resp = await axios.delete( `${homeUrl}/api/install/configs/audit_log_streaming_destinations`, user ); assert.equal(resp.status, 403); assert.deepEqual(resp.data, { error: "Access denied" }); } }); it("returns 404 if key doesn't exist", async function () { const resp = await axios.delete( `${homeUrl}/api/install/configs/audit_log_streaming_destinations`, support ); assert.equal(resp.status, 404); assert.deepEqual(resp.data, { error: "config not found", }); }); }); });