Spaces:
Runtime error
Runtime error
Commit ·
02426f0
1
Parent(s): 1476658
Handle OAuth invalid_grant gracefully behind proxy
Browse files- app/__init__.py +18 -2
- app/templates/base.html +11 -0
app/__init__.py
CHANGED
|
@@ -2,6 +2,8 @@ import os
|
|
| 2 |
from typing import Optional
|
| 3 |
|
| 4 |
from flask import Flask, flash, redirect, url_for
|
|
|
|
|
|
|
| 5 |
|
| 6 |
# Allow OAuth scope to change (e.g. Discord adding 'guilds.join') without raising an error
|
| 7 |
os.environ["OAUTHLIB_RELAX_TOKEN_SCOPE"] = "1"
|
|
@@ -18,6 +20,8 @@ from .models import OAuth, User
|
|
| 18 |
def create_app():
|
| 19 |
app = Flask(__name__)
|
| 20 |
app.config.from_object("config.Config")
|
|
|
|
|
|
|
| 21 |
|
| 22 |
db.init_app(app)
|
| 23 |
migrate.init_app(app, db)
|
|
@@ -44,7 +48,6 @@ def create_app():
|
|
| 44 |
"https://www.googleapis.com/auth/userinfo.email",
|
| 45 |
"openid",
|
| 46 |
],
|
| 47 |
-
redirect_url="/login/google/authorized",
|
| 48 |
reprompt_consent=True,
|
| 49 |
)
|
| 50 |
app.register_blueprint(google_bp, url_prefix="/login")
|
|
@@ -53,7 +56,6 @@ def create_app():
|
|
| 53 |
client_id=app.config["DISCORD_CLIENT_ID"],
|
| 54 |
client_secret=app.config["DISCORD_CLIENT_SECRET"],
|
| 55 |
scope=["identify", "email"],
|
| 56 |
-
redirect_url="/login/discord/authorized",
|
| 57 |
)
|
| 58 |
app.register_blueprint(discord_bp, url_prefix="/login")
|
| 59 |
|
|
@@ -169,5 +171,19 @@ def create_app():
|
|
| 169 |
def oauth_error_handler(blueprint, error, error_description=None, error_uri=None):
|
| 170 |
message = f"{blueprint.name.title()} OAuth error: {error_description or error}"
|
| 171 |
app.logger.error(message)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 172 |
|
| 173 |
return app
|
|
|
|
| 2 |
from typing import Optional
|
| 3 |
|
| 4 |
from flask import Flask, flash, redirect, url_for
|
| 5 |
+
from oauthlib.oauth2.rfc6749.errors import InvalidGrantError
|
| 6 |
+
from werkzeug.middleware.proxy_fix import ProxyFix
|
| 7 |
|
| 8 |
# Allow OAuth scope to change (e.g. Discord adding 'guilds.join') without raising an error
|
| 9 |
os.environ["OAUTHLIB_RELAX_TOKEN_SCOPE"] = "1"
|
|
|
|
| 20 |
def create_app():
|
| 21 |
app = Flask(__name__)
|
| 22 |
app.config.from_object("config.Config")
|
| 23 |
+
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_port=1)
|
| 24 |
+
app.config.setdefault("PREFERRED_URL_SCHEME", "https")
|
| 25 |
|
| 26 |
db.init_app(app)
|
| 27 |
migrate.init_app(app, db)
|
|
|
|
| 48 |
"https://www.googleapis.com/auth/userinfo.email",
|
| 49 |
"openid",
|
| 50 |
],
|
|
|
|
| 51 |
reprompt_consent=True,
|
| 52 |
)
|
| 53 |
app.register_blueprint(google_bp, url_prefix="/login")
|
|
|
|
| 56 |
client_id=app.config["DISCORD_CLIENT_ID"],
|
| 57 |
client_secret=app.config["DISCORD_CLIENT_SECRET"],
|
| 58 |
scope=["identify", "email"],
|
|
|
|
| 59 |
)
|
| 60 |
app.register_blueprint(discord_bp, url_prefix="/login")
|
| 61 |
|
|
|
|
| 171 |
def oauth_error_handler(blueprint, error, error_description=None, error_uri=None):
|
| 172 |
message = f"{blueprint.name.title()} OAuth error: {error_description or error}"
|
| 173 |
app.logger.error(message)
|
| 174 |
+
flash(
|
| 175 |
+
"Login failed. Please try again. If it keeps happening, recheck OAuth callback URL and server time.",
|
| 176 |
+
"error",
|
| 177 |
+
)
|
| 178 |
+
return redirect(url_for("main.login"))
|
| 179 |
+
|
| 180 |
+
@app.errorhandler(InvalidGrantError)
|
| 181 |
+
def handle_invalid_grant(error):
|
| 182 |
+
app.logger.warning(f"OAuth invalid_grant: {error}")
|
| 183 |
+
flash(
|
| 184 |
+
"Google/Discord sign-in expired or mismatched. Please retry login once.",
|
| 185 |
+
"error",
|
| 186 |
+
)
|
| 187 |
+
return redirect(url_for("main.login"))
|
| 188 |
|
| 189 |
return app
|
app/templates/base.html
CHANGED
|
@@ -276,6 +276,17 @@
|
|
| 276 |
<!-- Main Content -->
|
| 277 |
<!-- Increased padding-top to account for floating navbar -->
|
| 278 |
<main class="relative pt-32 pb-20 flex-grow">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 279 |
{% block content %}{% endblock %}
|
| 280 |
</main>
|
| 281 |
|
|
|
|
| 276 |
<!-- Main Content -->
|
| 277 |
<!-- Increased padding-top to account for floating navbar -->
|
| 278 |
<main class="relative pt-32 pb-20 flex-grow">
|
| 279 |
+
{% with messages = get_flashed_messages(with_categories=true) %}
|
| 280 |
+
{% if messages %}
|
| 281 |
+
<div class="max-w-7xl mx-auto px-4 sm:px-6 mb-6">
|
| 282 |
+
{% for category, message in messages %}
|
| 283 |
+
<div class="glass rounded-xl px-4 py-3 font-mono text-sm {% if category == 'error' %}text-red-300 border-red-400/30{% else %}text-blue-300 border-blue-400/30{% endif %}">
|
| 284 |
+
{{ message }}
|
| 285 |
+
</div>
|
| 286 |
+
{% endfor %}
|
| 287 |
+
</div>
|
| 288 |
+
{% endif %}
|
| 289 |
+
{% endwith %}
|
| 290 |
{% block content %}{% endblock %}
|
| 291 |
</main>
|
| 292 |
|