-
Notifications
You must be signed in to change notification settings - Fork 799
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
[backend] Improve handling of refs relationships (#4476) #5004
Changes from all commits
335d897
fe57f8f
17d25d5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,26 @@ | ||
import { dissoc, propOr } from 'ramda'; | ||
import { createRelation, deleteElementById, updateAttribute } from '../database/middleware'; | ||
import { | ||
deleteElementById, | ||
storeLoadByIdWithRefs, | ||
updateAttribute, | ||
updateAttributeFromLoadedWithRefs | ||
} from '../database/middleware'; | ||
import { BUS_TOPICS } from '../config/conf'; | ||
import { notify } from '../database/redis'; | ||
import { ABSTRACT_STIX_REF_RELATIONSHIP, ABSTRACT_STIX_RELATIONSHIP } from '../schema/general'; | ||
import { FunctionalError } from '../config/errors'; | ||
import { isStixRefRelationship, META_RELATIONS, STIX_REF_RELATIONSHIP_TYPES } from '../schema/stixRefRelationship'; | ||
import { listRelations, storeLoadById } from '../database/middleware-loader'; | ||
import { internalLoadById, listRelations, storeLoadById } from '../database/middleware-loader'; | ||
import { stixCoreRelationshipCleanContext, stixCoreRelationshipEditContext } from './stixCoreRelationship'; | ||
import { schemaTypesDefinition } from '../schema/schema-types'; | ||
import { schemaRelationsRefDefinition } from '../schema/schema-relationsRef'; | ||
import { findById as findStixObjectOrStixRelationshipById } from './stixObjectOrStixRelationship'; | ||
import { elCount } from '../database/engine'; | ||
import { READ_INDEX_STIX_CYBER_OBSERVABLE_RELATIONSHIPS, READ_INDEX_STIX_META_RELATIONSHIPS } from '../database/utils'; | ||
import { | ||
READ_INDEX_STIX_CYBER_OBSERVABLE_RELATIONSHIPS, | ||
READ_INDEX_STIX_META_RELATIONSHIPS, | ||
UPDATE_OPERATION_ADD | ||
} from '../database/utils'; | ||
|
||
// Query | ||
|
||
|
@@ -48,14 +57,36 @@ export const isDatable = (entityType, relationshipType) => { | |
}; | ||
|
||
// Mutation | ||
|
||
// @Deprecated method. | ||
// updateField must be directly used | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did not find this method in the project. What are you referring to ? Is it a TODO ? |
||
export const addStixRefRelationship = async (context, user, stixRefRelationship) => { | ||
if (!isStixRefRelationship(stixRefRelationship.relationship_type)) { | ||
throw FunctionalError(`Only ${ABSTRACT_STIX_REF_RELATIONSHIP} can be added through this method, got ${stixRefRelationship.relationship_type}.`); | ||
} | ||
return createRelation(context, user, stixRefRelationship).then((relationData) => { | ||
return notify(BUS_TOPICS[ABSTRACT_STIX_REF_RELATIONSHIP].ADDED_TOPIC, relationData, user); | ||
}); | ||
const fromPromise = storeLoadByIdWithRefs(context, user, stixRefRelationship.fromId); | ||
const toPromise = internalLoadById(context, user, stixRefRelationship.toId); | ||
const [from, to] = await Promise.all([fromPromise, toPromise]); | ||
if (!from || !to) { | ||
throw FunctionalError('MISSING_ELEMENTS', { | ||
from: stixRefRelationship.fromId, | ||
from_missing: !from, | ||
to: stixRefRelationship.toId, | ||
to_missing: !to | ||
}); | ||
} | ||
const refInputName = schemaRelationsRefDefinition.convertDatabaseNameToInputName(from.entity_type, stixRefRelationship.relationship_type); | ||
const inputs = [{ key: refInputName, value: [stixRefRelationship.toId], operation: UPDATE_OPERATION_ADD }]; | ||
await updateAttributeFromLoadedWithRefs(context, user, from, inputs); | ||
const opts = { | ||
first: 1, | ||
connectionFormat: false, | ||
fromId: from.internal_id, | ||
toId: to.internal_id, | ||
orderBy: 'created_at', | ||
orderMode: 'desc' | ||
}; | ||
const lastCreatedRef = await listRelations(context, user, stixRefRelationship.relationship_type, opts); | ||
return notify(BUS_TOPICS[ABSTRACT_STIX_REF_RELATIONSHIP].ADDED_TOPIC, lastCreatedRef[0], user); | ||
}; | ||
export const stixRefRelationshipEditField = async (context, user, stixRefRelationshipId, input) => { | ||
// Not use ABSTRACT_STIX_REF_RELATIONSHIP to have compatibility on parent type with ABSTRACT_STIX_CYBER_OBSERVABLE_RELATIONSHIP type | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -63,56 +63,56 @@ schemaRelationsRefDefinition.registerRelationsRef( | |
); | ||
|
||
schemaRelationsRefDefinition.registerRelationsRef(ENTITY_DIRECTORY, [ | ||
buildRelationRef(contains, (fromType: string, toType: string) => [ENTITY_DIRECTORY, ENTITY_HASHED_OBSERVABLE_STIX_FILE].includes(toType)) | ||
buildRelationRef(contains, (_: string, toType: string) => [ENTITY_DIRECTORY, ENTITY_HASHED_OBSERVABLE_STIX_FILE].includes(toType)) | ||
]); | ||
schemaRelationsRefDefinition.registerRelationsRef(ENTITY_DOMAIN_NAME, [ | ||
buildRelationRef(resolvesTo, (fromType: string, toType: string) => [ENTITY_DOMAIN_NAME, ENTITY_IPV4_ADDR, ENTITY_IPV6_ADDR].includes(toType)) | ||
buildRelationRef(resolvesTo, (_: string, toType: string) => [ENTITY_DOMAIN_NAME, ENTITY_IPV4_ADDR, ENTITY_IPV6_ADDR].includes(toType)) | ||
]); | ||
schemaRelationsRefDefinition.registerRelationsRef(ENTITY_EMAIL_MESSAGE, [ | ||
buildRelationRef(from, (fromType: string, toType: string) => ENTITY_EMAIL_ADDR === toType), | ||
buildRelationRef(sender, (fromType: string, toType: string) => ENTITY_EMAIL_ADDR === toType), | ||
buildRelationRef(to, (fromType: string, toType: string) => ENTITY_EMAIL_ADDR === toType), | ||
buildRelationRef(cc, (fromType: string, toType: string) => ENTITY_EMAIL_ADDR === toType), | ||
buildRelationRef(bcc, (fromType: string, toType: string) => ENTITY_EMAIL_ADDR === toType), | ||
buildRelationRef(bodyMultipart, (fromType: string, toType: string) => ENTITY_EMAIL_MIME_PART_TYPE === toType), | ||
buildRelationRef(rawEmail, (fromType: string, toType: string) => ENTITY_HASHED_OBSERVABLE_ARTIFACT === toType), | ||
buildRelationRef(from, (_: string, toType: string) => ENTITY_EMAIL_ADDR === toType), | ||
buildRelationRef(sender, (_: string, toType: string) => ENTITY_EMAIL_ADDR === toType), | ||
buildRelationRef(to, (_: string, toType: string) => ENTITY_EMAIL_ADDR === toType), | ||
buildRelationRef(cc, (_: string, toType: string) => ENTITY_EMAIL_ADDR === toType), | ||
buildRelationRef(bcc, (_: string, toType: string) => ENTITY_EMAIL_ADDR === toType), | ||
buildRelationRef(bodyMultipart, (_: string, toType: string) => ENTITY_EMAIL_MIME_PART_TYPE === toType), | ||
buildRelationRef(rawEmail, (_: string, toType: string) => ENTITY_HASHED_OBSERVABLE_ARTIFACT === toType), | ||
]); | ||
schemaRelationsRefDefinition.registerRelationsRef(ENTITY_EMAIL_ADDR, [ | ||
buildRelationRef(belongsTo, (fromType: string, toType: string) => ENTITY_USER_ACCOUNT === toType) | ||
buildRelationRef(belongsTo, (_: string, toType: string) => ENTITY_USER_ACCOUNT === toType) | ||
Comment on lines
+66
to
+81
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since the Checker type is only used in this file, maybe we could update it by removing |
||
]); | ||
schemaRelationsRefDefinition.registerRelationsRef(ENTITY_EMAIL_MIME_PART_TYPE, [ | ||
buildRelationRef(bodyRaw, (fromType: string, toType: string) => [ENTITY_HASHED_OBSERVABLE_ARTIFACT, ENTITY_HASHED_OBSERVABLE_STIX_FILE].includes(toType)) | ||
buildRelationRef(bodyRaw, (_: string, toType: string) => [ENTITY_HASHED_OBSERVABLE_ARTIFACT, ENTITY_HASHED_OBSERVABLE_STIX_FILE].includes(toType)) | ||
]); | ||
schemaRelationsRefDefinition.registerRelationsRef(ENTITY_HASHED_OBSERVABLE_STIX_FILE, [ | ||
buildRelationRef(contains, (fromType: string, toType: string) => getParentTypes(toType).includes(ABSTRACT_STIX_CYBER_OBSERVABLE)), | ||
buildRelationRef(parentDirectory, (fromType: string, toType: string) => ENTITY_DIRECTORY === toType), | ||
buildRelationRef(obsContent, (fromType: string, toType: string) => ENTITY_HASHED_OBSERVABLE_ARTIFACT === toType), | ||
buildRelationRef(contains, (_: string, toType: string) => getParentTypes(toType).includes(ABSTRACT_STIX_CYBER_OBSERVABLE)), | ||
buildRelationRef(parentDirectory, (_: string, toType: string) => ENTITY_DIRECTORY === toType), | ||
buildRelationRef(obsContent, (_: string, toType: string) => ENTITY_HASHED_OBSERVABLE_ARTIFACT === toType), | ||
]); | ||
schemaRelationsRefDefinition.registerRelationsRef(ENTITY_IPV4_ADDR, [ | ||
buildRelationRef(resolvesTo, (fromType: string, toType: string) => ENTITY_MAC_ADDR === toType), | ||
buildRelationRef(belongsTo, (fromType: string, toType: string) => ENTITY_AUTONOMOUS_SYSTEM === toType), | ||
buildRelationRef(resolvesTo, (_: string, toType: string) => ENTITY_MAC_ADDR === toType), | ||
buildRelationRef(belongsTo, (_: string, toType: string) => ENTITY_AUTONOMOUS_SYSTEM === toType), | ||
]); | ||
schemaRelationsRefDefinition.registerRelationsRef(ENTITY_IPV6_ADDR, [ | ||
buildRelationRef(resolvesTo, (fromType: string, toType: string) => ENTITY_MAC_ADDR === toType), | ||
buildRelationRef(belongsTo, (fromType: string, toType: string) => ENTITY_AUTONOMOUS_SYSTEM === toType), | ||
buildRelationRef(resolvesTo, (_: string, toType: string) => ENTITY_MAC_ADDR === toType), | ||
buildRelationRef(belongsTo, (_: string, toType: string) => ENTITY_AUTONOMOUS_SYSTEM === toType), | ||
]); | ||
schemaRelationsRefDefinition.registerRelationsRef(ENTITY_NETWORK_TRAFFIC, [ | ||
buildRelationRef(src, (fromType: string, toType: string) => [ENTITY_DOMAIN_NAME, ENTITY_IPV4_ADDR, ENTITY_IPV6_ADDR, ENTITY_MAC_ADDR].includes(toType)), | ||
buildRelationRef(dst, (fromType: string, toType: string) => [ENTITY_DOMAIN_NAME, ENTITY_IPV4_ADDR, ENTITY_IPV6_ADDR, ENTITY_MAC_ADDR].includes(toType)), | ||
buildRelationRef(srcPayload, (fromType: string, toType: string) => ENTITY_HASHED_OBSERVABLE_ARTIFACT === toType), | ||
buildRelationRef(dstPayload, (fromType: string, toType: string) => ENTITY_HASHED_OBSERVABLE_ARTIFACT === toType), | ||
buildRelationRef(encapsulates, (fromType: string, toType: string) => ENTITY_NETWORK_TRAFFIC === toType), | ||
buildRelationRef(encapsulatedBy, (fromType: string, toType: string) => ENTITY_NETWORK_TRAFFIC === toType), | ||
buildRelationRef(src, (_: string, toType: string) => [ENTITY_DOMAIN_NAME, ENTITY_IPV4_ADDR, ENTITY_IPV6_ADDR, ENTITY_MAC_ADDR].includes(toType)), | ||
buildRelationRef(dst, (_: string, toType: string) => [ENTITY_DOMAIN_NAME, ENTITY_IPV4_ADDR, ENTITY_IPV6_ADDR, ENTITY_MAC_ADDR].includes(toType)), | ||
buildRelationRef(srcPayload, (_: string, toType: string) => ENTITY_HASHED_OBSERVABLE_ARTIFACT === toType), | ||
buildRelationRef(dstPayload, (_: string, toType: string) => ENTITY_HASHED_OBSERVABLE_ARTIFACT === toType), | ||
buildRelationRef(encapsulates, (_: string, toType: string) => ENTITY_NETWORK_TRAFFIC === toType), | ||
buildRelationRef(encapsulatedBy, (_: string, toType: string) => ENTITY_NETWORK_TRAFFIC === toType), | ||
]); | ||
schemaRelationsRefDefinition.registerRelationsRef(ENTITY_PROCESS, [ | ||
buildRelationRef(openedConnections, (fromType: string, toType: string) => ENTITY_NETWORK_TRAFFIC === toType), | ||
buildRelationRef(creatorUser, (fromType: string, toType: string) => ENTITY_USER_ACCOUNT === toType), | ||
buildRelationRef(image, (fromType: string, toType: string) => ENTITY_HASHED_OBSERVABLE_STIX_FILE === toType), | ||
buildRelationRef(parent, (fromType: string, toType: string) => ENTITY_PROCESS === toType), | ||
buildRelationRef(child, (fromType: string, toType: string) => ENTITY_PROCESS === toType), | ||
buildRelationRef(serviceDlls, (fromType: string, toType: string) => ENTITY_HASHED_OBSERVABLE_STIX_FILE === toType), | ||
buildRelationRef(openedConnections, (_: string, toType: string) => ENTITY_NETWORK_TRAFFIC === toType), | ||
buildRelationRef(creatorUser, (_: string, toType: string) => ENTITY_USER_ACCOUNT === toType), | ||
buildRelationRef(image, (_: string, toType: string) => ENTITY_HASHED_OBSERVABLE_STIX_FILE === toType), | ||
buildRelationRef(parent, (_: string, toType: string) => ENTITY_PROCESS === toType), | ||
buildRelationRef(child, (_: string, toType: string) => ENTITY_PROCESS === toType), | ||
buildRelationRef(serviceDlls, (_: string, toType: string) => ENTITY_HASHED_OBSERVABLE_STIX_FILE === toType), | ||
]); | ||
schemaRelationsRefDefinition.registerRelationsRef(ENTITY_WINDOWS_REGISTRY_KEY, [ | ||
buildRelationRef(values, (fromType: string, toType: string) => ENTITY_WINDOWS_REGISTRY_VALUE_TYPE === toType), | ||
buildRelationRef(creatorUser, (fromType: string, toType: string) => ENTITY_USER_ACCOUNT === toType), | ||
buildRelationRef(values, (_: string, toType: string) => ENTITY_WINDOWS_REGISTRY_VALUE_TYPE === toType), | ||
buildRelationRef(creatorUser, (_: string, toType: string) => ENTITY_USER_ACCOUNT === toType), | ||
]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those lines are duplicates from
domain/stix.js
.I took the liberty to refactor both files with a dedicated function reducing the nesting of
if
and the code duplication