|
@@ -0,0 +1,87 @@
|
|
|
+import base64
|
|
|
+import os
|
|
|
+
|
|
|
+import requests
|
|
|
+from flask import Flask, redirect, request, session
|
|
|
+
|
|
|
+app = Flask(__name__)
|
|
|
+app.secret_key = os.urandom(24)
|
|
|
+
|
|
|
+# Mazda OAuth2 configuration
|
|
|
+CLIENT_ID = "YOUR_CLIENT_ID"
|
|
|
+CLIENT_SECRET = "YOUR_CLIENT_SECRET"
|
|
|
+AUTHORIZATION_BASE_URL = "https://mappsacc.mazdaeur.com/oauth/authorize"
|
|
|
+TOKEN_URL = "https://mappsacc.mazdaeur.com/oauth/token"
|
|
|
+REDIRECT_URI = "http://localhost:5000/callback"
|
|
|
+
|
|
|
+
|
|
|
+@app.route("/")
|
|
|
+def home():
|
|
|
+ return '<a href="/login">Login with Mazda</a>'
|
|
|
+
|
|
|
+
|
|
|
+@app.route("/login")
|
|
|
+def login():
|
|
|
+ state = os.urandom(8).hex()
|
|
|
+ session["oauth_state"] = state
|
|
|
+ auth_url = (
|
|
|
+ f"{AUTHORIZATION_BASE_URL}?response_type=code"
|
|
|
+ f"&client_id={CLIENT_ID}"
|
|
|
+ f"&redirect_uri={REDIRECT_URI}"
|
|
|
+ f"&state={state}"
|
|
|
+ )
|
|
|
+ return redirect(auth_url)
|
|
|
+
|
|
|
+
|
|
|
+@app.route("/callback")
|
|
|
+def callback():
|
|
|
+ code = request.args.get("code")
|
|
|
+ state = request.args.get("state")
|
|
|
+
|
|
|
+ if state != session.get("oauth_state"):
|
|
|
+ return "State mismatch. Possible CSRF attack.", 400
|
|
|
+
|
|
|
+ # Exchange code for token
|
|
|
+ auth = base64.b64encode(f"{CLIENT_ID}:{CLIENT_SECRET}".encode()).decode()
|
|
|
+ headers = {"Authorization": f"Basic {auth}", "Content-Type": "application/x-www-form-urlencoded"}
|
|
|
+ data = {"grant_type": "authorization_code", "code": code, "redirect_uri": REDIRECT_URI}
|
|
|
+
|
|
|
+ response = requests.post(TOKEN_URL, headers=headers, data=data)
|
|
|
+ token_data = response.json()
|
|
|
+
|
|
|
+ session["access_token"] = token_data.get("access_token")
|
|
|
+ session["refresh_token"] = token_data.get("refresh_token")
|
|
|
+
|
|
|
+ return f"Access Token: {session['access_token']}<br>Refresh Token: {session['refresh_token']}"
|
|
|
+
|
|
|
+
|
|
|
+@app.route("/refresh")
|
|
|
+def refresh_token():
|
|
|
+ refresh_token = session.get("refresh_token")
|
|
|
+ if not refresh_token:
|
|
|
+ return "No refresh token available.", 400
|
|
|
+
|
|
|
+ auth = base64.b64encode(f"{CLIENT_ID}:{CLIENT_SECRET}".encode()).decode()
|
|
|
+ headers = {"Authorization": f"Basic {auth}", "Content-Type": "application/x-www-form-urlencoded"}
|
|
|
+ data = {"grant_type": "refresh_token", "refresh_token": refresh_token}
|
|
|
+
|
|
|
+ response = requests.post(TOKEN_URL, headers=headers, data=data)
|
|
|
+ token_data = response.json()
|
|
|
+
|
|
|
+ session["access_token"] = token_data.get("access_token")
|
|
|
+ session["refresh_token"] = token_data.get("refresh_token")
|
|
|
+
|
|
|
+ return f"New Access Token: {session['access_token']}"
|
|
|
+
|
|
|
+
|
|
|
+if __name__ == "__main__":
|
|
|
+ app.run(
|
|
|
+ host="0.0.0.0",
|
|
|
+ port="5000",
|
|
|
+ ssl_context=(
|
|
|
+ "config/cert/global-cube.com.crt",
|
|
|
+ "config/cert/global-cube.com.key",
|
|
|
+ # "config/cert/intermediate.crt",
|
|
|
+ ),
|
|
|
+ debug=True,
|
|
|
+ )
|