aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-17 09:09:39 +0200
committerDanilo M. <danix@danix.xyz>2026-09-17 09:09:39 +0200
commita55051da4a286649361d1fc811ecfccacde17695 (patch)
tree5be442a299332c3e401fd4f3720be69ad611cf9a
parent2218d1afe5750558f222c048525cb32f8781c260 (diff)
downloadconky-theme-udt-a55051da4a286649361d1fc811ecfccacde17695.tar.gz
conky-theme-udt-a55051da4a286649361d1fc811ecfccacde17695.zip
fix: correct the .cod rationale, and stop world-reading the cache
The comment claimed a bad key returns HTTP 200 with an error body, so the status code alone proves nothing. Measured against the live API, that is wrong: a bad key returns 401 and an unknown city 404, and with curl -f both fail at curl without the .cod check ever running. The claim came from the polybar script, which ran curl WITHOUT -f and so genuinely did receive error bodies with a success exit. The check was ported but not the reason for it. It still earns its place behind -f, for a 200 whose body is not usable weather, and the comment now says that instead of something false. The spec carried the same wrong sentence and is corrected too. Separately, the cache landed at 644 in a directory where every other generated file is 600, and the response carries the configured city and its coordinates. A umask before the write puts it at 600 without a window where it is briefly readable. The .cod discrepancy was found by the Task 6 implementer, which noticed the bad-key test produced a different message than the plan predicted and said so rather than reporting the expected text as achieved. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
-rwxr-xr-xbin/weather-fetch.sh16
-rw-r--r--docs/superpowers/plans/2026-09-17-weather-widget.md16
-rw-r--r--docs/superpowers/specs/2026-09-17-weather-widget-design.md11
3 files changed, 33 insertions, 10 deletions
diff --git a/bin/weather-fetch.sh b/bin/weather-fetch.sh
index aaa48e2..76aa07b 100755
--- a/bin/weather-fetch.sh
+++ b/bin/weather-fetch.sh
@@ -33,6 +33,12 @@ mkdir -p "$CACHE_DIR"
TMP="$CACHE.tmp.$$"
trap 'rm -f "$TMP"' EXIT
+# The response carries the configured city and its coordinates. That is not a
+# secret, but it is location data and it shares a directory with UDT's other
+# generated state, all of which is 600. Set the mode before the body lands in
+# the file rather than after, so it is never briefly world-readable.
+umask 077
+
URL="https://api.openweathermap.org/data/2.5/weather"
if ! curl -fsS --max-time 15 --get "$URL" \
--data-urlencode "appid=$KEY" \
@@ -44,9 +50,13 @@ if ! curl -fsS --max-time 15 --get "$URL" \
exit 1
fi
-# A bad key returns HTTP 200 with a JSON error body, so the status code alone
-# proves nothing. This check is carried over from the polybar script, which
-# learned it the same way.
+# Belt and braces behind `curl -f`. Measured against the live API: a bad key
+# returns 401 and an unknown city 404, so curl -f already rejects both and this
+# branch is not what catches them. It stays for the case -f cannot see: a 200
+# whose body is not usable weather, which is what the polybar script this was
+# ported from actually hit, since it ran curl WITHOUT -f and so received error
+# bodies with a success exit. Without this, such a body would reach the parser
+# and replace a good cache.
if [ "$(jq -r '.cod // empty' "$TMP" 2>/dev/null)" != "200" ]; then
echo "weather-fetch: API error: $(jq -r '.message // "unknown"' "$TMP" 2>/dev/null)" >&2
exit 1
diff --git a/docs/superpowers/plans/2026-09-17-weather-widget.md b/docs/superpowers/plans/2026-09-17-weather-widget.md
index 0b78b83..36e2dc1 100644
--- a/docs/superpowers/plans/2026-09-17-weather-widget.md
+++ b/docs/superpowers/plans/2026-09-17-weather-widget.md
@@ -778,6 +778,12 @@ mkdir -p "$CACHE_DIR"
TMP="$CACHE.tmp.$$"
trap 'rm -f "$TMP"' EXIT
+# The response carries the configured city and its coordinates. That is not a
+# secret, but it is location data and it shares a directory with UDT's other
+# generated state, all of which is 600. Set the mode before the body lands in
+# the file rather than after, so it is never briefly world-readable.
+umask 077
+
URL="https://api.openweathermap.org/data/2.5/weather"
if ! curl -fsS --max-time 15 --get "$URL" \
--data-urlencode "appid=$KEY" \
@@ -789,9 +795,13 @@ if ! curl -fsS --max-time 15 --get "$URL" \
exit 1
fi
-# A bad key returns HTTP 200 with a JSON error body, so the status code alone
-# proves nothing. This check is carried over from the polybar script, which
-# learned it the same way.
+# Belt and braces behind `curl -f`. Measured against the live API: a bad key
+# returns 401 and an unknown city 404, so curl -f already rejects both and this
+# branch is not what catches them. It stays for the case -f cannot see: a 200
+# whose body is not usable weather, which is what the polybar script this was
+# ported from actually hit, since it ran curl WITHOUT -f and so received error
+# bodies with a success exit. Without this, such a body would reach the parser
+# and replace a good cache.
if [ "$(jq -r '.cod // empty' "$TMP" 2>/dev/null)" != "200" ]; then
echo "weather-fetch: API error: $(jq -r '.message // "unknown"' "$TMP" 2>/dev/null)" >&2
exit 1
diff --git a/docs/superpowers/specs/2026-09-17-weather-widget-design.md b/docs/superpowers/specs/2026-09-17-weather-widget-design.md
index 412adac..60fa7d9 100644
--- a/docs/superpowers/specs/2026-09-17-weather-widget-design.md
+++ b/docs/superpowers/specs/2026-09-17-weather-widget-design.md
@@ -174,10 +174,13 @@ single transient failure does not flag the card.
The fetch script exits non-zero with a message on stderr when the key is
missing or curl fails, and **leaves any existing cache untouched** rather than
-overwriting it with an error body. OWM returns HTTP 200 with a JSON error body
-for a bad key, so the script checks that `.cod` is 200 before replacing the
-cache. That check is carried over from the reference script, which learned it
-the same way.
+overwriting it with an error body.
+
+The script checks `.cod` is 200 before replacing the cache, behind `curl -f`.
+Measured against the live API, a bad key returns 401 and an unknown city 404,
+so `-f` rejects both before `.cod` is read; the check covers the remaining case
+of a 200 whose body is not usable weather. The reference script needed it as
+its only defence because it ran curl without `-f`.
## Secrets and personal data