Last active
February 4, 2023 23:39
-
-
Save regulad/5af87bf50a9c2637dd5e014e3445c713 to your computer and use it in GitHub Desktop.
A test case that tests all of the known Twitter OAuth1a client tokens & secrets. Requires a dperson/torproxy to proxy requests.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Copyright (c) 2023 by Parker Wahle. All rights reserved. | |
# Requires pytest, tweepy, pytest, pytest-selenium, selenium, & tor-python-easy | |
# Up a Tor proxy with https://github.com/markowanga/tor-python-easy | |
# I used the Chrome driver, but I've written code to use any driver. | |
import pytest | |
from selenium.webdriver import Proxy | |
from selenium.webdriver.chrome.options import Options as ChromeOptions | |
from selenium.webdriver.common.by import By | |
from selenium.webdriver.edge.options import Options as EdgeOptions | |
from selenium.webdriver.firefox.options import Options as FirefoxOptions | |
from selenium.webdriver.remote.webdriver import WebDriver | |
from tor_python_easy.tor_control_port_client import TorControlPortClient | |
from tor_python_easy.tor_socks_get_ip_client import TorSocksGetIpClient | |
from tweepy import OAuth1UserHandler, API | |
from tweepy.models import Status | |
@pytest.fixture(scope="session") | |
def username(): | |
# sleet.cope_0i@icloud.com | |
return "oauthtest91239" | |
@pytest.fixture(scope="session") | |
def password(): | |
return "9%Vz^&XeYjo^4A%9" | |
@pytest.fixture(scope="session") | |
def tor_host(): | |
return "localhost" | |
@pytest.fixture(scope="session") | |
def tor_port(): | |
return 9050 | |
@pytest.fixture(scope="session") | |
def tor_control_port(): | |
return 9051 | |
@pytest.fixture(scope="session") | |
def tor_control_password(): | |
return "test1234" | |
@pytest.fixture(scope="session") | |
def socks5_proxy(tor_host, tor_port): | |
return f"socks5://{tor_host}:{tor_port}" | |
@pytest.fixture(scope="session") | |
def raw_proxy(socks5_proxy): | |
return { | |
"http": socks5_proxy, | |
"https": socks5_proxy, | |
"ftp": socks5_proxy, | |
} | |
@pytest.fixture(scope="session") | |
def tor_socks_get_ip_client(raw_proxy): | |
return TorSocksGetIpClient(raw_proxy) | |
@pytest.fixture(scope="session") | |
def tor_control_port_client(tor_host, tor_control_port, tor_control_password): | |
return TorControlPortClient(tor_host, tor_control_port, tor_control_password) | |
@pytest.fixture | |
def tor_ip(tor_socks_get_ip_client, tor_control_port_client): | |
old_ip = tor_socks_get_ip_client.get_ip() | |
if hasattr(tor_socks_get_ip_client, "__old_ip"): | |
tor_control_port_client.change_connection_ip(seconds_wait=10) | |
new_ip = tor_socks_get_ip_client.get_ip() | |
assert old_ip != new_ip | |
tor_socks_get_ip_client.__old_ip = new_ip | |
return new_ip | |
else: | |
tor_socks_get_ip_client.__old_ip = old_ip | |
return old_ip | |
@pytest.fixture | |
def proxy(raw_proxy): | |
selenium_raw = {(key + "Proxy"): value for key, value in raw_proxy.items()} | |
return Proxy(raw=selenium_raw) | |
@pytest.fixture | |
def chrome_options(chrome_options: ChromeOptions, proxy, socks5_proxy, tor_host): | |
chrome_options.proxy = proxy | |
# NOTE: proxies don't work in chrome | |
# chrome_options.add_argument(f"--proxy-server=\"{socks5_proxy}\"") | |
# chrome_options.add_argument(f"--host-resolver-rules=\"MAP * ~NOTFOUND , EXCLUDE {tor_host}\"") | |
return chrome_options | |
@pytest.fixture | |
def firefox_options(firefox_options: FirefoxOptions, proxy): | |
firefox_options.proxy = proxy | |
# NOTE: proxies don't work in firefox | |
return firefox_options | |
@pytest.fixture | |
def edge_options(edge_options: EdgeOptions, proxy): | |
edge_options.proxy = proxy | |
# NOTE: proxies don't work in edge | |
return edge_options | |
@pytest.mark.parametrize("consumer_key, consumer_secret, name", [ | |
("IQKbtAYlXLripLGPWd0HUA", "GgDYlkSvaPxGxC4X8liwpUoqKwwr3lCADbz8A7ADU", "iPhone"), # Twitter for iPhone | |
("3nVuSoBZnx6U4vzUxf5w", "Bcs59EFbbsdF6Sl9Ng71smgStWEGwXXKSjYvPVt7qys", "Android"), # Twitter for Android | |
("iAtYJ4HpUVfIUoNnif1DA", "172fOpzuZoYzNYaU3mMYvE8m8MEyLbztOdbrUolU", "Google TV"), # Twitter for Google TV | |
("CjulERsDeqhhjSme66ECg", "IQWdVyqFxghAtURHGeGiWAsmCAGmdW3WmbEx6Hck", "iPad"), # Twitter for iPad | |
("3rJOl1ODzm9yZy63FACdg", "5jPoQ5kQvMJFDYRNE8bQ4rHuds4xJqhvgNJM4awaE8", "Mac"), # Twitter for Mac | |
("yN3DUNVO0Me63IAQdhTfCA", "c768oTKdzAjIYCmpSNIdZbGaG0t6rOhSFQP0S5uC79g", "Windows Phone"), # Twitter for Windows Phone | |
("yT577ApRtZw51q4NPMPPOQ", "3neq3XqN5fO3obqwZoajavGFCUrC42ZfbrLXy5sCv8", "TweetDeck"), # TweetDeck | |
]) | |
def test_oauth( | |
tor_ip, | |
selenium: WebDriver, | |
raw_proxy, | |
username, | |
password, | |
consumer_key, | |
consumer_secret, | |
name | |
): | |
oauth = OAuth1UserHandler( | |
consumer_key=consumer_key, | |
consumer_secret=consumer_secret, | |
callback="oob" | |
) | |
oauth.oauth.proxies = raw_proxy # use the proxy we setup | |
twitter_url = oauth.get_authorization_url(signin_with_twitter=True) | |
# get the code | |
# Login page | |
selenium.get(twitter_url) | |
selenium.find_element(By.ID, "username_or_email").send_keys(username) | |
selenium.find_element(By.ID, "password").send_keys(password) | |
selenium.find_element(By.ID, "allow").click() | |
# OAuth page | |
oauth_pin = selenium.find_element(By.ID, "oauth_pin").find_element(By.TAG_NAME, "code").text | |
# use the code | |
oauth.get_access_token(oauth_pin) | |
api = API(oauth) | |
# testing | |
status: Status = api.update_status(f"Hi from {name} @ {tor_ip}!") | |
assert status.text == f"Hi from {name} @ {tor_ip}!" # type: ignore |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment