-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
create syncOneTrustAssessments and enrichOneTrustAssessment helpers
- Loading branch information
1 parent
4b428dc
commit 13e80e9
Showing
5 changed files
with
180 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import { | ||
OneTrustAssessment, | ||
OneTrustGetAssessmentResponse, | ||
OneTrustGetRiskResponse, | ||
} from '@transcend-io/privacy-types'; | ||
import keyBy from 'lodash/keyBy'; | ||
import { OneTrustEnrichedAssessment } from '../codecs'; | ||
|
||
/** | ||
* Merge the assessment, assessmentDetails, and riskDetails into one object. | ||
* | ||
* @param param - the assessment and risk information | ||
* @returns the assessment enriched with details and risk information | ||
*/ | ||
export const enrichOneTrustAssessment = ({ | ||
assessment, | ||
assessmentDetails, | ||
riskDetails, | ||
}: { | ||
/** The OneTrust risk details */ | ||
riskDetails: OneTrustGetRiskResponse[]; | ||
/** The OneTrust assessment as returned from Get List of Assessments endpoint */ | ||
assessment: OneTrustAssessment; | ||
/** The OneTrust assessment details */ | ||
assessmentDetails: OneTrustGetAssessmentResponse; | ||
}): OneTrustEnrichedAssessment => { | ||
const riskDetailsById = keyBy(riskDetails, 'id'); | ||
const { sections, ...restAssessmentDetails } = assessmentDetails; | ||
const sectionsWithEnrichedRisk = sections.map((section) => { | ||
const { questions, ...restSection } = section; | ||
const enrichedQuestions = questions.map((question) => { | ||
const { risks, ...restQuestion } = question; | ||
const enrichedRisks = (risks ?? []).map((risk) => { | ||
const details = riskDetailsById[risk.riskId]; | ||
// TODO: missing the risk meta data and links to the assessment | ||
return { | ||
...risk, | ||
description: details.description, | ||
name: details.name, | ||
treatment: details.treatment, | ||
treatmentStatus: details.treatmentStatus, | ||
type: details.type, | ||
state: details.state, | ||
stage: details.stage, | ||
result: details.result, | ||
categories: details.categories, | ||
}; | ||
}); | ||
return { | ||
...restQuestion, | ||
risks: enrichedRisks, | ||
}; | ||
}); | ||
return { | ||
...restSection, | ||
questions: enrichedQuestions, | ||
}; | ||
}); | ||
|
||
// combine the two assessments into a single enriched result | ||
|
||
return { | ||
...assessment, | ||
...restAssessmentDetails, | ||
sections: sectionsWithEnrichedRisk, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import { Got } from 'got/dist/source'; | ||
import { | ||
getListOfOneTrustAssessments, | ||
getOneTrustAssessment, | ||
getOneTrustRisk, | ||
} from '../endpoints'; | ||
import { map, mapSeries } from 'bluebird'; | ||
import { logger } from '../../logger'; | ||
import { | ||
OneTrustAssessmentQuestion, | ||
OneTrustAssessmentSection, | ||
OneTrustGetRiskResponse, | ||
} from '@transcend-io/privacy-types'; | ||
import uniq from 'lodash/uniq'; | ||
import { enrichOneTrustAssessment } from './enrichOneTrustAssessment'; | ||
import { writeOneTrustAssessment } from './writeOneTrustAssessment'; | ||
import { OneTrustFileFormat } from '../../enums'; | ||
|
||
export const syncOneTrustAssessments = async ({ | ||
oneTrust, | ||
file, | ||
fileFormat, | ||
dryRun, | ||
}: { | ||
/** the OneTrust client instance */ | ||
oneTrust: Got; | ||
/** Whether to write to file instead of syncing to Transcend */ | ||
dryRun: boolean; | ||
/** the path to the file in case dryRun is true */ | ||
file?: string; | ||
/** the format of the file in case dryRun is true */ | ||
fileFormat?: OneTrustFileFormat; | ||
}): Promise<void> => { | ||
// fetch the list of all assessments in the OneTrust organization | ||
logger.info('Getting list of all assessments from OneTrust...'); | ||
const assessments = await getListOfOneTrustAssessments({ oneTrust }); | ||
|
||
/** | ||
* fetch details about one assessment in series and push to transcend or write to disk | ||
* (depending on the dryRun argument) right away to avoid running out of memory | ||
*/ | ||
await mapSeries(assessments, async (assessment, index) => { | ||
logger.info( | ||
`Fetching details about assessment ${index + 1} of ${ | ||
assessments.length | ||
}...`, | ||
); | ||
const assessmentDetails = await getOneTrustAssessment({ | ||
oneTrust, | ||
assessmentId: assessment.assessmentId, | ||
}); | ||
|
||
// enrich assessments with risk information | ||
let riskDetails: OneTrustGetRiskResponse[] = []; | ||
const riskIds = uniq( | ||
assessmentDetails.sections.flatMap((s: OneTrustAssessmentSection) => | ||
s.questions.flatMap((q: OneTrustAssessmentQuestion) => | ||
(q.risks ?? []).flatMap((r) => r.riskId), | ||
), | ||
), | ||
); | ||
if (riskIds.length > 0) { | ||
logger.info( | ||
`Fetching details about ${riskIds.length} risks for assessment ${ | ||
index + 1 | ||
} of ${assessments.length}...`, | ||
); | ||
riskDetails = await map( | ||
riskIds, | ||
(riskId) => getOneTrustRisk({ oneTrust, riskId: riskId as string }), | ||
{ | ||
concurrency: 5, | ||
}, | ||
); | ||
} | ||
|
||
// enrich the sections with risk details | ||
const enrichedAssessment = enrichOneTrustAssessment({ | ||
assessment, | ||
assessmentDetails, | ||
riskDetails, | ||
}); | ||
|
||
if (dryRun && file && fileFormat) { | ||
writeOneTrustAssessment({ | ||
assessment: enrichedAssessment, | ||
index, | ||
total: assessments.length, | ||
file, | ||
fileFormat, | ||
}); | ||
} | ||
}); | ||
}; |