From 6fb0dc1067710253b00175f1623c402e55202777 Mon Sep 17 00:00:00 2001 From: "jm.balestek" <157660869+balestek@users.noreply.github.com> Date: Tue, 23 Jul 2024 16:19:43 +0200 Subject: [PATCH] Adding permutator feature for usernames (#1575) * Adding permutator feature for usernames ("", "_", "-", ".") when id_type == username File : maigret/permutator.py Arg : --permute For now, only permute from 2 elements and doesn't return single elements (element1, _element1, element1_, element2, _element2, ...). 12 permuts for 2 elements. To return single elements as well, Permute(usernames).gather(method="all"), but not implemented in maigrat.py. 18 permuts for 2 elements. Should we ? With another argument ? * Update test_cli.py permute arg added --- maigret/maigret.py | 16 ++++++++++++++++ maigret/permutator.py | 26 ++++++++++++++++++++++++++ tests/test_cli.py | 1 + 3 files changed, 43 insertions(+) create mode 100644 maigret/permutator.py diff --git a/maigret/maigret.py b/maigret/maigret.py index 6e74598..18844dd 100755 --- a/maigret/maigret.py +++ b/maigret/maigret.py @@ -41,6 +41,7 @@ from .submit import Submitter from .types import QueryResultWrapper from .utils import get_dict_ascii_tree from .settings import Settings +from .permutator import Permute def notify_about_errors(search_results: QueryResultWrapper, query_notify): @@ -205,6 +206,12 @@ def setup_arguments_parser(settings: Settings): choices=SUPPORTED_IDS, help="Specify identifier(s) type (default: username).", ) + parser.add_argument( + "--permute", + action="store_true", + default=False, + help="Permute at least 2 usernames to generate more possible usernames.", + ) parser.add_argument( "--db", metavar="DB_FILE", @@ -502,6 +509,10 @@ async def main(): for u in args.username if u and u not in ['-'] and u not in args.ignore_ids_list } + original_usernames = "" + if args.permute and len(usernames) > 1 and args.id_type == 'username': + original_usernames = " ".join(usernames.keys()) + usernames = Permute(usernames).gather(method='strict') parsing_enabled = not args.disable_extracting recursive_search_enabled = not args.disable_recursive_search @@ -591,6 +602,11 @@ async def main(): query_notify.warning('No usernames to check, exiting.') sys.exit(0) + if len(usernames) > 1 and args.permute and args.id_type == 'username': + query_notify.warning( + f"{len(usernames)} permutations from {original_usernames} to check..." + ) + if not site_data: query_notify.warning('No sites to check, exiting!') sys.exit(2) diff --git a/maigret/permutator.py b/maigret/permutator.py new file mode 100644 index 0000000..49b1cc2 --- /dev/null +++ b/maigret/permutator.py @@ -0,0 +1,26 @@ +# License MIT. by balestek https://github.com/balestek +from itertools import permutations + + +class Permute: + def __init__(self, elements: dict): + self.separators = ["", "_", "-", "."] + self.elements = elements + + def gather(self, method: str = "strict" or "all") -> dict: + permutations_dict = {} + for i in range(1, len(self.elements) + 1): + for subset in permutations(self.elements, i): + if i == 1: + if method == "all": + permutations_dict[subset[0]] = self.elements[subset[0]] + permutations_dict["_" + subset[0]] = self.elements[subset[0]] + permutations_dict[subset[0] + "_"] = self.elements[subset[0]] + else: + for separator in self.separators: + perm = separator.join(subset) + permutations_dict[perm] = self.elements[subset[0]] + if separator == "": + permutations_dict["_" + perm] = self.elements[subset[0]] + permutations_dict[perm + "_"] = self.elements[subset[0]] + return permutations_dict diff --git a/tests/test_cli.py b/tests/test_cli.py index 8d677f1..4bda012 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -23,6 +23,7 @@ DEFAULT_ARGS: Dict[str, Any] = { 'no_progressbar': False, 'parse_url': '', 'pdf': False, + 'permute': False, 'print_check_errors': False, 'print_not_found': False, 'proxy': None,