Repository navigation
feat(web): make the dashboard show what needs attention (spec 0016) - #15
Merged
Merged
Conversation
Replaces the spec 0003 stub with expiring certificates, inventory counts, the CA's own expiry, CRL freshness, service state and recent activity. The counts run the same filters the inventory runs, so a tile and the page it links to cannot disagree. The services section keeps /settings' role: a viewer must not learn configuration here that they are refused there.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements spec 0016. Stacked on #14 — review that one first; this PR's diff is only the dashboard.
Why
GET /has been a stub since spec 0003, which called it that in as many words. It showed the user's name, their role, and the cabin version — all three of which #14 moved into the navigation rail. Its entire remaining content was a warning that is only true in the first five minutes after installation.Meanwhile the question an internal CA actually gets asked was on no page: what is about to stop working? The inventory could answer it, but only if someone thought to filter by
status=expiring. Nothing surfaced the two expiries that take real work to fix — the intermediate's and the root's — and nothing said whether the published CRL was still inside its validity window.What it shows
cabin.ca.certs.status_counts()that reuses the same_filtersthe inventory uses, so a tile and the page behind it cannot disagree. A second expression of "what expiring means" is exactly the kind of duplicate that drifts.staleflag once that has passed. A stale CRL is the difference between clients seeing a revocation and clients silently trusting a revoked certificate./settings. The dashboard aggregates pages with different roles attached; it has to keep each one, or it becomes a way around authorisation.No new table, no background job, no new dependency. Every figure is read from what the database already holds, off one clock taken per request so counts, tags and "days remaining" on a single render cannot straddle a tick.
Two corrections made while implementing
The warning I specified could never fire. FR-6 originally called for an "enabled but no base URL" warning. Spec 0010 FR-5 and spec 0013 FR-4 already refuse to store that combination —
POST /settingsanswers 400. The warning would have been code that never runs, so it is gone; the spec now says why, and the test asserts the rejection instead, so that if that gate is ever relaxed the test says the warning is needed again.A tag class with no rule renders grey. The dashboard's "expires in 364 days" shipped colourless in my first pass: #14 renamed the tag rules to value names (
tag-expiring) while this view emitted role names (tag-warn), which no longer existed.assert "tag-warn" in pagepassed the whole time. Fixed by defining the role classes alongside the value classes, and bytest_every_rendered_tag_class_has_a_rule, which renders pages in states that actually reach every alarm tag — asserting first that the fixture produced them — and then checks each emitted class resolves to a rule or is on an explicit neutral list.Verification
make check: 491 passed, no skips. 15 new tests intests/test_web_dashboard.py.Both new tests were checked for sensitivity, not assumed: removing the
.tag-warnrule turns the tag test red, and an earlier version of it passed against the broken CSS because its fixture never reached a warning state — that version was thrown away rather than kept as reassurance.One fixture bug worth noting: my first
_inserthelper wrote microsecond-precisionnot_aftervalues. Real certificates are second-granular (X.509 has no sub-second validity), and at the exact 30-day boundary the string comparison flips on that difference. The helper now truncates, like a real certificate does.