Repository: valayDave/tell-me-your-secrets

Issue:
Return all issues 
I noticed that this script returns first issue identified in a file rather than them all. 

Would you be open to changing the behaviour to return all? 

I can implement the change 👍🏼 

Discussion:

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5e28236..263889c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,10 @@
 
 - Improved processing to use multiprocessing (#35)
 
+### Improved
+
+- Return all signature matches within a file (#37)
+
 ### Fixed
 
 - Fixed bug with gitignore flag and non-existent `.gitignore` file (#35)
diff --git a/tell_me_your_secrets/processor.py b/tell_me_your_secrets/processor.py
index 2669a25..5e2e225 100644
--- a/tell_me_your_secrets/processor.py
+++ b/tell_me_your_secrets/processor.py
@@ -1,4 +1,4 @@
-from typing import Optional, Tuple
+from typing import List
 
 from tell_me_your_secrets.logger import get_logger
 from tell_me_your_secrets.utils import get_file_data
@@ -6,44 +6,48 @@ from tell_me_your_secrets.utils import get_file_data
 module_logger = get_logger()
 
 
+class SignatureMatch:
+    name: str
+    part: str
+    path: str
+
+    def __init__(self, name: str, part: str, path: str):
+        self.name = name
+        self.part = part
+        self.path = path
+
+
 class Processor:
     def __init__(self, signatures: list, whitelisted_strings: list, print_results: bool):
         self.signatures = signatures
         self.whitelisted_strings = whitelisted_strings
         self.print_results = print_results
 
-    def process_file(self, possible_compromised_path: str) -> list:
+    def process_file(self, possible_compromised_path: str) -> List[SignatureMatch]:
         module_logger.debug(f'Opening File : {possible_compromised_path}')
-        matched_signatures = []
         file_content = get_file_data(possible_compromised_path)
         if file_content is None:
-            return matched_signatures
-        # $ Run the Signature Checking Engine over here For different Pattern Signatures.
-        signature_name, signature_part = self.run_signatures(possible_compromised_path, file_content)
-        if signature_name is not None:
-            matched_signatures.append(self.create_matched_signature_object(signature_name, signature_part,
-                                                                           possible_compromised_path))
-            if self.print_results:
-                module_logger.info(f'Signature Matched : {signature_name} | On Part : {signature_part} | With '
-                                   f'File : {possible_compromised_path}')
+            return []
+
+        matched_signatures = self.run_signatures(possible_compromised_path, file_content)
         return matched_signatures
 
-    def run_signatures(self, file_path, content) -> Tuple[Optional[str], Optional[str]]:
+    def run_signatures(self, file_path, content) -> List[SignatureMatch]:
+        matches: List[SignatureMatch] = []
         for signature in self.signatures:
             match_result = signature.match(file_path, content)
-            if match_result.is_match:
-                if match_result.matched_value in self.whitelisted_strings:
-                    module_logger.debug(f'Signature {signature.name} matched {match_result.matched_value} but skipping'
-                                        f' since it is whitelisted')
-                    continue
-                # $ Return the first signature Match.
-                return signature.name, signature.part
-        return None, None
-
-    @staticmethod
-    def create_matched_signature_object(name: str, part: str, file_path: str) -> dict:
-        return {
-            'name': name,
-            'part': part,
-            'path': file_path
-        }
+            if not match_result.is_match:
+                continue
+
+            if match_result.matched_value in self.whitelisted_strings:
+                module_logger.debug(f'Signature {signature.name} matched {match_result.matched_value} but skipping'
+                                    f' since it is whitelisted')
+                continue
+
+            if self.print_results:
+                module_logger.info(f'Signature Matched : {signature.name} | On Part : {signature.part} | With '
+                                   f'File : {file_path}')
+
+            matches.append(SignatureMatch(signature.name, signature.part, file_path))
+
+        return matches


Test patch:
diff --git a/test/test_processor.py b/test/test_processor.py
index 91a1a33..0c2b4d5 100644
--- a/test/test_processor.py
+++ b/test/test_processor.py
@@ -23,6 +23,7 @@ class RunSignaturesTest(unittest.TestCase):
         ]
         processor = Processor(signatures, [], False)
 
-        result = processor.run_signatures('file/with/issues', 'dodgy-content')
-        self.assertEqual('Mock Signature', result[0])
-        self.assertEqual('file', result[1])
+        results = processor.run_signatures('file/with/issues', 'dodgy-content')
+        self.assertEqual(1, len(results))
+        self.assertEqual('Mock Signature', results[0].name)
+        self.assertEqual('file', results[0].part)