annator-command-center / scripts /legacy /complete_oauth_server_with_azure.py
techprotrade's picture
Deploy ATOM FastAPI command center runtime (part 6)
383cb38 verified
Raw
History Blame Contribute Delete
12.7 kB
#!/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'
}
}
@app.route("/")
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')
}
})
@app.route("/healthz")
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"
})
@app.route("/api/auth/<service>/status", methods=['GET'])
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('_', ' ')}"
})
@app.route("/api/auth/<service>/authorize", methods=['GET'])
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"
})
@app.route("/api/auth/<service>/callback", methods=['GET', 'POST'])
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"
})
@app.route("/api/auth/oauth-status", methods=['GET'])
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"
})
@app.route("/api/auth/services", methods=['GET'])
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)