#!/usr/bin/env python3 # -*- coding: utf-8 -*- import requests import json import getpass # Needed for secure user input # from onetimepass import get_totp # Kann für automatisches TOTP verwendet werden # --- Global Configuration --- API_ENDPOINT = "https://api.domrobot.com/jsonrpc/" GLOBAL_SESSION = None # Stores the requests.Session object for all API calls def api_call(method, params={}): """ Executes an API call using the global requests.Session object. Cookies and session state are managed automatically. """ global GLOBAL_SESSION if GLOBAL_SESSION is None: print("[FATAL] Session not initialized. Please log in first.") return None headers = {"Content-Type": "application/json"} payload = { "jsonrpc": "2.0", "method": method, "params": params, "id": 1 } try: # Use the GLOBAL_SESSION object for the request response = GLOBAL_SESSION.post(API_ENDPOINT, headers=headers, data=json.dumps(payload), timeout=10) response.raise_for_status() return response.json() except requests.exceptions.RequestException as e: print(f"\n[ERROR] API call failed for {method}: {e}") return None def login_2fa_unlock(): """Performs the 2FA unlock step using the account.unlock API method.""" # Prompt user securely for the TOTP code topt_code = input("Enter your TOTP/2FA code: ").strip() # Use account.unlock with the token (tan) to complete the login unlock_result = api_call("account.unlock", {'tan': topt_code}) if unlock_result and unlock_result.get('code') == 1000: print("[SUCCESS] 2FA Unlock successful.") return True else: print(f"[ERROR] 2FA Unlock failed: {unlock_result.get('msg', 'Incorrect code or unknown error.')}") return False def login(user, password): """ Logs into the INWX API, initializes the global session, and handles 2FA challenges. """ global GLOBAL_SESSION print("--- Attempting standard login...") # Initialize the global session object GLOBAL_SESSION = requests.Session() headers = {"Content-Type": "application/json"} payload = { "jsonrpc": "2.0", "method": "account.login", "params": {"user": user, "pass": password}, "id": 1 } try: # Send Request using the newly initialized session response = GLOBAL_SESSION.post(API_ENDPOINT, headers=headers, data=json.dumps(payload), timeout=10) response.raise_for_status() result_json = response.json() # 1. Standard Login Successful if result_json.get('code') == 1000: # Check for immediate 2FA requirement (if 'tfa' is not '0') if result_json.get('resData', {}).get('tfa') not in [None, '0']: print("[NOTICE] Two-Factor Authentication (2FA) required.") return login_2fa_unlock() # Proceed to 2FA unlock flow # Regular login successful (or 2FA successful via unlock) print("[SUCCESS] Login successful! Session stored.") return True # 2. Other Login Error else: print(f"[ERROR] Login failed: {result_json.get('msg', 'Unknown error.')}") except requests.exceptions.RequestException as e: print(f"\n[ERROR] API request failed during standard login: {e}") return False def logout(): """Logs out of the INWX API and clears the global session object.""" global GLOBAL_SESSION if GLOBAL_SESSION is None: return print("\n--- Logging out...") # Use api_call, which uses GLOBAL_SESSION, to send the logout request api_call("account.logout", {}) GLOBAL_SESSION = None print("[SUCCESS] Logout successful.")