From 94740aceb066aff8d1280e2c7a6b223868b7b9a4 Mon Sep 17 00:00:00 2001 From: PC-Admin Date: Fri, 21 Jul 2023 03:15:08 +0800 Subject: [PATCH] add functions to collect account data, list account pushers, set account rate limiting and check if an account exists --- README.md | 13 +++-- moderation_tool.py | 102 +++++++++++++++++++-------------- user_commands.py | 138 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 201 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index 13f0bd2..aa9a7de 100755 --- a/README.md +++ b/README.md @@ -75,13 +75,13 @@ With the popular [matrix-docker-ansible-deploy](https://github.com/spantaleev/ma To do: 1) Add the following functions: -- https://github.com/matrix-org/synapse/blob/master/docs/admin_api/delete_group.md -- https://matrix-org.github.io/synapse/latest/admin_api/user_admin_api.html#account-data -- https://matrix-org.github.io/synapse/latest/admin_api/user_admin_api.html#list-all-pushers -- https://matrix-org.github.io/synapse/latest/admin_api/user_admin_api.html#override-ratelimiting-for-users -- https://matrix-org.github.io/synapse/latest/admin_api/user_admin_api.html#check-username-availability +- https://matrix-org.github.io/synapse/latest/admin_api/user_admin_api.html#account-data - DONE +- https://matrix-org.github.io/synapse/latest/admin_api/user_admin_api.html#list-all-pushers - DONE +- https://matrix-org.github.io/synapse/latest/admin_api/user_admin_api.html#override-ratelimiting-for-users - DONE +- https://matrix-org.github.io/synapse/latest/admin_api/user_admin_api.html#check-username-availability - DONE - https://matrix-org.github.io/synapse/latest/admin_api/user_admin_api.html#find-a-user-based-on-their-id-in-an-auth-provider - https://matrix-org.github.io/synapse/latest/admin_api/user_admin_api.html#find-a-user-based-on-their-third-party-id-threepid-or-3pid +- https://github.com/matrix-org/synapse/blob/master/docs/admin_api/delete_group.md 2) Make the menu prettier! - DONE 3) Modularise the functions into multiple files - DONE 4) Use URI module for all API calls instead of curl - DONE @@ -95,7 +95,8 @@ To do: - Pushers List - List of the rooms the user is participating in, divided into 1:1 conversations and larger rooms - The content of the messages they've sent (if they were sent to rooms your server is participating in) -- Copies of any media they've sent +- Copies of any media they've sent? +- Description of report format and contents (to guide the reader) 7) Add a room report function to create a properly formatted report for rdlist 8) Add a function to extract a users email or 3PID 9) Do room shutdowns in parallel? diff --git a/moderation_tool.py b/moderation_tool.py index 0b533e7..db106ff 100755 --- a/moderation_tool.py +++ b/moderation_tool.py @@ -32,31 +32,35 @@ while pass_token == False: print("\nA tool for making common Synapse moderation tasks easier. Created by @PC-Admin.") print("\n----------------------------------------------") print("\n#### User Account Commands ####\t\t\t#### Room Commands ####") - print("1) Deactivate a user account.\t\t\t14) List details of a room.") - print("2) Deactivate multiple user accounts.\t\t15) Export the state events of a target room.") - print("3) Create a user account.\t\t\t16) List rooms in public directory.") - print("4) Create multiple user accounts.\t\t17) Remove a room from the public directory.") - print("5) Reset a users password.\t\t\t18) Remove multiple rooms from the public directory.") - print("6) Whois user account.\t\t\t\t19) Redact a room event.") - print("7) Whois multiple user accounts.\t\t20) List/Download all media in a room.") - print("8) Query user account.\t\t\t\t21) Download media from multiple rooms.") - print("9) Query multiple user accounts.\t\t22) Quarantine all media in a room.") - print("10) List room memberships of user.\t\t23) Shutdown a room.") - print("11) Promote a user to server admin.\t\t24) Shutdown multiple rooms.") - print("12) List all user accounts.\t\t\t25) Delete a room.") - print("13) Quarantine all media a users uploaded.\t26) Delete multiple rooms.") - print("\t\t\t\t\t\t27) Purge the event history of a room to a specific timestamp.") - print("\t\t\t\t\t\t28) Purge the event history of multiple rooms to a specific timestamp.") + print("1) Deactivate a user account.\t\t\t20) List details of a room.") + print("2) Deactivate multiple user accounts.\t\t21) Export the state events of a target room.") + print("3) Create a user account.\t\t\t22) List rooms in public directory.") + print("4) Create multiple user accounts.\t\t23) Remove a room from the public directory.") + print("5) Reset a users password.\t\t\t24) Remove multiple rooms from the public directory.") + print("6) Whois user account.\t\t\t\t25) Redact a room event.") + print("7) Whois multiple user accounts.\t\t26) List/Download all media in a room.") + print("8) Query user account.\t\t\t\t27) Download media from multiple rooms.") + print("9) Query multiple user accounts.\t\t28) Quarantine all media in a room.") + print("10) List room memberships of user.\t\t29) Shutdown a room.") + print("11) Promote a user to server admin.\t\t30) Shutdown multiple rooms.") + print("12) List all user accounts.\t\t\t31) Delete a room.") + print("13) Quarantine all media a users uploaded.\t32) Delete multiple rooms.") + print("14) Collect account data.\t\t\t33) Purge the event history of a room to a specific timestamp.") + print("15) List account pushers.\t\t\t34) Purge the event history of multiple rooms to a specific timestamp.") + print("16) Get rate limit of a user account.") + print("17) Set rate limit of a user account.") + print("18) Delete rate limit of a user account.") + print("19) Check if user account exists.") print("\n#### Server Commands ####") - print("29) Delete and block a specific media.") - print("30) Purge remote media repository up to a certain date.") - print("31) Prepare database for copying events of multiple rooms.") + print("40) Delete and block a specific media.") + print("41) Purge remote media repository up to a certain date.") + print("42) Prepare database for copying events of multiple rooms.") print("\n#### rdlist ####") - print("32) Block all rooms with specific rdlist tags.") - print("34) Block all rooms with recommended rdlist tags.") + print("50) Block all rooms with specific rdlist tags.") + print("51) Block all rooms with recommended rdlist tags.") print("\n#### ipinfo.io ####") - print("40) Analyse a users country of origin.") - print("41) Analyse multiple users country of origin.") + print("60) Analyse a users country of origin.") + print("61) Analyse multiple users country of origin.") print("\nPlease enter a number from the above menu, or enter 'q' or 'e' to exit.\n") menu_input = input() if menu_input == "1": @@ -86,48 +90,60 @@ while pass_token == False: elif menu_input == "13": user_commands.quarantine_users_media() elif menu_input == "14": - room_commands.list_room_details('') + user_commands.collect_account_data('') elif menu_input == "15": - room_commands.export_room_state('') + user_commands.list_account_pushers('') elif menu_input == "16": - room_commands.list_directory_rooms() + user_commands.get_rate_limit() elif menu_input == "17": - room_commands.remove_room_from_directory('') + user_commands.set_rate_limit() elif menu_input == "18": - room_commands.remove_multiple_rooms_from_directory() + user_commands.delete_rate_limit() elif menu_input == "19": - room_commands.redact_room_event() + user_commands.check_user_account_exists('') elif menu_input == "20": - room_commands.list_and_download_media_in_room('','','','./') + room_commands.list_room_details('') elif menu_input == "21": - room_commands.download_media_from_multiple_rooms() + room_commands.export_room_state('') elif menu_input == "22": - room_commands.quarantine_media_in_room() + room_commands.list_directory_rooms() elif menu_input == "23": - room_commands.shutdown_room('','','','','','') + room_commands.remove_room_from_directory('') elif menu_input == "24": - room_commands.shutdown_multiple_rooms() + room_commands.remove_multiple_rooms_from_directory() elif menu_input == "25": - room_commands.delete_room('') + room_commands.redact_room_event() elif menu_input == "26": - room_commands.delete_multiple_rooms() + room_commands.list_and_download_media_in_room('','','','./') elif menu_input == "27": - room_commands.purge_room_to_timestamp('','') + room_commands.download_media_from_multiple_rooms() elif menu_input == "28": - room_commands.purge_multiple_rooms_to_timestamp() + room_commands.quarantine_media_in_room() elif menu_input == "29": - server_commands.delete_block_media() + room_commands.shutdown_room('','','','','','') elif menu_input == "30": - server_commands.purge_remote_media_repo() + room_commands.shutdown_multiple_rooms() elif menu_input == "31": - server_commands.prepare_database_copy_of_multiple_rooms() + room_commands.delete_room('') elif menu_input == "32": - rdlist_commands.block_all_rooms_with_rdlist_tags(False,'','','','','') + room_commands.delete_multiple_rooms() + elif menu_input == "33": + room_commands.purge_room_to_timestamp('','') elif menu_input == "34": - rdlist_commands.block_recommended_rdlist_tags() + room_commands.purge_multiple_rooms_to_timestamp() elif menu_input == "40": - user_commands.analyse_account_ip('') + server_commands.delete_block_media() elif menu_input == "41": + server_commands.purge_remote_media_repo() + elif menu_input == "42": + server_commands.prepare_database_copy_of_multiple_rooms() + elif menu_input == "50": + rdlist_commands.block_all_rooms_with_rdlist_tags(False,'','','','','') + elif menu_input == "51": + rdlist_commands.block_recommended_rdlist_tags() + elif menu_input == "60": + user_commands.analyse_account_ip('') + elif menu_input == "61": 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") diff --git a/user_commands.py b/user_commands.py index 9075392..a7f7572 100644 --- a/user_commands.py +++ b/user_commands.py @@ -213,7 +213,7 @@ def whois_account(preset_username, output_file=None): return response.text # Example: -# $ curl -kXGET https://matrix.perthchat.org/_matrix/client/r0/admin/whois/@PC-Admin:perthchat.org?access_token=ACCESS_TOKEN +# $ curl -kXGET https://matrix.perthchat.org/_matrix/client/r0/admin/whois/@dogpoo:perthchat.org?access_token=ACCESS_TOKEN def whois_multiple_accounts(): print("Whois multiple user accounts selected") @@ -339,7 +339,7 @@ def list_joined_rooms(preset_username): print(f"Error querying joined rooms: {response.status_code}, {response.text}") # Example: -# $ curl -kXGET https://matrix.perthchat.org/_synapse/admin/v1/users/@PC-Admin:perthchat.org/joined_rooms?access_token=ACCESS_TOKEN +# $ curl -kXGET https://matrix.perthchat.org/_synapse/admin/v1/users/@dogpoo:perthchat.org/joined_rooms?access_token=ACCESS_TOKEN def list_accounts(): deactivated_choice = input("Do you want to include deactivated accounts y/n? ") @@ -445,4 +445,136 @@ def quarantine_users_media(): print(f"Error quarantining user's media: {response.status_code}, {response.text}") # Example: -# $ curl -X POST https://matrix.perthchat.org/_synapse/admin/v1/user/@PC-Admin:perthchat.org/media/quarantine?access_token=ACCESS_TOKEN \ No newline at end of file +# $ curl -X POST https://matrix.perthchat.org/_synapse/admin/v1/user/@dogpoo:perthchat.org/media/quarantine?access_token=ACCESS_TOKEN + +def collect_account_data(preset_username): + if len(preset_username) == 0: + username = input("\nPlease enter the username to collect account data: ") + username = parse_username(username) + elif len(preset_username) > 0: + username = parse_username(preset_username) + + url = f"https://{hardcoded_variables.homeserver_url}/_synapse/admin/v1/users/@{username}:{hardcoded_variables.base_url}/accountdata?access_token={hardcoded_variables.access_token}" + + print("\n" + url + "\n") + response = requests.get(url, verify=True) + + if response.status_code == 200: + print(response.text) + else: + print(f"Error querying account: {response.status_code}, {response.text}") + + return response.text + +# Example: +# $ curl -X GET https://matrix.perthchat.org/_synapse/admin/v1/users/@dogpoo:perthchat.org/accountdata?access_token=ACCESS_TOKEN + +def list_account_pushers(preset_username): + if len(preset_username) == 0: + username = input("\nPlease enter the username to list all pushers: ") + username = parse_username(username) + elif len(preset_username) > 0: + username = parse_username(preset_username) + + url = f"https://{hardcoded_variables.homeserver_url}/_synapse/admin/v1/users/@{username}:{hardcoded_variables.base_url}/pushers?access_token={hardcoded_variables.access_token}" + + print("\n" + url + "\n") + response = requests.get(url, verify=True) + + if response.status_code == 200: + print(response.text) + else: + print(f"Error querying account: {response.status_code}, {response.text}") + + return response.text + +# Example: +# $ curl -X GET https://matrix.perthchat.org/_synapse/admin/v1/users/@dogpoo:perthchat.org/pushers + +def get_rate_limit(): + username = input("\nPlease enter the username to get its ratelimiting: ") + + url = f"https://{hardcoded_variables.homeserver_url}/_synapse/admin/v1/users/@{username}:{hardcoded_variables.base_url}/override_ratelimit?access_token={hardcoded_variables.access_token}" + + print("\n" + url + "\n") + response = requests.get(url, verify=True) + + if response.status_code == 200: + print(response.text) + else: + print(f"Error querying account: {response.status_code}, {response.text}") + + return response.text + +# Example: +# $ curl -X GET https://matrix.perthchat.org/_synapse/admin/v1/users/@dogpoo:perthchat.org/override_ratelimit?access_token=ACCESS_TOKEN + +def set_rate_limit(): + username = input("\nPlease enter the username to adjust its ratelimiting: ") + + messages_per_second = input("\nPlease enter the desired messages per second: ") + burst_count = input("\nPlease enter the desired burst count: ") + + url = f"https://{hardcoded_variables.homeserver_url}/_synapse/admin/v1/users/@{username}:{hardcoded_variables.base_url}/override_ratelimit?access_token={hardcoded_variables.access_token}" + + headers = {'Content-Type': 'application/json'} + data = { + "messages_per_second": int(messages_per_second), + "burst_count": int(burst_count) + } + + print("\n" + url + "\n") + + response = requests.post(url, headers=headers, data=json.dumps(data), verify=True) + + if response.status_code == 200: + print(response.text) + else: + print(f"Error querying account: {response.status_code}, {response.text}") + + return response.text + +# Example: +# $ curl -X POST -H "Content-Type: application/json" -d '{"messages_per_second": 0,"burst_count": 0}' https://matrix.perthchat.org/_synapse/admin/v1/users/@dogpoo:perthchat.org/override_ratelimit?access_token=ACCESS_TOKEN + +def delete_rate_limit(): + username = input("\nPlease enter the username to delete its ratelimiting: ") + + url = f"https://{hardcoded_variables.homeserver_url}/_synapse/admin/v1/users/@{username}:{hardcoded_variables.base_url}/override_ratelimit?access_token={hardcoded_variables.access_token}" + + print("\n" + url + "\n") + response = requests.delete(url, verify=True) + + if response.status_code == 200: + print(response.text) + else: + print(f"Error querying account: {response.status_code}, {response.text}") + + return response.text + +# Example: +# $ curl -X DELETE https://matrix.perthchat.org/_synapse/admin/v1/users/@dogpoo:perthchat.org/override_ratelimit?access_token=ACCESS_TOKEN + +def check_user_account_exists(preset_username): + if len(preset_username) == 0: + username = input("\nPlease enter the username to check if it exists: ") + username = parse_username(username) + elif len(preset_username) > 0: + username = parse_username(preset_username) + + url = f"https://{hardcoded_variables.homeserver_url}/_synapse/admin/v1/username_available?username={username}&access_token={hardcoded_variables.access_token}" + + print("\n" + url + "\n") + response = requests.get(url, verify=True) + + if response.status_code == 200: + print("User ID is available.") + elif response.status_code == 400: + print(f"User ID already taken.") + else: + print(f"Error querying account: {response.status_code}, {response.text}") + + return response.text + +# Example: +# $ curl -X GET /_synapse/admin/v1/username_available?username=dogpoo&access_token=ACCESS_TOKEN