diff --git a/packages/cli/src/commands/database/ogcio/applications.ts b/packages/cli/src/commands/database/ogcio/applications.ts index 08fd097992f..56d50d850a9 100644 --- a/packages/cli/src/commands/database/ogcio/applications.ts +++ b/packages/cli/src/commands/database/ogcio/applications.ts @@ -6,6 +6,7 @@ import { sql, type DatabaseTransactionConnection } from '@silverhand/slonik'; import { type ApplicationSeeder } from './ogcio-seeder.js'; import { createOrUpdateItem } from './queries.js'; +import { applyManagementApiRole } from './resources-rbac.js'; type SeedingApplication = { id: string; @@ -91,5 +92,18 @@ export const seedApplications = async (params: { await Promise.all(queries); + // Seed the M2M application with the correct role + const m2mManagementAPIsApplicationId = params.applications.find( + (app) => app.apply_management_api_role + )?.id; + + if (m2mManagementAPIsApplicationId) { + await applyManagementApiRole( + params.transaction, + params.tenantId, + m2mManagementAPIsApplicationId + ); + } + return appsToCreate; }; diff --git a/packages/cli/src/commands/database/ogcio/ogcio-seeder-local.json b/packages/cli/src/commands/database/ogcio/ogcio-seeder-local.json index fe48e1eab60..31ca6a34f55 100644 --- a/packages/cli/src/commands/database/ogcio/ogcio-seeder-local.json +++ b/packages/cli/src/commands/database/ogcio/ogcio-seeder-local.json @@ -107,30 +107,24 @@ "id": "upload-public-servant", "name": "File Upload Public Servant", "description": "File Upload Public servant", - "specific_permissions": [ - "upload:file:*", "profile:user:read" - ] + "specific_permissions": ["upload:file:*", "profile:user:read"] }, { "id": "bb-inactive-ps", "name": "Inactive Public Servant", "description": "Inactive Public Servant", - "specific_permissions": [ - "bb:public-servant.inactive:*" - ] + "specific_permissions": ["bb:public-servant.inactive:*"] }, { "id": "m2m-ps-profile-reader", "name": "M2M Public Servant Profile Reader", "description": "Role for M2M Applications that need to read from Profile resources", - "specific_permissions": [ - "profile:user:read" - ], + "specific_permissions": ["profile:user:read"], "type": "MachineToMachine", "related_applications": [ - {"application_id":"ddl4llp30risjwcjymqw3", "organization_id": "ogcio"}, - {"application_id":"ddl4llp30risjwcjymqw3", "organization_id": "first-testing"}, - {"application_id":"ddl4llp30risjwcjymqw3", "organization_id": "second-testing"} + { "application_id": "ddl4llp30risjwcjymqw3", "organization_id": "ogcio" }, + { "application_id": "ddl4llp30risjwcjymqw3", "organization_id": "first-testing" }, + { "application_id": "ddl4llp30risjwcjymqw3", "organization_id": "second-testing" } ] }, { @@ -147,8 +141,8 @@ ], "type": "MachineToMachine", "related_applications": [ - {"application_id":"qrtllp45fgbvsdjyasd5", "organization_id": "first-testing"}, - {"application_id":"qrtllp45fgbvsdjyasd5", "organization_id": "second-testing"} + { "application_id": "qrtllp45fgbvsdjyasd5", "organization_id": "first-testing" }, + { "application_id": "qrtllp45fgbvsdjyasd5", "organization_id": "second-testing" } ] } ], @@ -243,6 +237,17 @@ "secret": "e2e_tester_local_secret", "id": "qrtllp45fgbvsdjyasd5", "is_third_party": false + }, + { + "name": "M2M Management APIs", + "description": "Machine 2 Machine application used to communicate with the Logto Management APIs", + "type": "MachineToMachine", + "redirect_uri": "", + "logout_redirect_uri": "", + "secret": "m2m_management_api_local_secret", + "id": "46ewhh940rn1e29cmecxs", + "is_third_party": false, + "apply_management_api_role": true } ], "resources": [ @@ -308,10 +313,7 @@ }, { "resource_id": "upload-api", - "specific_permissions": [ - "upload:file.self:write", - "upload:file.self:read" - ] + "specific_permissions": ["upload:file.self:write", "upload:file.self:read"] } ], "resource_roles": [ @@ -350,9 +352,7 @@ }, { "resource_id": "upload-api", - "specific_permissions": [ - "upload:file.self:read" - ] + "specific_permissions": ["upload:file.self:read"] } ] }, @@ -363,9 +363,7 @@ "permissions": [ { "resource_id": "profile-api", - "specific_permissions": [ - "profile:user:read" - ] + "specific_permissions": ["profile:user:read"] } ], "type": "MachineToMachine", diff --git a/packages/cli/src/commands/database/ogcio/ogcio-seeder-testing.json b/packages/cli/src/commands/database/ogcio/ogcio-seeder-testing.json index d23e13fb15f..f632f9943c6 100644 --- a/packages/cli/src/commands/database/ogcio/ogcio-seeder-testing.json +++ b/packages/cli/src/commands/database/ogcio/ogcio-seeder-testing.json @@ -91,22 +91,18 @@ "id": "bb-inactive-ps", "name": "Inactive Public Servant", "description": "Inactive Public Servant", - "specific_permissions": [ - "bb:public-servant.inactive:*" - ] + "specific_permissions": ["bb:public-servant.inactive:*"] }, { "id": "m2m-ps-profile-reader", "name": "M2M Public Servant Profile Reader", "description": "Role for M2M Applications that need to read from Profile resources", - "specific_permissions": [ - "profile:user:read" - ], + "specific_permissions": ["profile:user:read"], "type": "MachineToMachine", "related_applications": [ - {"application_id":"tty6llp30risjwcjhbvc9", "organization_id": "ogcio"}, - {"application_id":"tty6llp30risjwcjhbvc9", "organization_id": "first-testing"}, - {"application_id":"tty6llp30risjwcjhbvc9", "organization_id": "second-testing"} + { "application_id": "tty6llp30risjwcjhbvc9", "organization_id": "ogcio" }, + { "application_id": "tty6llp30risjwcjhbvc9", "organization_id": "first-testing" }, + { "application_id": "tty6llp30risjwcjhbvc9", "organization_id": "second-testing" } ] }, { @@ -123,8 +119,8 @@ ], "type": "MachineToMachine", "related_applications": [ - {"application_id":"treftr21fgbvsdjwlol9", "organization_id": "first-testing"}, - {"application_id":"treftr21fgbvsdjwlol9", "organization_id": "second-testing"} + { "application_id": "treftr21fgbvsdjwlol9", "organization_id": "first-testing" }, + { "application_id": "treftr21fgbvsdjwlol9", "organization_id": "second-testing" } ] } ], @@ -208,6 +204,17 @@ "secret": "", "id": "treftr21fgbvsdjwlol9", "is_third_party": false + }, + { + "name": "M2M Management APIs", + "description": "Machine 2 Machine application used to communicate with the Logto Management APIs", + "type": "MachineToMachine", + "redirect_uri": "", + "logout_redirect_uri": "", + "secret": "", + "id": "46ewhh940rn1e29cmecxs", + "is_third_party": false, + "apply_management_api_role": true } ], "resources": [ @@ -273,10 +280,7 @@ }, { "resource_id": "upload-api", - "specific_permissions": [ - "upload:file.self:write", - "upload:file.self:read" - ] + "specific_permissions": ["upload:file.self:write", "upload:file.self:read"] } ], "resource_roles": [ @@ -315,9 +319,7 @@ }, { "resource_id": "upload-api", - "specific_permissions": [ - "upload:file.self:read" - ] + "specific_permissions": ["upload:file.self:read"] } ] }, @@ -328,9 +330,7 @@ "permissions": [ { "resource_id": "profile-api", - "specific_permissions": [ - "profile:user:read" - ] + "specific_permissions": ["profile:user:read"] } ], "type": "MachineToMachine", diff --git a/packages/cli/src/commands/database/ogcio/ogcio-seeder.json b/packages/cli/src/commands/database/ogcio/ogcio-seeder.json index 48b1107ff24..a3f511ed4c8 100644 --- a/packages/cli/src/commands/database/ogcio/ogcio-seeder.json +++ b/packages/cli/src/commands/database/ogcio/ogcio-seeder.json @@ -103,19 +103,17 @@ "id": "bb-inactive-ps", "name": "Inactive Public Servant", "description": "Inactive Public Servant", - "specific_permissions": [ - "bb:public-servant.inactive:*" - ] + "specific_permissions": ["bb:public-servant.inactive:*"] }, { "id": "m2m-ps-profile-reader", "name": "M2M Public Servant Profile Reader", "description": "Role for M2M Applications that need to read from Profile resources", - "specific_permissions": [ - "profile:user:read" - ], + "specific_permissions": ["profile:user:read"], "type": "MachineToMachine", - "related_applications": [{"application_id":"tty6llp30risjwcjhbvc9", "organization_id": "ogcio"}] + "related_applications": [ + { "application_id": "tty6llp30risjwcjhbvc9", "organization_id": "ogcio" } + ] } ], "applications": [ @@ -199,6 +197,17 @@ "secret": "", "id": "tty6llp30risjwcjhbvc9", "is_third_party": false + }, + { + "name": "M2M Management APIs", + "description": "Machine 2 Machine application used to communicate with the Logto Management APIs", + "type": "MachineToMachine", + "redirect_uri": "", + "logout_redirect_uri": "", + "secret": "", + "id": "46ewhh940rn1e29cmecxs", + "is_third_party": false, + "apply_management_api_role": true } ], "resources": [ @@ -264,10 +273,7 @@ }, { "resource_id": "upload-api", - "specific_permissions": [ - "upload:file.self:write", - "upload:file.self:read" - ] + "specific_permissions": ["upload:file.self:write", "upload:file.self:read"] } ], "resource_roles": [ @@ -306,9 +312,7 @@ }, { "resource_id": "upload-api", - "specific_permissions": [ - "upload:file.self:read" - ] + "specific_permissions": ["upload:file.self:read"] } ] }, @@ -319,9 +323,7 @@ "permissions": [ { "resource_id": "profile-api", - "specific_permissions": [ - "profile:user:read" - ] + "specific_permissions": ["profile:user:read"] } ], "type": "MachineToMachine", diff --git a/packages/cli/src/commands/database/ogcio/ogcio-seeder.ts b/packages/cli/src/commands/database/ogcio/ogcio-seeder.ts index 2565ebb815d..4c7184c7274 100644 --- a/packages/cli/src/commands/database/ogcio/ogcio-seeder.ts +++ b/packages/cli/src/commands/database/ogcio/ogcio-seeder.ts @@ -47,6 +47,7 @@ export type ApplicationSeeder = { secret: string; is_third_party?: boolean; always_issue_refresh_token?: boolean; + apply_management_api_role?: boolean; }; export type ResourceSeeder = { diff --git a/packages/cli/src/commands/database/ogcio/queries.ts b/packages/cli/src/commands/database/ogcio/queries.ts index d2498d004fc..27f0651f5f9 100644 --- a/packages/cli/src/commands/database/ogcio/queries.ts +++ b/packages/cli/src/commands/database/ogcio/queries.ts @@ -3,6 +3,8 @@ /* eslint-disable @silverhand/fp/no-mutating-methods */ /* eslint-disable @silverhand/fp/no-mutation */ /* eslint-disable @typescript-eslint/no-non-null-assertion */ + +import { Roles } from '@logto/schemas'; import { generateStandardId } from '@logto/shared'; import { type DatabaseTransactionConnection, @@ -201,3 +203,11 @@ export const deleteQuery = (whereClauses: ValueExpression[], table: string) => { where ${sql.join(whereClauses, sql` AND `)} `; }; + +export const findManagementApiRole = async (transaction: DatabaseTransactionConnection) => { + const role = await transaction.query>(sql` + select id from ${sql.identifier([Roles.table])} + where name='Logto Management API access' limit 1`); + + return getColumnValueByQueryResult(role, 'id'); +}; diff --git a/packages/cli/src/commands/database/ogcio/resources-rbac.ts b/packages/cli/src/commands/database/ogcio/resources-rbac.ts index c2848b33d27..7ae0321757f 100644 --- a/packages/cli/src/commands/database/ogcio/resources-rbac.ts +++ b/packages/cli/src/commands/database/ogcio/resources-rbac.ts @@ -14,7 +14,7 @@ import { type ResourcePermissionSeeder, type ScopePerResourceRoleSeeder, } from './ogcio-seeder.js'; -import { createOrUpdateItem, deleteQuery } from './queries.js'; +import { createOrUpdateItem, deleteQuery, findManagementApiRole } from './queries.js'; import { type SeedingResource } from './resources.js'; type SeedingScope = { @@ -303,3 +303,19 @@ const assignRoleToM2MApplication = async ( ], toInsert: relation, }); + +export const applyManagementApiRole = async ( + transaction: DatabaseTransactionConnection, + tenantId: string, + appId: string +) => { + const roleId = await findManagementApiRole(transaction); + if (!roleId) { + throw new Error("Cannot find 'Logto Management API access' role"); + } + + return assignRoleToM2MApplication(transaction, tenantId, { + role_id: roleId, + application_id: appId, + }); +};