Skip to content
Snippets Groups Projects
Select Git revision
  • a5093c9aea97aa69d57f9c56abfa4f7e5a14eadb
  • main default protected
  • React-Branch
3 results

url-intelligence.go

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    diagramParser.py 6.07 KiB
    import pandas as pd 
    import ERFormatConstants as const
    import components as component
    import logging as log
    import matrices as matrix
    
    
    # Function will parse a csv file and extract the necessary information, this is step 1 of the parse 
    def parseDiagramFile(csvFile) -> component.Diagram: 
        df = pd.read_csv(csvFile)    
        df.drop(["Shape Library", "Page ID", "Contained By", "Group", "Comments", "property 1"], axis=1, inplace=True) #Removing unecessary data
        
        diagram = component.Diagram()   # Defines the diagram object
        
        diagram = matrix.parseTable(df, diagram)            #Parse the table and finds all indicators
        diagram = parseArchitectureDiagram(df, diagram)     #Parse the architecture diagram and finds all ER components along with indicators and reasoning
    
        diagram = parseThreats(df, diagram)                 # 
        diagram = parseConsequences(df, diagram)    
        diagram = parseAttacks(df, diagram)
        
        print("Diagram successfully parsed")
        
        return diagram        
            
    # Function will parse the threats and add them to the dictionary    
    def parseThreats(df,diagram: component.Diagram):
        for i in range(len(df)):
            if df[const.ThreatComponent][i] == const.Threat: #If the row in the dataframe is a threat
                            
                threat = component.Threat(      
                    df[const.Id][i],                # Component ID
                    df[const.ThreatMethodID][i],     # ID from ER
                    df[const.ThreatName][i],   # Name of the threat
                    df[const.ThreatDescription][i], 
                    df[const.ThreatSource][i], 
                    df[const.Likelihood][i], 
                    )
                diagram.threats[df[const.ThreatMethodID][i]] = threat
                
                threat.findIndicatorsThreat(df, diagram) # Find the indicators associated with the threat
                
        return diagram
    
    #Parses consequences and adds it to dictionary 
    def parseConsequences(df, diagram: component.Diagram):
        for i in range(len(df)):
            if df[const.ConsequenceComponent][i] == const.Consequence:
                            
                consequence = component.Consequence(
                    df[const.Id][i],
                    df[const.ConsequenceID][i],
                    df[const.ConsequenceName][i],
                    df[const.ConsequenceDescription][i],
                    df[const.ConsequenceScore][i],
                    )
                diagram.consequences[df[const.ConsequenceID][i]] = consequence
                consequence.findIndicatorsConsequence(df, diagram) # Find the indicators associated with the consequence
                
        return diagram
    
    def parseAttacks(df, diagram: component.Diagram):
        for i in range(len(df)):
            if df[const.AttackComponent][i] == const.Attack:
                            
                attack = component.Attack(
                    df[const.Id][i],
                    df[const.AttackType][i],
                    df[const.AttackDescription][i],
                    )
                diagram.attacks[df.Id[i]] = attack #! Note that the ID is the component ID from LucidChart, not my ID
                
        return diagram        
    
    #Parses metrics components and adds it to list
    def parseArchitectureDiagram(df, diagram: component.Diagram):
        for i in range(len(df)):     
            # Iterates through the dataframe
            if df[const.textArea1][i] == const.relationship:                    # If the component is a dynamic component
                if df[const.typeField][i] == "ER":                              # * If the component is an ER component                # Find the line where the component is the source
                    diagram = parseRelationshipComponentER(df, diagram, i)    
                
        return diagram                    
                
    def parseRelationshipComponentER(df: pd.DataFrame, diagram: component.Diagram, row) -> None:
        
        relationshipComponent = df.loc[row] # Define the relationship component
                
        indicatorList = {} # Define a list over relevant indicators to individual relationship component
        erComponents = {} # Define a list over ER components
    
        #* Iterate over the Relationship component to find all the indicators, and the reasoning for each
        for i in range(6 ,len(relationshipComponent), 2):
            
            if pd.isnull(relationshipComponent[f"Text Area {i}"]) == True:
                break
            
            indicatorID = relationshipComponent[f"Text Area {i}"]
            indicatorReason = relationshipComponent[f"Text Area {i+1}"]
            indicatorList[indicatorID] = indicatorReason
        
        # * Find all the lines associated with the component
        linesFrom = df.loc[df[const.From] == relationshipComponent[const.Id].item()]  # Find the component associated with the line
        linesTo = df.loc[df[const.To] == relationshipComponent[const.Id].item()]  # Find the component associated with the line
        
        allLines = pd.concat([linesFrom, linesTo]) # Merge the two dataframes
        
        # * Iterate through both lines, and find the ER components related to the relationship component
        for index, row in allLines.iterrows():
            objectTo = row[const.To]
            objectFrom = row[const.From]
            
            
            if df.loc[df[const.Id] == objectTo][const.typeField].item() == "ER":
                row = df.loc[df[const.Id] == objectFrom]
            else:
                row = df.loc[df[const.Id] == objectTo]
                    
            # Defines values
            name = row[const.erName].item()
            entityRelationshipId = row[const.erID].item()
            description = row[const.erDescription].item()
            entityrelationshipType = row[const.erType].item()
                    
            # Create ER component
            erComponent = component.ERComponent(name,entityRelationshipId, description, entityrelationshipType)
            # Add indicators to the ER component
            erComponent.linkedIndicators.update(indicatorList)
            erComponents[erComponent.id]= erComponent
            
        for i in indicatorList.keys():
            # We need to update the indicators with the ER components and the reasoning for the indicator annotation
            index = int(i)
                    
            diagram.indicators[index].erAssociates.update(erComponents)
    
        return diagram