Fix OAuth navigation from sandboxed Space iframe
#12
by DineshAI - opened
- app.py +4 -2
- test_app.py +5 -2
app.py
CHANGED
|
@@ -74,15 +74,17 @@ def stats_line(rec):
|
|
| 74 |
|
| 75 |
|
| 76 |
def auth_control(profile: gr.OAuthProfile | None):
|
| 77 |
-
"""Render
|
| 78 |
if profile is None:
|
| 79 |
href = "/oauth-login"
|
|
|
|
| 80 |
label = "🤗 Sign in with Hugging Face"
|
| 81 |
else:
|
| 82 |
href = "/logout?_target_url=/"
|
|
|
|
| 83 |
label = f"Logout (@{escape(profile.username)})"
|
| 84 |
return (
|
| 85 |
-
f'<a href="{href}" target="
|
| 86 |
'style="display:inline-block;background:#111827;color:#fff;font-weight:700;'
|
| 87 |
'padding:10px 18px;border-radius:8px;text-decoration:none">'
|
| 88 |
f"{label}</a>"
|
|
|
|
| 74 |
|
| 75 |
|
| 76 |
def auth_control(profile: gr.OAuthProfile | None):
|
| 77 |
+
"""Render OAuth controls that work inside the sandboxed Space iframe."""
|
| 78 |
if profile is None:
|
| 79 |
href = "/oauth-login"
|
| 80 |
+
target = "_blank"
|
| 81 |
label = "🤗 Sign in with Hugging Face"
|
| 82 |
else:
|
| 83 |
href = "/logout?_target_url=/"
|
| 84 |
+
target = "_self"
|
| 85 |
label = f"Logout (@{escape(profile.username)})"
|
| 86 |
return (
|
| 87 |
+
f'<a href="{href}" target="{target}" rel="noopener" role="button" '
|
| 88 |
'style="display:inline-block;background:#111827;color:#fff;font-weight:700;'
|
| 89 |
'padding:10px 18px;border-radius:8px;text-decoration:none">'
|
| 90 |
f"{label}</a>"
|
test_app.py
CHANGED
|
@@ -12,6 +12,7 @@ os.environ.setdefault("OAUTH_CLIENT_ID", "test-client")
|
|
| 12 |
os.environ.setdefault("OAUTH_CLIENT_SECRET", "test-secret")
|
| 13 |
os.environ.setdefault("OAUTH_SCOPES", "openid profile")
|
| 14 |
os.environ.setdefault("OPENID_PROVIDER_URL", "https://huggingface.co")
|
|
|
|
| 15 |
|
| 16 |
certificate_app = importlib.import_module("app")
|
| 17 |
|
|
@@ -30,15 +31,17 @@ def test_oauth_login_clears_stale_session_before_redirecting():
|
|
| 30 |
assert "secure" in cookie
|
| 31 |
|
| 32 |
|
| 33 |
-
def
|
| 34 |
logged_out = certificate_app.auth_control(None)
|
| 35 |
logged_in = certificate_app.auth_control(
|
| 36 |
SimpleNamespace(username='person<script>alert("x")</script>')
|
| 37 |
)
|
| 38 |
|
| 39 |
assert 'href="/oauth-login"' in logged_out
|
| 40 |
-
assert 'target="
|
| 41 |
assert 'href="/logout?_target_url=/"' in logged_in
|
|
|
|
|
|
|
| 42 |
assert "<script>" not in logged_in
|
| 43 |
assert "<script>" in logged_in
|
| 44 |
|
|
|
|
| 12 |
os.environ.setdefault("OAUTH_CLIENT_SECRET", "test-secret")
|
| 13 |
os.environ.setdefault("OAUTH_SCOPES", "openid profile")
|
| 14 |
os.environ.setdefault("OPENID_PROVIDER_URL", "https://huggingface.co")
|
| 15 |
+
os.environ.setdefault("GRADIO_SSR_MODE", "true")
|
| 16 |
|
| 17 |
certificate_app = importlib.import_module("app")
|
| 18 |
|
|
|
|
| 31 |
assert "secure" in cookie
|
| 32 |
|
| 33 |
|
| 34 |
+
def test_auth_control_uses_sandbox_safe_navigation():
|
| 35 |
logged_out = certificate_app.auth_control(None)
|
| 36 |
logged_in = certificate_app.auth_control(
|
| 37 |
SimpleNamespace(username='person<script>alert("x")</script>')
|
| 38 |
)
|
| 39 |
|
| 40 |
assert 'href="/oauth-login"' in logged_out
|
| 41 |
+
assert 'target="_blank"' in logged_out
|
| 42 |
assert 'href="/logout?_target_url=/"' in logged_in
|
| 43 |
+
assert 'target="_self"' in logged_in
|
| 44 |
+
assert 'target="_top"' not in logged_out + logged_in
|
| 45 |
assert "<script>" not in logged_in
|
| 46 |
assert "<script>" in logged_in
|
| 47 |
|