From f8ae3588d29ba67b0a3c4f2fef03ae4a7ec54810 Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Tue, 5 Mar 2024 16:32:59 +0800 Subject: [PATCH] feat(cli): setup logs pruner application for admin tenant --- .../cli/src/commands/database/seed/cloud.ts | 77 ++++++++++++++++++- .../cli/src/commands/database/seed/tables.ts | 7 +- 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/commands/database/seed/cloud.ts b/packages/cli/src/commands/database/seed/cloud.ts index a6cc6446d..3a45bad34 100644 --- a/packages/cli/src/commands/database/seed/cloud.ts +++ b/packages/cli/src/commands/database/seed/cloud.ts @@ -6,8 +6,16 @@ import { createAdminTenantApplicationRole, createCloudConnectionConfig, AdminTenantRole, + CloudScope, + cloudApiIndicator, + RoleType, + ApplicationType, + type CreateApplication, + type CreateRole, + type CreateScope, + type CreateApplicationsRole, } from '@logto/schemas'; -import { GlobalValues } from '@logto/shared'; +import { GlobalValues, generateStandardId, generateStandardSecret } from '@logto/shared'; import { appendPath } from '@silverhand/essentials'; import type { CommonQueryMethods } from 'slonik'; import { sql } from 'slonik'; @@ -15,6 +23,8 @@ import { sql } from 'slonik'; import { insertInto } from '../../../database.js'; import { consoleLog } from '../../../utils.js'; +import { assignScopesToRole } from './tenant.js'; + /** * Append Redirect URIs for the default tenant callback in cloud Admin Console. * It reads the same env variables as core to construct the cloud `UrlSet`. @@ -92,3 +102,68 @@ export const seedTenantCloudServiceApplication = async ( consoleLog.succeed('Cloud Service Application successfully created for:', tenantId); }; + +/** + * Setup Logs Pruner application for admin tenant + */ +export const setupLogsPrunerApplicationForAdminTenant = async (pool: CommonQueryMethods) => { + // Add CloudScope.PruneLogs scope to cloud api resource + const { id: cloudApiResourceId } = await pool.one<{ id: string }>(sql` + select id from resources + where indicator = ${cloudApiIndicator} + and tenant_id = ${adminTenantId} + `); + + const pruneLogsScope: CreateScope = { + tenantId: adminTenantId, + id: generateStandardId(), + name: CloudScope.PruneLogs, + description: + 'Allow pruning logs which are expired. This scope is only available to Logs Pruner M2M application.', + resourceId: cloudApiResourceId, + }; + + await pool.query(insertInto(pruneLogsScope, 'scopes')); + + // Create logs pruner role + const logsPrunerRole: CreateRole = { + tenantId: adminTenantId, + id: generateStandardId(), + name: 'logs-pruner', + description: 'The role for the application that prunes logs which are expired.', + type: RoleType.MachineToMachine, + }; + await pool.query(insertInto(logsPrunerRole, 'roles')); + + // Assign CloudScope.PruneLogs to logsPruner role + await assignScopesToRole(pool, adminTenantId, logsPrunerRole.id, pruneLogsScope.id); + + // Create Logs Pruner M2M application + const logsPrunerApplication: CreateApplication = { + tenantId: adminTenantId, + id: generateStandardId(), + name: 'Logs Pruner', + description: 'The application that prunes logs which are expired.', + type: ApplicationType.MachineToMachine, + secret: generateStandardSecret(), + oidcClientMetadata: { + redirectUris: [], + postLogoutRedirectUris: [], + }, + customClientMetadata: {}, + }; + await pool.query(insertInto(logsPrunerApplication, 'applications')); + + // Assign logs-pruner role to Logs Pruner application + const applicationRoleRelation: CreateApplicationsRole = { + id: generateStandardId(), + tenantId: adminTenantId, + applicationId: logsPrunerApplication.id, + roleId: logsPrunerRole.id, + }; + await pool.query(insertInto(applicationRoleRelation, 'applications_roles')); + + consoleLog.succeed( + 'Logs Pruner machine-to-machine application successfully setup for admin tenant' + ); +}; diff --git a/packages/cli/src/commands/database/seed/tables.ts b/packages/cli/src/commands/database/seed/tables.ts index 33723c080..fbcce0aa3 100644 --- a/packages/cli/src/commands/database/seed/tables.ts +++ b/packages/cli/src/commands/database/seed/tables.ts @@ -38,7 +38,11 @@ import { getDatabaseName } from '../../../queries/database.js'; import { updateDatabaseTimestamp } from '../../../queries/system.js'; import { consoleLog, getPathInModule } from '../../../utils.js'; -import { appendAdminConsoleRedirectUris, seedTenantCloudServiceApplication } from './cloud.js'; +import { + appendAdminConsoleRedirectUris, + setupLogsPrunerApplicationForAdminTenant, + seedTenantCloudServiceApplication, +} from './cloud.js'; import { seedOidcConfigs } from './oidc-config.js'; import { seedTenantOrganizations } from './tenant-organizations.js'; import { @@ -198,6 +202,7 @@ export const seedCloud = async (connection: DatabaseTransactionConnection) => { await Promise.all([ appendAdminConsoleRedirectUris(connection), seedTenantCloudServiceApplication(connection, adminTenantId), + setupLogsPrunerApplicationForAdminTenant(connection), ]); };