Skip to content

Commit

Permalink
create getOneTrustUser and cache fetched users
Browse files Browse the repository at this point in the history
  • Loading branch information
abrantesarthur committed Jan 21, 2025
1 parent 6a1d610 commit 42116b7
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 6 deletions.
117 changes: 117 additions & 0 deletions src/oneTrust/endpoints/getOneTrustUser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import * as t from 'io-ts';
import { Got } from 'got';
import { decodeCodec } from '@transcend-io/type-utils';

/**
* FIXME: move to privacy-types
*/

// Nested types first
const OneTrustUserMetadata = t.type({
/** When the user was created */
created: t.string,
/** When the user was modified */
lastModified: t.string,
/** The URI for accessing information about the user */
location: t.string,
/** The resource type */
resourceType: t.literal('User'),
});
/** Type override */
export type OneTrustUserMetadata = t.TypeOf<typeof OneTrustUserMetadata>;

const OneTrustUserName = t.type({
/** The user's family name */
familyName: t.string,
/** The user's given name */
givenName: t.string,
});
/** Type override */
export type OneTrustUserName = t.TypeOf<typeof OneTrustUserName>;

const OneTrustUserGroup = t.type({
/** The user group's identification */
value: t.string,
/** The user group's display name */
display: t.string,
});
/** Type override */
export type OneTrustUserGroup = t.TypeOf<typeof OneTrustUserGroup>;

const OneTrustUserGroups = t.array(OneTrustUserGroup);
/** Type override */
export type OneTrustUserGroups = t.TypeOf<typeof OneTrustUserGroups>;

const OneTrustUserEmail = t.type({
/** The email value */
value: t.string,
/** The email display name */
display: t.string,
/** Whether this is the primary email */
primary: t.boolean,
/** The email type */
type: t.union([t.string, t.literal('work')]),
});
/** Type override */
export type OneTrustUserEmail = t.TypeOf<typeof OneTrustUserEmail>;

const OneTrustUserEmails = t.array(OneTrustUserEmail);
/** Type override */
export type OneTrustUserEmails = t.TypeOf<typeof OneTrustUserEmails>;

/**
* The response type of the OneTrust GetUser endpoint
* ref: https://developer.onetrust.com/onetrust/reference/getriskusingget
*/
export const OneTrustGetUserResponse = t.type({
/** ID of the user. */
id: t.string,
/** External ID of the user. */
externalId: t.union([t.string, t.null]),
/** Metadata of the user. */
meta: OneTrustUserMetadata,
/** Schemas of the user */
schemas: t.array(t.string),
/** Name or email of the user */
userName: t.string,
/** Full name of the user */
name: OneTrustUserName,
/** Type of the user */
userType: t.union([t.string, t.literal('Internal')]),
/** Flag to check if the user is an active user or not. */
active: t.boolean,
/** The groups that the user belongs to */
groups: OneTrustUserGroups,
/** The emails of the user */
emails: OneTrustUserEmails,
/** The roles of the user */
roles: t.array(t.string),
/** The title of the user */
title: t.union([t.string, t.null]),
});

/** Type override */

/** Type override */
export type OneTrustGetUserResponse = t.TypeOf<typeof OneTrustGetUserResponse>;

/**
* Retrieve details about a particular user.
* ref: https://developer.onetrust.com/onetrust/reference/getriskusingget
*
* @param param - the information about the OneTrust client and risk to retrieve
* @returns the OneTrust risk
*/
export const getOneTrustUser = async ({
oneTrust,
creatorId,
}: {
/** The OneTrust client instance */
oneTrust: Got;
/** The ID of the OneTrust user to retrieve */
creatorId: string;
}): Promise<OneTrustGetUserResponse> => {
const { body } = await oneTrust.get(`api/scim/v2/Users/${creatorId}`);

return decodeCodec(OneTrustGetUserResponse, body);
};
25 changes: 19 additions & 6 deletions src/oneTrust/helpers/syncOneTrustAssessments.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Got } from 'got/dist/source';
import {
OneTrustGetUserResponse,
getListOfOneTrustAssessments,
getOneTrustAssessment,
getOneTrustRisk,
Expand Down Expand Up @@ -48,6 +49,9 @@ export const syncOneTrustAssessments = async ({
logger.info('Getting list of all assessments from OneTrust...');
const assessments = await getListOfOneTrustAssessments({ oneTrust });

// a cache of OneTrust users so we avoid sending requests for users already fetched
const allOneTrustUsers: Record<string, OneTrustGetUserResponse> = {};

/**
* fetch details about each assessment in series and write to transcend or to disk
* (depending on the dryRun argument) right away to avoid running out of memory
Expand All @@ -63,19 +67,28 @@ export const syncOneTrustAssessments = async ({
assessmentId: assessment.assessmentId,
});

// enrich assessments with user information
const creator = await getOneTrustUser({
oneTrust,
creatorId: assessmentDetails.createdBy.id,
});
// fetch assessment's creator information
logger.info(
`Fetching details about assessment ${index + 1} of ${
assessments.length
} creator...`,
);
const creatorId = assessmentDetails.createdBy.id;
const creator =
allOneTrustUsers[creatorId] ??
(await getOneTrustUser({
oneTrust,
creatorId: assessmentDetails.createdBy.id,
}));
allOneTrustUsers[creatorId] = creator;

/**
* FIXME: enrich rootRequestInformationIds
*/

// console.log({ creator });

// enrich assessments with risk information
// fetch assessment risk information
let riskDetails: OneTrustGetRiskResponse[] = [];
const riskIds = uniq(
assessmentDetails.sections.flatMap((s: OneTrustAssessmentSection) =>
Expand Down

0 comments on commit 42116b7

Please sign in to comment.