tests: All passing again

This commit is contained in:
Andrey Petrov 2016-09-13 21:51:27 -04:00
parent 0096404142
commit 3ef404198d
5 changed files with 43 additions and 31 deletions

View File

@ -25,19 +25,21 @@ func BufferedScreen(name string, screen io.WriteCloser) *bufferedScreen {
func PipedScreen(name string, screen io.WriteCloser) *pipedScreen { func PipedScreen(name string, screen io.WriteCloser) *pipedScreen {
return &pipedScreen{ return &pipedScreen{
baseScreen: &baseScreen{ baseScreen: Screen(name),
User: NewUser(name),
},
WriteCloser: screen, WriteCloser: screen,
} }
} }
func HandledScreen(name string, handler func(Message) error) *handledScreen { func HandledScreen(name string, handler func(Message) error) *handledScreen {
return &handledScreen{ return &handledScreen{
baseScreen: &baseScreen{ baseScreen: Screen(name),
User: NewUser(name), handler: handler,
}, }
handler: handler, }
func Screen(name string) *baseScreen {
return &baseScreen{
User: NewUser(name),
} }
} }

View File

@ -3,13 +3,19 @@ package sshchat
import ( import (
"time" "time"
"github.com/shazow/ssh-chat/chat"
"github.com/shazow/ssh-chat/chat/message" "github.com/shazow/ssh-chat/chat/message"
"github.com/shazow/ssh-chat/sshd" "github.com/shazow/ssh-chat/sshd"
) )
type Client struct { type Client struct {
user *message.User user chat.Member
conn sshd.Connection conn sshd.Connection
timestamp time.Time timestamp time.Time
} }
type Replier interface {
ReplyTo() message.Author
SetReplyTo(message.Author)
}

37
host.go
View File

@ -35,7 +35,7 @@ type Host struct {
mu sync.Mutex mu sync.Mutex
motd string motd string
count int count int
clients map[*message.User][]Client clients map[chat.Member][]Client
} }
// NewHost creates a Host on top of an existing listener. // NewHost creates a Host on top of an existing listener.
@ -46,7 +46,7 @@ func NewHost(listener *sshd.SSHListener, auth *Auth) *Host {
listener: listener, listener: listener,
commands: chat.Commands{}, commands: chat.Commands{},
auth: auth, auth: auth,
clients: map[*message.User][]Client{}, clients: map[chat.Member][]Client{},
} }
// Make our own commands registry instance. // Make our own commands registry instance.
@ -75,7 +75,7 @@ func (h *Host) SetMotd(motd string) {
// Connect a specific Terminal to this host and its room. // Connect a specific Terminal to this host and its room.
func (h *Host) Connect(term *sshd.Terminal) { func (h *Host) Connect(term *sshd.Terminal) {
requestedName := term.Conn.Name() requestedName := term.Conn.Name()
user := message.NewScreen(requestedName, term) user := message.BufferedScreen(requestedName, term)
client := h.addClient(user, term.Conn) client := h.addClient(user, term.Conn)
defer h.removeClient(user, client) defer h.removeClient(user, client)
@ -180,7 +180,7 @@ func (h *Host) Connect(term *sshd.Terminal) {
logger.Debugf("[%s] Leaving: %s", term.Conn.RemoteAddr(), user.Name()) logger.Debugf("[%s] Leaving: %s", term.Conn.RemoteAddr(), user.Name())
} }
func (h *Host) addClient(user *message.User, conn sshd.Connection) *Client { func (h *Host) addClient(user chat.Member, conn sshd.Connection) *Client {
client := Client{ client := Client{
user: user, user: user,
conn: conn, conn: conn,
@ -195,7 +195,7 @@ func (h *Host) addClient(user *message.User, conn sshd.Connection) *Client {
return &client return &client
} }
func (h *Host) removeClient(user *message.User, client *Client) { func (h *Host) removeClient(user chat.Member, client *Client) {
h.mu.Lock() h.mu.Lock()
defer h.mu.Unlock() defer h.mu.Unlock()
@ -212,7 +212,7 @@ func (h *Host) removeClient(user *message.User, client *Client) {
} }
} }
func (h *Host) findClients(user *message.User) []Client { func (h *Host) findClients(user chat.Member) []Client {
h.mu.Lock() h.mu.Lock()
defer h.mu.Unlock() defer h.mu.Unlock()
return h.clients[user] return h.clients[user]
@ -244,7 +244,7 @@ func (h *Host) completeCommand(partial string) string {
} }
// AutoCompleteFunction returns a callback for terminal autocompletion // AutoCompleteFunction returns a callback for terminal autocompletion
func (h *Host) AutoCompleteFunction(u *message.User) func(line string, pos int, key rune) (newLine string, newPos int, ok bool) { func (h *Host) AutoCompleteFunction(u Replier) func(line string, pos int, key rune) (newLine string, newPos int, ok bool) {
return func(line string, pos int, key rune) (newLine string, newPos int, ok bool) { return func(line string, pos int, key rune) (newLine string, newPos int, ok bool) {
if key != 9 { if key != 9 {
return return
@ -301,13 +301,12 @@ func (h *Host) AutoCompleteFunction(u *message.User) func(line string, pos int,
} }
// GetUser returns a message.User based on a name. // GetUser returns a message.User based on a name.
func (h *Host) GetUser(name string) (*message.User, bool) { func (h *Host) GetUser(name string) (chat.Member, bool) {
m, ok := h.MemberByID(name) m, ok := h.MemberByID(name)
if !ok { if !ok {
return nil, false return nil, false
} }
u, ok := m.Member.(*message.User) return m.Member, true
return u, ok
} }
// InitCommands adds host-specific commands to a Commands container. These will // InitCommands adds host-specific commands to a Commands container. These will
@ -337,7 +336,7 @@ func (h *Host) InitCommands(c *chat.Commands) {
txt := fmt.Sprintf("[Sent PM to %s]", target.Name()) txt := fmt.Sprintf("[Sent PM to %s]", target.Name())
ms := message.NewSystemMsg(txt, msg.From()) ms := message.NewSystemMsg(txt, msg.From())
room.Send(ms) room.Send(ms)
target.SetReplyTo(msg.From()) target.(Replier).SetReplyTo(msg.From())
return nil return nil
}, },
}) })
@ -353,7 +352,7 @@ func (h *Host) InitCommands(c *chat.Commands) {
return errors.New("must specify message") return errors.New("must specify message")
} }
target := msg.From().ReplyTo() target := msg.From().(Replier).ReplyTo()
if target == nil { if target == nil {
return errors.New("no message to reply to") return errors.New("no message to reply to")
} }
@ -392,7 +391,7 @@ func (h *Host) InitCommands(c *chat.Commands) {
// FIXME: Handle many clients // FIXME: Handle many clients
clients := h.findClients(target) clients := h.findClients(target)
var whois string var whois string
switch room.IsOp(msg.From()) { switch room.IsOp(msg.From().(chat.Member)) {
case true: case true:
whois = whoisAdmin(clients) whois = whoisAdmin(clients)
case false: case false:
@ -428,7 +427,7 @@ func (h *Host) InitCommands(c *chat.Commands) {
PrefixHelp: "USER [DURATION]", PrefixHelp: "USER [DURATION]",
Help: "Set USER as admin.", Help: "Set USER as admin.",
Handler: func(room *chat.Room, msg message.CommandMsg) error { Handler: func(room *chat.Room, msg message.CommandMsg) error {
if !room.IsOp(msg.From()) { if !room.IsOp(msg.From().(chat.Member)) {
return errors.New("must be op") return errors.New("must be op")
} }
@ -471,7 +470,7 @@ func (h *Host) InitCommands(c *chat.Commands) {
Help: "Ban USER from the server.", Help: "Ban USER from the server.",
Handler: func(room *chat.Room, msg message.CommandMsg) error { Handler: func(room *chat.Room, msg message.CommandMsg) error {
// TODO: Would be nice to specify what to ban. Key? Ip? etc. // TODO: Would be nice to specify what to ban. Key? Ip? etc.
if !room.IsOp(msg.From()) { if !room.IsOp(msg.From().(chat.Member)) {
return errors.New("must be op") return errors.New("must be op")
} }
@ -498,7 +497,7 @@ func (h *Host) InitCommands(c *chat.Commands) {
body := fmt.Sprintf("%s was banned by %s.", target.Name(), msg.From().Name()) body := fmt.Sprintf("%s was banned by %s.", target.Name(), msg.From().Name())
room.Send(message.NewAnnounceMsg(body)) room.Send(message.NewAnnounceMsg(body))
target.Close() target.(io.Closer).Close()
logger.Debugf("Banned: \n-> %s", whoisAdmin(clients)) logger.Debugf("Banned: \n-> %s", whoisAdmin(clients))
@ -512,7 +511,7 @@ func (h *Host) InitCommands(c *chat.Commands) {
PrefixHelp: "USER", PrefixHelp: "USER",
Help: "Kick USER from the server.", Help: "Kick USER from the server.",
Handler: func(room *chat.Room, msg message.CommandMsg) error { Handler: func(room *chat.Room, msg message.CommandMsg) error {
if !room.IsOp(msg.From()) { if !room.IsOp(msg.From().(chat.Member)) {
return errors.New("must be op") return errors.New("must be op")
} }
@ -528,7 +527,7 @@ func (h *Host) InitCommands(c *chat.Commands) {
body := fmt.Sprintf("%s was kicked by %s.", target.Name(), msg.From().Name()) body := fmt.Sprintf("%s was kicked by %s.", target.Name(), msg.From().Name())
room.Send(message.NewAnnounceMsg(body)) room.Send(message.NewAnnounceMsg(body))
target.Close() target.(io.Closer).Close()
return nil return nil
}, },
}) })
@ -550,7 +549,7 @@ func (h *Host) InitCommands(c *chat.Commands) {
room.Send(message.NewSystemMsg(motd, user)) room.Send(message.NewSystemMsg(motd, user))
return nil return nil
} }
if !room.IsOp(user) { if !room.IsOp(user.(chat.Member)) {
return errors.New("must be OP to modify the MOTD") return errors.New("must be OP to modify the MOTD")
} }

View File

@ -28,7 +28,7 @@ func stripPrompt(s string) string {
func TestHostGetPrompt(t *testing.T) { func TestHostGetPrompt(t *testing.T) {
var expected, actual string var expected, actual string
u := message.NewUser("foo") u := message.Screen("foo")
actual = u.Prompt() actual = u.Prompt()
expected = "[foo] " expected = "[foo] "
@ -40,7 +40,7 @@ func TestHostGetPrompt(t *testing.T) {
Theme: &message.Themes[0], Theme: &message.Themes[0],
}) })
actual = u.Prompt() actual = u.Prompt()
expected = "[\033[38;05;88mfoo\033[0m] " expected = "[\033[38;05;1mfoo\033[0m] "
if actual != expected { if actual != expected {
t.Errorf("Got: %q; Expected: %q", actual, expected) t.Errorf("Got: %q; Expected: %q", actual, expected)
} }

View File

@ -2,6 +2,7 @@ package sshchat
import ( import (
"net" "net"
"time"
humanize "github.com/dustin/go-humanize" humanize "github.com/dustin/go-humanize"
"github.com/shazow/ssh-chat/chat/message" "github.com/shazow/ssh-chat/chat/message"
@ -10,6 +11,10 @@ import (
// Helpers for printing whois messages // Helpers for printing whois messages
type joinTimestamped interface {
Joined() time.Time
}
func whoisPublic(clients []Client) string { func whoisPublic(clients []Client) string {
// FIXME: Handle many clients // FIXME: Handle many clients
conn, u := clients[0].conn, clients[0].user conn, u := clients[0].conn, clients[0].user
@ -21,7 +26,7 @@ func whoisPublic(clients []Client) string {
return "name: " + u.Name() + message.Newline + return "name: " + u.Name() + message.Newline +
" > fingerprint: " + fingerprint + message.Newline + " > fingerprint: " + fingerprint + message.Newline +
" > client: " + SanitizeData(string(conn.ClientVersion())) + message.Newline + " > client: " + SanitizeData(string(conn.ClientVersion())) + message.Newline +
" > joined: " + humanize.Time(u.Joined()) " > joined: " + humanize.Time(u.(joinTimestamped).Joined())
} }
func whoisAdmin(clients []Client) string { func whoisAdmin(clients []Client) string {
@ -37,5 +42,5 @@ func whoisAdmin(clients []Client) string {
" > ip: " + ip + message.Newline + " > ip: " + ip + message.Newline +
" > fingerprint: " + fingerprint + message.Newline + " > fingerprint: " + fingerprint + message.Newline +
" > client: " + SanitizeData(string(conn.ClientVersion())) + message.Newline + " > client: " + SanitizeData(string(conn.ClientVersion())) + message.Newline +
" > joined: " + humanize.Time(u.Joined()) " > joined: " + humanize.Time(u.(joinTimestamped).Joined())
} }