Entering a wrong token looked exactly like entering none: the page came back unchanged, so a typo, a token from the wrong repository and a rotated one were indistinguishable from a broken button. The page asks the server before it stores anything. A new endpoint answers 204 or 403 for a token in the header — the header, because this is asked before a cookie exists and because a foreign page cannot set one — and the key reports a refusal at once, naming where the right token lives, without storing it. A stored token the server no longer accepts turns the key red instead of leaving the page looking untouched. The instance also logs the absolute path of its token file at startup: it is relative to the service's working directory, which on an instance serving several repositories is the one the systemd unit names and not any of the others, and a token from the wrong one is silently just a wrong token. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: mhoennig <michael@hoennig.de> Reviewed-on: #47
4.1 KiB
WARNING: This document describes only the change applied in this PR. It may already be outdated once the next PR is merged. Historic PR-documentation is not maintained along with new PRs — treat it as a snapshot, not as current documentation.
Related Links
- PR#43 — introduced the key in the header and the token cookie.
The Problem
Entering the control token has no visible effect when the token is wrong, and no way to tell that apart from a bug.
The page comes back exactly as it was: the actions stay grey, a private repository stays hidden, the key stays pale. That is the same picture as before entering anything, so a typo, a token copied from the wrong repository, or one that has been rotated all look identical — and identical to "the button is broken".
The wrong-repository case is easy to walk into. The token file is .git/werkator/control-token relative to the working directory of the service, which on an instance serving several repositories is the one its systemd unit names and not any of the others. Nothing said which one that is, and running werkator control-token in the wrong repository does not warn — it creates and prints a different token.
Non-Goals
- No change to what the token protects, or to how it travels. It stays a header for anything that acts and a cookie for what may be seen.
- No way to read the token out of the server. The new endpoint confirms a token that is already known; it never hands one out.
The Scenarios
Feature: telling a wrong token from no token
Scenario#47.01: The server answers whether a token is the right one
So that the page can say what is wrong before it stores anything.
- Given the correct control token in the request header
- When
GET /api/control-token/verifyis called - Then it answers
204with an empty body - Given a wrong token, or none
- Then it answers
403, alike, and says nothing further - And the answer is never stored by a cache
Verified by
Scenario#47.02: The key says what happened
- Given a token entered at the key in the header
- When the server refuses it
- Then it is not stored, and a message says so and where the right one lives
- When the server accepts it
- Then it is stored and the page fetched afresh, in its operator form
- Given a stored token that leaves the page in its visitor form
- Then the key is red
- and its tooltip says the token is not accepted when the server refuses it
- and says the token is correct but is not arriving when the server accepts it — the cookie is being blocked or dropped on the way, which used to look exactly like a wrong token
Feature: finding the token
Scenario#47.03: The instance says where its token is
- When the server starts
- Then it logs the absolute path of its control-token file once
The Solution
ControlTokenApiController answers one question — is this the token — from the header only, with 204 or 403 and no body.
The header, not the cookie, because the page asks before setting a cookie, and because a header cannot be sent by a foreign page.
The key button asks before storing anything. A refused token is reported at once, naming where the right one is, and is not stored, so nothing has to be undone. An accepted one is stored and the page fetched afresh, as before.
A token that was accepted once and is not any more used to be invisible; on load the key now compares "something is stored" with "the server trusts me" and turns red when the two disagree. It then asks the same endpoint with the header to tell the two causes apart, because a wrong token and a cookie that never arrives produce the identical page and need opposite reactions.
ServerConfiguration logs the resolved absolute path of the token file at startup, because "relative to the working directory" is not something an operator can see from the outside.
Additional Changes
- Version 1.5.3 and its release-notes entry, since this is what gets deployed.