0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-03-17 22:31:28 -05:00

feat: create pre-configured role with m-api access when seeding db (#5908)

This commit is contained in:
Xiao Yijun 2024-05-23 13:58:41 +08:00 committed by GitHub
parent b5104d8c19
commit 25d67f33f3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 163 additions and 0 deletions

View file

@ -0,0 +1,6 @@
---
"@logto/schemas": minor
"@logto/cli": minor
---
create a pre-configured role with Management API access when seeding the database

View file

@ -0,0 +1,44 @@
import {
PredefinedScope,
getManagementApiResourceIndicator,
createPreConfiguredManagementApiAccessRole,
} from '@logto/schemas';
import { generateStandardId } from '@logto/shared';
import { sql, type CommonQueryMethods } from '@silverhand/slonik';
import { insertInto } from '../../../database.js';
/**
* Create a pre-configured role with Management API access
*
* Caution:
* This function should only be called after the tenant's Management API resource and the related all scope have been created.
*/
export const seedPreConfiguredManagementApiAccessRole = async (
pool: CommonQueryMethods,
tenantId: string
) => {
const role = createPreConfiguredManagementApiAccessRole(tenantId);
await pool.query(insertInto(role, 'roles'));
// Assign Logto Management API permission `all` to the Logto Management API M2M role
await pool.query(sql`
insert into roles_scopes (id, role_id, scope_id, tenant_id)
values (
${generateStandardId()},
${role.id},
(
select scopes.id
from scopes
join resources on
scopes.tenant_id = resources.tenant_id and
scopes.resource_id = resources.id
where resources.indicator = ${getManagementApiResourceIndicator(tenantId)}
and scopes.name = ${PredefinedScope.All}
and scopes.tenant_id = ${tenantId}
),
${tenantId}
)
`);
};

View file

@ -40,6 +40,7 @@ import { consoleLog, getPathInModule } from '../../../utils.js';
import { appendAdminConsoleRedirectUris, seedTenantCloudServiceApplication } from './cloud.js';
import { seedOidcConfigs } from './oidc-config.js';
import { seedPreConfiguredManagementApiAccessRole } from './roles.js';
import { seedTenantOrganizations } from './tenant-organizations.js';
import {
assignScopesToRole,
@ -150,6 +151,14 @@ export const seedTables = async (
await seedOidcConfigs(connection, defaultTenantId);
await seedAdminData(connection, defaultManagementApi);
/**
* Create a pre-configured role for the Logto Management API access
* in the default tenant (the default tenant is the only tenant for the OSS version, and the initial tenant for cloud).
*
* Called after the default tenant's Management API resource and the related all scope have been created.
*/
await seedPreConfiguredManagementApiAccessRole(connection, defaultTenantId);
await createTenant(connection, adminTenantId);
await seedOidcConfigs(connection, adminTenantId);
await seedAdminData(connection, createAdminDataInAdminTenant(defaultTenantId));

View file

@ -0,0 +1,93 @@
import { ConsoleLog, generateStandardId } from '@logto/shared';
import { yes } from '@silverhand/essentials';
import { sql } from '@silverhand/slonik';
import type { AlterationScript } from '../lib/types/alteration.js';
const isCi = yes(process.env.CI);
const defaultTenantId = 'default';
const defaultTenantManagementApiIndicator = `https://${defaultTenantId}.logto.app/api`;
const roleName = 'Logto Management API access';
const roleDescription = 'This default role grants access to the Logto management API.';
enum RoleType {
MachineToMachine = 'MachineToMachine',
}
enum PredefinedScope {
All = 'all',
}
const consoleLog = new ConsoleLog();
/**
* This script is to create a pre-configured Management API M2M role for new users.
* This script is **only for CI**, since we won't create this role for existing users, so this script is not applicable for existing db data.
*/
const alteration: AlterationScript = {
up: async (pool) => {
if (!isCi) {
consoleLog.info(
"Skipping the alteration script `next-1716291265-create-pre-configured-m-api-role.ts` since it's should not be applied to existing db data."
);
return;
}
/**
* Only affect the `default` tenant, since this is the only tenant in the OSS version and the initial tenant in the cloud version.
* So we only need to care about this role for the `default` tenant.
*/
const roleId = generateStandardId();
await pool.query(sql`
insert into roles (id, tenant_id, name, description, type)
values (
${roleId},
${defaultTenantId},
${roleName},
${roleDescription},
${RoleType.MachineToMachine}
);
`);
// Assign Logto Management API permission `all` to the Logto Management API M2M role
await pool.query(sql`
insert into roles_scopes (id, role_id, scope_id, tenant_id)
values (
${generateStandardId()},
${roleId},
(
select scopes.id
from scopes
join resources on
scopes.tenant_id = resources.tenant_id and
scopes.resource_id = resources.id
where resources.indicator = ${defaultTenantManagementApiIndicator}
and scopes.name = ${PredefinedScope.All}
and scopes.tenant_id = ${defaultTenantId}
),
${defaultTenantId}
)
`);
},
down: async (pool) => {
if (!isCi) {
consoleLog.info(
"Skipping the down script `next-1716291265-create-pre-configured-m-api-role.ts` since it's should not be applied to production db."
);
return;
}
// Delete the created role
await pool.query(sql`
delete from roles
where tenant_id = ${defaultTenantId}
and name = ${roleName}
and description = ${roleDescription}
and type = ${RoleType.MachineToMachine}
`);
},
};
export default alteration;

View file

@ -176,3 +176,14 @@ export const createMeApiInAdminTenant = () => {
},
} satisfies AdminData);
};
/**
* Create a pre-configured M2M role for Management API access.
*/
export const createPreConfiguredManagementApiAccessRole = (tenantId: string): CreateRole => ({
tenantId,
id: generateStandardId(),
description: 'This default role grants access to the Logto management API.',
name: 'Logto Management API access',
type: RoleType.MachineToMachine,
});