From 47881b6d6e054d128788e3b581d3500c4581f6e9 Mon Sep 17 00:00:00 2001 From: wangsijie Date: Tue, 14 Mar 2023 15:15:45 +0800 Subject: [PATCH] feat(schemas): add service logs table (#3390) --- packages/core/src/tenants/utils.ts | 6 ++- .../next-1678716747-service-logs.ts | 51 +++++++++++++++++++ packages/schemas/tables/_after_all.sql | 5 ++ packages/schemas/tables/service_logs.sql | 17 +++++++ 4 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 packages/schemas/alterations/next-1678716747-service-logs.ts create mode 100644 packages/schemas/tables/service_logs.sql diff --git a/packages/core/src/tenants/utils.ts b/packages/core/src/tenants/utils.ts index bcfdda2a0..64aa2ac85 100644 --- a/packages/core/src/tenants/utils.ts +++ b/packages/core/src/tenants/utils.ts @@ -1,4 +1,4 @@ -import { Systems } from '@logto/schemas'; +import { ServiceLogs, Systems } from '@logto/schemas'; import { Tenants } from '@logto/schemas/models'; import { isKeyInObject } from '@logto/shared'; import { conditional, conditionalString } from '@silverhand/essentials'; @@ -55,7 +55,9 @@ export const checkRowLevelSecurity = async (client: CommonQueryMethods) => { and rowsecurity=false `); - const rlsDisabled = rows.filter(({ tablename }) => tablename !== Systems.table); + const rlsDisabled = rows.filter( + ({ tablename }) => tablename !== Systems.table && tablename !== ServiceLogs.table + ); if (rlsDisabled.length > 0) { throw new Error( diff --git a/packages/schemas/alterations/next-1678716747-service-logs.ts b/packages/schemas/alterations/next-1678716747-service-logs.ts new file mode 100644 index 000000000..b9437531e --- /dev/null +++ b/packages/schemas/alterations/next-1678716747-service-logs.ts @@ -0,0 +1,51 @@ +import type { CommonQueryMethods } from 'slonik'; +import { sql } from 'slonik'; + +import type { AlterationScript } from '../lib/types/alteration.js'; + +const getId = (value: string) => sql.identifier([value]); + +const getDatabaseName = async (pool: CommonQueryMethods) => { + const { currentDatabase } = await pool.one<{ currentDatabase: string }>(sql` + select current_database(); + `); + + return currentDatabase.replaceAll('-', '_'); +}; + +const alteration: AlterationScript = { + up: async (pool) => { + const database = await getDatabaseName(pool); + const baseRole = `logto_tenant_${database}`; + const baseRoleId = getId(baseRole); + + await pool.query(sql` + create table service_logs ( + id varchar(21) not null, + tenant_id varchar(21) not null + references tenants (id) on update cascade on delete cascade, + type varchar(64) not null, + payload jsonb /* @use ArbitraryObject */ not null default '{}'::jsonb, + created_at timestamptz not null default(now()), + primary key (id) + ); + + create index service_logs__id + on service_logs (id); + + create index service_logs__tenant_id__type + on service_logs (tenant_id, type); + + revoke all privileges + on table service_logs + from ${baseRoleId}; + `); + }, + down: async (pool) => { + await pool.query(sql` + drop table service_logs; + `); + }, +}; + +export default alteration; diff --git a/packages/schemas/tables/_after_all.sql b/packages/schemas/tables/_after_all.sql index 513d9cd5a..8a3d9b0e4 100644 --- a/packages/schemas/tables/_after_all.sql +++ b/packages/schemas/tables/_after_all.sql @@ -28,6 +28,11 @@ revoke all privileges on table systems from logto_tenant_${database}; +---- Revoke all privileges on service_logs table for tenant roles ---- +revoke all privileges + on table service_logs + from logto_tenant_${database}; + ---- Create policies to make internal roles read-only ---- /** diff --git a/packages/schemas/tables/service_logs.sql b/packages/schemas/tables/service_logs.sql new file mode 100644 index 000000000..c9642d90e --- /dev/null +++ b/packages/schemas/tables/service_logs.sql @@ -0,0 +1,17 @@ +create table service_logs ( + id varchar(21) not null, + tenant_id varchar(21) not null + references tenants (id) on update cascade on delete cascade, + type varchar(64) not null, + payload jsonb /* @use ArbitraryObject */ not null default '{}'::jsonb, + created_at timestamptz not null default(now()), + primary key (id) +); + +create index service_logs__id + on service_logs (id); + +create index service_logs__tenant_id__type + on service_logs (tenant_id, type); + +/* no_after_each */