Spend 0030's password on one writer, and refuse an answer with a fact missing - #260
Merged
Merged
Conversation
… missing 0030 decides that the password exists between the caller handing it over and the request carrying it being written, that the route adds no error vocabulary of its own, and that no branch of it returns a session with a field missing. None of that was in the tree. `src/session/password.rs` holds the part a type and a closure over three values settle. The password is neither `Copy` nor `Clone`, has no accessor and no printable form, and `present` takes it by move, so the three shapes 0030 names as the ones that keep a credential alive - a credentials object held for a retry, a field on the session for a renewal, a parameter threaded through a helper so a test can sign in twice - are refused by the compiler rather than by a review. It performs no scrub and claims none: 0030 takes a plain string and states that residual, and this states it in the same words. `what_the_answer_yields` is 0004's closure rule at this door. A body that parsed and omitted the token, the account identifier or the validity statement is `answer-not-understood` at the answer body, and the facts a session needs are a type whose three members are all present, so an incomplete session has nothing to be returned in. A value that arrived empty is read as one that did not arrive, which is this module's reading rather than a sentence in 0030 and says so where it is made. `Failure::from_status_with_no_token_presented` is the third half, in the module 0037 fixes as the one mapping point rather than beside the route. It moves the 401 payload alone and leaves every other row of the table as `from_status` reads it. The comment inside that function said no caller knew whether a token had been presented and that the flag was the honest half until one existed; a caller exists now, and the comment says what the default is for instead. What this prevents is a wrong payload three calls from where it was produced: a sign-in reporting a refused credential as a token presented and rejected is read by 0034 as a session that has ended, which answers a person's mistyped password with a renewal for a session that was never established. #30 stays open. Its condition is a sign-in against the fake server in #21, and the transport that would carry one is #27. Signed-off-by: Nils Lehnen <30603423+iderex@users.noreply.github.com>
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.
The issue this belongs to
#30. This does not close it, and the reason is at the end.
What changed
src/session/password.rsholds the part of 0030 a type and a closure over threevalues settle.
The password is a value with no accessor, no copy and no printable form.
Password::presenttakes it by move and hands a borrow to one writer, so thethree shapes 0030 names as the ones that keep a credential alive past its
request - a credentials object held so a retry is easy, a field on the session so
a renewal can re-authenticate, a parameter threaded through a helper so a test
can sign in twice - do not compile. It performs no scrub and claims none: 0030
takes a plain string and states what the runtime leaves behind as a real cost and
an unmeasurable one, and the module states the same thing in the place a reader
would look for a promise.
The account name is the opposite case beside it, kept exactly as it was typed,
for the reason 0028 refuses to repair an address.
what_the_answer_yieldsis 0004's closure rule at this door. A body that parsedand omitted the token, the account identifier or the validity statement is
answer-not-understoodat the answer body expecting a field the core needs, andthe success side is a type whose three members are all present, so a branch that
wanted to return a session with a hole in it has nothing to return it in. A value
that arrived empty is read as one that did not arrive; that is this module's
reading rather than a sentence in 0030 and it is written as one, with the
argument for it, on the function that makes it.
Failure::from_status_with_no_token_presentedis the third thing 0030 decides,and it is in
src/failure/mod.rsrather than beside the route because 0037 fixesone mapping point for every value of the vocabulary. It moves the 401 payload
alone and is
from_statusunchanged for every other row.No field name of any server appears anywhere in the change. What a body calls
these three is read where the body is read, which is #27, and a name written here
today would be a claim about an interface nobody has read - the same reason
tests/fake_server/surface.rsgives for the bodies it answers with.What failure it prevents
A wrong payload three calls away from where it was produced.
from_statusmappedevery 401 as a token presented and rejected, because the status does not carry
the difference and no caller existed that knew it. 0034 reads that payload as a
session that has ended and starts a renewal; the same payload out of a sign-in
would answer a mistyped password with a renewal for a session that was never
established, and
not-authenticatedwith no token presented is exactly thedistinction #34 and #35 branch on.
Beside it, the lifetime. 0030's own argument is that none of the three shapes
looks wrong in review, because the wrongness is the lifetime rather than the line
and a lifetime is not visible at a call site. This is that argument taken to the
type, so the first sign-in call written against #27 cannot take any of the three
without the build refusing it.
This is a failure that could happen rather than one that has: there is no sign-in
call in this tree to have got it wrong yet, which is the point of writing the
constraint before the caller.
Evidence
Every command run at
3c983246029d4cf4f54399c88ef1d70d08b7052e, the head beingpushed.
The legs of the gate this machine can run, each by its own script and each by its
own exit code:
The analyser was also run directly, with the groups the
lintcheck denies:What a guard here refuses, and the proof it bites
The password cannot be read twice, and the near miss is a compile failure
rather than a red line. That is stated plainly rather than dressed as a test
result:
Passwordis neitherCopynorCloneandpresenttakesself, sothe violation reddens the build and not a case. The violation and the run:
Without that line the same run is the green one pasted above.
The 401 payload at this door is the other one, and the near miss is the door
that reports a refused credential as a token presented. Putting the default
back is the deliberate violation:
An answer missing one of the three yields no session. Taking the token check
out is the violation:
The three that go red are the three that ask the question. Each violation above
was applied to the working tree, run, and reverted; the tree pushed is the one
the green runs at the top of this section were taken from.
What this does not cover
#30's own condition is untouched and this does not close it. The condition is
a sign-in against the fake server in #21 with each of three failures a distinct
named kind, and the transport that would carry one is #27, which is not built.
Nothing here sends or receives a byte. The reading already on the issue about the
grep half of that condition is not restated in this body.
No scrub, and no claim of one. Nothing here erases the bytes of a password.
What a heap page, a core dump or a suspended process holds afterwards is outside
everything in this change, and 0030's own alternatives section is where that
residual was accepted.
The coverage leg was not judged on this machine, and what it reports is not
this change's. It reports the same on an unmodified checkout of the default
branch:
The instrumentation reads zero lines for every area here,
src/included, so thenumber is absent rather than low, and it is absent before the change as well as
after it.
.github/workflows/coverage.ymlruns on this pull request and is whatjudges it. The pinned-surface register carries the new module with its reason, so
the surface is declared rather than left for a run to find missing.
Three other legs were not run here.
headlessneeds a program this machinedoes not carry (
ip: command not found),thread-detectorneeds a nightlycompiler this tree deliberately does not pin, and
mutationis weekly ratherthan a pull-request leg. None of the three was skipped by editing anything; they
were not run, and the workflows are what run them.
Nothing was run against a real server, and nothing in this change has a real
server in its subject.
Who has read it
Nobody but me has read this change. There is no second reader on this board
tonight, and the evidence above stands in place of one rather than the question
being left open.