LAN admin on 10.0.0.128 plus quick campaign mint form (#12)
Closes #11. ## Summary - Serve Django admin on LAN IP `10.0.0.128` (not `piha.li`). Compose now publishes `0.0.0.0:8005` and passes `SHORT_ADMIN_HOSTS` into the container. - Admin index has a campaign mint form: domain, campaign, source, metric. Save builds `https://{domain}/?utm_campaign=&utm_source=&utm_medium=` (metric) and shows a copyable short URL. - Public `/admin/` on `piha.lc` / `piha.li` stays 404. ## Test plan - [ ] `cd site && uv run python manage.py test` - [ ] Recreate compose (`docker compose up --build`) so `WEB_BIND` / `SHORT_ADMIN_HOSTS` take effect - [ ] From another LAN machine: `http://10.0.0.128:8005/admin/` (staff login) shows the mint form - [ ] Save a link for an allowlisted domain, copy the short URL, confirm it 302s - [ ] `https://piha.li/admin` still 404 Reviewed-on: #12
This commit was merged in pull request #12.
This commit is contained in:
+79
-1
@@ -426,7 +426,11 @@ class DebugCreateTests(TestCase):
|
||||
self.assertContains(response, link.public_short_url)
|
||||
|
||||
|
||||
ADMIN_SETTINGS = {**SETTINGS, "SHORT_ADMIN_HOSTS": ["testserver", "localhost"]}
|
||||
ADMIN_SETTINGS = {
|
||||
**SETTINGS,
|
||||
"SHORT_ADMIN_HOSTS": ["testserver", "localhost", "10.0.0.128"],
|
||||
"ALLOWED_HOSTS": [*SETTINGS["ALLOWED_HOSTS"], "10.0.0.128"],
|
||||
}
|
||||
|
||||
|
||||
@override_settings(**ADMIN_SETTINGS)
|
||||
@@ -497,3 +501,77 @@ class AdminTests(TestCase):
|
||||
self.assertEqual(response.status_code, 404)
|
||||
response = self.client.get("/admin/", HTTP_HOST="shortener.example.com")
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_admin_200_on_lan_ip(self):
|
||||
response = self.client.get("/admin/", HTTP_HOST="10.0.0.128")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, "Create a short link")
|
||||
self.assertContains(response, "Domain")
|
||||
self.assertContains(response, "Campaign")
|
||||
self.assertContains(response, "Source")
|
||||
self.assertContains(response, "Metric")
|
||||
|
||||
def test_quick_mint_creates_tracked_url(self):
|
||||
response = self.client.post(
|
||||
"/admin/",
|
||||
{
|
||||
"domain": "mkdrealtor.com",
|
||||
"campaign": "open-house",
|
||||
"source": "sms",
|
||||
"metric": "listing-click",
|
||||
},
|
||||
HTTP_HOST="10.0.0.128",
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
created = ShortLink.objects.exclude(code="a3k9xm").get()
|
||||
self.assertEqual(
|
||||
created.target_url,
|
||||
"https://mkdrealtor.com/?utm_campaign=open-house&utm_source=sms&utm_medium=listing-click",
|
||||
)
|
||||
self.assertEqual(created.title, "open-house")
|
||||
self.assertEqual(created.created_by_token, "admin")
|
||||
self.assertContains(response, created.public_short_url)
|
||||
self.assertContains(response, "Copy")
|
||||
|
||||
def test_quick_mint_rejects_unknown_host(self):
|
||||
response = self.client.post(
|
||||
"/admin/",
|
||||
{
|
||||
"domain": "evil.example",
|
||||
"campaign": "spam",
|
||||
"source": "sms",
|
||||
"metric": "click",
|
||||
},
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(ShortLink.objects.exclude(code="a3k9xm").count(), 0)
|
||||
self.assertContains(response, "host not allowlisted")
|
||||
|
||||
|
||||
class TrackedUrlTests(TestCase):
|
||||
@override_settings(**SETTINGS)
|
||||
def test_build_tracked_url(self):
|
||||
from links.services import build_tracked_url
|
||||
|
||||
url = build_tracked_url(
|
||||
domain="https://mkdrealtor.com/ignored",
|
||||
campaign="open house",
|
||||
source="sms",
|
||||
metric="listing-click",
|
||||
)
|
||||
self.assertEqual(
|
||||
url,
|
||||
"https://mkdrealtor.com/?utm_campaign=open+house&utm_source=sms&utm_medium=listing-click",
|
||||
)
|
||||
|
||||
@override_settings(**SETTINGS)
|
||||
def test_build_tracked_url_rejects_unknown_host(self):
|
||||
from links.services import ValidationError, build_tracked_url
|
||||
|
||||
with self.assertRaises(ValidationError):
|
||||
build_tracked_url(
|
||||
domain="evil.example",
|
||||
campaign="c",
|
||||
source="s",
|
||||
metric="m",
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user