summaryrefslogtreecommitdiff
path: root/Biz/PodcastItLater
diff options
context:
space:
mode:
Diffstat (limited to 'Biz/PodcastItLater')
-rw-r--r--Biz/PodcastItLater/Web.py184
1 files changed, 106 insertions, 78 deletions
diff --git a/Biz/PodcastItLater/Web.py b/Biz/PodcastItLater/Web.py
index a6eb1f6..c1698f4 100644
--- a/Biz/PodcastItLater/Web.py
+++ b/Biz/PodcastItLater/Web.py
@@ -616,6 +616,86 @@ def index(request: Request) -> HomePage:
)
+def _handle_test_login(email: str, request: Request) -> Response:
+ """Handle login in test mode."""
+ user = Core.Database.get_user_by_email(email)
+ if not user:
+ user_id, token = Core.Database.create_user(email)
+ user = {
+ "id": user_id,
+ "email": email,
+ "token": token,
+ "status": "pending",
+ }
+
+ # Check if user is active
+ if user.get("status") != "active":
+ return Response(
+ '<div style="color: #dc3545;">'
+ "Your account is pending approval. "
+ 'Please email <a href="mailto:ben@bensima.com">'
+ "ben@bensima.com</a> "
+ 'or message <a href="https://x.com/bensima" '
+ 'target="_blank">@bensima on x.com</a> '
+ "to get approved.</div>",
+ status_code=403,
+ )
+
+ # Set session with extended lifetime
+ request.session["user_id"] = user["id"]
+ request.session["permanent"] = True
+
+ return Response(
+ '<div style="color: #28a745;">✓ Logged in (dev mode)</div>',
+ status_code=200,
+ headers={"HX-Redirect": "/"},
+ )
+
+
+def _handle_production_login(email: str) -> Response:
+ """Handle login in production mode."""
+ pending_message = (
+ '<div style="color: #ffa500;">'
+ "Account created, currently pending. "
+ 'Email <a href="mailto:ben@bensima.com">ben@bensima.com</a> '
+ 'or message <a href="https://x.com/bensima" '
+ 'target="_blank">@bensima</a> '
+ "to get your account activated.</div>"
+ )
+
+ # Get or create user
+ user = Core.Database.get_user_by_email(email)
+ if not user:
+ user_id, token = Core.Database.create_user(email)
+ user = {
+ "id": user_id,
+ "email": email,
+ "token": token,
+ "status": "pending",
+ }
+ # For new users, show the pending message
+ return Response(pending_message, status_code=200)
+
+ # Check if user is active
+ if user.get("status") != "active":
+ return Response(pending_message, status_code=200)
+
+ # Generate magic link token
+ magic_token = magic_link_serializer.dumps({
+ "user_id": user["id"],
+ "email": email,
+ })
+
+ # Send email
+ send_magic_link(email, magic_token)
+
+ return Response(
+ f'<div style="color: #28a745;">✓ Magic link sent to {email}. '
+ f"Check your email!</div>",
+ status_code=200,
+ )
+
+
@app.post("/login")
def login(request: Request, data: FormData) -> Response:
"""Handle login/registration."""
@@ -632,78 +712,8 @@ def login(request: Request, data: FormData) -> Response:
area = App.from_env()
if area == App.Area.Test:
- # Development mode: instant login
- user = Core.Database.get_user_by_email(email)
- if not user:
- user_id, token = Core.Database.create_user(
- email,
- )
- user = {
- "id": user_id,
- "email": email,
- "token": token,
- "status": "pending",
- }
-
- # Check if user is active
- if user.get("status") != "active":
- return Response(
- '<div style="color: #dc3545;">'
- "Your account is pending approval. "
- 'Please email <a href="mailto:ben@bensima.com">'
- "ben@bensima.com</a> "
- 'or message <a href="https://x.com/bensima" '
- 'target="_blank">@bensima on x.com</a> '
- "to get approved.</div>",
- status_code=403,
- )
-
- # Set session with extended lifetime
- request.session["user_id"] = user["id"]
- request.session["permanent"] = True
-
- return Response(
- '<div style="color: #28a745;">✓ Logged in (dev mode)</div>',
- status_code=200,
- headers={"HX-Redirect": "/"},
- )
-
- # Production mode: send magic link
- # Get or create user
- user = Core.Database.get_user_by_email(email)
- if not user:
- user_id, token = Core.Database.create_user(
- email,
- )
- user = {"id": user_id, "email": email, "token": token}
-
- # Check if user is active
- if user.get("status") != "active":
- return Response(
- '<div style="color: #dc3545;">'
- "Your account is pending approval. "
- 'Please email <a href="mailto:ben@bensima.com">'
- "ben@bensima.com</a> "
- 'or message <a href="https://x.com/bensima" '
- 'target="_blank">@bensima on x.com</a> '
- "to get approved.</div>",
- status_code=403,
- )
-
- # Generate magic link token
- magic_token = magic_link_serializer.dumps({
- "user_id": user["id"],
- "email": email,
- })
-
- # Send email
- send_magic_link(email, magic_token)
-
- return Response(
- f'<div style="color: #28a745;">✓ Magic link sent to {email}. '
- f"Check your email!</div>",
- status_code=200,
- )
+ return _handle_test_login(email, request)
+ return _handle_production_login(email)
except Exception as e:
logger.exception("Login error")
@@ -952,10 +962,10 @@ class TestAuthentication(BaseWebTest):
response = self.client.post("/login", data={"email": "new@example.com"})
- self.assertEqual(response.status_code, 403)
- self.assertIn("Your account is pending approval", response.text)
+ self.assertEqual(response.status_code, 200)
+ self.assertIn("Account created, currently pending", response.text)
self.assertIn("ben@bensima.com", response.text)
- self.assertIn("@bensima on x.com", response.text)
+ self.assertIn("@bensima", response.text)
# Verify user was created with pending status
user = Core.Database.get_user_by_email(
@@ -983,6 +993,24 @@ class TestAuthentication(BaseWebTest):
self.assertEqual(response.status_code, 200)
self.assertIn("HX-Redirect", response.headers)
+ def test_login_existing_pending_user(self) -> None:
+ """Existing pending users should see the pending message."""
+ # Create a pending user
+ _user_id, _ = Core.Database.create_user(
+ "pending@example.com",
+ )
+ # User is pending by default
+
+ response = self.client.post(
+ "/login",
+ data={"email": "pending@example.com"},
+ )
+
+ self.assertEqual(response.status_code, 200)
+ self.assertIn("Account created, currently pending", response.text)
+ self.assertIn("ben@bensima.com", response.text)
+ self.assertIn("@bensima", response.text)
+
def test_login_disabled_user(self) -> None:
"""Disabled users should not be able to login."""
# Create user and set to disabled
@@ -999,8 +1027,8 @@ class TestAuthentication(BaseWebTest):
data={"email": "disabled@example.com"},
)
- self.assertEqual(response.status_code, 403)
- self.assertIn("Your account is pending approval", response.text)
+ self.assertEqual(response.status_code, 200)
+ self.assertIn("Account created, currently pending", response.text)
def test_login_invalid_email(self) -> None:
"""Reject malformed emails."""
@@ -1030,7 +1058,7 @@ class TestAuthentication(BaseWebTest):
"/login",
data={"email": "pending@example.com"},
)
- self.assertEqual(response.status_code, 403)
+ self.assertEqual(response.status_code, 200)
# Should not have session
response = self.client.get("/")