1. Analyse der Änderungen:
* superoffice_client.py: Implementierung der Methoden create_contact (Standardfelder) und create_person (inkl. Firmenverknüpfung).
* auth_handler.py: Härtung der Authentifizierung durch Priorisierung von SO_CLIENT_ID und Unterstützung für load_dotenv(override=True).
* main.py: Erweiterung des Test-Workflows für den vollständigen Lese- und Schreib-Durchstich (Erstellung von Demo-Firmen und Personen).
* README.md: Aktualisierung des Status Quo und der verfügbaren Client-Methoden.
67 lines
2.4 KiB
Python
67 lines
2.4 KiB
Python
import os
|
|
import logging
|
|
import time
|
|
import requests
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
class AuthHandler:
|
|
def __init__(self):
|
|
# Load configuration from environment
|
|
self.client_id = os.getenv("SO_CLIENT_ID")
|
|
if not self.client_id:
|
|
self.client_id = os.getenv("SO_SOD")
|
|
if self.client_id:
|
|
logger.info("Using SO_SOD as Client ID")
|
|
else:
|
|
logger.info("Using SO_CLIENT_ID as Client ID")
|
|
|
|
self.client_secret = os.getenv("SO_CLIENT_SECRET")
|
|
self.refresh_token = os.getenv("SO_REFRESH_TOKEN")
|
|
self.tenant_id = os.getenv("SO_CONTEXT_IDENTIFIER") # e.g., Cust55774
|
|
|
|
# OAuth Token Endpoint for SOD
|
|
self.token_url = "https://sod.superoffice.com/login/common/oauth/tokens"
|
|
|
|
self._access_token = None
|
|
self._webapi_url = None
|
|
self._expiry = 0
|
|
|
|
def get_ticket(self):
|
|
if self._access_token and time.time() < self._expiry:
|
|
return self._access_token, self._webapi_url
|
|
return self.refresh_access_token()
|
|
|
|
def refresh_access_token(self):
|
|
logger.info(f"Refreshing Access Token for Client ID: {self.client_id[:5]}...")
|
|
|
|
payload = {
|
|
"grant_type": "refresh_token",
|
|
"client_id": self.client_id,
|
|
"client_secret": self.client_secret,
|
|
"refresh_token": self.refresh_token
|
|
}
|
|
|
|
headers = {
|
|
"Content-Type": "application/x-www-form-urlencoded",
|
|
"Accept": "application/json"
|
|
}
|
|
|
|
try:
|
|
resp = requests.post(self.token_url, data=payload, headers=headers, timeout=30)
|
|
resp.raise_for_status()
|
|
data = resp.json()
|
|
|
|
self._access_token = data.get("access_token")
|
|
# Based on user's browser URL
|
|
self._webapi_url = f"https://app-sod.superoffice.com/{self.tenant_id}"
|
|
|
|
self._expiry = time.time() + int(data.get("expires_in", 3600)) - 60
|
|
logger.info("Successfully refreshed Access Token.")
|
|
return self._access_token, self._webapi_url
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error refreshing access token: {e}")
|
|
if hasattr(e, 'response') and e.response is not None:
|
|
logger.error(f"Response: {e.response.text}")
|
|
raise |