wu981526092 commited on
Commit
2175f7f
·
1 Parent(s): 64857c1

Separate login page to HTML template for better maintainability

Browse files
backend/routers/auth.py CHANGED
@@ -8,8 +8,10 @@ import os
8
  import logging
9
  import secrets
10
  from typing import Optional
 
11
  from fastapi import APIRouter, Request, Response, HTTPException
12
  from fastapi.responses import RedirectResponse, HTMLResponse, JSONResponse
 
13
  from utils.environment import should_enable_auth, get_oauth_config, is_huggingface_space
14
  import requests
15
 
@@ -17,6 +19,10 @@ logger = logging.getLogger(__name__)
17
 
18
  router = APIRouter(prefix="/auth", tags=["authentication"])
19
 
 
 
 
 
20
 
21
  @router.get("/status")
22
  async def auth_status(request: Request):
@@ -282,191 +288,12 @@ async def get_current_user(request: Request):
282
  @router.get("/login-page")
283
  async def login_page(request: Request):
284
  """
285
- Serve a login page explaining why authentication is required.
286
  """
287
  if not should_enable_auth():
288
  return RedirectResponse(url="/", status_code=302)
289
 
290
- html_content = """
291
- <!DOCTYPE html>
292
- <html lang="en" class="dark">
293
- <head>
294
- <meta charset="UTF-8">
295
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
296
- <title>AgentGraph - Interactive Analysis Platform for Agentic AI Systems</title>
297
- <meta http-equiv="Permissions-Policy" content="payment=(), microphone=(), camera=(), geolocation=()">
298
- <script src="https://cdn.tailwindcss.com"></script>
299
- <style>
300
- :root {
301
- --background: 240 10% 3.9%;
302
- --foreground: 210 40% 98%;
303
- --card: 240 10% 3.9%;
304
- --card-foreground: 210 40% 98%;
305
- --popover: 240 10% 3.9%;
306
- --popover-foreground: 210 40% 98%;
307
- --primary: 262 83% 58%;
308
- --primary-foreground: 210 40% 98%;
309
- --secondary: 240 3.7% 15.9%;
310
- --secondary-foreground: 210 40% 98%;
311
- --muted: 240 3.7% 15.9%;
312
- --muted-foreground: 240 5% 64.9%;
313
- --accent: 240 3.7% 15.9%;
314
- --accent-foreground: 210 40% 98%;
315
- --destructive: 0 62.8% 30.6%;
316
- --destructive-foreground: 210 40% 98%;
317
- --border: 240 3.7% 15.9%;
318
- --input: 240 3.7% 15.9%;
319
- --ring: 262 83% 58%;
320
- --radius: 0.5rem;
321
- }
322
-
323
- body {
324
- background: hsl(var(--background));
325
- color: hsl(var(--foreground));
326
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
327
- }
328
-
329
- .glass-card {
330
- background: rgba(255, 255, 255, 0.05);
331
- backdrop-filter: blur(20px);
332
- -webkit-backdrop-filter: blur(20px);
333
- border: 1px solid rgba(255, 255, 255, 0.1);
334
- box-shadow:
335
- 0 8px 32px rgba(0, 0, 0, 0.3),
336
- inset 0 1px 0 rgba(255, 255, 255, 0.1);
337
- transition: all 0.3s ease;
338
- }
339
-
340
- .glass-card:hover {
341
- background: rgba(255, 255, 255, 0.08);
342
- border: 1px solid rgba(255, 255, 255, 0.15);
343
- box-shadow:
344
- 0 12px 48px rgba(0, 0, 0, 0.4),
345
- inset 0 1px 0 rgba(255, 255, 255, 0.15);
346
- transform: translateY(-2px);
347
- }
348
-
349
- .btn-primary {
350
- background: linear-gradient(135deg, hsl(var(--primary)) 0%, hsl(var(--primary) / 0.8) 100%);
351
- color: hsl(var(--primary-foreground));
352
- border: 1px solid hsl(var(--primary) / 0.3);
353
- box-shadow: 0 4px 14px hsl(var(--primary) / 0.3);
354
- transition: all 0.3s ease;
355
- }
356
-
357
- .btn-primary:hover {
358
- box-shadow: 0 8px 25px hsl(var(--primary) / 0.4);
359
- transform: translateY(-2px);
360
- }
361
-
362
- .gradient-text {
363
- background: linear-gradient(135deg, hsl(var(--foreground)) 0%, hsl(var(--muted-foreground)) 100%);
364
- -webkit-background-clip: text;
365
- -webkit-text-fill-color: transparent;
366
- background-clip: text;
367
- }
368
-
369
- @keyframes gentle-pulse {
370
- 0%, 100% { opacity: 1; }
371
- 50% { opacity: 0.8; }
372
- }
373
-
374
- .animate-pulse-gentle {
375
- animation: gentle-pulse 2s ease-in-out infinite;
376
- }
377
- </style>
378
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
379
- </head>
380
- <body>
381
- <div class="min-h-screen bg-gradient-to-br from-background via-background to-secondary">
382
- <!-- Background decoration -->
383
- <div class="absolute inset-0 bg-gradient-to-br from-primary/5 via-transparent to-secondary/10 pointer-events-none"></div>
384
-
385
- <div class="container mx-auto px-4 py-20 relative z-10">
386
- <div class="grid lg:grid-cols-2 gap-16 items-center max-w-6xl mx-auto">
387
- <!-- Content Section -->
388
- <div class="space-y-8">
389
- <!-- Badge -->
390
- <div class="inline-flex items-center px-3 py-1.5 rounded-full border border-border bg-muted/20 text-sm font-medium text-muted-foreground">
391
- <svg class="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 20 20">
392
- <path fill-rule="evenodd" d="M10.394 2.08a1 1 0 00-.788 0l-7 3a1 1 0 000 1.84L5.25 8.051a.999.999 0 01.356-.257l4-1.714a1 1 0 11.788 1.838L7.667 9.088l1.94.831a1 1 0 00.787 0l7-3a1 1 0 000-1.838l-7-3zM3.31 9.397L5 10.12v4.102a8.969 8.969 0 00-1.05-.174 1 1 0 01-.89-.89 11.115 11.115 0 01.25-3.762zM9.3 16.573A9.026 9.026 0 007 14.935v-3.957l1.818.78a3 3 0 002.364 0l5.508-2.361a11.026 11.026 0 01.25 3.762 1 1 0 01-.89.89 8.968 8.968 0 00-5.35 2.524 1 1 0 01-1.4 0zM6 18a1 1 0 001-1v-2.065a8.935 8.935 0 00-2-.712V17a1 1 0 001 1z" clip-rule="evenodd"></path>
393
- </svg>
394
- Research Platform
395
- </div>
396
-
397
- <!-- Title -->
398
- <div class="space-y-4">
399
- <h1 class="text-4xl lg:text-6xl font-bold gradient-text tracking-tight">
400
- AgentGraph
401
- </h1>
402
- <p class="text-xl text-muted-foreground leading-relaxed">
403
- Trace-to-Graph Platform for Interactive Analysis and Robustness Testing in Agentic AI Systems
404
- </p>
405
- </div>
406
-
407
- <!-- Description -->
408
- <p class="text-lg text-muted-foreground leading-relaxed">
409
- Convert execution logs into interactive knowledge graphs with actionable insights for AI system analysis and robustness testing.
410
- </p>
411
-
412
- <!-- CTA Section -->
413
- <div class="space-y-4">
414
- <a href="/auth/login"
415
- class="btn-primary inline-flex items-center justify-center px-8 py-4 text-lg font-semibold rounded-lg transition-all duration-300 group">
416
- Access Research Platform
417
- <svg class="ml-2 w-5 h-5 transition-transform group-hover:translate-x-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
418
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7l5 5m0 0l-5 5m5-5H6"></path>
419
- </svg>
420
- </a>
421
-
422
- <div class="glass-card p-4 rounded-lg">
423
- <p class="text-sm text-muted-foreground">
424
- Authentication required for responsible AI resource usage
425
- </p>
426
- </div>
427
- </div>
428
-
429
- <!-- Institutions -->
430
- <div class="pt-6 border-t border-border">
431
- <p class="text-xs text-muted-foreground uppercase tracking-wider mb-2">
432
- Research Collaboration
433
- </p>
434
- <p class="text-sm text-foreground font-medium">
435
- Holistic AI × Centre for Artificial Intelligence, UCL
436
- </p>
437
- </div>
438
- </div>
439
-
440
- <!-- Video Section -->
441
- <div class="relative">
442
- <div class="glass-card rounded-2xl overflow-hidden">
443
- <!-- Live Demo Badge -->
444
- <div class="absolute -top-3 -right-3 z-10">
445
- <div class="bg-green-500 text-white px-3 py-1.5 rounded-lg text-sm font-semibold shadow-lg animate-pulse-gentle">
446
- <span class="inline-block w-2 h-2 bg-white rounded-full mr-2"></span>
447
- Live Demo
448
- </div>
449
- </div>
450
-
451
- <div class="relative aspect-video">
452
- <iframe
453
- src="https://www.youtube.com/embed/btrS9pfDYJY?si=dDX4tIs-oS2O2d2p"
454
- title="AgentGraph: Interactive Analysis Platform Demo"
455
- allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
456
- allowfullscreen
457
- class="w-full h-full rounded-2xl">
458
- </iframe>
459
- </div>
460
- </div>
461
- </div>
462
- </div>
463
- </div>
464
- </div>
465
- </body>
466
- </html>
467
- """
468
-
469
- return HTMLResponse(content=html_content)
470
 
471
 
472
  @router.get("/debug")
 
8
  import logging
9
  import secrets
10
  from typing import Optional
11
+ from pathlib import Path
12
  from fastapi import APIRouter, Request, Response, HTTPException
13
  from fastapi.responses import RedirectResponse, HTMLResponse, JSONResponse
14
+ from fastapi.templating import Jinja2Templates
15
  from utils.environment import should_enable_auth, get_oauth_config, is_huggingface_space
16
  import requests
17
 
 
19
 
20
  router = APIRouter(prefix="/auth", tags=["authentication"])
21
 
22
+ # Setup templates
23
+ templates_dir = Path(__file__).parent.parent / "templates"
24
+ templates = Jinja2Templates(directory=str(templates_dir))
25
+
26
 
27
  @router.get("/status")
28
  async def auth_status(request: Request):
 
288
  @router.get("/login-page")
289
  async def login_page(request: Request):
290
  """
291
+ Serve the login page using Jinja2 template.
292
  """
293
  if not should_enable_auth():
294
  return RedirectResponse(url="/", status_code=302)
295
 
296
+ return templates.TemplateResponse("login.html", {"request": request})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
297
 
298
 
299
  @router.get("/debug")
backend/templates/login.html ADDED
@@ -0,0 +1,229 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en" class="dark">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>
7
+ AgentGraph - Interactive Analysis Platform for Agentic AI Systems
8
+ </title>
9
+ <meta
10
+ http-equiv="Permissions-Policy"
11
+ content="payment=(), microphone=(), camera=(), geolocation=()"
12
+ />
13
+ <script src="https://cdn.tailwindcss.com"></script>
14
+ <style>
15
+ :root {
16
+ --background: 240 10% 3.9%;
17
+ --foreground: 210 40% 98%;
18
+ --card: 240 10% 3.9%;
19
+ --card-foreground: 210 40% 98%;
20
+ --popover: 240 10% 3.9%;
21
+ --popover-foreground: 210 40% 98%;
22
+ --primary: 262 83% 58%;
23
+ --primary-foreground: 210 40% 98%;
24
+ --secondary: 240 3.7% 15.9%;
25
+ --secondary-foreground: 210 40% 98%;
26
+ --muted: 240 3.7% 15.9%;
27
+ --muted-foreground: 240 5% 64.9%;
28
+ --accent: 240 3.7% 15.9%;
29
+ --accent-foreground: 210 40% 98%;
30
+ --destructive: 0 62.8% 30.6%;
31
+ --destructive-foreground: 210 40% 98%;
32
+ --border: 240 3.7% 15.9%;
33
+ --input: 240 3.7% 15.9%;
34
+ --ring: 262 83% 58%;
35
+ --radius: 0.5rem;
36
+ }
37
+
38
+ body {
39
+ background: hsl(var(--background));
40
+ color: hsl(var(--foreground));
41
+ font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI",
42
+ Roboto, sans-serif;
43
+ }
44
+
45
+ .glass-card {
46
+ background: rgba(255, 255, 255, 0.05);
47
+ backdrop-filter: blur(20px);
48
+ -webkit-backdrop-filter: blur(20px);
49
+ border: 1px solid rgba(255, 255, 255, 0.1);
50
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3),
51
+ inset 0 1px 0 rgba(255, 255, 255, 0.1);
52
+ transition: all 0.3s ease;
53
+ }
54
+
55
+ .glass-card:hover {
56
+ background: rgba(255, 255, 255, 0.08);
57
+ border: 1px solid rgba(255, 255, 255, 0.15);
58
+ box-shadow: 0 12px 48px rgba(0, 0, 0, 0.4),
59
+ inset 0 1px 0 rgba(255, 255, 255, 0.15);
60
+ transform: translateY(-2px);
61
+ }
62
+
63
+ .btn-primary {
64
+ background: linear-gradient(
65
+ 135deg,
66
+ hsl(var(--primary)) 0%,
67
+ hsl(var(--primary) / 0.8) 100%
68
+ );
69
+ color: hsl(var(--primary-foreground));
70
+ border: 1px solid hsl(var(--primary) / 0.3);
71
+ box-shadow: 0 4px 14px hsl(var(--primary) / 0.3);
72
+ transition: all 0.3s ease;
73
+ }
74
+
75
+ .btn-primary:hover {
76
+ box-shadow: 0 8px 25px hsl(var(--primary) / 0.4);
77
+ transform: translateY(-2px);
78
+ }
79
+
80
+ .gradient-text {
81
+ background: linear-gradient(
82
+ 135deg,
83
+ hsl(var(--foreground)) 0%,
84
+ hsl(var(--muted-foreground)) 100%
85
+ );
86
+ -webkit-background-clip: text;
87
+ -webkit-text-fill-color: transparent;
88
+ background-clip: text;
89
+ }
90
+
91
+ @keyframes gentle-pulse {
92
+ 0%,
93
+ 100% {
94
+ opacity: 1;
95
+ }
96
+ 50% {
97
+ opacity: 0.8;
98
+ }
99
+ }
100
+
101
+ .animate-pulse-gentle {
102
+ animation: gentle-pulse 2s ease-in-out infinite;
103
+ }
104
+ </style>
105
+ <link
106
+ href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap"
107
+ rel="stylesheet"
108
+ />
109
+ </head>
110
+ <body>
111
+ <div
112
+ class="min-h-screen bg-gradient-to-br from-background via-background to-secondary"
113
+ >
114
+ <!-- Background decoration -->
115
+ <div
116
+ class="absolute inset-0 bg-gradient-to-br from-primary/5 via-transparent to-secondary/10 pointer-events-none"
117
+ ></div>
118
+
119
+ <div class="container mx-auto px-4 py-20 relative z-10">
120
+ <div class="grid lg:grid-cols-2 gap-16 items-center max-w-6xl mx-auto">
121
+ <!-- Content Section -->
122
+ <div class="space-y-8">
123
+ <!-- Badge -->
124
+ <div
125
+ class="inline-flex items-center px-3 py-1.5 rounded-full border border-border bg-muted/20 text-sm font-medium text-muted-foreground"
126
+ >
127
+ <svg class="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 20 20">
128
+ <path
129
+ fill-rule="evenodd"
130
+ d="M10.394 2.08a1 1 0 00-.788 0l-7 3a1 1 0 000 1.84L5.25 8.051a.999.999 0 01.356-.257l4-1.714a1 1 0 11.788 1.838L7.667 9.088l1.94.831a1 1 0 00.787 0l7-3a1 1 0 000-1.838l-7-3zM3.31 9.397L5 10.12v4.102a8.969 8.969 0 00-1.05-.174 1 1 0 01-.89-.89 11.115 11.115 0 01.25-3.762zM9.3 16.573A9.026 9.026 0 007 14.935v-3.957l1.818.78a3 3 0 002.364 0l5.508-2.361a11.026 11.026 0 01.25 3.762 1 1 0 01-.89.89 8.968 8.968 0 00-5.35 2.524 1 1 0 01-1.4 0zM6 18a1 1 0 001-1v-2.065a8.935 8.935 0 00-2-.712V17a1 1 0 001 1z"
131
+ clip-rule="evenodd"
132
+ ></path>
133
+ </svg>
134
+ Research Platform
135
+ </div>
136
+
137
+ <!-- Title -->
138
+ <div class="space-y-4">
139
+ <h1
140
+ class="text-4xl lg:text-6xl font-bold gradient-text tracking-tight"
141
+ >
142
+ AgentGraph
143
+ </h1>
144
+ <p class="text-xl text-muted-foreground leading-relaxed">
145
+ Trace-to-Graph Platform for Interactive Analysis and Robustness
146
+ Testing in Agentic AI Systems
147
+ </p>
148
+ </div>
149
+
150
+ <!-- Description -->
151
+ <p class="text-lg text-muted-foreground leading-relaxed">
152
+ Convert execution logs into interactive knowledge graphs with
153
+ actionable insights for AI system analysis and robustness testing.
154
+ </p>
155
+
156
+ <!-- CTA Section -->
157
+ <div class="space-y-4">
158
+ <a
159
+ href="/auth/login"
160
+ class="btn-primary inline-flex items-center justify-center px-8 py-4 text-lg font-semibold rounded-lg transition-all duration-300 group"
161
+ >
162
+ Access Research Platform
163
+ <svg
164
+ class="ml-2 w-5 h-5 transition-transform group-hover:translate-x-1"
165
+ fill="none"
166
+ stroke="currentColor"
167
+ viewBox="0 0 24 24"
168
+ >
169
+ <path
170
+ stroke-linecap="round"
171
+ stroke-linejoin="round"
172
+ stroke-width="2"
173
+ d="M13 7l5 5m0 0l-5 5m5-5H6"
174
+ ></path>
175
+ </svg>
176
+ </a>
177
+
178
+ <div class="glass-card p-4 rounded-lg">
179
+ <p class="text-sm text-muted-foreground">
180
+ Authentication required for responsible AI resource usage
181
+ </p>
182
+ </div>
183
+ </div>
184
+
185
+ <!-- Institutions -->
186
+ <div class="pt-6 border-t border-border">
187
+ <p
188
+ class="text-xs text-muted-foreground uppercase tracking-wider mb-2"
189
+ >
190
+ Research Collaboration
191
+ </p>
192
+ <p class="text-sm text-foreground font-medium">
193
+ Holistic AI × Centre for Artificial Intelligence, UCL
194
+ </p>
195
+ </div>
196
+ </div>
197
+
198
+ <!-- Video Section -->
199
+ <div class="relative">
200
+ <div class="glass-card rounded-2xl overflow-hidden">
201
+ <!-- Live Demo Badge -->
202
+ <div class="absolute -top-3 -right-3 z-10">
203
+ <div
204
+ class="bg-green-500 text-white px-3 py-1.5 rounded-lg text-sm font-semibold shadow-lg animate-pulse-gentle"
205
+ >
206
+ <span
207
+ class="inline-block w-2 h-2 bg-white rounded-full mr-2"
208
+ ></span>
209
+ Live Demo
210
+ </div>
211
+ </div>
212
+
213
+ <div class="relative aspect-video">
214
+ <iframe
215
+ src="https://www.youtube.com/embed/btrS9pfDYJY?si=dDX4tIs-oS2O2d2p"
216
+ title="AgentGraph: Interactive Analysis Platform Demo"
217
+ allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
218
+ allowfullscreen
219
+ class="w-full h-full rounded-2xl"
220
+ >
221
+ </iframe>
222
+ </div>
223
+ </div>
224
+ </div>
225
+ </div>
226
+ </div>
227
+ </div>
228
+ </body>
229
+ </html>