Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| """ | |
| Complete OAuth System Test with Azure Credentials | |
| """ | |
| import os | |
| import secrets | |
| import urllib.parse | |
| from flask import Flask, jsonify, request | |
| # Load all credentials from .env | |
| GITHUB_CLIENT_ID = os.getenv('GITHUB_CLIENT_ID') | |
| GOOGLE_CLIENT_ID = os.getenv('GOOGLE_CLIENT_ID') | |
| SLACK_CLIENT_ID = os.getenv('SLACK_CLIENT_ID') | |
| TRELLO_API_KEY = os.getenv('TRELLO_API_KEY') | |
| ASANA_CLIENT_ID = os.getenv('ASANA_CLIENT_ID') | |
| NOTION_CLIENT_ID = os.getenv('NOTION_CLIENT_ID') | |
| DROPBOX_APP_KEY = os.getenv('DROPBOX_APP_KEY') | |
| LINEAR_CLIENT_ID = os.getenv('LINEAR_CLIENT_ID') | |
| OUTLOOK_CLIENT_ID = os.getenv('OUTLOOK_CLIENT_ID') | |
| OUTLOOK_CLIENT_SECRET = os.getenv('OUTLOOK_CLIENT_SECRET') | |
| OUTLOOK_TENANT_ID = os.getenv('OUTLOOK_TENANT_ID') | |
| TEAMS_CLIENT_ID = os.getenv('TEAMS_CLIENT_ID') | |
| TEAMS_CLIENT_SECRET = os.getenv('TEAMS_CLIENT_SECRET') | |
| TEAMS_TENANT_ID = os.getenv('TEAMS_TENANT_ID') | |
| print("🔧 LOADING COMPLETE CREDENTIALS FROM .ENV") | |
| print(f" GITHUB_CLIENT_ID: {GITHUB_CLIENT_ID[:10] if GITHUB_CLIENT_ID else 'MISSING'}...") | |
| print(f" GOOGLE_CLIENT_ID: {GOOGLE_CLIENT_ID[:10] if GOOGLE_CLIENT_ID else 'MISSING'}...") | |
| print(f" SLACK_CLIENT_ID: {SLACK_CLIENT_ID[:10] if SLACK_CLIENT_ID else 'MISSING'}...") | |
| print(f" ASANA_CLIENT_ID: {ASANA_CLIENT_ID[:10] if ASANA_CLIENT_ID else 'MISSING'}...") | |
| print(f" NOTION_CLIENT_ID: {NOTION_CLIENT_ID[:10] if NOTION_CLIENT_ID else 'MISSING'}...") | |
| print(f" LINEAR_CLIENT_ID: {LINEAR_CLIENT_ID[:10] if LINEAR_CLIENT_ID else 'MISSING'}...") | |
| print(f" OUTLOOK_CLIENT_ID: {OUTLOOK_CLIENT_ID[:10] if OUTLOOK_CLIENT_ID else 'MISSING'}...") | |
| print(f" TEAMS_CLIENT_ID: {TEAMS_CLIENT_ID[:10] if TEAMS_CLIENT_ID else 'MISSING'}...") | |
| app = Flask(__name__) | |
| app.secret_key = os.getenv("FLASK_SECRET_KEY", "atom-oauth-complete-secret-2025") | |
| # Service configurations | |
| services_config = { | |
| 'gmail': { | |
| 'status': 'connected' if GOOGLE_CLIENT_ID else 'needs_credentials', | |
| 'credentials': 'real' if GOOGLE_CLIENT_ID else 'placeholder', | |
| 'client_id': GOOGLE_CLIENT_ID or 'placeholder_google_client_id', | |
| 'auth_url': 'https://accounts.google.com/o/oauth2/v2/auth' | |
| }, | |
| 'outlook': { | |
| 'status': 'connected' if OUTLOOK_CLIENT_ID else 'needs_credentials', | |
| 'credentials': 'real' if OUTLOOK_CLIENT_ID else 'placeholder', | |
| 'client_id': OUTLOOK_CLIENT_ID or 'placeholder_outlook_client_id', | |
| 'auth_url': 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize' | |
| }, | |
| 'slack': { | |
| 'status': 'connected' if SLACK_CLIENT_ID else 'needs_credentials', | |
| 'credentials': 'real' if SLACK_CLIENT_ID else 'placeholder', | |
| 'client_id': SLACK_CLIENT_ID or 'placeholder_slack_client_id', | |
| 'auth_url': 'https://slack.com/oauth/v2/authorize' | |
| }, | |
| 'teams': { | |
| 'status': 'connected' if TEAMS_CLIENT_ID else 'needs_credentials', | |
| 'credentials': 'real' if TEAMS_CLIENT_ID else 'placeholder', | |
| 'client_id': TEAMS_CLIENT_ID or 'placeholder_teams_client_id', | |
| 'auth_url': 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize' | |
| }, | |
| 'trello': { | |
| 'status': 'connected' if TRELLO_API_KEY else 'needs_credentials', | |
| 'credentials': 'real' if TRELLO_API_KEY else 'placeholder', | |
| 'client_id': TRELLO_API_KEY or 'placeholder_trello_key', | |
| 'auth_url': 'https://trello.com/1/authorize' | |
| }, | |
| 'asana': { | |
| 'status': 'connected' if ASANA_CLIENT_ID else 'needs_credentials', | |
| 'credentials': 'real' if ASANA_CLIENT_ID else 'placeholder', | |
| 'client_id': ASANA_CLIENT_ID or 'placeholder_asana_client_id', | |
| 'auth_url': 'https://app.asana.com/-/oauth_authorize' | |
| }, | |
| 'notion': { | |
| 'status': 'connected' if NOTION_CLIENT_ID else 'needs_credentials', | |
| 'credentials': 'real' if NOTION_CLIENT_ID else 'placeholder', | |
| 'client_id': NOTION_CLIENT_ID or 'placeholder_notion_client_id', | |
| 'auth_url': 'https://api.notion.com/v1/oauth/authorize' | |
| }, | |
| 'github': { | |
| 'status': 'connected' if GITHUB_CLIENT_ID else 'needs_credentials', | |
| 'credentials': 'real' if GITHUB_CLIENT_ID else 'placeholder', | |
| 'client_id': GITHUB_CLIENT_ID or 'placeholder_github_client_id', | |
| 'auth_url': 'https://github.com/login/oauth/authorize' | |
| }, | |
| 'dropbox': { | |
| 'status': 'connected' if DROPBOX_APP_KEY else 'needs_credentials', | |
| 'credentials': 'real' if DROPBOX_APP_KEY else 'placeholder', | |
| 'client_id': DROPBOX_APP_KEY or 'placeholder_dropbox_key', | |
| 'auth_url': 'https://www.dropbox.com/oauth2/authorize' | |
| }, | |
| 'gdrive': { | |
| 'status': 'connected' if GOOGLE_CLIENT_ID else 'needs_credentials', | |
| 'credentials': 'real' if GOOGLE_CLIENT_ID else 'placeholder', | |
| 'client_id': GOOGLE_CLIENT_ID or 'placeholder_google_client_id', | |
| 'auth_url': 'https://accounts.google.com/o/oauth2/v2/auth' | |
| }, | |
| 'linear': { | |
| 'status': 'connected' if LINEAR_CLIENT_ID else 'needs_credentials', | |
| 'credentials': 'real' if LINEAR_CLIENT_ID else 'placeholder', | |
| 'client_id': LINEAR_CLIENT_ID or 'placeholder_linear_client_id', | |
| 'auth_url': 'https://linear.app/oauth/authorize' | |
| }, | |
| 'github': { | |
| 'status': 'connected' if GITHUB_CLIENT_ID else 'needs_credentials', | |
| 'credentials': 'real' if GITHUB_CLIENT_ID else 'placeholder', | |
| 'client_id': GITHUB_CLIENT_ID or 'placeholder_github_client_id', | |
| 'auth_url': 'https://github.com/login/oauth/authorize' | |
| } | |
| } | |
| def index(): | |
| return jsonify({ | |
| "message": "ATOM Complete OAuth Server Running", | |
| "services": len(services_config), | |
| "credentials_loaded": { | |
| "github": bool(GITHUB_CLIENT_ID), | |
| "outlook": bool(OUTLOOK_CLIENT_ID), | |
| "teams": bool(TEAMS_CLIENT_ID), | |
| "total_real": sum(1 for s, c in services_config.items() if c.get('credentials') == 'real') | |
| } | |
| }) | |
| def health(): | |
| return jsonify({ | |
| "status": "ok", | |
| "service": "atom-python-api-oauth-complete-with-azure", | |
| "version": "1.0.0-complete-azure-oauth", | |
| "message": "API server is running with complete OAuth endpoints including Azure", | |
| "timestamp": "2025-11-01T12:30:00Z" | |
| }) | |
| def oauth_status(service): | |
| if service not in services_config: | |
| return jsonify({"error": f"Service {service} not supported"}), 404 | |
| config = services_config[service] | |
| return jsonify({ | |
| "ok": True, | |
| "service": service, | |
| "user_id": request.args.get("user_id", "test_user"), | |
| "status": config['status'], | |
| "credentials": config['credentials'], | |
| "client_id": config['client_id'], | |
| "last_check": "2025-11-01T12:30:00Z", | |
| "message": f"{service.title()} OAuth is {config['status'].replace('_', ' ')}" | |
| }) | |
| def oauth_authorize(service): | |
| user_id = request.args.get("user_id") | |
| if not user_id: | |
| return jsonify({"error": "user_id parameter is required"}), 400 | |
| if service not in services_config: | |
| return jsonify({"error": f"Service {service} not supported"}), 404 | |
| config = services_config[service] | |
| if config['credentials'] == 'placeholder': | |
| return jsonify({ | |
| "ok": True, | |
| "service": service, | |
| "user_id": user_id, | |
| "status": "needs_credentials", | |
| "message": f"{service.title()} OAuth needs real credentials configuration", | |
| "credentials": "placeholder" | |
| }), 200 | |
| # Generate authorization URL for real credentials | |
| csrf_token = secrets.token_urlsafe(32) | |
| auth_params = { | |
| "client_id": config['client_id'], | |
| "redirect_uri": f"http://localhost:5058/api/auth/{service}/callback", | |
| "response_type": "code", | |
| "state": csrf_token, | |
| } | |
| # Add service-specific parameters | |
| if service in ['gmail', 'gdrive']: | |
| auth_params.update({ | |
| "scope": "email profile", | |
| "access_type": "offline", | |
| "prompt": "consent" | |
| }) | |
| elif service == 'slack': | |
| auth_params.update({"scope": "chat:read chat:write"}) | |
| elif service == 'trello': | |
| auth_params.update({ | |
| "scope": "read,write", | |
| "expiration": "never", | |
| "name": "ATOM Integration" | |
| }) | |
| elif service == 'github': | |
| auth_params.update({"scope": "repo user"}) | |
| elif service == 'notion': | |
| auth_params.update({"owner": "user"}) | |
| elif service in ['outlook', 'teams']: | |
| auth_params.update({ | |
| "scope": "openid profile offline_access Mail.Read Mail.Send", | |
| "response_mode": "query" | |
| }) | |
| auth_url = f"{config['auth_url']}?{urllib.parse.urlencode(auth_params)}" | |
| return jsonify({ | |
| "ok": True, | |
| "service": service, | |
| "user_id": user_id, | |
| "auth_url": auth_url, | |
| "csrf_token": csrf_token, | |
| "client_id": config['client_id'], | |
| "credentials": config['credentials'], | |
| "message": f"{service.title()} OAuth authorization URL generated successfully" | |
| }) | |
| def oauth_callback(service): | |
| if service not in services_config: | |
| return jsonify({"error": f"Service {service} not supported"}), 404 | |
| return jsonify({ | |
| "ok": True, | |
| "service": service, | |
| "message": f"{service.title()} OAuth callback received", | |
| "code": request.args.get("code"), | |
| "state": request.args.get("state"), | |
| "redirect": f"/settings?service={service}&status=connected" | |
| }) | |
| def comprehensive_oauth_status(): | |
| user_id = request.args.get("user_id", "test_user") | |
| results = {} | |
| connected_count = 0 | |
| needs_credentials_count = 0 | |
| for service, config in services_config.items(): | |
| status_info = { | |
| "ok": True, | |
| "service": service, | |
| "user_id": user_id, | |
| "status": config['status'], | |
| "credentials": config['credentials'], | |
| "client_id": config['client_id'], | |
| "message": f"{service.title()} OAuth is {config['status'].replace('_', ' ')}" | |
| } | |
| results[service] = status_info | |
| if config['status'] == 'connected': | |
| connected_count += 1 | |
| elif config['credentials'] == 'placeholder': | |
| needs_credentials_count += 1 | |
| return jsonify({ | |
| "ok": True, | |
| "user_id": user_id, | |
| "total_services": len(services_config), | |
| "connected_services": connected_count, | |
| "services_needing_credentials": needs_credentials_count, | |
| "success_rate": f"{connected_count/len(services_config)*100:.1f}%", | |
| "results": results, | |
| "timestamp": "2025-11-01T12:30:00Z" | |
| }) | |
| def oauth_services_list(): | |
| return jsonify({ | |
| "ok": True, | |
| "services": list(services_config.keys()), | |
| "total_services": len(services_config), | |
| "services_with_real_credentials": len([ | |
| s for s, c in services_config.items() | |
| if c.get('credentials') == 'real' | |
| ]), | |
| "services_needing_credentials": len([ | |
| s for s, c in services_config.items() | |
| if c.get('credentials') == 'placeholder' | |
| ]), | |
| "timestamp": "2025-11-01T12:30:00Z" | |
| }) | |
| if __name__ == "__main__": | |
| print("🚀 ATOM COMPLETE OAUTH SERVER WITH AZURE") | |
| print("=" * 70) | |
| # Count real credentials | |
| real_count = sum(1 for s, c in services_config.items() if c.get('credentials') == 'real') | |
| placeholder_count = sum(1 for s, c in services_config.items() if c.get('credentials') == 'placeholder') | |
| print(f"🔧 COMPLETE CREDENTIALS STATUS: {real_count} real, {placeholder_count} placeholder") | |
| print(f"🌐 Server starting on http://localhost:5058") | |
| print(f"📋 Available OAuth Endpoints: {len(services_config) * 3} total") | |
| # Show key services status | |
| key_services = ['github', 'outlook', 'teams'] | |
| for service in key_services: | |
| config = services_config[service] | |
| status = "✅ REAL CREDENTIALS" if config['credentials'] == 'real' else "❌ PLACEHOLDER" | |
| print(f" {service.upper()}: {status}") | |
| print("=" * 70) | |
| try: | |
| app.run(host='127.0.0.1', port=5058, debug=False, use_reloader=False) | |
| except Exception as e: | |
| print(f"❌ Failed to start server: {e}") | |
| exit(1) |