mirror of
				https://github.com/PC-Admin/matrix-moderation-tool.git
				synced 2025-10-31 18:20:30 -04:00 
			
		
		
		
	add ipinfo function for determining an accounts country of origin, add multiple whois and query account functions
This commit is contained in:
		| @@ -4,6 +4,8 @@ | ||||
| homeserver_url = "matrix.example.org" | ||||
| base_url = "example.org" | ||||
| access_token = "" | ||||
| # ipinfo.io token | ||||
| ipinfo_token = "" | ||||
| # rdlist specific | ||||
| rdlist_bot_username = "mod_team" | ||||
| ########################################################################### | ||||
|   | ||||
| @@ -32,7 +32,7 @@ if length_access_token == 0: | ||||
|  | ||||
| pass_token = False | ||||
| while pass_token == False: | ||||
| 	menu_input = input('\nPlease select one of the following options:\n#### User Account Commands ####\n1) Deactivate a user account.\n2) Deactivate multiple user accounts.\n3) Create a user account.\n4) Create multiple user accounts.\n5) Reset a users password.\n6) Whois user account.\n7) Whois multiple user accounts.\n8) List room memberships of user.\n9) Promote a user to server admin.\n10) List all user accounts.\n11) Quarantine all media a users uploaded.\n#### Room Commands ####\n12) List details of a room.\n13) Export the state events of a target room.\n14) List rooms in public directory.\n15) Remove a room from the public directory.\n16) Remove multiple rooms from the public directory.\n17) Redact a room event. (Like abusive avatars or display names.) \n18) List/Download all media in a room.\n19) Download media from multiple rooms.\n20) Quarantine all media in a room.\n21) Shutdown a room.\n22) Shutdown multiple rooms.\n23) Delete a room.\n24) Delete multiple rooms.\n25) Purge the event history of a room to a specific timestamp.\n26) Purge the event history of multiple rooms to a specific timestamp.\n#### Server Commands ####\n27) Delete and block a specific media. (Like an abusive avatar.) \n28) Purge remote media repository up to a certain date.\n29) Prepare database for copying events of multiple rooms.\n#### rdlist ####\n30) Block all rooms with specific rdlist tags.\n34) Block all rooms with recommended rdlist tags.\n(\'q\' or \'e\') Exit.\n\n') | ||||
| 	menu_input = input('\nPlease select one of the following options:\n#### User Account Commands ####\n1) Deactivate a user account.\n2) Deactivate multiple user accounts.\n3) Create a user account.\n4) Create multiple user accounts.\n5) Reset a users password.\n6) Whois user account.\n7) Whois multiple user accounts.\n8) Query user account.\n9) Query multiple user accounts.\n10) List room memberships of user.\n11) Promote a user to server admin.\n12) List all user accounts.\n13) Quarantine all media a users uploaded.\n#### Room Commands ####\n14) List details of a room.\n15) Export the state events of a target room.\n16) List rooms in public directory.\n17) Remove a room from the public directory.\n18) Remove multiple rooms from the public directory.\n19) Redact a room event. (Like abusive avatars or display names.) \n20) List/Download all media in a room.\n21) Download media from multiple rooms.\n22) Quarantine all media in a room.\n23) Shutdown a room.\n24) Shutdown multiple rooms.\n25) Delete a room.\n26) Delete multiple rooms.\n27) Purge the event history of a room to a specific timestamp.\n28) Purge the event history of multiple rooms to a specific timestamp.\n#### Server Commands ####\n29) Delete and block a specific media. (Like an abusive avatar.) \n30) Purge remote media repository up to a certain date.\n31) Prepare database for copying events of multiple rooms.\n#### rdlist ####\n32) Block all rooms with specific rdlist tags.\n34) Block all rooms with recommended rdlist tags.\n#### ipinfo.io ####\n40) Analyse a users country of origin.\n41) Analyse multiple users country of origin.\n(\'q\' or \'e\') Exit.\n\n') | ||||
| 	if menu_input == "1": | ||||
| 		user_commands.deactivate_account('') | ||||
| 	elif menu_input == "2": | ||||
| @@ -41,60 +41,68 @@ while pass_token == False: | ||||
| 		user_commands.create_account('','') | ||||
| 	elif menu_input == "4": | ||||
| 		user_commands.create_multiple_accounts() | ||||
| 	elif menu_input == "6": | ||||
| 	elif menu_input == "5": | ||||
| 		user_commands.reset_password('','') | ||||
| 	elif menu_input == "6": | ||||
| 		user_commands.whois_account('') | ||||
| 	elif menu_input == "7": | ||||
| 		user_commands.whois_multiple_accounts() | ||||
| 	elif menu_input == "8": | ||||
| 		user_commands.list_joined_rooms('') | ||||
| 		user_commands.query_account() | ||||
| 	elif menu_input == "9": | ||||
| 		user_commands.set_user_server_admin('') | ||||
| 		user_commands.query_multiple_accounts() | ||||
| 	elif menu_input == "10": | ||||
| 		user_commands.list_accounts() | ||||
| 		user_commands.list_joined_rooms('') | ||||
| 	elif menu_input == "11": | ||||
| 		user_commands.quarantine_users_media() | ||||
| 		user_commands.set_user_server_admin('') | ||||
| 	elif menu_input == "12": | ||||
| 		room_commands.list_room_details('') | ||||
| 		user_commands.list_accounts() | ||||
| 	elif menu_input == "13": | ||||
| 		room_commands.export_room_state('') | ||||
| 		user_commands.quarantine_users_media() | ||||
| 	elif menu_input == "14": | ||||
| 		room_commands.list_directory_rooms() | ||||
| 		room_commands.list_room_details('') | ||||
| 	elif menu_input == "15": | ||||
| 		room_commands.remove_room_from_directory('') | ||||
| 		room_commands.export_room_state('') | ||||
| 	elif menu_input == "16": | ||||
| 		room_commands.remove_multiple_rooms_from_directory() | ||||
| 		room_commands.list_directory_rooms() | ||||
| 	elif menu_input == "17": | ||||
| 		room_commands.redact_room_event() | ||||
| 		room_commands.remove_room_from_directory('') | ||||
| 	elif menu_input == "18": | ||||
| 		room_commands.list_and_download_media_in_room('','','','./') | ||||
| 		room_commands.remove_multiple_rooms_from_directory() | ||||
| 	elif menu_input == "19": | ||||
| 		room_commands.download_media_from_multiple_rooms() | ||||
| 		room_commands.redact_room_event() | ||||
| 	elif menu_input == "20": | ||||
| 		room_commands.quarantine_media_in_room() | ||||
| 		room_commands.list_and_download_media_in_room('','','','./') | ||||
| 	elif menu_input == "21": | ||||
| 		room_commands.shutdown_room('','','','','','') | ||||
| 		room_commands.download_media_from_multiple_rooms() | ||||
| 	elif menu_input == "22": | ||||
| 		room_commands.shutdown_multiple_rooms() | ||||
| 		room_commands.quarantine_media_in_room() | ||||
| 	elif menu_input == "23": | ||||
| 		room_commands.delete_room('') | ||||
| 		room_commands.shutdown_room('','','','','','') | ||||
| 	elif menu_input == "24": | ||||
| 		room_commands.delete_multiple_rooms() | ||||
| 		room_commands.shutdown_multiple_rooms() | ||||
| 	elif menu_input == "25": | ||||
| 		room_commands.purge_room_to_timestamp('','') | ||||
| 		room_commands.delete_room('') | ||||
| 	elif menu_input == "26": | ||||
| 		room_commands.purge_multiple_rooms_to_timestamp() | ||||
| 		room_commands.delete_multiple_rooms() | ||||
| 	elif menu_input == "27": | ||||
| 		server_commands.delete_block_media() | ||||
| 		room_commands.purge_room_to_timestamp('','') | ||||
| 	elif menu_input == "28": | ||||
| 		server_commands.purge_remote_media_repo() | ||||
| 		room_commands.purge_multiple_rooms_to_timestamp() | ||||
| 	elif menu_input == "29": | ||||
| 		server_commands.prepare_database_copy_of_multiple_rooms() | ||||
| 		server_commands.delete_block_media() | ||||
| 	elif menu_input == "30": | ||||
| 		server_commands.purge_remote_media_repo() | ||||
| 	elif menu_input == "31": | ||||
| 		server_commands.prepare_database_copy_of_multiple_rooms() | ||||
| 	elif menu_input == "32": | ||||
| 		rdlist_commands.block_all_rooms_with_rdlist_tags(False,'','','','','') | ||||
| 	elif menu_input == "34": | ||||
| 		rdlist_commands.block_recommended_rdlist_tags() | ||||
| 	elif menu_input == "40": | ||||
| 		user_commands.analyse_account_ip('') | ||||
| 	elif menu_input == "41": | ||||
| 		user_commands.analyse_multiple_account_ips() | ||||
| 	elif menu_input == "q" or menu_input == "Q" or menu_input == "e" or menu_input == "E": | ||||
| 		print("\nExiting...\n") | ||||
| 		pass_token = True | ||||
|   | ||||
							
								
								
									
										173
									
								
								user_commands.py
									
									
									
									
									
								
							
							
						
						
									
										173
									
								
								user_commands.py
									
									
									
									
									
								
							| @@ -1,9 +1,11 @@ | ||||
|  | ||||
| import os | ||||
| import requests | ||||
| import json | ||||
| import time | ||||
| import csv | ||||
| import hardcoded_variables | ||||
| import socket | ||||
|  | ||||
| def parse_username(username): | ||||
| 	tail_end = ':' + hardcoded_variables.base_url | ||||
| @@ -183,7 +185,7 @@ def set_user_server_admin(preset_username): | ||||
| # Example: | ||||
| # $ curl -kX POST -H 'Content-Type: application/json' -d '{"admin": "true"}' https://matrix.perthchat.org/_synapse/admin/v2/users/@dogpoo:perthchat.org?access_token=ACCESS_TOKEN | ||||
|  | ||||
| def whois_account(preset_username): | ||||
| def whois_account(preset_username, output_file=None): | ||||
| 	if preset_username == '': | ||||
| 		username = input("\nPlease enter the username you wish to whois: ") | ||||
| 	elif preset_username != '': | ||||
| @@ -196,10 +198,17 @@ def whois_account(preset_username): | ||||
| 	print("\n" + url + "\n") | ||||
| 	response = requests.get(url, verify=True) | ||||
|  | ||||
| 	output_text = "" | ||||
| 	if response.status_code == 200: | ||||
| 		print(response.text + "\n") | ||||
| 		output_text = response.text + "\n" | ||||
| 	else: | ||||
| 		print(f"Error retrieving account info: {response.status_code}, {response.text}\n") | ||||
| 		output_text = f"Error retrieving account info: {response.status_code}, {response.text}\n" | ||||
|  | ||||
| 	if output_file: | ||||
| 		with open(output_file, 'a') as f: | ||||
| 			f.write(output_text) | ||||
| 	else: | ||||
| 		print(output_text) | ||||
|  | ||||
| 	return response.text | ||||
|  | ||||
| @@ -207,24 +216,110 @@ def whois_account(preset_username): | ||||
| # $ curl -kXGET https://matrix.perthchat.org/_matrix/client/r0/admin/whois/@PC-Admin:perthchat.org?access_token=ACCESS_TOKEN | ||||
|  | ||||
| def whois_multiple_accounts(): | ||||
| 	print("Whois multiple user accounts selected") | ||||
| 	user_list_location = input("\nPlease enter the path of the file containing a newline seperated list of Matrix usernames: ") | ||||
| 	with open(user_list_location, newline='') as f: | ||||
| 		reader = csv.reader(f) | ||||
| 		data = list(reader) | ||||
| 		print(len(data)) | ||||
| 	whois_confirmation = input("\n" + str(data) + "\n\nAre you sure you want to whois all of these users? y/n?\n") | ||||
| 	if whois_confirmation == "y" or whois_confirmation == "Y" or whois_confirmation == "yes" or whois_confirmation == "Yes":   | ||||
| 		x = 0 | ||||
| 		while x <= (len(data) - 1): | ||||
| 			print(data[x][0]) | ||||
| 			query_account(data[x][0]) | ||||
| 			list_joined_rooms(data[x][0]) | ||||
| 			x += 1 | ||||
| 			#print(x) | ||||
| 			time.sleep(1) | ||||
| 	if whois_confirmation == "n" or whois_confirmation == "N" or whois_confirmation == "no" or whois_confirmation == "No": | ||||
| 		print("\nExiting...\n") | ||||
|     print("Whois multiple user accounts selected") | ||||
|     user_list_location = input("\nPlease enter the path of the file containing a newline seperated list of Matrix usernames: ") | ||||
|     with open(user_list_location, newline='') as f: | ||||
|         reader = csv.reader(f) | ||||
|         data = list(reader) | ||||
|         print(len(data)) | ||||
|  | ||||
|     print("\n" + str(data)) | ||||
|  | ||||
|     output_file = None | ||||
|     if len(data) > 10: | ||||
|         file_confirmation = input("\nThere are more than 10 users. Would you like to save the output to a file? y/n?\n") | ||||
|         if file_confirmation.lower() in ("y", "yes"): | ||||
|             output_file = input("\nPlease enter the desired output file path:\n") | ||||
|  | ||||
|     whois_confirmation = input("\n\nAre you sure you want to whois all of these users? y/n?\n") | ||||
|  | ||||
|     if whois_confirmation.lower() in ("y", "yes"):   | ||||
|         x = 0 | ||||
|         while x <= (len(data) - 1): | ||||
|             output = whois_account(data[x][0]) | ||||
|  | ||||
|             # if output file is specified, append to file | ||||
|             if output_file: | ||||
|                 with open(output_file, 'a') as f: | ||||
|                     f.write(output + "\n") | ||||
|             x += 1 | ||||
|             time.sleep(1) | ||||
|  | ||||
|     if whois_confirmation.lower() in ("n", "no"): | ||||
|         print("\nExiting...\n") | ||||
|  | ||||
|     if output_file and os.path.isfile(output_file): | ||||
|         print(f"Output saved to {output_file}") | ||||
|  | ||||
| def is_valid_ipv4(ip): | ||||
|     try: | ||||
|         socket.inet_pton(socket.AF_INET, ip) | ||||
|     except socket.error:  # not a valid address | ||||
|         return False | ||||
|     return True | ||||
|  | ||||
| def analyse_account_ip(preset_username): | ||||
|     if not preset_username: | ||||
|         preset_username = input("\nPlease enter a username to analyse their country of origin: ") | ||||
|     user_info = whois_account(preset_username=preset_username) | ||||
|  | ||||
|     data = json.loads(user_info) | ||||
|      | ||||
|     user_id = data['user_id'] | ||||
|     #print(f'user_id: {user_id}') | ||||
|     device_data = data['devices'] | ||||
|     #print(f'device_data: {device_data}') | ||||
|  | ||||
|     countries = [] | ||||
|     for device_id, device_info in device_data.items(): | ||||
|         for session in device_info['sessions']: | ||||
|             for connection in session['connections']: | ||||
|                 ip = connection['ip'] | ||||
|                 if is_valid_ipv4(ip): | ||||
|                     res = requests.get(f"https://ipinfo.io/{ip}",  | ||||
|                                        headers={"Authorization": f"Bearer {hardcoded_variables.ipinfo_token}"}) | ||||
|                     if res.status_code == 200: | ||||
|                         country = res.json().get('country') | ||||
|                         countries.append(country) | ||||
|  | ||||
|     print(f"User: {user_id} from Countries: {countries}") | ||||
|     return(f"User: {user_id} from Countries: {countries}") | ||||
|  | ||||
| def analyse_multiple_account_ips(): | ||||
|     print("Analyse multiple user IPs selected") | ||||
|     user_list_location = input("\nPlease enter the path of the file containing a newline seperated list of Matrix usernames: ") | ||||
|     with open(user_list_location, newline='') as f: | ||||
|         reader = csv.reader(f) | ||||
|         data = list(reader) | ||||
|         print(len(data)) | ||||
|  | ||||
|     print("\n" + str(data)) | ||||
|  | ||||
|     output_file = None | ||||
|     if len(data) > 10: | ||||
|         file_confirmation = input("\nThere are more than 10 users. Would you like to save the output to a file? y/n?\n") | ||||
|         if file_confirmation.lower() in ("y", "yes"): | ||||
|             output_file = input("\nPlease enter the desired output file path:\n") | ||||
|  | ||||
|     analyse_confirmation = input("\n\nAre you sure you want to analyse the IP of all of these users? y/n?\n") | ||||
|  | ||||
|     if analyse_confirmation.lower() in ("y", "yes"):   | ||||
|         x = 0 | ||||
|         while x <= (len(data) - 1): | ||||
|             output = analyse_account_ip(data[x][0]) | ||||
|  | ||||
|             # if output file is specified, append to file | ||||
|             if output_file: | ||||
|                 with open(output_file, 'a') as f: | ||||
|                     f.write(output + "\n") | ||||
|             x += 1 | ||||
|             time.sleep(1) | ||||
|  | ||||
|     if analyse_confirmation.lower() in ("n", "no"): | ||||
|         print("\nExiting...\n") | ||||
|  | ||||
|     if output_file and os.path.isfile(output_file): | ||||
|         print(f"Output saved to {output_file}") | ||||
|  | ||||
| def list_joined_rooms(preset_username): | ||||
| 	if preset_username == '': | ||||
| @@ -299,6 +394,42 @@ def query_account(preset_username): | ||||
| # Example: | ||||
| # $ curl -kX GET https://matrix.perthchat.org/_synapse/admin/v2/users/@billybob:perthchat.org?access_token=ACCESS_TOKEN | ||||
|  | ||||
| def query_multiple_accounts(): | ||||
|     print("Query multiple user accounts selected") | ||||
|     user_list_location = input("\nPlease enter the path of the file containing a newline seperated list of Matrix usernames: ") | ||||
|     with open(user_list_location, newline='') as f: | ||||
|         reader = csv.reader(f) | ||||
|         data = list(reader) | ||||
|         print(len(data)) | ||||
|  | ||||
|     print("\n" + str(data)) | ||||
|  | ||||
|     output_file = None | ||||
|     if len(data) > 10: | ||||
|         file_confirmation = input("\nThere are more than 10 users. Would you like to save the output to a file? y/n?\n") | ||||
|         if file_confirmation.lower() in ("y", "yes"): | ||||
|             output_file = input("\nPlease enter the desired output file path:\n") | ||||
|  | ||||
|     query_confirmation = input("\n\nAre you sure you want to query all of these users? y/n?\n") | ||||
|  | ||||
|     if query_confirmation.lower() in ("y", "yes"):   | ||||
|         x = 0 | ||||
|         while x <= (len(data) - 1): | ||||
|             output = query_account(data[x][0]) | ||||
|  | ||||
|             # if output file is specified, append to file | ||||
|             if output_file: | ||||
|                 with open(output_file, 'a') as f: | ||||
|                     f.write(output + "\n") | ||||
|             x += 1 | ||||
|             time.sleep(1) | ||||
|  | ||||
|     if query_confirmation.lower() in ("n", "no"): | ||||
|         print("\nExiting...\n") | ||||
|  | ||||
|     if output_file and os.path.isfile(output_file): | ||||
|         print(f"Output saved to {output_file}") | ||||
|  | ||||
| def quarantine_users_media(): | ||||
| 	username = input("\nPlease enter the username of the user who's media you want to quarantine: ") | ||||
| 	username = parse_username(username) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user