Remove login links from L1 - L1 doesn't know where L2 is
L1 can't redirect users to login because it doesn't know which L2 server they use. Users must log in directly at their L2 server, and the shared cookie will authenticate them on L1. - Replace "Log in" links with "Not logged in" text - Remove /login and /register routes - Keep /logout to just clear cookie and redirect home - Remove unused DEFAULT_L2_SERVER config Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
56
server.py
56
server.py
@@ -66,9 +66,6 @@ def compute_run_id(input_hashes: list[str], recipe: str, recipe_hash: str = None
|
||||
json_str = json.dumps(data, sort_keys=True, separators=(",", ":"))
|
||||
return hashlib.sha3_256(json_str.encode()).hexdigest()
|
||||
|
||||
# Default L2 for login redirect when not logged in (user can login to any L2)
|
||||
DEFAULT_L2_SERVER = os.environ.get("DEFAULT_L2_SERVER", "http://localhost:8200")
|
||||
|
||||
# IPFS gateway URL for public access to IPFS content
|
||||
IPFS_GATEWAY_URL = os.environ.get("IPFS_GATEWAY_URL", "")
|
||||
|
||||
@@ -526,7 +523,7 @@ def render_home_html(actor_id: Optional[str] = None) -> str:
|
||||
Logged in as <a href="{l2_user_url}" class="text-blue-400 hover:text-blue-300">{actor_id}</a>
|
||||
</div>'''
|
||||
else:
|
||||
user_section = '''<a href="/login" class="ml-auto px-4 py-2 bg-blue-600 hover:bg-blue-700 rounded-md text-white font-medium transition-colors">Login via L2</a>'''
|
||||
user_section = '''<span class="ml-auto text-sm text-gray-400">Not logged in</span>'''
|
||||
|
||||
return f"""
|
||||
<!DOCTYPE html>
|
||||
@@ -967,7 +964,7 @@ async def run_detail(run_id: str, request: Request):
|
||||
if wants_html(request):
|
||||
ctx = await get_user_context_from_cookie(request)
|
||||
if not ctx:
|
||||
content = '<p class="text-gray-400 py-8 text-center"><a href="/login" class="text-blue-400 hover:text-blue-300">Login via L2</a> to view run details.</p>'
|
||||
content = '<p class="text-gray-400 py-8 text-center">Not logged in.</p>'
|
||||
return HTMLResponse(render_page("Login Required", content, None, active_tab="runs"), status_code=401)
|
||||
|
||||
# Check user owns this run
|
||||
@@ -1219,7 +1216,7 @@ async def list_runs(request: Request, page: int = 1, limit: int = 20):
|
||||
|
||||
if wants_html(request):
|
||||
if not ctx:
|
||||
content = '<p class="text-gray-400 py-8 text-center"><a href="/login" class="text-blue-400 hover:text-blue-300">Login via L2</a> to see your runs.</p>'
|
||||
content = '<p class="text-gray-400 py-8 text-center">Not logged in.</p>'
|
||||
return HTMLResponse(render_page("Runs", content, None, active_tab="runs"))
|
||||
|
||||
if not runs_page:
|
||||
@@ -1402,7 +1399,7 @@ async def list_recipes_api(request: Request, page: int = 1, limit: int = 20):
|
||||
if not ctx:
|
||||
return HTMLResponse(render_page(
|
||||
"Recipes",
|
||||
'<p class="text-gray-400 py-8 text-center"><a href="/login" class="text-blue-400 hover:text-blue-300">Login via L2</a> to see recipes.</p>',
|
||||
'<p class="text-gray-400 py-8 text-center">Not logged in.</p>',
|
||||
None,
|
||||
active_tab="recipes"
|
||||
))
|
||||
@@ -1895,7 +1892,7 @@ async def ui_recipes_list(request: Request):
|
||||
ctx = await get_user_context_from_cookie(request)
|
||||
|
||||
if not ctx:
|
||||
return '<p class="text-gray-400 py-8 text-center"><a href="/login" class="text-blue-400 hover:text-blue-300">Login via L2</a> to see recipes.</p>'
|
||||
return '<p class="text-gray-400 py-8 text-center">Not logged in.</p>'
|
||||
|
||||
all_recipes = list_all_recipes()
|
||||
|
||||
@@ -2019,7 +2016,7 @@ async def get_cached(content_hash: str, request: Request):
|
||||
# Raw data is only served from /cache/{hash}/raw endpoint
|
||||
if True: # Always show HTML page, raw data via /raw endpoint
|
||||
if not ctx:
|
||||
content = '<p class="text-gray-400 py-8 text-center"><a href="/login" class="text-blue-400 hover:text-blue-300">Login via L2</a> to view cached content.</p>'
|
||||
content = '<p class="text-gray-400 py-8 text-center">Not logged in.</p>'
|
||||
return HTMLResponse(render_page("Login Required", content, None, active_tab="media"), status_code=401)
|
||||
|
||||
# Check user has access
|
||||
@@ -2661,7 +2658,7 @@ async def list_media(
|
||||
if wants_html(request):
|
||||
# Require login for HTML media view
|
||||
if not ctx:
|
||||
content = '<p class="text-gray-400 py-8 text-center"><a href="/login" class="text-blue-400 hover:text-blue-300">Login via L2</a> to see media.</p>'
|
||||
content = '<p class="text-gray-400 py-8 text-center">Not logged in.</p>'
|
||||
return HTMLResponse(render_page("Media", content, None, active_tab="media"))
|
||||
|
||||
# Get hashes owned by/associated with this user
|
||||
@@ -3727,8 +3724,8 @@ def render_page(title: str, content: str, actor_id: Optional[str] = None, active
|
||||
'''
|
||||
else:
|
||||
user_info = '''
|
||||
<div class="text-sm">
|
||||
<a href="/login" class="text-blue-400 hover:text-blue-300">Login via L2</a>
|
||||
<div class="text-sm text-gray-400">
|
||||
Not logged in
|
||||
</div>
|
||||
'''
|
||||
|
||||
@@ -3789,8 +3786,8 @@ def render_ui_html(actor_id: Optional[str] = None, tab: str = "runs") -> str:
|
||||
'''
|
||||
else:
|
||||
user_info = '''
|
||||
<div class="text-sm">
|
||||
<a href="/login" class="text-blue-400 hover:text-blue-300">Login via L2</a>
|
||||
<div class="text-sm text-gray-400">
|
||||
Not logged in
|
||||
</div>
|
||||
'''
|
||||
|
||||
@@ -3841,32 +3838,13 @@ def render_ui_html(actor_id: Optional[str] = None, tab: str = "runs") -> str:
|
||||
"""
|
||||
|
||||
|
||||
# Auth routes - L1 never handles credentials, redirects to L2
|
||||
# L2 sets auth_token cookie with domain=.rose-ash.com for shared auth
|
||||
|
||||
L1_PUBLIC_URL = os.environ.get("L1_PUBLIC_URL", "http://localhost:8100")
|
||||
|
||||
|
||||
@app.get("/login")
|
||||
async def login_page():
|
||||
"""Redirect to L2 server for login. L1 never handles credentials."""
|
||||
# Redirect to default L2 with return URL so L2 can redirect back after login
|
||||
return_url = f"{L1_PUBLIC_URL}/runs"
|
||||
return RedirectResponse(url=f"{DEFAULT_L2_SERVER}/login?return_to={return_url}", status_code=302)
|
||||
|
||||
|
||||
@app.get("/register")
|
||||
async def register_page():
|
||||
"""Redirect to L2 server for registration. L1 never handles credentials."""
|
||||
return_url = f"{L1_PUBLIC_URL}/runs"
|
||||
return RedirectResponse(url=f"{DEFAULT_L2_SERVER}/register?return_to={return_url}", status_code=302)
|
||||
|
||||
# Auth - L1 doesn't handle login (user logs in at their L2 server)
|
||||
# Shared cookie authenticates across L1 and L2
|
||||
|
||||
@app.get("/logout")
|
||||
async def logout():
|
||||
"""Logout - clear cookie and redirect to L2 logout."""
|
||||
# Clear local cookie and redirect to L2 to clear shared cookie
|
||||
response = RedirectResponse(url=f"{DEFAULT_L2_SERVER}/logout?return_to={L1_PUBLIC_URL}/", status_code=302)
|
||||
"""Logout - clear local cookie and redirect to home."""
|
||||
response = RedirectResponse(url="/", status_code=302)
|
||||
response.delete_cookie("auth_token")
|
||||
return response
|
||||
|
||||
@@ -3965,7 +3943,7 @@ async def ui_runs(request: Request):
|
||||
|
||||
# Require login to see runs
|
||||
if not ctx:
|
||||
return '<p class="text-gray-400 py-8 text-center"><a href="/login" class="text-blue-400 hover:text-blue-300">Login via L2</a> to see your runs.</p>'
|
||||
return '<p class="text-gray-400 py-8 text-center">Not logged in.</p>'
|
||||
|
||||
# Filter runs by user - match both plain username and ActivityPub format (@user@domain)
|
||||
runs = [r for r in runs if r.username in (ctx.username, ctx.actor_id)]
|
||||
@@ -4064,7 +4042,7 @@ async def ui_media_list(
|
||||
|
||||
# Require login to see media
|
||||
if not ctx:
|
||||
return '<p class="text-gray-400 py-8 text-center"><a href="/login" class="text-blue-400 hover:text-blue-300">Login via L2</a> to see media.</p>'
|
||||
return '<p class="text-gray-400 py-8 text-center">Not logged in.</p>'
|
||||
|
||||
# Get hashes owned by/associated with this user
|
||||
user_hashes = await get_user_cache_hashes(ctx.username, ctx.actor_id)
|
||||
|
||||
Reference in New Issue
Block a user