Tentacle support enhancements.
This commit is contained in:
1 parent
4cf3335017
commit
24261edb3d
12 files changed
+560
-30
No files matched your search
@@ -25,6 +25,14 @@ type Interaction struct {
|
||||
Clipboard *string `json:"clipboard,omitempty"`
|
||||
Done bool `json:"done,omitempty"`
|
||||
Reader *ReaderRequest `json:"reader,omitempty"`
|
||||
Remote *RemoteRequest `json:"remote,omitempty"`
|
||||
}
|
||||
|
||||
// RemoteRequest asks the reader to show its own local consent form. It never
|
||||
// grants access by itself and can target only the requesting process session.
|
||||
type RemoteRequest struct {
|
||||
Role string `json:"role"`
|
||||
Grants []string `json:"grants"`
|
||||
}
|
||||
|
||||
type Submission struct {
|
||||
@@ -34,6 +42,7 @@ type Submission struct {
|
||||
Item *Item `json:"item,omitempty"`
|
||||
Error string `json:"error,omitempty"`
|
||||
Reader *ReaderState `json:"reader,omitempty"`
|
||||
Remote *SessionEvent `json:"remote,omitempty"`
|
||||
}
|
||||
|
||||
// Item is a single copied value, without accessible identities or native handles.
|
||||
@@ -71,7 +80,11 @@ func DecodeInteraction(data []byte) (Interaction, error) {
|
||||
if value.Source != "" && value.Source != "focus" && value.Source != "clipboard" {
|
||||
return value, ErrProtocol
|
||||
}
|
||||
if value.Reader != nil {
|
||||
if value.Remote != nil {
|
||||
if !ValidRoleGrants(value.Remote.Role, value.Remote.Grants) || value.Next == "" || value.Reader != nil || value.Form != nil || value.Source != "" || value.Poll != "" || value.Clipboard != nil || value.Done {
|
||||
return value, ErrProtocol
|
||||
}
|
||||
} else if value.Reader != nil {
|
||||
if ValidateReaderRequest(*value.Reader) != nil || value.Form != nil || value.Source != "" || value.Poll != "" || value.Clipboard != nil || value.Done || value.Reader.Snapshot && value.Next == "" {
|
||||
return value, ErrProtocol
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package tentaclewire
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRemoteConsentInteractionValidation(t *testing.T) {
|
||||
valid := Interaction{Remote: &RemoteRequest{Role: "controller", Grants: []string{"remote-present"}}, Next: "approved"}
|
||||
data, _ := json.Marshal(valid)
|
||||
if _, err := DecodeInteraction(data); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, raw := range []string{
|
||||
`{"remote":null,"next":"approved"}`,
|
||||
`{"remote":{"role":"controller","grants":["remote-present"]}}`,
|
||||
`{"remote":{"role":"controller","grants":["keyboard-inject"]},"next":"approved"}`,
|
||||
`{"remote":{"role":"controlled","grants":[]},"next":"approved"}`,
|
||||
`{"remote":{"role":"controlled","grants":["output-observe","output-observe"]},"next":"approved"}`,
|
||||
`{"remote":{"role":"controlled","grants":["output-observe"],"session":"other"},"next":"approved"}`,
|
||||
} {
|
||||
if _, err := DecodeInteraction([]byte(raw)); err == nil {
|
||||
t.Fatal("invalid remote interaction accepted", raw)
|
||||
}
|
||||
}
|
||||
for _, field := range []string{`"clipboard":"text"`, `"source":"clipboard"`, `"done":true`, `"poll":"poll"`, `"reader":{"snapshot":true}`} {
|
||||
raw := `{"remote":{"role":"controller","grants":["remote-present"]},"next":"approved",` + field + `}`
|
||||
if _, err := DecodeInteraction([]byte(raw)); err == nil {
|
||||
t.Fatal("remote consent mixed with another effect", field)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user