feat(rbac): role-based access control module (#14310)

This commit is contained in:
Carlos R. L. Rodrigues authored and GitHub committed 2026-01-07 05:36:39 -03:00
1 parent d6d7d14a6a
commit 1bfde8dc57
74 files changed
+4186 -3

No files matched your search

+1
View File
@@ -21,6 +21,7 @@ export * from "./pricing"
export * from "./product"
export * from "./product-category"
export * from "./promotion"
export * from "./rbac"
export * from "./region"
export * from "./reservation"
export * from "./return-reason"
@@ -0,0 +1,2 @@
export * from "./steps"
export * from "./workflows"
@@ -0,0 +1,40 @@
import { Modules } from "@medusajs/framework/utils"
import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk"
import { IRbacModuleService } from "@medusajs/types"
export type CreateRbacPolicyDTO = {
key: string
resource: string
operation: string
name?: string | null
description?: string | null
metadata?: Record<string, unknown> | null
}
export type CreateRbacPoliciesStepInput = {
policies: CreateRbacPolicyDTO[]
}
export const createRbacPoliciesStepId = "create-rbac-policies"
export const createRbacPoliciesStep = createStep(
createRbacPoliciesStepId,
async (data: CreateRbacPoliciesStepInput, { container }) => {
const service = container.resolve<IRbacModuleService>(Modules.RBAC)
const created = await service.createRbacPolicies(data.policies)
return new StepResponse(
created,
(created ?? []).map((p) => p.id)
)
},
async (createdIds: string[] | undefined, { container }) => {
if (!createdIds?.length) {
return
}
const service = container.resolve<IRbacModuleService>(Modules.RBAC)
await service.deleteRbacPolicies(createdIds)
}
)
@@ -0,0 +1,43 @@
import { Modules } from "@medusajs/framework/utils"
import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk"
import { IRbacModuleService } from "@medusajs/types"
export type CreateRbacRoleInheritanceDTO = {
role_id: string
inherited_role_id: string
metadata?: Record<string, unknown> | null
}
export type CreateRbacRoleInheritancesStepInput = {
role_inheritances: CreateRbacRoleInheritanceDTO[]
}
export const createRbacRoleInheritancesStepId = "create-rbac-role-inheritances"
export const createRbacRoleInheritancesStep = createStep(
createRbacRoleInheritancesStepId,
async (data: CreateRbacRoleInheritancesStepInput, { container }) => {
const service = container.resolve<IRbacModuleService>(Modules.RBAC)
if (!data.role_inheritances || data.role_inheritances.length === 0) {
return new StepResponse([], [])
}
const created = await service.createRbacRoleInheritances(
data.role_inheritances
)
return new StepResponse(
created,
(created ?? []).map((ri) => ri.id)
)
},
async (createdIds: string[] | undefined, { container }) => {
if (!createdIds?.length) {
return
}
const service = container.resolve<IRbacModuleService>(Modules.RBAC)
await service.deleteRbacRoleInheritances(createdIds)
}
)
@@ -0,0 +1,37 @@
import { Modules } from "@medusajs/framework/utils"
import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk"
import { IRbacModuleService } from "@medusajs/types"
export type CreateRbacRolePolicyDTO = {
role_id: string
scope_id: string
metadata?: Record<string, unknown> | null
}
export type CreateRbacRolePoliciesStepInput = {
role_policies: CreateRbacRolePolicyDTO[]
}
export const createRbacRolePoliciesStepId = "create-rbac-role-policies"
export const createRbacRolePoliciesStep = createStep(
createRbacRolePoliciesStepId,
async (data: CreateRbacRolePoliciesStepInput, { container }) => {
const service = container.resolve<IRbacModuleService>(Modules.RBAC)
const created = await service.createRbacRolePolicies(data.role_policies)
return new StepResponse(
created,
(created ?? []).map((rp) => rp.id)
)
},
async (createdIds: string[] | undefined, { container }) => {
if (!createdIds?.length) {
return
}
const service = container.resolve<IRbacModuleService>(Modules.RBAC)
await service.deleteRbacRolePolicies(createdIds)
}
)
@@ -0,0 +1,37 @@
import { Modules } from "@medusajs/framework/utils"
import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk"
import { IRbacModuleService } from "@medusajs/types"
export type CreateRbacRoleDTO = {
name: string
description?: string | null
metadata?: Record<string, unknown> | null
}
export type CreateRbacRolesStepInput = {
roles: CreateRbacRoleDTO[]
}
export const createRbacRolesStepId = "create-rbac-roles"
export const createRbacRolesStep = createStep(
createRbacRolesStepId,
async (data: CreateRbacRolesStepInput, { container }) => {
const service = container.resolve<IRbacModuleService>(Modules.RBAC)
const created = await service.createRbacRoles(data.roles)
return new StepResponse(
created,
(created ?? []).map((r) => r.id)
)
},
async (createdIds: string[] | undefined, { container }) => {
if (!createdIds?.length) {
return
}
const service = container.resolve<IRbacModuleService>(Modules.RBAC)
await service.deleteRbacRoles(createdIds)
}
)
@@ -0,0 +1,17 @@
import { Modules } from "@medusajs/framework/utils"
import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk"
import { IRbacModuleService } from "@medusajs/types"
export type DeleteRbacPoliciesStepInput = string[]
export const deleteRbacPoliciesStepId = "delete-rbac-policies"
export const deleteRbacPoliciesStep = createStep(
{ name: deleteRbacPoliciesStepId, noCompensation: true },
async (ids: DeleteRbacPoliciesStepInput, { container }) => {
const service = container.resolve<IRbacModuleService>(Modules.RBAC)
await service.deleteRbacPolicies(ids)
return new StepResponse(void 0)
},
async () => {}
)
@@ -0,0 +1,17 @@
import { Modules } from "@medusajs/framework/utils"
import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk"
import { IRbacModuleService } from "@medusajs/types"
export type DeleteRbacRolePoliciesStepInput = string[]
export const deleteRbacRolePoliciesStepId = "delete-rbac-role-policies"
export const deleteRbacRolePoliciesStep = createStep(
{ name: deleteRbacRolePoliciesStepId, noCompensation: true },
async (ids: DeleteRbacRolePoliciesStepInput, { container }) => {
const service = container.resolve<IRbacModuleService>(Modules.RBAC)
await service.deleteRbacRolePolicies(ids)
return new StepResponse(void 0)
},
async () => {}
)
@@ -0,0 +1,17 @@
import { Modules } from "@medusajs/framework/utils"
import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk"
import { IRbacModuleService } from "@medusajs/types"
export type DeleteRbacRolesStepInput = string[]
export const deleteRbacRolesStepId = "delete-rbac-roles"
export const deleteRbacRolesStep = createStep(
{ name: deleteRbacRolesStepId, noCompensation: true },
async (ids: DeleteRbacRolesStepInput, { container }) => {
const service = container.resolve<IRbacModuleService>(Modules.RBAC)
await service.deleteRbacRoles(ids)
return new StepResponse(void 0)
},
async () => {}
)
@@ -0,0 +1,14 @@
export * from "./create-rbac-roles"
export * from "./delete-rbac-roles"
export * from "./update-rbac-roles"
export * from "./create-rbac-policies"
export * from "./delete-rbac-policies"
export * from "./update-rbac-policies"
export * from "./create-rbac-role-policies"
export * from "./delete-rbac-role-policies"
export * from "./update-rbac-role-policies"
export * from "./create-rbac-role-inheritances"
export * from "./set-role-inheritance"
@@ -0,0 +1,122 @@
import { Modules } from "@medusajs/framework/utils"
import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk"
import { IRbacModuleService } from "@medusajs/types"
export type SetRoleInheritanceStepInput = Array<{
role_id: string
inherited_role_ids: string[]
}>
export const setRoleInheritanceStepId = "set-role-inheritance"
export const setRoleInheritanceStep = createStep(
setRoleInheritanceStepId,
async (data: SetRoleInheritanceStepInput, { container }) => {
const service = container.resolve<IRbacModuleService>(Modules.RBAC)
const allCompensationData: Array<{
role_id: string
previousInheritedRoleIds: string[]
}> = []
if (!data || data.length === 0) {
return new StepResponse(
{ created: [], removedCount: 0 },
allCompensationData
)
}
const allToRemoveIds: string[] = []
const allToCreate: Array<{
role_id: string
inherited_role_id: string
}> = []
for (const roleData of data) {
const existingInheritance = await service.listRbacRoleInheritances({
role_id: roleData.role_id,
})
const existingInheritedRoleIds = existingInheritance.map(
(ri) => ri.inherited_role_id
)
allCompensationData.push({
role_id: roleData.role_id,
previousInheritedRoleIds: existingInheritedRoleIds,
})
const toAdd = roleData.inherited_role_ids.filter(
(id) => !existingInheritedRoleIds.includes(id)
)
const toRemove = existingInheritedRoleIds.filter(
(id) => !roleData.inherited_role_ids.includes(id)
)
if (toRemove.length > 0) {
const toRemoveRecords = existingInheritance.filter((ri) =>
toRemove.includes(ri.inherited_role_id)
)
allToRemoveIds.push(...toRemoveRecords.map((ri) => ri.id))
}
if (toAdd.length > 0) {
allToCreate.push(
...toAdd.map((inherited_role_id) => ({
role_id: roleData.role_id,
inherited_role_id,
}))
)
}
}
if (allToRemoveIds.length > 0) {
await service.deleteRbacRoleInheritances(allToRemoveIds)
}
let created: any[] = []
if (allToCreate.length > 0) {
created = await service.createRbacRoleInheritances(allToCreate)
}
return new StepResponse(
{ created, removedCount: allToRemoveIds.length },
allCompensationData
)
},
async (
compensationData:
| Array<{ role_id: string; previousInheritedRoleIds: string[] }>
| undefined,
{ container }
) => {
if (!compensationData || compensationData.length === 0) {
return
}
const service = container.resolve<IRbacModuleService>(Modules.RBAC)
for (const roleCompensation of compensationData) {
const currentInheritance = await service.listRbacRoleInheritances({
role_id: roleCompensation.role_id,
})
if (currentInheritance.length > 0) {
await service.deleteRbacRoleInheritances(
currentInheritance.map((ri) => ri.id)
)
}
if (roleCompensation.previousInheritedRoleIds.length > 0) {
await service.createRbacRoleInheritances(
roleCompensation.previousInheritedRoleIds.map(
(inherited_role_id) => ({
role_id: roleCompensation.role_id,
inherited_role_id,
})
)
)
}
}
}
)
@@ -0,0 +1,61 @@
import {
getSelectsAndRelationsFromObjectArray,
Modules,
} from "@medusajs/framework/utils"
import { createStep, StepResponse } from "@medusajs/framework/workflows-sdk"
import { IRbacModuleService, UpdateRbacPolicyDTO } from "@medusajs/types"
export type UpdateRbacPoliciesStepInput = {
selector: Record<string, any>
update: Omit<UpdateRbacPolicyDTO, "id">
}
export const updateRbacPoliciesStepId = "update-rbac-policies"
export const updateRbacPoliciesStep = createStep(
updateRbacPoliciesStepId,
async (data: UpdateRbacPoliciesStepInput, { container }) => {
const service = container.resolve<IRbacModuleService>(Modules.RBAC)
const { selects, relations } = getSelectsAndRelationsFromObjectArray([
data.update,
])
const prevData = await service.listRbacPolicies(data.selector, {
select: selects,
relations,
})
const updates = (prevData ?? []).map((p) => ({
id: p.id,
...data.update,
})) as UpdateRbacPolicyDTO[]
const updated = await service.updateRbacPolicies(updates)
return new StepResponse(updated, {
prevData,
updateKeys: Object.keys(data.update ?? {}),
})
},
async (
compensationData: { prevData: any[]; updateKeys: string[] } | undefined,
{ container }
) => {
if (!compensationData?.prevData?.length) {
return
}
const service = container.resolve<IRbacModuleService>(Modules.RBAC)
const updates = compensationData.prevData.map((p) => {
const payload: Record<string, any> = { id: p.id }
for (const key of compensationData.updateKeys) {
payload[key] = p[key]
}
return payload
}) as UpdateRbacPolicyDTO[]
await service.updateRbacPolicies(updates)
}
)
@@ -0,0 +1,61 @@
import {
getSelectsAndRelationsFromObjectArray,
Modules,
} from "@medusajs/framework/utils"
import { createStep, StepResponse } from "@medusajs/framework/workflows-sdk"
import { IRbacModuleService, UpdateRbacRolePolicyDTO } from "@medusajs/types"
export type UpdateRbacRolePoliciesStepInput = {
selector: Record<string, any>
update: Omit<UpdateRbacRolePolicyDTO, "id">
}
export const updateRbacRolePoliciesStepId = "update-rbac-role-policies"
export const updateRbacRolePoliciesStep = createStep(
updateRbacRolePoliciesStepId,
async (data: UpdateRbacRolePoliciesStepInput, { container }) => {
const service = container.resolve<IRbacModuleService>(Modules.RBAC)
const { selects, relations } = getSelectsAndRelationsFromObjectArray([
data.update,
])
const prevData = await service.listRbacRolePolicies(data.selector, {
select: selects,
relations,
})
const updates = (prevData ?? []).map((rp) => ({
id: rp.id,
...data.update,
})) as UpdateRbacRolePolicyDTO[]
const updated = await service.updateRbacRolePolicies(updates)
return new StepResponse(updated, {
prevData,
updateKeys: Object.keys(data.update ?? {}),
})
},
async (
compensationData: { prevData: any[]; updateKeys: string[] } | undefined,
{ container }
) => {
if (!compensationData?.prevData?.length) {
return
}
const service = container.resolve<IRbacModuleService>(Modules.RBAC)
const updates = compensationData.prevData.map((rp) => {
const payload: Record<string, any> = { id: rp.id }
for (const key of compensationData.updateKeys) {
payload[key] = rp[key]
}
return payload
}) as UpdateRbacRolePolicyDTO[]
await service.updateRbacRolePolicies(updates)
}
)
@@ -0,0 +1,61 @@
import {
getSelectsAndRelationsFromObjectArray,
Modules,
} from "@medusajs/framework/utils"
import { createStep, StepResponse } from "@medusajs/framework/workflows-sdk"
import { IRbacModuleService, UpdateRbacRoleDTO } from "@medusajs/types"
export type UpdateRbacRolesStepInput = {
selector: Record<string, any>
update: Omit<UpdateRbacRoleDTO, "id">
}
export const updateRbacRolesStepId = "update-rbac-roles"
export const updateRbacRolesStep = createStep(
updateRbacRolesStepId,
async (data: UpdateRbacRolesStepInput, { container }) => {
const service = container.resolve<IRbacModuleService>(Modules.RBAC)
const { selects, relations } = getSelectsAndRelationsFromObjectArray([
data.update,
])
const prevData = await service.listRbacRoles(data.selector, {
select: selects,
relations,
})
const updates = (prevData ?? []).map((r) => ({
id: r.id,
...data.update,
})) as UpdateRbacRoleDTO[]
const updated = await service.updateRbacRoles(updates)
return new StepResponse(updated, {
prevData,
updateKeys: Object.keys(data.update ?? {}),
})
},
async (
compensationData: { prevData: any[]; updateKeys: string[] } | undefined,
{ container }
) => {
if (!compensationData?.prevData?.length) {
return
}
const service = container.resolve<IRbacModuleService>(Modules.RBAC)
const updates = compensationData.prevData.map((r) => {
const payload: Record<string, any> = { id: r.id }
for (const key of compensationData.updateKeys) {
payload[key] = r[key]
}
return payload
}) as UpdateRbacRoleDTO[]
await service.updateRbacRoles(updates)
}
)
@@ -0,0 +1,19 @@
import {
WorkflowData,
WorkflowResponse,
createWorkflow,
} from "@medusajs/framework/workflows-sdk"
import { createRbacPoliciesStep } from "../steps"
export type CreateRbacPoliciesWorkflowInput = {
policies: any[]
}
export const createRbacPoliciesWorkflowId = "create-rbac-policies"
export const createRbacPoliciesWorkflow = createWorkflow(
createRbacPoliciesWorkflowId,
(input: WorkflowData<CreateRbacPoliciesWorkflowInput>) => {
return new WorkflowResponse(createRbacPoliciesStep(input))
}
)
@@ -0,0 +1,19 @@
import {
WorkflowData,
WorkflowResponse,
createWorkflow,
} from "@medusajs/framework/workflows-sdk"
import { createRbacRolePoliciesStep } from "../steps"
export type CreateRbacRolePoliciesWorkflowInput = {
role_policies: any[]
}
export const createRbacRolePoliciesWorkflowId = "create-rbac-role-policies"
export const createRbacRolePoliciesWorkflow = createWorkflow(
createRbacRolePoliciesWorkflowId,
(input: WorkflowData<CreateRbacRolePoliciesWorkflowInput>) => {
return new WorkflowResponse(createRbacRolePoliciesStep(input))
}
)
@@ -0,0 +1,80 @@
import {
WorkflowData,
WorkflowResponse,
createWorkflow,
transform,
} from "@medusajs/framework/workflows-sdk"
import {
createRbacRoleInheritancesStep,
createRbacRolePoliciesStep,
createRbacRolesStep,
} from "../steps"
export type CreateRbacRolesWorkflowInput = {
roles: {
name: string
description?: string | null
metadata?: Record<string, unknown> | null
inherited_role_ids?: string[]
policy_ids?: string[]
}[]
}
export const createRbacRolesWorkflowId = "create-rbac-roles"
export const createRbacRolesWorkflow = createWorkflow(
createRbacRolesWorkflowId,
(input: WorkflowData<CreateRbacRolesWorkflowInput>) => {
const roleData = transform({ input }, ({ input }) => ({
roles: input.roles.map((r) => ({
name: r.name,
description: r.description,
metadata: r.metadata,
})),
}))
const createdRoles = createRbacRolesStep(roleData)
const inheritanceData = transform(
{ input, createdRoles },
({ input, createdRoles }) => {
const inheritances: any[] = []
createdRoles.forEach((role, index) => {
const inheritedRoleIds = input.roles[index].inherited_role_ids || []
inheritedRoleIds.forEach((inheritedRoleId) => {
inheritances.push({
role_id: role.id,
inherited_role_id: inheritedRoleId,
})
})
})
return { role_inheritances: inheritances }
}
)
const policiesData = transform(
{ input, createdRoles },
({ input, createdRoles }) => {
const allPolicies: any[] = []
createdRoles.forEach((role, index) => {
const policyIds = input.roles[index].policy_ids || []
policyIds.forEach((policy_id) => {
allPolicies.push({
role_id: role.id,
scope_id: policy_id,
})
})
})
return { role_policies: allPolicies }
}
)
createRbacRoleInheritancesStep(inheritanceData)
createRbacRolePoliciesStep(policiesData)
return new WorkflowResponse(createdRoles)
}
)
@@ -0,0 +1,17 @@
import { WorkflowData, createWorkflow } from "@medusajs/framework/workflows-sdk"
import { deleteRbacPoliciesStep } from "../steps"
export type DeleteRbacPoliciesWorkflowInput = {
ids: string[]
}
export const deleteRbacPoliciesWorkflowId = "delete-rbac-policies"
export const deleteRbacPoliciesWorkflow = createWorkflow(
deleteRbacPoliciesWorkflowId,
(
input: WorkflowData<DeleteRbacPoliciesWorkflowInput>
): WorkflowData<void> => {
deleteRbacPoliciesStep(input.ids)
}
)
@@ -0,0 +1,17 @@
import { WorkflowData, createWorkflow } from "@medusajs/framework/workflows-sdk"
import { deleteRbacRolePoliciesStep } from "../steps"
export type DeleteRbacRolePoliciesWorkflowInput = {
ids: string[]
}
export const deleteRbacRolePoliciesWorkflowId = "delete-rbac-role-policies"
export const deleteRbacRolePoliciesWorkflow = createWorkflow(
deleteRbacRolePoliciesWorkflowId,
(
input: WorkflowData<DeleteRbacRolePoliciesWorkflowInput>
): WorkflowData<void> => {
deleteRbacRolePoliciesStep(input.ids)
}
)
@@ -0,0 +1,15 @@
import { WorkflowData, createWorkflow } from "@medusajs/framework/workflows-sdk"
import { deleteRbacRolesStep } from "../steps"
export type DeleteRbacRolesWorkflowInput = {
ids: string[]
}
export const deleteRbacRolesWorkflowId = "delete-rbac-roles"
export const deleteRbacRolesWorkflow = createWorkflow(
deleteRbacRolesWorkflowId,
(input: WorkflowData<DeleteRbacRolesWorkflowInput>): WorkflowData<void> => {
deleteRbacRolesStep(input.ids)
}
)
@@ -0,0 +1,11 @@
export * from "./create-rbac-roles"
export * from "./delete-rbac-roles"
export * from "./update-rbac-roles"
export * from "./create-rbac-policies"
export * from "./delete-rbac-policies"
export * from "./update-rbac-policies"
export * from "./create-rbac-role-policies"
export * from "./delete-rbac-role-policies"
export * from "./update-rbac-role-policies"
@@ -0,0 +1,21 @@
import {
WorkflowData,
WorkflowResponse,
createWorkflow,
} from "@medusajs/framework/workflows-sdk"
import { UpdateRbacPolicyDTO } from "@medusajs/types"
import { updateRbacPoliciesStep } from "../steps/update-rbac-policies"
export type UpdateRbacPoliciesWorkflowInput = {
selector: Record<string, any>
update: Omit<UpdateRbacPolicyDTO, "id">
}
export const updateRbacPoliciesWorkflowId = "update-rbac-policies"
export const updateRbacPoliciesWorkflow = createWorkflow(
updateRbacPoliciesWorkflowId,
(input: WorkflowData<UpdateRbacPoliciesWorkflowInput>) => {
return new WorkflowResponse(updateRbacPoliciesStep(input))
}
)
@@ -0,0 +1,21 @@
import {
WorkflowData,
WorkflowResponse,
createWorkflow,
} from "@medusajs/framework/workflows-sdk"
import { UpdateRbacRolePolicyDTO } from "@medusajs/types"
import { updateRbacRolePoliciesStep } from "../steps/update-rbac-role-policies"
export type UpdateRbacRolePoliciesWorkflowInput = {
selector: Record<string, any>
update: Omit<UpdateRbacRolePolicyDTO, "id">
}
export const updateRbacRolePoliciesWorkflowId = "update-rbac-role-policies"
export const updateRbacRolePoliciesWorkflow = createWorkflow(
updateRbacRolePoliciesWorkflowId,
(input: WorkflowData<UpdateRbacRolePoliciesWorkflowInput>) => {
return new WorkflowResponse(updateRbacRolePoliciesStep(input))
}
)
@@ -0,0 +1,77 @@
import { isDefined } from "@medusajs/framework/utils"
import {
WorkflowData,
WorkflowResponse,
createWorkflow,
transform,
} from "@medusajs/framework/workflows-sdk"
import { UpdateRbacRoleDTO } from "@medusajs/types"
import { createRbacRolePoliciesStep, setRoleInheritanceStep } from "../steps"
import { updateRbacRolesStep } from "../steps/update-rbac-roles"
export type UpdateRbacRolesWorkflowInput = {
selector: Record<string, any>
update: Omit<UpdateRbacRoleDTO, "id"> & {
inherited_role_ids?: string[]
policy_ids?: string[]
}
}
export const updateRbacRolesWorkflowId = "update-rbac-roles"
export const updateRbacRolesWorkflow = createWorkflow(
updateRbacRolesWorkflowId,
(input: WorkflowData<UpdateRbacRolesWorkflowInput>) => {
const roleUpdateData = transform({ input }, ({ input }) => ({
selector: input.selector,
update: {
name: input.update.name,
description: input.update.description,
metadata: input.update.metadata,
},
}))
const updatedRoles = updateRbacRolesStep(roleUpdateData)
const inheritanceUpdateData = transform(
{ input, updatedRoles },
({ input, updatedRoles }) => {
if (!isDefined(input.update.inherited_role_ids)) {
return []
}
return updatedRoles.map((role) => ({
role_id: role.id,
inherited_role_ids: input.update.inherited_role_ids || [],
}))
}
)
setRoleInheritanceStep(inheritanceUpdateData)
const policiesUpdateData = transform(
{ input, updatedRoles },
({ input, updatedRoles }) => {
if (!isDefined(input.update.policy_ids)) {
return { role_policies: [] }
}
const allPolicies: any[] = []
updatedRoles.forEach((role) => {
const policyIds = input.update.policy_ids || []
policyIds.forEach((policy_id) => {
allPolicies.push({
role_id: role.id,
scope_id: policy_id,
})
})
})
return { role_policies: allPolicies }
}
)
createRbacRolePoliciesStep(policiesUpdateData)
return new WorkflowResponse(updatedRoles)
}
)
@@ -21,6 +21,7 @@ import {
IPricingModuleService,
IProductModuleService,
IPromotionModuleService,
IRbacModuleService,
IRegionModuleService,
ISalesChannelModuleService,
ISettingsModuleService,
@@ -82,6 +83,7 @@ declare module "@medusajs/types" {
[Modules.CACHING]: ICachingModuleService
[Modules.INDEX]: IIndexService
[Modules.TRANSLATION]: ITranslationModuleService
[Modules.RBAC]: IRbacModuleService
}
}
+1
View File
@@ -32,6 +32,7 @@ export * from "./pricing"
export * from "./product"
export * from "./product-category"
export * from "./promotion"
export * from "./rbac"
export * from "./region"
export * from "./sales-channel"
export * from "./search"
+56
View File
@@ -0,0 +1,56 @@
export type RbacRoleDTO = {
id: string
name: string
description?: string | null
metadata?: Record<string, unknown> | null
}
export type FilterableRbacRoleProps = {
id?: string | string[]
name?: string
q?: string
}
export type RbacPolicyDTO = {
id: string
key: string
resource: string
operation: string
name?: string | null
description?: string | null
metadata?: Record<string, unknown> | null
}
export type FilterableRbacPolicyProps = {
id?: string | string[]
key?: string
resource?: string
operation?: string
q?: string
}
export type RbacRolePolicyDTO = {
id: string
role_id: string
scope_id: string
metadata?: Record<string, unknown> | null
}
export type FilterableRbacRolePolicyProps = {
id?: string | string[]
role_id?: string | string[]
scope_id?: string | string[]
}
export type RbacRoleInheritanceDTO = {
id: string
role_id: string
inherited_role_id: string
metadata?: Record<string, unknown> | null
}
export type FilterableRbacRoleInheritanceProps = {
id?: string | string[]
role_id?: string | string[]
inherited_role_id?: string | string[]
}
+3
View File
@@ -0,0 +1,3 @@
export * from "./common"
export * from "./mutations"
export * from "./service"
+43
View File
@@ -0,0 +1,43 @@
export type CreateRbacRoleDTO = {
name: string
description?: string | null
metadata?: Record<string, unknown> | null
}
export type UpdateRbacRoleDTO = Partial<CreateRbacRoleDTO> & {
id: string
}
export type CreateRbacPolicyDTO = {
key: string
resource: string
operation: string
name?: string | null
description?: string | null
metadata?: Record<string, unknown> | null
}
export type UpdateRbacPolicyDTO = Partial<CreateRbacPolicyDTO> & {
id: string
}
export type CreateRbacRolePolicyDTO = {
role_id: string
scope_id: string
metadata?: Record<string, unknown> | null
}
export type UpdateRbacRolePolicyDTO = Partial<CreateRbacRolePolicyDTO> & {
id: string
}
export type CreateRbacRoleInheritanceDTO = {
role_id: string
inherited_role_id: string
metadata?: Record<string, unknown> | null
}
export type UpdateRbacRoleInheritanceDTO =
Partial<CreateRbacRoleInheritanceDTO> & {
id: string
}
+194
View File
@@ -0,0 +1,194 @@
import { FindConfig } from "../common"
import { IModuleService } from "../modules-sdk"
import { Context } from "../shared-context"
import {
FilterableRbacPolicyProps,
FilterableRbacRoleInheritanceProps,
FilterableRbacRolePolicyProps,
FilterableRbacRoleProps,
RbacPolicyDTO,
RbacRoleDTO,
RbacRoleInheritanceDTO,
RbacRolePolicyDTO,
} from "./common"
import {
CreateRbacPolicyDTO,
CreateRbacRoleDTO,
CreateRbacRoleInheritanceDTO,
CreateRbacRolePolicyDTO,
UpdateRbacPolicyDTO,
UpdateRbacRoleDTO,
UpdateRbacRoleInheritanceDTO,
UpdateRbacRolePolicyDTO,
} from "./mutations"
export interface IRbacModuleService extends IModuleService {
createRbacRoles(
data: CreateRbacRoleDTO,
sharedContext?: Context
): Promise<RbacRoleDTO>
createRbacRoles(
data: CreateRbacRoleDTO[],
sharedContext?: Context
): Promise<RbacRoleDTO[]>
updateRbacRoles(
data: UpdateRbacRoleDTO,
sharedContext?: Context
): Promise<RbacRoleDTO>
updateRbacRoles(
data: UpdateRbacRoleDTO[],
sharedContext?: Context
): Promise<RbacRoleDTO[]>
deleteRbacRoles(
ids: string | string[],
sharedContext?: Context
): Promise<void>
retrieveRbacRole(
id: string,
config?: FindConfig<RbacRoleDTO>,
sharedContext?: Context
): Promise<RbacRoleDTO>
listRbacRoles(
filters?: FilterableRbacRoleProps,
config?: FindConfig<RbacRoleDTO>,
sharedContext?: Context
): Promise<RbacRoleDTO[]>
listAndCountRbacRoles(
filters?: FilterableRbacRoleProps,
config?: FindConfig<RbacRoleDTO>,
sharedContext?: Context
): Promise<[RbacRoleDTO[], number]>
createRbacPolicies(
data: CreateRbacPolicyDTO,
sharedContext?: Context
): Promise<RbacPolicyDTO>
createRbacPolicies(
data: CreateRbacPolicyDTO[],
sharedContext?: Context
): Promise<RbacPolicyDTO[]>
updateRbacPolicies(
data: UpdateRbacPolicyDTO,
sharedContext?: Context
): Promise<RbacPolicyDTO>
updateRbacPolicies(
data: UpdateRbacPolicyDTO[],
sharedContext?: Context
): Promise<RbacPolicyDTO[]>
deleteRbacPolicies(
ids: string | string[],
sharedContext?: Context
): Promise<void>
retrieveRbacPolicy(
id: string,
config?: FindConfig<RbacPolicyDTO>,
sharedContext?: Context
): Promise<RbacPolicyDTO>
listRbacPolicies(
filters?: FilterableRbacPolicyProps,
config?: FindConfig<RbacPolicyDTO>,
sharedContext?: Context
): Promise<RbacPolicyDTO[]>
listAndCountRbacPolicies(
filters?: FilterableRbacPolicyProps,
config?: FindConfig<RbacPolicyDTO>,
sharedContext?: Context
): Promise<[RbacPolicyDTO[], number]>
createRbacRolePolicies(
data: CreateRbacRolePolicyDTO,
sharedContext?: Context
): Promise<RbacRolePolicyDTO>
createRbacRolePolicies(
data: CreateRbacRolePolicyDTO[],
sharedContext?: Context
): Promise<RbacRolePolicyDTO[]>
updateRbacRolePolicies(
data: UpdateRbacRolePolicyDTO,
sharedContext?: Context
): Promise<RbacRolePolicyDTO>
updateRbacRolePolicies(
data: UpdateRbacRolePolicyDTO[],
sharedContext?: Context
): Promise<RbacRolePolicyDTO[]>
deleteRbacRolePolicies(
ids: string | string[],
sharedContext?: Context
): Promise<void>
retrieveRbacRolePolicy(
id: string,
config?: FindConfig<RbacRolePolicyDTO>,
sharedContext?: Context
): Promise<RbacRolePolicyDTO>
listRbacRolePolicies(
filters?: FilterableRbacRolePolicyProps,
config?: FindConfig<RbacRolePolicyDTO>,
sharedContext?: Context
): Promise<RbacRolePolicyDTO[]>
listAndCountRbacRolePolicies(
filters?: FilterableRbacRolePolicyProps,
config?: FindConfig<RbacRolePolicyDTO>,
sharedContext?: Context
): Promise<[RbacRolePolicyDTO[], number]>
createRbacRoleInheritances(
data: CreateRbacRoleInheritanceDTO,
sharedContext?: Context
): Promise<RbacRoleInheritanceDTO>
createRbacRoleInheritances(
data: CreateRbacRoleInheritanceDTO[],
sharedContext?: Context
): Promise<RbacRoleInheritanceDTO[]>
updateRbacRoleInheritances(
data: UpdateRbacRoleInheritanceDTO,
sharedContext?: Context
): Promise<RbacRoleInheritanceDTO>
updateRbacRoleInheritances(
data: UpdateRbacRoleInheritanceDTO[],
sharedContext?: Context
): Promise<RbacRoleInheritanceDTO[]>
deleteRbacRoleInheritances(
ids: string | string[],
sharedContext?: Context
): Promise<void>
retrieveRbacRoleInheritance(
id: string,
config?: FindConfig<RbacRoleInheritanceDTO>,
sharedContext?: Context
): Promise<RbacRoleInheritanceDTO>
listRbacRoleInheritances(
filters?: FilterableRbacRoleInheritanceProps,
config?: FindConfig<RbacRoleInheritanceDTO>,
sharedContext?: Context
): Promise<RbacRoleInheritanceDTO[]>
listAndCountRbacRoleInheritances(
filters?: FilterableRbacRoleInheritanceProps,
config?: FindConfig<RbacRoleInheritanceDTO>,
sharedContext?: Context
): Promise<[RbacRoleInheritanceDTO[], number]>
listPoliciesForRole(
roleId: string,
sharedContext?: Context
): Promise<RbacPolicyDTO[]>
}
@@ -29,6 +29,7 @@ export const Modules = {
SETTINGS: "settings",
CACHING: "caching",
TRANSLATION: "translation",
RBAC: "rbac",
} as const
export const MODULE_PACKAGE_NAMES = {
@@ -62,6 +63,7 @@ export const MODULE_PACKAGE_NAMES = {
[Modules.SETTINGS]: "@medusajs/medusa/settings",
[Modules.CACHING]: "@medusajs/caching",
[Modules.TRANSLATION]: "@medusajs/translation",
[Modules.RBAC]: "@medusajs/medusa/rbac",
}
export const REVERSED_MODULE_PACKAGE_NAMES = Object.entries(
@@ -1,10 +1,10 @@
import { join } from "path"
import { Modules } from "./definition"
import type { LoadedModule } from "@medusajs/types"
import { join } from "path"
import { FileSystem } from "../common/file-system"
import { toUnixSlash } from "../common/to-unix-slash"
import { toCamelCase } from "../common/to-camel-case"
import { toUnixSlash } from "../common/to-unix-slash"
import { upperCaseFirst } from "../common/upper-case-first"
import { Modules } from "./definition"
/**
* For known services that has interfaces, we will set the container
@@ -37,6 +37,10 @@ const SERVICES_INTERFACES = {
[Modules.FILE]: "IFileModuleService",
[Modules.NOTIFICATION]: "INotificationModuleService",
[Modules.LOCKING]: "ILockingModule",
[Modules.SETTINGS]: "ISettingsModuleService",
[Modules.CACHING]: "ICachingModuleService",
[Modules.TRANSLATION]: "ITranslationModuleService",
[Modules.RBAC]: "IRbacModuleService",
}
/**