diff --git a/backend/src/ee/routes/v1/scim-router.ts b/backend/src/ee/routes/v1/scim-router.ts index 8965c28f3b..0a45486ef1 100644 --- a/backend/src/ee/routes/v1/scim-router.ts +++ b/backend/src/ee/routes/v1/scim-router.ts @@ -362,6 +362,7 @@ export const registerScimRouter = async (server: FastifyZodProvider) => { const groups = await req.server.services.scim.listScimGroups({ orgId: req.permission.orgId, startIndex: req.query.startIndex, + filter: req.query.filter, limit: req.query.count }); diff --git a/backend/src/ee/services/scim/scim-fns.ts b/backend/src/ee/services/scim/scim-fns.ts index ec54a4d1fc..08b6521851 100644 --- a/backend/src/ee/services/scim/scim-fns.ts +++ b/backend/src/ee/services/scim/scim-fns.ts @@ -18,6 +18,20 @@ export const buildScimUserList = ({ }; }; +export const parseScimFilter = (filterToParse: string | undefined) => { + if (!filterToParse) return {}; + const [parsedName, parsedValue] = filterToParse.split("eq").map((s) => s.trim()); + + let attributeName = parsedName; + if (parsedName === "userName") { + attributeName = "email"; + } else if (parsedName === "displayName") { + attributeName = "name"; + } + + return { [attributeName]: parsedValue.replace(/"/g, "") }; +}; + export const buildScimUser = ({ orgMembershipId, username, diff --git a/backend/src/ee/services/scim/scim-service.ts b/backend/src/ee/services/scim/scim-service.ts index 9a084c6d71..e0d344a961 100644 --- a/backend/src/ee/services/scim/scim-service.ts +++ b/backend/src/ee/services/scim/scim-service.ts @@ -30,7 +30,7 @@ import { UserAliasType } from "@app/services/user-alias/user-alias-types"; import { TLicenseServiceFactory } from "../license/license-service"; import { OrgPermissionActions, OrgPermissionSubjects } from "../permission/org-permission"; import { TPermissionServiceFactory } from "../permission/permission-service"; -import { buildScimGroup, buildScimGroupList, buildScimUser, buildScimUserList } from "./scim-fns"; +import { buildScimGroup, buildScimGroupList, buildScimUser, buildScimUserList, parseScimFilter } from "./scim-fns"; import { TCreateScimGroupDTO, TCreateScimTokenDTO, @@ -184,18 +184,6 @@ export const scimServiceFactory = ({ status: 403 }); - const parseFilter = (filterToParse: string | undefined) => { - if (!filterToParse) return {}; - const [parsedName, parsedValue] = filterToParse.split("eq").map((s) => s.trim()); - - let attributeName = parsedName; - if (parsedName === "userName") { - attributeName = "email"; - } - - return { [attributeName]: parsedValue.replace(/"/g, "") }; - }; - const findOpts = { ...(startIndex && { offset: startIndex - 1 }), ...(limit && { limit }) @@ -204,7 +192,7 @@ export const scimServiceFactory = ({ const users = await orgDAL.findMembership( { [`${TableName.OrgMembership}.orgId` as "id"]: orgId, - ...parseFilter(filter) + ...parseScimFilter(filter) }, findOpts ); @@ -557,7 +545,7 @@ export const scimServiceFactory = ({ return {}; // intentionally return empty object upon success }; - const listScimGroups = async ({ orgId, startIndex, limit }: TListScimGroupsDTO) => { + const listScimGroups = async ({ orgId, startIndex, limit, filter }: TListScimGroupsDTO) => { const plan = await licenseService.getPlan(orgId); if (!plan.groups) throw new BadRequestError({ @@ -580,7 +568,8 @@ export const scimServiceFactory = ({ const groups = await groupDAL.findGroups( { - orgId + orgId, + ...(filter && parseScimFilter(filter)) }, { offset: startIndex - 1, diff --git a/backend/src/ee/services/scim/scim-types.ts b/backend/src/ee/services/scim/scim-types.ts index 46ab90b8f0..cffc804070 100644 --- a/backend/src/ee/services/scim/scim-types.ts +++ b/backend/src/ee/services/scim/scim-types.ts @@ -66,6 +66,7 @@ export type TDeleteScimUserDTO = { export type TListScimGroupsDTO = { startIndex: number; + filter?: string; limit: number; orgId: string; };