Esempio n. 1
0
    def __simplify_graph(self, graph: Subgraph) -> Subgraph:
        # List edges
        edge_dict = dict()
        edge_deny = dict()
        for edge in graph.relationships():
            source = edge.start_node()['name']
            target = edge.end_node()['name']
            edge_dict.setdefault(source + target, [])
            if not edge.type() in edge_dict[source + target]:
                edge_dict[source + target].append(edge.type())
            else:
                edge['__drop__'] = 1

            edge_deny.setdefault(source + target, False)
            edge_deny[source + target] |= bool(edge['DENY'])

        # Group edges
        new_edges = []
        for edge in graph.relationships():
            source = edge.start_node()['name']
            target = edge.end_node()['name']
            tags = edge_dict.get(source + target, [])
            if len(tags) > 1:
                edge['__drop__'] = 1
                if '__done__' not in tags:
                    new_rel = Relationship(edge.start_node(), ','.join(tags),
                                           edge.end_node())
                    if edge_deny.get(source + target):
                        new_rel['DENY'] = 1
                    edge_dict[source + target].append('__done__')

                    new_edges.append(new_rel)

        # Build the simplified graph
        new_graph = Subgraph(
            nodes=[x for x in graph.nodes()],
            relationships=[
                x for x in graph.relationships() if not x['__drop__']
            ] + new_edges)

        return new_graph
Esempio n. 2
0
    def __denyace(self, graph: Subgraph, graph_target: str) -> Subgraph:
        if not self.__workdir:
            self.logger.warning(
                'No denyace applied - dump directory not provided')
            return graph

        rels = dict()

        # Load DENY Ace from Relation folder
        if not self.__denied_ace:
            for deny_file in (self.__workdir / 'Relations').glob('*.deny.csv'):
                with deny_file.open('r', encoding='utf-16-le') as ifile:
                    self.logger.debug('Parsing denied ACE from %s', deny_file)
                    reader = DictReader(ifile)
                    for row in reader:
                        self.__denied_ace.append(row)
            self.logger.debug('Denied ACE : %d', len(self.__denied_ace))

        nodes = dict()

        # Step 1 : cut all direct relationships
        for edge in graph.relationships():
            source = edge.start_node()['name']
            nodes.setdefault(source, edge.start_node())

            target = edge.end_node()['name']
            nodes.setdefault(target, edge.end_node())

            denied = []
            for x in self.__denied_ace:
                try:
                    if x['dnMaster:START_ID'] == source and x[
                            'dnSlave:END_ID'] == target and x[
                                'keyword:TYPE'] == edge.type():
                        denied.append(x)
                except:
                    if x[':START_ID'] == source and x[
                            ':END_ID'] == target and x[':TYPE'] == edge.type():
                        denied.append(x)

            if len(denied) > 0:
                self.logger.debug('DENY edge (%s) --[%s]--> (%s)', source,
                                  edge.type(), target)
                edge['DENY'] = '1'

        # Step 2 : build relation map
        for edge in graph.relationships():
            if edge['denied']:
                continue
            source = edge.start_node()['name']
            target = edge.end_node()['name']
            rels.setdefault(source, dict())
            rels[source].setdefault(target, [])
            rels[source][target].append(edge.type())

        # Step 3 : map denied to relationships
        nolink_nodes = []
        for source in rels:
            path_count = 0
            denies = 0
            for rel in self.__get_rels(rels, source):
                if rel['target'] == graph_target:
                    path_count += 1

                denied = []
                for x in self.__denied_ace:
                    try:
                        if x['dnMaster:START_ID'] == source and x[
                                'dnSlave:END_ID'] == target and x[
                                    'keyword:TYPE'] == edge.type():
                            denied.append(x)
                    except:
                        if x[':START_ID'] == source and x[
                                ':END_ID'] == target and x[
                                    ':TYPE'] == edge.type():
                            denied.append(x)

                if len(denied) > 0:
                    path_count -= 1
                    denies += 1
                    deny_edge = Relationship(nodes[rel['source']],
                                             'DENY_{}'.format(rel['type']),
                                             nodes[rel['target']],
                                             DENY=1)
                    graph |= deny_edge

            if path_count == 0 and denies > 0:
                nolink_nodes.append(source)

        # Step 4 : tag unlinked nodes
        for node in graph.nodes():
            if node['name'] in nolink_nodes:
                node['NO_LINKS'] = True

        return graph