Tests pass.

This commit is contained in:
Andrey Petrov 2015-01-01 18:51:34 -08:00
parent 6a662bf358
commit 4dd80fb822
5 changed files with 85 additions and 7 deletions

68
auth.go Normal file
View File

@ -0,0 +1,68 @@
package main
import (
"errors"
"sync"
"github.com/shazow/ssh-chat/sshd"
)
// Auth stores fingerprint lookups
type Auth struct {
whitelist map[string]struct{}
banned map[string]struct{}
ops map[string]struct{}
sshd.Auth
sync.RWMutex
}
// AllowAnonymous determines if anonymous users are permitted.
func (a Auth) AllowAnonymous() bool {
a.RLock()
ok := len(a.whitelist) == 0
a.RUnlock()
return ok
}
// Check determines if a pubkey fingerprint is permitted.
func (a Auth) Check(fingerprint string) (bool, error) {
a.RLock()
defer a.RUnlock()
if len(a.whitelist) > 0 {
// Only check whitelist if there is something in it, otherwise it's disabled.
_, whitelisted := a.whitelist[fingerprint]
if !whitelisted {
return false, errors.New("not whitelisted")
}
}
_, banned := a.banned[fingerprint]
if banned {
return false, errors.New("banned")
}
return true, nil
}
// Op will set a fingerprint as a known operator.
func (a *Auth) Op(fingerprint string) {
a.Lock()
a.ops[fingerprint] = struct{}{}
a.Unlock()
}
// Whitelist will set a fingerprint as a whitelisted user.
func (a *Auth) Whitelist(fingerprint string) {
a.Lock()
a.whitelist[fingerprint] = struct{}{}
a.Unlock()
}
// Ban will set a fingerprint as banned.
func (a *Auth) Ban(fingerprint string) {
a.Lock()
a.banned[fingerprint] = struct{}{}
a.Unlock()
}

View File

@ -51,8 +51,8 @@ func (ch *Channel) SetCommands(commands Commands) {
func (ch *Channel) Close() {
ch.closeOnce.Do(func() {
ch.closed = true
ch.members.Each(func(u Item) {
u.(*User).Close()
ch.members.Each(func(m Item) {
m.(*Member).Close()
})
ch.members.Clear()
close(ch.broadcast)

View File

@ -1,6 +1,7 @@
// FIXME: Would be sweet if we could piggyback on a cli parser or something.
package chat
// FIXME: Would be sweet if we could piggyback on a cli parser or something.
import (
"errors"
"fmt"
@ -93,8 +94,12 @@ func (c Commands) Help(showOp bool) string {
var defaultCommands *Commands
func init() {
c := Commands{}
defaultCommands = &Commands{}
InitCommands(defaultCommands)
}
// InitCommands injects default commands into a Commands registry.
func InitCommands(c *Commands) {
c.Add(Command{
Prefix: "/help",
Handler: func(channel *Channel, msg CommandMsg) error {
@ -217,6 +222,4 @@ func init() {
return nil
},
})
defaultCommands = &c
}

View File

@ -17,7 +17,7 @@ type help struct {
}
// NewCommandsHelp creates a help container from a commands container.
func NewCommandsHelp(c []*Command) *help {
func NewCommandsHelp(c []*Command) fmt.Stringer {
lookup := map[string]struct{}{}
h := help{
items: []helpItem{},

View File

@ -14,6 +14,7 @@ import (
type Host struct {
listener *sshd.SSHListener
channel *chat.Channel
commands *chat.Commands
motd string
auth *Auth
@ -26,6 +27,12 @@ func NewHost(listener *sshd.SSHListener) *Host {
listener: listener,
channel: ch,
}
// Make our own commands registry instance.
commands := chat.Commands{}
chat.InitCommands(&commands)
ch.SetCommands(commands)
go ch.Serve()
return &h
}