Merge pull request 'A machine joins through the tunnel: a token issued for its tunnel key (hq ADR 0169)' (#132) from feat/a-machine-joins-through-the-tunnel into main
This commit was merged in pull request #132.
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
-- A token issued for a tunnel key (novox/hq ADR 0169).
|
||||
--
|
||||
-- A machine that joins through the tunnel makes its key first, and the token is issued for it: the
|
||||
-- hub is told the key before the token is shown. So enrolment must take that key and no other — a
|
||||
-- different one is a machine the hub does not know, offering a tunnel that would never answer. Null
|
||||
-- for a token issued without one, which enrols as before.
|
||||
alter table enrolment_token add column overlay_key text;
|
||||
@@ -361,6 +361,33 @@ func (i *Inventory) Claim(ctx context.Context, secret, by string, again bool) (N
|
||||
return scanNode(i.store.Pool().QueryRow(ctx, `select `+nodeColumns+` from node where id = $1`, id))
|
||||
}
|
||||
|
||||
// BindTokenToKey records the tunnel key a node's live token was issued for (novox/hq ADR 0169), so
|
||||
// enrolment takes that key and no other. Refused when the node has no live token to bind: a key
|
||||
// recorded against nothing would be a promise nothing keeps.
|
||||
func (i *Inventory) BindTokenToKey(ctx context.Context, node, key string) error {
|
||||
tag, err := i.store.Pool().Exec(ctx,
|
||||
`update enrolment_token set overlay_key = $2
|
||||
where node = $1 and redeemed is null and expires > now()`, node, key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if tag.RowsAffected() == 0 {
|
||||
return fmt.Errorf("no live token to issue for the tunnel key")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TokenKey is the tunnel key a token was issued for, or empty when it was issued without one.
|
||||
func (i *Inventory) TokenKey(ctx context.Context, secret string) (string, error) {
|
||||
var key *string
|
||||
err := i.store.Pool().QueryRow(ctx,
|
||||
`select overlay_key from enrolment_token where secret = $1`, hashSecret(secret)).Scan(&key)
|
||||
if err != nil || key == nil {
|
||||
return "", err
|
||||
}
|
||||
return *key, nil
|
||||
}
|
||||
|
||||
// Spend makes a claimed token used, only for the presenter holding the claim. The last write to the
|
||||
// store in an enrolment, so a token is spent exactly when the node it enrolled is complete. Spent
|
||||
// again by the same presenter is not an error: an answer lost after the first spend.
|
||||
|
||||
Reference in New Issue
Block a user