Support compact Remote setup with reader-owned access selection
This commit is contained in:
1 parent
952d3c8204
commit
bf4a23645e
9 files changed
+274
-61
No files matched your search
@@ -105,56 +105,105 @@ func next_remote_form(t *testing.T, forms *consentTestForms) consentFormRequest
|
||||
func select_remote_relay(t *testing.T, forms *consentTestForms, address, role string) consentFormRequest {
|
||||
t.Helper()
|
||||
selection := next_remote_form(t, forms)
|
||||
if !strings.Contains(selection.form.Title, "Remote relay and role") || selection.form.Elements[0].ID != "cancel" {
|
||||
t.Fatal("missing safe endpoint/role selection")
|
||||
if selection.form.Title != "Remote" || selection.form.Elements[0].ID != "cancel" {
|
||||
t.Fatal("missing compact connection form")
|
||||
}
|
||||
// Required entry validation applies to every button in native forms. An
|
||||
// empty relay must not prevent the initially focused Cancel from working.
|
||||
selectionSession, _ := interaction.NewSession(selection.form)
|
||||
if effect := selectionSession.Handle(interaction.Event{Key: interaction.Enter}); effect.Activated != "cancel" {
|
||||
t.Fatal("empty relay entries blocked the Cancel button")
|
||||
t.Fatal("empty entries blocked Cancel")
|
||||
}
|
||||
host, port, err := net.SplitHostPort(address)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
for _, element := range selection.form.Elements {
|
||||
if element.ID == "channel-key" && (!element.Secret || element.Text != "") {
|
||||
t.Fatal("key unmasked or prefilled")
|
||||
}
|
||||
if element.Kind == interaction.CheckBox {
|
||||
t.Fatal("permissions duplicated")
|
||||
}
|
||||
}
|
||||
selection.reply <- internalUIResult{Activated: "review-access", Values: map[string]interaction.Value{"host": {Text: host}, "port": {Text: port}, "role": {Selected: role}}}
|
||||
consent := next_remote_form(t, forms)
|
||||
if !strings.Contains(consent.form.Title, "Remote access for remote") || consent.form.Elements[0].ID != "cancel" {
|
||||
t.Fatal("connection skipped reader-owned consent")
|
||||
selection.reply <- internalUIResult{Activated: "options", Values: map[string]interaction.Value{"host": {Text: address}, "role": {Selected: role}}}
|
||||
options := next_remote_form(t, forms)
|
||||
if options.form.Title != "Remote options" {
|
||||
t.Fatal("missing options")
|
||||
}
|
||||
return options
|
||||
}
|
||||
|
||||
func approve_remote_form(t *testing.T, forms *consentTestForms, consent consentFormRequest, role string) consentFormRequest {
|
||||
t.Helper()
|
||||
if !strings.Contains(consent.form.Title, "Remote access for remote") {
|
||||
t.Fatal("missing reader approval")
|
||||
}
|
||||
for _, element := range consent.form.Elements {
|
||||
if element.Checked {
|
||||
t.Fatal("permission preselected")
|
||||
}
|
||||
}
|
||||
return consent
|
||||
}
|
||||
|
||||
func approve_remote_form(t *testing.T, forms *consentTestForms, consent consentFormRequest, role string) consentFormRequest {
|
||||
t.Helper()
|
||||
grant := "remote-present"
|
||||
if role == "controlled" {
|
||||
grant = "output-observe"
|
||||
}
|
||||
consent.reply <- internalUIResult{Activated: "approve", Values: map[string]interaction.Value{grant: {Checked: true}}}
|
||||
credentials := next_remote_form(t, forms)
|
||||
if credentials.form.Title != "Connect Remote relay" {
|
||||
t.Fatal("approval did not reach connection controls", credentials.form.Title)
|
||||
progress := next_remote_form(t, forms)
|
||||
if progress.form.Title != "Connecting Remote" {
|
||||
t.Fatal("approval did not start connection", progress.form.Title)
|
||||
}
|
||||
for _, element := range credentials.form.Elements {
|
||||
if element.ID == "channel-key" && (!element.Secret || element.Text != "") {
|
||||
t.Fatal("unmasked or prefilled channel key")
|
||||
return progress
|
||||
}
|
||||
|
||||
func remote_consent_listener(t *testing.T) net.Listener {
|
||||
t.Helper()
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
template := &x509.Certificate{SerialNumber: big.NewInt(1), NotBefore: time.Now().Add(-time.Hour), NotAfter: time.Now().Add(time.Hour), KeyUsage: x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}}
|
||||
der, err := x509.CreateCertificate(rand.Reader, template, template, &key.PublicKey, key)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
listener, err := tls.Listen("tcp", "127.0.0.1:0", &tls.Config{Certificates: []tls.Certificate{{Certificate: [][]byte{der}, PrivateKey: key}}, MinVersion: tls.VersionTLS12})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(func() { listener.Close() })
|
||||
go func() {
|
||||
for {
|
||||
connection, err := listener.Accept()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
defer connection.Close()
|
||||
connection.SetDeadline(time.Now().Add(5 * time.Second))
|
||||
io.Copy(io.Discard, connection)
|
||||
}()
|
||||
}
|
||||
}()
|
||||
return listener
|
||||
}
|
||||
|
||||
func prepare_remote_consent(t *testing.T, forms *consentTestForms, address, role string) consentFormRequest {
|
||||
t.Helper()
|
||||
options := select_remote_relay(t, forms, address, role)
|
||||
options.reply <- internalUIResult{Activated: "inspect-certificate"}
|
||||
next_remote_form(t, forms) // Cancellable progress.
|
||||
review := next_remote_form(t, forms) // Poll replaces progress automatically.
|
||||
if review.form.Title != "Review Remote relay certificate" {
|
||||
t.Fatal("inspection did not advance")
|
||||
}
|
||||
return credentials
|
||||
review.reply <- internalUIResult{Activated: "trust-once"}
|
||||
options = next_remote_form(t, forms)
|
||||
options.reply <- internalUIResult{Activated: "connect", Values: map[string]interaction.Value{"channel-key": {Text: "synthetic-fixture"}}}
|
||||
next_remote_form(t, forms) // Verified preflight; no lease/key sent.
|
||||
return next_remote_form(t, forms)
|
||||
}
|
||||
|
||||
func TestRemoteConnectionCommandConsentDenialAndPolicyCancellation(t *testing.T) {
|
||||
for _, mode := range []string{"deny", "empty", "lock", "handoff"} {
|
||||
t.Run(mode, func(t *testing.T) {
|
||||
runtime, forms, command := remote_command_fixture(t)
|
||||
consent := select_remote_relay(t, forms, "127.0.0.1:6837", "controller")
|
||||
listener := remote_consent_listener(t)
|
||||
consent := prepare_remote_consent(t, forms, listener.Addr().String(), "controller")
|
||||
switch mode {
|
||||
case "deny":
|
||||
consent.reply <- internalUIResult{Cancelled: true}
|
||||
@@ -174,7 +223,7 @@ func TestRemoteConnectionCommandConsentDenialAndPolicyCancellation(t *testing.T)
|
||||
// keeping an awaiting flag or reviving the previous approval.
|
||||
runtime.Invoke(t.Context(), command)
|
||||
form := next_remote_form(t, forms)
|
||||
if !strings.Contains(form.form.Title, "Remote relay and role") {
|
||||
if form.form.Title != "Remote" {
|
||||
t.Fatal("stale setup survived cancellation")
|
||||
}
|
||||
form.reply <- internalUIResult{Cancelled: true}
|
||||
@@ -203,8 +252,7 @@ func TestRemoteConnectionCommandCancelsInspectionOnHandoff(t *testing.T) {
|
||||
close(closed)
|
||||
}()
|
||||
runtime, forms, _ := remote_command_fixture(t)
|
||||
consent := select_remote_relay(t, forms, listener.Addr().String(), "controller")
|
||||
credentials := approve_remote_form(t, forms, consent, "controller")
|
||||
credentials := select_remote_relay(t, forms, listener.Addr().String(), "controller")
|
||||
credentials.reply <- internalUIResult{Activated: "inspect-certificate"}
|
||||
inspection := next_remote_form(t, forms)
|
||||
select {
|
||||
@@ -276,6 +324,16 @@ func TestRemoteConnectionCommandPrivateRelay(t *testing.T) {
|
||||
t.Error("certificate inspection sent application data")
|
||||
}
|
||||
close(probed)
|
||||
preflight, err := listener.Accept()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
preflight.SetDeadline(time.Now().Add(5 * time.Second))
|
||||
preflightData, _ := io.ReadAll(preflight)
|
||||
preflight.Close()
|
||||
if len(preflightData) != 0 {
|
||||
t.Error("preflight sent application data before approval")
|
||||
}
|
||||
connection, err := listener.Accept()
|
||||
if err != nil {
|
||||
return
|
||||
@@ -382,8 +440,7 @@ func TestRemoteConnectionCommandPrivateRelay(t *testing.T) {
|
||||
t.Fatal("Remote fixture session unavailable")
|
||||
}
|
||||
}
|
||||
consent := select_remote_relay(t, forms, listener.Addr().String(), role)
|
||||
credentials := approve_remote_form(t, forms, consent, role)
|
||||
credentials := select_remote_relay(t, forms, listener.Addr().String(), role)
|
||||
credentials.reply <- internalUIResult{Activated: "inspect-certificate"}
|
||||
inspection := next_remote_form(t, forms)
|
||||
select {
|
||||
@@ -391,29 +448,49 @@ func TestRemoteConnectionCommandPrivateRelay(t *testing.T) {
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Fatal("certificate probe did not finish")
|
||||
}
|
||||
for inspection.form.Title != "Review Remote relay certificate" {
|
||||
inspection.reply <- internalUIResult{Activated: "refresh"}
|
||||
inspection = next_remote_form(t, forms)
|
||||
inspection = next_remote_form(t, forms)
|
||||
if inspection.form.Title != "Review Remote relay certificate" {
|
||||
t.Fatal("certificate result was not automatic")
|
||||
}
|
||||
inspection.reply <- internalUIResult{Activated: "trust-once"}
|
||||
credentials = next_remote_form(t, forms)
|
||||
credentials.reply <- internalUIResult{Activated: "connect", Values: map[string]interaction.Value{"channel-key": {Text: "synthetic-fixture"}}}
|
||||
status := next_remote_form(t, forms)
|
||||
next_remote_form(t, forms) // Verified certificate progress.
|
||||
consent := next_remote_form(t, forms)
|
||||
status := approve_remote_form(t, forms, consent, role)
|
||||
select {
|
||||
case <-joined:
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Fatal("Remote did not join the private relay")
|
||||
}
|
||||
if status.form.Title != "Remote relay status" {
|
||||
t.Fatal("missing connection status")
|
||||
if status.form.Title != "Connecting Remote" {
|
||||
t.Fatal("missing connecting form")
|
||||
}
|
||||
// Open has already succeeded before the relay can join. Return to
|
||||
// ordinary desktop work without holding either runtime slot or form.
|
||||
status.reply <- internalUIResult{Activated: "desktop"}
|
||||
// Poll returns to the desktop after the verified join.
|
||||
waitTentacle(t, func() bool { return len(runtime.resultSlots) == 0 && len(runtime.interactionSlots) == 0 })
|
||||
if status.ctx.Err() == nil {
|
||||
t.Fatal("background connection retained its form context")
|
||||
}
|
||||
for _, closeMode := range []string{"close", "escape"} {
|
||||
runtime.Invoke(t.Context(), shortcut)
|
||||
reopened := next_remote_form(t, forms)
|
||||
if reopened.form.Title != "Remote status" {
|
||||
t.Fatal("status reopening requested new consent")
|
||||
}
|
||||
reply := internalUIResult{Activated: "desktop"}
|
||||
if closeMode == "escape" {
|
||||
reply = internalUIResult{Cancelled: true}
|
||||
}
|
||||
reopened.reply <- reply
|
||||
waitTentacle(t, func() bool { return len(runtime.resultSlots) == 0 && len(runtime.interactionSlots) == 0 })
|
||||
select {
|
||||
case <-closed:
|
||||
t.Fatal(closeMode + " disconnected the live lease")
|
||||
default:
|
||||
}
|
||||
}
|
||||
if test.playback {
|
||||
waitTentacle(t, func() bool {
|
||||
worker := runtime.output.speech
|
||||
@@ -434,7 +511,7 @@ func TestRemoteConnectionCommandPrivateRelay(t *testing.T) {
|
||||
// mailbox owner remain usable for an explicit new connection.
|
||||
runtime.Invoke(t.Context(), shortcut)
|
||||
selection := next_remote_form(t, forms)
|
||||
if selection.form.Title == "Remote relay status" {
|
||||
if selection.form.Title == "Remote status" {
|
||||
// An ended attempt remains inspectable until explicitly
|
||||
// closed, as with ordinary transport failure.
|
||||
selection.reply <- internalUIResult{Activated: "cancel"}
|
||||
@@ -442,7 +519,7 @@ func TestRemoteConnectionCommandPrivateRelay(t *testing.T) {
|
||||
runtime.Invoke(t.Context(), shortcut)
|
||||
selection = next_remote_form(t, forms)
|
||||
}
|
||||
if !strings.Contains(selection.form.Title, "Remote relay and role") {
|
||||
if selection.form.Title != "Remote" {
|
||||
t.Fatal("backend failure retained a connected workflow")
|
||||
}
|
||||
selection.reply <- internalUIResult{Cancelled: true}
|
||||
@@ -522,7 +599,7 @@ func TestRemoteConnectionCommandPrivateRelay(t *testing.T) {
|
||||
deadline := time.Now().Add(5 * time.Second)
|
||||
for {
|
||||
encoded, _ := json.Marshal(status.form)
|
||||
if strings.Contains(string(encoded), "One opposite-role peer has joined") {
|
||||
if strings.Contains(string(encoded), "Connected to the other computer.") {
|
||||
break
|
||||
}
|
||||
if time.Now().After(deadline) {
|
||||
@@ -660,10 +737,10 @@ func TestRemoteConnectionCommandPrivateRelay(t *testing.T) {
|
||||
case "disconnect":
|
||||
runtime.Invoke(t.Context(), shortcut)
|
||||
status = next_remote_form(t, forms)
|
||||
if status.form.Title != "Remote relay status" {
|
||||
if status.form.Title != "Remote status" {
|
||||
t.Fatal("reopening lost the approved connection")
|
||||
}
|
||||
status.reply <- internalUIResult{Activated: "cancel"}
|
||||
status.reply <- internalUIResult{Activated: "disconnect"}
|
||||
case "lock":
|
||||
runtime.output.gate.SetLocked(true, nil, nil, nil, nil, &brailleWorker{})
|
||||
runtime.output.gate.SetLocked(false, nil, nil, nil, nil, &brailleWorker{})
|
||||
|
||||
Reference in new issue
Block a user