Fixes Env Vars to pass config to ssh-chat.

The env vars were beign parsed and set to the host
before the user was even added to the host and
hence ignored. This change moves the env var parsing
to after initializing the user.

TODO: tests, completeness+reliability
This commit is contained in:
Akshay 2021-05-01 09:41:25 -07:00
parent 46eaf037e3
commit f8f8d1f3cf
2 changed files with 87 additions and 27 deletions

53
host.go
View File

@ -114,32 +114,6 @@ func (h *Host) Connect(term *sshd.Terminal) {
}
user.SetConfig(cfg)
// Load user config overrides from ENV
// TODO: Would be nice to skip the command parsing pipeline just to load
// config values. Would need to factor out some command handler logic into
// accessible helpers.
env := term.Env()
for _, e := range env {
switch e.Key {
case "SSHCHAT_TIMESTAMP":
if e.Value != "" && e.Value != "0" {
cmd := "/timestamp"
if e.Value != "1" {
cmd += " " + e.Value
}
if msg, ok := message.NewPublicMsg(cmd, user).ParseCommand(); ok {
h.Room.HandleMsg(msg)
}
}
case "SSHCHAT_THEME":
cmd := "/theme " + e.Value
if msg, ok := message.NewPublicMsg(cmd, user).ParseCommand(); ok {
h.Room.HandleMsg(msg)
}
}
}
go user.Consume()
// Close term once user is closed.
@ -168,6 +142,33 @@ func (h *Host) Connect(term *sshd.Terminal) {
return
}
// Load user config overrides from ENV
// TODO: Would be nice to skip the command parsing pipeline just to load
// config values. Would need to factor out some command handler logic into
// accessible helpers.
env := term.Env()
for _, e := range env {
switch e.Key {
case "SSHCHAT_TIMESTAMP":
if e.Value != "" && e.Value != "0" {
fmt.Println("got timestamp", e.Value)
cmd := "/timestamp"
if e.Value != "1" {
cmd += " " + e.Value
}
if msg, ok := message.NewPublicMsg(cmd, user).ParseCommand(); ok {
fmt.Println("sending command to server:", cmd)
h.Room.HandleMsg(msg)
}
}
case "SSHCHAT_THEME":
cmd := "/theme " + e.Value
if msg, ok := message.NewPublicMsg(cmd, user).ParseCommand(); ok {
h.Room.HandleMsg(msg)
}
}
}
// Successfully joined.
if !apiMode {
term.SetPrompt(GetPrompt(user))

View File

@ -78,7 +78,7 @@ func TestHostGetPrompt(t *testing.T) {
func TestHostNameCollision(t *testing.T) {
t.Skip("Test is flakey on CI. :(")
key, err := sshd.NewRandomSigner(512)
if err != nil {
t.Fatal(err)
@ -284,3 +284,62 @@ func TestHostKick(t *testing.T) {
t.Error(err)
}
}
func TestClientEnvConfig(t *testing.T) {
key, err := sshd.NewRandomSigner(512)
if err != nil {
t.Fatal(err)
}
config := sshd.MakeNoAuth()
config.AddHostKey(key)
s, err := sshd.ListenSSH("localhost:0", config)
if err != nil {
t.Fatal(err)
}
defer s.Close()
host := NewHost(s, nil)
go host.Serve()
clientConfig := sshd.NewClientConfig("dingus")
conn, err := ssh.Dial("tcp", s.Addr().String(), clientConfig)
if err != nil {
t.Error(err)
}
defer conn.Close()
session, err := conn.NewSession()
if err != nil {
t.Error(err)
}
defer session.Close()
session.Setenv("SSHCHAT_TIMESTAMP", "datetime +8h")
stdout, err := session.StdoutPipe()
if err != nil {
t.Error(err)
}
err = session.Shell()
if err != nil {
t.Error(err)
}
// consume
bufio.NewScanner(stdout).Scan()
// this fails occasionally because the user has not been registered by the server yet
// add some kind of wait/synchornization mechanism
u, ok := host.GetUser("dingus")
if !ok {
t.Fatal("test user not found in host: ", host.Members)
}
userConfig := u.Config()
// add cases
// /timestamp datetime => 2006-01-02 15:04:05
// /timestamp time => 15:04
if userConfig.Timeformat != nil && *userConfig.Timeformat != "2006-01-02 15:04:05" {
t.Fatal("unexpected timeformat:", *userConfig.Timeformat)
}
}