annator-command-center / scripts /legacy /improved_oauth_server.py
techprotrade's picture
Deploy ATOM FastAPI command center runtime (part 6)
383cb38 verified
Raw
History Blame Contribute Delete
11.5 kB
#!/usr/bin/env python3
"""
IMPROVED OAUTH SERVER - Emergency Fix
Complete OAuth server with all required endpoints
"""
from datetime import datetime
import json
import os
import secrets
import urllib.parse
from flask import Flask, jsonify, request
def create_improved_oauth_server():
"""Create improved OAuth server with all endpoints"""
app = Flask(__name__)
app.secret_key = os.getenv("FLASK_SECRET_KEY", "emergency-oauth-secret")
# Enhanced services configuration
services_config = {
"github": {
"status": "configured"
if os.getenv("GITHUB_CLIENT_ID")
else "needs_credentials",
"client_id": os.getenv("GITHUB_CLIENT_ID", "github_placeholder_client_id"),
"auth_url": "https://github.com/login/oauth/authorize",
"scopes": ["repo", "user:email"],
},
"google": {
"status": "configured"
if os.getenv("GOOGLE_CLIENT_ID")
else "needs_credentials",
"client_id": os.getenv("GOOGLE_CLIENT_ID", "google_placeholder_client_id"),
"auth_url": "https://accounts.google.com/o/oauth2/v2/auth",
"scopes": ["email", "profile", "https://www.googleapis.com/auth/calendar"],
},
"slack": {
"status": "configured"
if os.getenv("SLACK_CLIENT_ID")
else "needs_credentials",
"client_id": os.getenv("SLACK_CLIENT_ID", "slack_placeholder_client_id"),
"auth_url": "https://slack.com/oauth/v2/authorize",
"scopes": ["chat:read", "chat:write", "channels:read"],
},
"dropbox": {
"status": "configured"
if os.getenv("DROPBOX_CLIENT_ID")
else "needs_credentials",
"client_id": os.getenv("DROPBOX_APP_KEY", "dropbox_placeholder_client_id"),
"auth_url": "https://www.dropbox.com/oauth2/authorize",
"scopes": [
"files.metadata.read",
"files.content.read",
"files.content.write",
],
},
"trello": {
"status": "configured"
if os.getenv("TRELLO_CLIENT_ID")
else "needs_credentials",
"client_id": os.getenv("TRELLO_API_KEY", "trello_placeholder_client_id"),
"auth_url": "https://trello.com/1/authorize",
"scopes": ["read", "write"],
},
}
# Health endpoint
@app.route("/healthz")
def health():
return jsonify(
{
"status": "ok",
"service": "atom-oauth-emergency-fix",
"version": "2.0.0-emergency",
"timestamp": datetime.now().isoformat(),
}
)
# Root endpoint
@app.route("/")
def root():
return jsonify(
{
"service": "ATOM OAuth Server (Emergency Fix)",
"status": "running",
"endpoints": [
"/healthz",
"/api/auth/oauth-status",
"/api/auth/services",
"/api/auth/{service}/authorize",
"/api/auth/{service}/status",
"/api/auth/{service}/callback",
],
}
)
# OAuth status endpoint
@app.route("/api/auth/oauth-status", methods=["GET"])
def oauth_status():
user_id = request.args.get("user_id", "emergency_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"],
"client_id": config["client_id"],
"message": f"{service.title()} OAuth is {config['status'].replace('_', ' ')}",
}
results[service] = status_info
if config["status"] == "configured":
connected_count += 1
elif "placeholder" in config["client_id"]:
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": datetime.now().isoformat(),
}
)
# Services list endpoint
@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("client_id")
and "placeholder" not in c.get("client_id", "")
]
),
"services_needing_credentials": len(
[
s
for s, c in services_config.items()
if "placeholder" in c.get("client_id", "")
]
),
"timestamp": datetime.now().isoformat(),
}
)
# OAuth authorize endpoint (works for all services)
@app.route("/api/auth/<service>/authorize", methods=["GET"])
def oauth_authorize(service):
user_id = request.args.get("user_id")
redirect_uri = request.args.get(
"redirect_uri", "http://localhost:3000/api/auth/callback"
)
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 "placeholder" in config["client_id"]:
return jsonify(
{
"ok": True,
"service": service,
"user_id": user_id,
"status": "needs_credentials",
"message": f"{service.title()} OAuth needs real credentials",
"setup_guide": f"Set {service.upper()}_CLIENT_ID and {service.upper()}_CLIENT_SECRET in .env",
"credentials": "placeholder",
"available_services": list(services_config.keys()),
"auth_url": config["auth_url"],
"timestamp": datetime.now().isoformat(),
}
), 200
# Generate authorization URL for real credentials
csrf_token = secrets.token_urlsafe(32)
state = f"csrf_token={csrf_token}&service={service}&user_id={user_id}"
auth_params = {
"client_id": config["client_id"],
"redirect_uri": redirect_uri,
"response_type": "code",
"state": state,
"scope": " ".join(config.get("scopes", [])),
}
if service in ["github"]:
auth_params["scope"] = " ".join(config["scopes"])
elif service in ["google", "gmail"]:
auth_params.update({"access_type": "offline", "prompt": "consent"})
elif service == "slack":
auth_params["scope"] = " ".join(config["scopes"])
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": "real",
"scopes": config.get("scopes", []),
"redirect_uri": redirect_uri,
"message": f"{service.title()} OAuth authorization URL generated successfully",
"timestamp": datetime.now().isoformat(),
}
)
# OAuth status endpoint (specific service)
@app.route("/api/auth/<service>/status", methods=["GET"])
def oauth_status_service(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", "emergency_test_user"),
"status": config["status"],
"client_id": config["client_id"],
"scopes": config.get("scopes", []),
"auth_url": config["auth_url"],
"last_check": datetime.now().isoformat(),
"message": f"{service.title()} OAuth is {config['status'].replace('_', ' ')}",
"timestamp": datetime.now().isoformat(),
}
)
# OAuth callback endpoint
@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
code = request.args.get("code")
state = request.args.get("state")
error = request.args.get("error")
if error:
return jsonify(
{
"ok": True,
"service": service,
"error": error,
"message": f"{service.title()} OAuth failed with error: {error}",
"redirect": f"/settings?service={service}&status=error&error={error}",
"timestamp": datetime.now().isoformat(),
}
)
return jsonify(
{
"ok": True,
"service": service,
"code": code,
"state": state,
"message": f"{service.title()} OAuth callback received successfully",
"redirect": f"/settings?service={service}&status=connected",
"token_exchange": "Use this code to exchange for access tokens",
"timestamp": datetime.now().isoformat(),
}
)
return app
if __name__ == "__main__":
app = create_improved_oauth_server()
print("🚨 ATOM EMERGENCY OAUTH SERVER")
print("=" * 45)
print("🌐 Server starting on http://localhost:5058")
print("📋 Available OAuth Services:")
print(" - github")
print(" - google")
print(" - slack")
print("📋 Available Endpoints:")
print(" - GET /healthz")
print(" - GET /api/auth/oauth-status")
print(" - GET /api/auth/services")
print(" - GET /api/auth/{service}/authorize")
print(" - GET /api/auth/{service}/status")
print(" - GET/POST /api/auth/{service}/callback")
print("=" * 45)
try:
app.run(host="0.0.0.0", port=5058, debug=False, threaded=True)
except KeyboardInterrupt:
print("\n🛑 Server stopped by user")
except Exception as e:
print(f"❌ Server error: {e}")