Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(insights): sanitize retention query #19979

Merged
merged 3 commits into from
Jan 26, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
PropertyFilterType,
PropertyGroupFilterValue,
PropertyOperator,
RetentionEntity,
} from '~/types'

const reverseInsightMap: Record<Exclude<InsightType, InsightType.JSON | InsightType.SQL>, InsightNodeKind> = {
Expand Down Expand Up @@ -104,6 +105,21 @@ export const cleanHiddenLegendSeries = (
.map(([k]) => k)
: undefined
}
export const sanitizeRetentionEntity = (entity: RetentionEntity | undefined): RetentionEntity | undefined => {
if (!entity) {
return undefined
}
const record = { ...entity }
for (const key of Object.keys(record)) {
if (!['id', 'kind', 'name', 'type', 'order', 'uuid', 'custom_name'].includes(key)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we were to add a new key to RetentionEntity, would we need to add it here too? May be worth a comment somewhere, otherwise we may get some confused devs in the future

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps... but I hope we won't need this soon anymore. As soon as the filters object is gone, this will be as well.

The backend has a more sensible allow-list approach though

return {
"type": entity.get("type"),
"id": entity.get("id"),
"name": entity.get("name"),
"custom_name": entity.get("custom_name"),
"order": entity.get("order"),
}

But since the tests are all green, I'll use the opportunity and merge it in. There will be more adjustments...

delete record[key]
}
}
if ('id' in record && record.type === 'actions') {
record.id = Number(record.id)
}
return record
}

const cleanProperties = (parentProperties: FilterType['properties']): InsightsQueryBase['properties'] => {
if (!parentProperties || !parentProperties.values) {
Expand Down Expand Up @@ -307,8 +323,8 @@ export const filtersToQueryNode = (filters: Partial<FilterType>): InsightQueryNo
retentionType: filters.retention_type,
retentionReference: filters.retention_reference,
totalIntervals: filters.total_intervals,
returningEntity: filters.returning_entity,
targetEntity: filters.target_entity,
returningEntity: sanitizeRetentionEntity(filters.returning_entity),
targetEntity: sanitizeRetentionEntity(filters.target_entity),
period: filters.period,
})
// TODO: query.aggregation_group_type_index
Expand Down
Loading