package cli import ( "path/filepath" "reflect" "strings" "testing" "debtik/internal/aerotun" "debtik/internal/auth" "debtik/internal/vpn" ) func TestQuotedCommandArguments(t *testing.T) { got, err := splitCommand(`/interface aerotun set test comment="office uplink" psk='literal $\\key' name=""`) want := []string{"/interface", "aerotun", "set", "test", "comment=office uplink", `psk=literal $\\key`, "name="} if err != nil || !reflect.DeepEqual(got, want) { t.Fatalf("%q %v", got, err) } if _, err := splitCommand(`comment="unfinished`); err == nil { t.Fatal("accepted unterminated quote") } } func TestBareLogAndHandlerRecovery(t *testing.T) { e := &Executor{} user := &auth.PublicUser{Role: auth.RoleFull} output, _ := e.Execute("/log", user) if commandExitStatus(output) != 0 { t.Fatal(output) } output, _ = e.Execute("/interface print", user) // absent manager simulates a handler failure if commandExitStatus(output) == 0 || !strings.Contains(output, "still running") { t.Fatal(output) } output, _ = e.Execute("nonsense", user) if commandExitStatus(output) == 0 { t.Fatal("unknown command returned success") } output, _ = e.Execute("/help", user) if commandExitStatus(output) != 0 { t.Fatal("help returned failure") } } func TestAeroTUNCLIConfigurationAndPermissions(t *testing.T) { m := aerotun.NewManagerWithPath(filepath.Join(t.TempDir(), "aerotun.json")) defer m.StopAll() e := &Executor{vpnMgr: &vpn.Manager{AeroTUN: m}} admin := &auth.PublicUser{Role: auth.RoleFull} psk := strings.Repeat("12", 32) command := `/interface aerotun add name=atest mode=server local-address=10.90.0.1/30 peer-address=10.90.0.2/32 allowed-ips=10.90.0.2/32 psk=` + psk + ` comment="office uplink"` output, _ := e.Execute(command, admin) if commandExitStatus(output) != 0 { t.Fatal(output) } inst := m.List()[0] if !inst.Disabled || inst.PublicKey == "" || inst.Comment != "office uplink" { t.Fatal("draft configuration not retained") } for _, role := range []auth.Role{auth.RoleRead, auth.RoleWrite} { output, _ = e.Execute("/interface aerotun remove atest", &auth.PublicUser{Role: role}) if commandExitStatus(output) == 0 { t.Fatal("non-admin removed tunnel") } } output, _ = e.Execute("/interface aerotun print detail=yes", admin) if strings.Contains(output, psk) || strings.Contains(output, inst.PrivateKey) || !strings.Contains(output, inst.PublicKey) { t.Fatal("secret disclosure or missing public identity") } output, _ = e.Execute(`/interface aerotun set atest comment="updated uplink"`, admin) if commandExitStatus(output) != 0 { t.Fatal(output) } updated, _ := m.Get(inst.ID) if updated.PSK != psk || updated.PublicKey != inst.PublicKey { t.Fatal("edit changed identity") } output, _ = e.Execute("/interface aerotun remove atest", admin) if commandExitStatus(output) != 0 || len(m.List()) != 0 { t.Fatal(output) } }