Skip to content

Commit

Permalink
feature 555 remove obsolete SAME/SAM linktype
Browse files Browse the repository at this point in the history
  • Loading branch information
northdpole committed Sep 21, 2024
1 parent bc98bd4 commit 16da64b
Show file tree
Hide file tree
Showing 16 changed files with 201 additions and 149 deletions.
53 changes: 22 additions & 31 deletions application/database/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class CRE(BaseModel): # type: ignore
class InternalLinks(BaseModel): # type: ignore
# model cre-groups linking cres
__tablename__ = "cre_links"
type = sqla.Column(sqla.String, default="SAME")
type = sqla.Column(sqla.String)

group = sqla.Column(
sqla.String,
Expand All @@ -134,7 +134,7 @@ class InternalLinks(BaseModel): # type: ignore

class Links(BaseModel): # type: ignore
__tablename__ = "cre_node_links"
type = sqla.Column(sqla.String, default="SAME")
type = sqla.Column(sqla.String)
cre = sqla.Column(
sqla.String,
sqla.ForeignKey("cre.id", onupdate="CASCADE", ondelete="CASCADE"),
Expand Down Expand Up @@ -329,8 +329,6 @@ class NeoCRE(NeoDocument): # type: ignore
auto_linked_to = RelationshipTo(
"NeoStandard", "AUTOMATICALLY_LINKED_TO", model=AutoLinkedToRel
)
same_as = RelationshipTo("NeoStandard", "SAME", model=SameRel)

@classmethod
def to_cre_def(self, node, parse_links=True) -> cre_defs.CRE:
return cre_defs.CRE(
Expand Down Expand Up @@ -554,13 +552,10 @@ def link_CRE_to_Node(self, CRE_id, node_id, link_type):
if link_type == cre_defs.LinkTypes.AutomaticallyLinkedTo.value:
cre.auto_linked_to.connect(node)
return
if link_type == cre_defs.LinkTypes.LinkedTo.value:
elif link_type == cre_defs.LinkTypes.LinkedTo.value:
cre.linked.connect(node)
return
if link_type == cre_defs.LinkTypes.Same.value:
cre.same_as.connect(node)
return
raise Exception(f"Unknown relation type {link_type}")
raise Exception(f"Unknown relation type {link_type} for Nodes to CREs")

@classmethod
def gap_analysis(self, name_1, name_2):
Expand Down Expand Up @@ -619,7 +614,6 @@ def format_segment(seg: StructuredRel, nodes):
RelatedRel: "RELATED",
ContainsRel: "CONTAINS",
LinkedToRel: "LINKED_TO",
SameRel: "SAME",
AutoLinkedToRel: "AUTOMATICALLY_LINKED_TO",
}
start_node = [
Expand Down Expand Up @@ -1361,9 +1355,6 @@ def get_cre_hierarchy(self, cre: cre_defs.CRE) -> int:
raise ValueError(f"CRE {cre.id} does not exist in the database")
credbid = credbid[0]

if len(self.graph.graph.edges) == 0:
logger.error("graph is empty")
return -1
return self.graph.get_hierarchy(rootIDs=root_cre_db_ids, creID=credbid)

# def all_nodes_with_pagination(
Expand Down Expand Up @@ -1490,23 +1481,26 @@ def add_node(
self.session.add(dbnode)
self.session.commit()
if self.graph:
self.graph = self.graph.add_dbnode(dbnode=dbnode, graph=self.graph)
self.graph.add_dbnode(dbnode=dbnode)
return dbnode

def add_internal_link(
self,
higher: CRE,
lower: CRE,
ltype: cre_defs.LinkTypes = cre_defs.LinkTypes.Same,
) -> None:
ltype,
) -> cre_defs.Link:
"""
adds a link between two CREs in the database,
Args:
higher (CRE): the higher level CRE that CONTAINS or is the SAME or is RELATED to lower
lower (CRE): the lower level CRE that is CONTAINED or is the SAME or is RELATED to higher
higher (CRE): the higher level CRE that CONTAINS or is RELATED to lower
lower (CRE): the lower level CRE that is CONTAINED or is RELATED to higher
ltype (cre_defs.LinkTypes, optional): the linktype
Defaults to cre_defs.LinkTypes.Same.
Returns: the cre_defs.Link or None in case of error (cycle)
"""
if ltype == None:
raise ValueError("Every link should have a link type")

if lower.id is None:
if lower.external_id is None:
lower = (
Expand Down Expand Up @@ -1579,7 +1573,7 @@ def add_internal_link(
# )
# entry_exists.ltype = ltype.value
# self.session.commit()
return
return cre_defs.Link(document=CREfromDB(lower),ltype=ltype)

logger.info(
"did not know of internal link"
Expand All @@ -1606,11 +1600,7 @@ def add_internal_link(
)
self.session.commit()
if self.graph:
self.graph = self.graph.add_graph_edge(
doc_from=higher_cre,
link_to=link_to,
graph=self.graph.graph,
)
self.graph.add_link(doc_from=higher_cre,link_to=link_to)
else:
for item in cycle:
from_id = item[0].replace("CRE: ", "")
Expand All @@ -1626,13 +1616,18 @@ def add_internal_link(
f" {lower.external_id}-{lower.name} "
f"would introduce cycle {cycle}, skipping"
)
return None
return cre_defs.Link(document=lower,ltype=ltype)

def add_link(
self,
cre: CRE,
node: Node,
ltype: cre_defs.LinkTypes = cre_defs.LinkTypes.Same,
ltype: cre_defs.LinkTypes,
) -> None:
if not ltype:
raise ValueError("every link should have a link type")

if cre.id is None:
cre = (
self.session.query(CRE).filter(sqla.and_(CRE.name == cre.name)).first()
Expand Down Expand Up @@ -1662,11 +1657,7 @@ def add_link(
)
self.session.add(Links(type=ltype.value, cre=cre.id, node=node.id))
if self.graph:
self.graph.add_graph_edge(
doc_from=CREfromDB(cre),
link_to=cre_defs.Link(document=nodeFromDB(node),ltype=ltype.value),
graph=self.graph.graph
)
self.graph.add_link(doc_from=CREfromDB(cre),link_to=cre_defs.Link(document=nodeFromDB(node),ltype=ltype.value))


self.session.commit()
Expand Down
5 changes: 1 addition & 4 deletions application/defs/cre_defs.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,6 @@ def from_str(typ: str) -> "Credoctypes":


class LinkTypes(str, Enum, metaclass=EnumMetaWithContains):
Same = "SAME"
LinkedTo = "Linked To" # Any standard entry is by default “linked”
PartOf = "Is Part Of" # Hierarchy above: “is part of”
Contains = "Contains" # Hierarchy below: “Contains”
Expand All @@ -205,8 +204,6 @@ class LinkTypes(str, Enum, metaclass=EnumMetaWithContains):

@staticmethod
def from_str(name: str) -> Any: # it returns LinkTypes but then it won't run
if name.upper().startswith("SAM"):
name = "SAME"
res = [x for x in LinkTypes if x.value == name]
if not res:
raise KeyError(
Expand Down Expand Up @@ -252,7 +249,7 @@ def from_str(tooltype: str) -> Optional["ToolTypes"]:
@dataclass
class Link:
document: "Document"
ltype: LinkTypes = LinkTypes.Same
ltype: LinkTypes
tags: List[str] = field(default_factory=list)

def __post_init__(self):
Expand Down
2 changes: 0 additions & 2 deletions application/frontend/src/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ export const TYPE_LINKED_TO = 'Linked To';
export const TYPE_LINKED_FROM = 'Linked From';
export const TYPE_CONTAINS = 'Contains';
export const TYPE_RELATED = 'Related';
export const TYPE_SAME = 'SAME';
export const TYPE_SAM = 'SAM';
export const TYPE_AUTOLINKED_TO = 'Automatically linked to';

export const DOCUMENT_TYPE_NAMES = {
Expand Down
2 changes: 1 addition & 1 deletion application/frontend/src/utils/document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const groupLinksByType = (node: Document): LinksByType =>
node.links ? groupBy(node.links, (link) => link.ltype) : {};

export const orderLinksByType = (lbt: LinksByType): LinksByType => {
const order = ['Contains', 'Linked To', 'Automatically linked to', 'SAME', 'SAM', 'Is Part Of', 'Related'];
const order = ['Contains', 'Linked To', 'Automatically linked to', 'Is Part Of', 'Related'];
const res: LinksByType = {};
for (const itm of order) {
if (lbt[itm]) {
Expand Down
10 changes: 6 additions & 4 deletions application/tests/capec_parser_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ class fakeRequest:
dbnode = self.collection.add_node(defs.Standard(name="CWE", sectionID=cwe))
cre = defs.CRE(id=f"{cwe}-{cwe}", name=f"CRE-{cwe}")
dbcre = self.collection.add_cre(cre=cre)
self.collection.add_link(cre=dbcre, node=dbnode)
self.collection.add_link(
cre=dbcre, node=dbnode, ltype=defs.LinkTypes.LinkedTo
)
entries = capec_parser.Capec().parse(
cache=self.collection,
ph=prompt_client.PromptHandler(database=self.collection),
Expand All @@ -43,9 +45,9 @@ class fakeRequest:
name="CAPEC",
doctype=defs.Credoctypes.Standard,
links=[
defs.Link(document=defs.CRE(name="CRE-276", id="276-276")),
defs.Link(document=defs.CRE(name="CRE-285", id="285-285")),
defs.Link(document=defs.CRE(name="CRE-434", id="434-434")),
defs.Link(document=defs.CRE(name="CRE-276", id="276-276"),ltype=defs.LinkTypes.LinkedTo),
defs.Link(document=defs.CRE(name="CRE-285", id="285-285"),ltype=defs.LinkTypes.LinkedTo),
defs.Link(document=defs.CRE(name="CRE-434", id="434-434"),ltype=defs.LinkTypes.LinkedTo),
],
hyperlink="https://capec.mitre.org/data/definitions/1.html",
sectionID="1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class fakeRequest:
dbnode = self.collection.add_node(
defs.Standard(name="fakeNode", sectionID="123-123")
)
self.collection.add_link(dbcre, dbnode)
self.collection.add_link(dbcre, dbnode, ltype=defs.LinkTypes.LinkedTo)

mock_requests.return_value = fakeRequest()
mock_get_text_embeddings.return_value = [0.1, 0.2]
Expand All @@ -64,7 +64,10 @@ class fakeRequest:
"variables or as a file",
hyperlink="https://github.com/cloud-native-security-controls/controls-catalog/blob/main/controls/controls_catalog.csv#L2",
links=[
defs.Link(document=defs.CRE(name="CRE-123", id="123-123")),
defs.Link(
document=defs.CRE(name="CRE-123", id="123-123"),
ltype=defs.LinkTypes.LinkedTo,
),
],
name="Cloud Native Security Controls",
section="Access",
Expand All @@ -78,7 +81,7 @@ class fakeRequest:
embeddings_text="Secrets are injected at runtime, such as environment variables or as a file",
hyperlink="https://github.com/cloud-native-security-controls/controls-catalog/blob/main/controls/controls_catalog.csv#L2",
links=[
defs.Link(document=defs.CRE(name="CRE-123", id="123-123")),
defs.Link(document=defs.CRE(name="CRE-123", id="123-123"),ltype=defs.LinkTypes.LinkedTo),
],
name="Cloud Native Security Controls",
section="Access",
Expand Down
Loading

0 comments on commit 16da64b

Please sign in to comment.