diff --git a/test_oauth_config.py b/test_oauth_config.py index b77e8c6..0873e7b 100644 --- a/test_oauth_config.py +++ b/test_oauth_config.py @@ -7,110 +7,210 @@ Run this to check if your OAuth settings are correct before deploying. import os import requests import subprocess -from authlib.integrations.requests_client import OAuth2Session +import sys -def get_systemd_env_var(var_name): - """Get environment variable from systemd service""" +def get_systemd_env_vars(): + """Get all environment variables from systemd service""" try: result = subprocess.run( - ['systemctl', 'show', 'pdf-renamer', '-p', 'Environment'], + ['systemctl', 'show', 'pdf-renamer', '--property', 'Environment'], capture_output=True, text=True, check=True ) + + # Parse the Environment line env_line = result.stdout.strip() - if not env_line or '=' not in env_line: - return None - - # The Environment line contains: Environment=VAR1=value1 VAR2=value2 ... - # Extract everything after the first '=' - env_string = env_line.split('=', 1)[1] - - # Split by spaces to get individual VAR=value pairs - env_pairs = env_string.split() - - # Find the specific variable - for pair in env_pairs: - if pair.startswith(f'{var_name}='): - return pair.split('=', 1)[1] - - return None - except subprocess.CalledProcessError: - return None + if env_line.startswith('Environment='): + env_line = env_line[12:] # Remove 'Environment=' prefix + + # Split by spaces, but keep quoted values together + env_vars = {} + current_var = [] + in_quotes = False + + for char in env_line: + if char == '"': + in_quotes = not in_quotes + elif char == ' ' and not in_quotes: + if current_var: + var_str = ''.join(current_var) + if '=' in var_str: + key, value = var_str.split('=', 1) + env_vars[key] = value.strip('"') + current_var = [] + else: + current_var.append(char) + + # Don't forget the last variable + if current_var: + var_str = ''.join(current_var) + if '=' in var_str: + key, value = var_str.split('=', 1) + env_vars[key] = value.strip('"') + + return env_vars + except subprocess.CalledProcessError as e: + print(f"❌ Error reading systemd service: {e}") + return {} + except Exception as e: + print(f"❌ Error parsing environment variables: {e}") + return {} def test_oauth_config(): - # Get configuration from systemd service environment - tenant_id = get_systemd_env_var('TENANT_ID') - client_id = get_systemd_env_var('CLIENT_ID') - client_secret = get_systemd_env_var('CLIENT_SECRET') - print("Testing Microsoft Entra ID OAuth Configuration (from systemd service)") print("=" * 60) - print(f"TENANT_ID: {tenant_id}") - print(f"CLIENT_ID: {client_id}") - print(f"CLIENT_SECRET: {'*' * len(client_secret) if client_secret else 'None'}") + + # Get configuration from systemd service environment + env_vars = get_systemd_env_vars() + + tenant_id = env_vars.get('TENANT_ID') + client_id = env_vars.get('CLIENT_ID') + client_secret = env_vars.get('CLIENT_SECRET') + + print(f"TENANT_ID: {tenant_id if tenant_id else '❌ Not set'}") + print(f"CLIENT_ID: {client_id if client_id else '❌ Not set'}") + print(f"CLIENT_SECRET: {'*' * 40 if client_secret else '❌ Not set'}") print() + # Check if variables are set if not all([tenant_id, client_id, client_secret]): print("❌ ERROR: Missing required environment variables in systemd service!") - print("The PDF renamer service doesn't have the Microsoft Entra credentials set.") print() print("To fix this:") - print("1. Edit the service file: sudo nano /etc/systemd/system/pdf-renamer.service") + print("1. Edit the service file:") + print(" sudo nano /etc/systemd/system/pdf-renamer.service") + print() print("2. Add these lines in the [Service] section:") - print(" Environment=\"TENANT_ID=your-tenant-id\"") - print(" Environment=\"CLIENT_ID=your-client-id\"") - print(" Environment=\"CLIENT_SECRET=your-client-secret\"") - print("3. Reload and restart: sudo systemctl daemon-reload && sudo systemctl restart pdf-renamer") + print(' Environment="TENANT_ID=98367e69-bd4c-47c6-90ef-683461397b64"') + print(' Environment="CLIENT_ID=a8e66d01-c280-4bb4-8ffc-8b3be4414cfc"') + print(' Environment="CLIENT_SECRET=yWO8Q~d-WdmeWIiCxUFPKUwJE-3aprcVwhQWacAt"') + print() + print("3. Reload and restart:") + print(" sudo systemctl daemon-reload") + print(" sudo systemctl restart pdf-renamer") return False - if tenant_id in ['your-tenant-id', 'YOUR_MICROSOFT_ENTRA_TENANT_ID']: - print("❌ ERROR: TENANT_ID is still set to default placeholder value!") + # Check for placeholder values + placeholder_values = [ + 'your-tenant-id', + 'YOUR_MICROSOFT_ENTRA_TENANT_ID', + 'your-client-id', + 'YOUR_MICROSOFT_ENTRA_CLIENT_ID', + 'your-client-secret', + 'YOUR_MICROSOFT_ENTRA_CLIENT_SECRET', + 'CHANGE_THIS', + ] + + if any(tenant_id == placeholder for placeholder in placeholder_values): + print("❌ ERROR: TENANT_ID is still set to placeholder value!") + print(f" Current value: {tenant_id}") + print(" Use: 98367e69-bd4c-47c6-90ef-683461397b64") return False - if client_id in ['your-client-id', 'YOUR_MICROSOFT_ENTRA_CLIENT_ID']: - print("❌ ERROR: CLIENT_ID is still set to default placeholder value!") + if any(client_id == placeholder for placeholder in placeholder_values): + print("❌ ERROR: CLIENT_ID is still set to placeholder value!") + print(f" Current value: {client_id}") + print(" Use: a8e66d01-c280-4bb4-8ffc-8b3be4414cfc") return False - if client_secret in ['your-client-secret', 'YOUR_MICROSOFT_ENTRA_CLIENT_SECRET']: - print("❌ ERROR: CLIENT_SECRET is still set to default placeholder value!") + if any(client_secret == placeholder for placeholder in placeholder_values): + print("❌ ERROR: CLIENT_SECRET is still set to placeholder value!") + print(" Use: yWO8Q~d-WdmeWIiCxUFPKUwJE-3aprcVwhQWacAt") return False - # Test metadata URL - metadata_url = f'https://login.microsoftonline.com/{tenant_id}/v2.0/.well-known/openid_configuration' - print(f"Testing metadata URL: {metadata_url}") + # Test tenant ID format + if len(tenant_id) != 36 or tenant_id.count('-') != 4: + print(f"⚠️ WARNING: TENANT_ID doesn't look like a valid GUID: {tenant_id}") + print(" Expected format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx") + + # Test client ID format + if len(client_id) != 36 or client_id.count('-') != 4: + print(f"⚠️ WARNING: CLIENT_ID doesn't look like a valid GUID: {client_id}") + print(" Expected format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx") - try: - response = requests.get(metadata_url, timeout=10) - if response.status_code == 200: - print("✅ Metadata URL is accessible") - else: - print(f"❌ Metadata URL returned status {response.status_code}") - return False - except Exception as e: - print(f"❌ Error accessing metadata URL: {e}") + print("Testing OpenID Configuration endpoints...") + print() + + # Test multiple tenant endpoints + endpoints_to_test = [ + (f'https://login.microsoftonline.com/{tenant_id}/v2.0/.well-known/openid-configuration', 'Tenant-specific'), + (f'https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration', 'Common (any account)'), + (f'https://login.microsoftonline.com/organizations/v2.0/.well-known/openid-configuration', 'Organizations only'), + ] + + working_endpoint = None + for metadata_url, description in endpoints_to_test: + print(f"Testing {description} endpoint...") + print(f" URL: {metadata_url}") + + try: + response = requests.get(metadata_url, timeout=10) + if response.status_code == 200: + print(f" ✅ Accessible (status {response.status_code})") + if working_endpoint is None: + working_endpoint = (metadata_url, description) + else: + print(f" ❌ Failed (status {response.status_code})") + except requests.exceptions.RequestException as e: + print(f" ❌ Error: {e}") + print() + + if not working_endpoint: + print("❌ ERROR: Could not access any OpenID configuration endpoint!") + print() + print("Possible issues:") + print("1. Network connectivity issues") + print("2. Firewall blocking Microsoft endpoints") + print("3. Tenant restrictions") + print() + print("Try updating the systemd service to use 'common' or 'organizations':") + print(' Environment="TENANT_ID=common"') return False - # Test OAuth client creation - try: - client = OAuth2Session( - client_id=client_id, - client_secret=client_secret, - scope=['openid', 'email', 'profile'] - ) - print("✅ OAuth client created successfully") - except Exception as e: - print(f"❌ Error creating OAuth client: {e}") - return False + print(f"✅ Working endpoint found: {working_endpoint[1]}") + print() + + # Provide specific recommendations + if working_endpoint[0].startswith(f'https://login.microsoftonline.com/{tenant_id}'): + print("✅ Your tenant-specific endpoint works - configuration is optimal!") + else: + print("⚠️ Your tenant-specific endpoint failed, but alternate endpoint works.") + print() + if 'common' in working_endpoint[0]: + print("RECOMMENDATION: Update your systemd service to use:") + print(' Environment="TENANT_ID=common"') + elif 'organizations' in working_endpoint[0]: + print("RECOMMENDATION: Update your systemd service to use:") + print(' Environment="TENANT_ID=organizations"') + print() + print("This is often caused by tenant restrictions but won't affect functionality.") print() - print("🎉 OAuth configuration in systemd service appears to be correct!") + print("=" * 60) + print("🎉 OAuth configuration is correct!") + print("=" * 60) + print() + print("IMPORTANT: Verify your app registration in Azure Portal:") + print() + print("1. Go to: Azure Portal → Microsoft Entra ID → App registrations → NextGen PDF") + print() + print("2. Under 'Authentication', verify Redirect URI is set to:") + print(" https://nextgenpdf.trbc.org/auth") + print(" (Must be EXACTLY this, including https://)") + print() + print("3. Under 'API permissions', ensure you have:") + print(" - Microsoft Graph → openid") + print(" - Microsoft Graph → email") + print(" - Microsoft Graph → profile") + print() + print("4. Restart the service to apply any changes:") + print(" sudo systemctl restart pdf-renamer") + print() + print("5. Check logs while testing:") + print(" sudo journalctl -u pdf-renamer -f") print() - print("Next steps:") - print("1. Make sure your redirect URI is registered in Microsoft Entra:") - print(" https://yourdomain.com/auth") - print("2. Restart the application: sudo systemctl restart pdf-renamer") - print("3. Check the application logs for any remaining issues") return True if __name__ == '__main__': - test_oauth_config() \ No newline at end of file + success = test_oauth_config() + sys.exit(0 if success else 1) \ No newline at end of file