#!/usr/bin/env python3 """ Auth0 CLI Authentication Module Handles authentication state and login flow for Auth0 CLI. """ import json import logging import subprocess from datetime import datetime from pathlib import Path logger = logging.getLogger(__name__) def auth0_login() -> None: """Authenticate with Auth0 CLI via browser-based authentication.""" logger.info('Initiating browser-based authentication...') cmd = ['auth0', 'login'] logger.info(f'Running: {" ".join(cmd)}') subprocess.run(cmd, check=True) logger.info('✓ Authentication complete') def check_auth0_login() -> None: """Verify Auth0 CLI is logged in and token is valid. Login if needed.""" config_path = Path.home() / '.config' / 'auth0' / 'config.json' if not config_path.exists(): logger.info('Not logged in to Auth0 CLI. Logging in...') auth0_login() return with open(config_path) as f: config = json.load(f) default_tenant = config.get('default_tenant') if not default_tenant: logger.info('No default tenant configured. Logging in...') auth0_login() return tenant_config = config['tenants'].get(default_tenant) if not tenant_config: logger.info(f'Tenant {default_tenant} not found in config. Logging in...') auth0_login() return # Check if token is expired expires_at = tenant_config.get('expires_at') if expires_at: # Parse the timestamp (Auth0 CLI uses this format) expires_dt = datetime.fromisoformat(expires_at.replace('Z', '+00:00')) now = datetime.now(expires_dt.tzinfo) if now >= expires_dt: logger.info(f'Auth0 token expired at {expires_at}. Re-authenticating...') auth0_login() return logger.info(f'✓ Logged in to: {default_tenant}') logger.info(f'✓ Token valid until: {expires_at}') # Verify we have necessary scopes scopes = tenant_config.get('scopes', []) required_scopes = ['read:users'] missing_scopes = [s for s in required_scopes if s not in scopes] if missing_scopes: logger.info(f'Missing required scopes: {missing_scopes}. Re-authenticating...') auth0_login() return logger.info('✓ Required scopes present')