187 lines
6.1 KiB
Python
Executable File
187 lines
6.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Bot Cloudflare - Récupère les API Global Keys depuis le dashboard
|
|
Usage: python3 cloudflare_api_key_bot.py [account_id]
|
|
"""
|
|
import os, sys, time, psycopg2
|
|
from selenium import webdriver
|
|
from selenium.webdriver.common.by import By
|
|
from selenium.webdriver.chrome.service import Service
|
|
from selenium.webdriver.chrome.options import Options
|
|
from selenium.webdriver.support.ui import WebDriverWait
|
|
from selenium.webdriver.support import expected_conditions as EC
|
|
|
|
DB_CONN = "dbname=adx_system user=admin password=admin123 host=localhost"
|
|
|
|
def get_db():
|
|
return psycopg2.connect(DB_CONN)
|
|
|
|
def get_accounts(account_id=None):
|
|
conn = get_db()
|
|
cur = conn.cursor()
|
|
if account_id:
|
|
cur.execute("SELECT id, email, password FROM admin.cloudflare_accounts WHERE id = %s", (account_id,))
|
|
else:
|
|
cur.execute("SELECT id, email, password FROM admin.cloudflare_accounts WHERE (api_key IS NULL OR api_key = '') AND status = 'active' LIMIT 10")
|
|
accounts = cur.fetchall()
|
|
conn.close()
|
|
return accounts
|
|
|
|
def update_api_key(account_id, api_key, cf_account_id=None):
|
|
conn = get_db()
|
|
cur = conn.cursor()
|
|
cur.execute("""
|
|
UPDATE admin.cloudflare_accounts
|
|
SET api_key = %s, cf_account_id = %s, api_status = 'valid', last_api_check = NOW()
|
|
WHERE id = %s
|
|
""", (api_key, cf_account_id, account_id))
|
|
conn.commit()
|
|
conn.close()
|
|
print(f"✅ API key saved for account {account_id}")
|
|
|
|
def start_browser():
|
|
opts = Options()
|
|
opts.add_argument('--no-sandbox')
|
|
opts.add_argument('--disable-dev-shm-usage')
|
|
opts.add_argument('--disable-blink-features=AutomationControlled')
|
|
opts.add_experimental_option('excludeSwitches', ['enable-automation'])
|
|
driver = webdriver.Chrome(service=Service("/usr/local/bin/chromedriver"), options=opts)
|
|
driver.maximize_window()
|
|
return driver
|
|
|
|
def login_cloudflare(driver, email, password):
|
|
print(f"🔐 Login {email}...")
|
|
driver.get("https://dash.cloudflare.com/login")
|
|
time.sleep(3)
|
|
|
|
try:
|
|
# Email
|
|
email_input = WebDriverWait(driver, 10).until(
|
|
EC.presence_of_element_located((By.CSS_SELECTOR, "input[type='email'], input[name='email']"))
|
|
)
|
|
email_input.clear()
|
|
email_input.send_keys(email)
|
|
time.sleep(0.5)
|
|
|
|
# Password
|
|
pwd_input = driver.find_element(By.CSS_SELECTOR, "input[type='password']")
|
|
pwd_input.clear()
|
|
pwd_input.send_keys(password)
|
|
time.sleep(0.5)
|
|
|
|
# Submit
|
|
submit = driver.find_element(By.CSS_SELECTOR, "button[type='submit']")
|
|
submit.click()
|
|
time.sleep(5)
|
|
|
|
# Check if logged in
|
|
if "dash.cloudflare.com" in driver.current_url and "login" not in driver.current_url:
|
|
print("✅ Login successful")
|
|
return True
|
|
else:
|
|
print("❌ Login failed - may need 2FA or captcha")
|
|
return False
|
|
except Exception as e:
|
|
print(f"❌ Login error: {e}")
|
|
return False
|
|
|
|
def get_api_key(driver):
|
|
print("🔑 Getting API key...")
|
|
try:
|
|
# Go to API tokens page
|
|
driver.get("https://dash.cloudflare.com/profile/api-tokens")
|
|
time.sleep(3)
|
|
|
|
# Click "View" on Global API Key
|
|
view_buttons = driver.find_elements(By.XPATH, "//button[contains(text(), 'View')]")
|
|
for btn in view_buttons:
|
|
try:
|
|
btn.click()
|
|
time.sleep(2)
|
|
|
|
# Enter password if prompted
|
|
pwd_inputs = driver.find_elements(By.CSS_SELECTOR, "input[type='password']")
|
|
if pwd_inputs:
|
|
# Need to handle password confirmation
|
|
print("⚠️ Password confirmation required")
|
|
return None
|
|
|
|
# Find the API key
|
|
api_key_elem = driver.find_element(By.CSS_SELECTOR, "code, .api-key, [data-testid='api-key']")
|
|
if api_key_elem:
|
|
api_key = api_key_elem.text.strip()
|
|
if len(api_key) > 20:
|
|
print(f"✅ API Key found: {api_key[:10]}...")
|
|
return api_key
|
|
except:
|
|
continue
|
|
|
|
print("❌ Could not find API key")
|
|
return None
|
|
except Exception as e:
|
|
print(f"❌ Error getting API key: {e}")
|
|
return None
|
|
|
|
def get_account_id(driver):
|
|
try:
|
|
# The account ID is in the URL after login
|
|
url = driver.current_url
|
|
if "/accounts/" in url:
|
|
parts = url.split("/accounts/")
|
|
if len(parts) > 1:
|
|
return parts[1].split("/")[0]
|
|
|
|
# Or go to main dashboard
|
|
driver.get("https://dash.cloudflare.com")
|
|
time.sleep(2)
|
|
url = driver.current_url
|
|
if "/accounts/" in url:
|
|
parts = url.split("/accounts/")
|
|
if len(parts) > 1:
|
|
return parts[1].split("/")[0]
|
|
except:
|
|
pass
|
|
return None
|
|
|
|
def process_account(account_id, email, password):
|
|
driver = None
|
|
try:
|
|
driver = start_browser()
|
|
|
|
if login_cloudflare(driver, email, password):
|
|
cf_account_id = get_account_id(driver)
|
|
api_key = get_api_key(driver)
|
|
|
|
if api_key:
|
|
update_api_key(account_id, api_key, cf_account_id)
|
|
return True
|
|
else:
|
|
print(f"⚠️ Could not get API key for {email}")
|
|
|
|
return False
|
|
except Exception as e:
|
|
print(f"❌ Error: {e}")
|
|
return False
|
|
finally:
|
|
if driver:
|
|
driver.quit()
|
|
|
|
def main():
|
|
account_id = int(sys.argv[1]) if len(sys.argv) > 1 else None
|
|
accounts = get_accounts(account_id)
|
|
|
|
if not accounts:
|
|
print("No accounts to process")
|
|
return
|
|
|
|
print(f"Processing {len(accounts)} accounts...")
|
|
|
|
for acc_id, email, password in accounts:
|
|
print(f"\n{'='*50}")
|
|
print(f"Account {acc_id}: {email}")
|
|
process_account(acc_id, email, password)
|
|
time.sleep(2)
|
|
|
|
if __name__ == "__main__":
|
|
main()
|