Tests pass.
This commit is contained in:
parent
6a662bf358
commit
4dd80fb822
|
@ -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()
|
||||||
|
}
|
|
@ -51,8 +51,8 @@ func (ch *Channel) SetCommands(commands Commands) {
|
||||||
func (ch *Channel) Close() {
|
func (ch *Channel) Close() {
|
||||||
ch.closeOnce.Do(func() {
|
ch.closeOnce.Do(func() {
|
||||||
ch.closed = true
|
ch.closed = true
|
||||||
ch.members.Each(func(u Item) {
|
ch.members.Each(func(m Item) {
|
||||||
u.(*User).Close()
|
m.(*Member).Close()
|
||||||
})
|
})
|
||||||
ch.members.Clear()
|
ch.members.Clear()
|
||||||
close(ch.broadcast)
|
close(ch.broadcast)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// FIXME: Would be sweet if we could piggyback on a cli parser or something.
|
|
||||||
package chat
|
package chat
|
||||||
|
|
||||||
|
// FIXME: Would be sweet if we could piggyback on a cli parser or something.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -93,8 +94,12 @@ func (c Commands) Help(showOp bool) string {
|
||||||
var defaultCommands *Commands
|
var defaultCommands *Commands
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
c := Commands{}
|
defaultCommands = &Commands{}
|
||||||
|
InitCommands(defaultCommands)
|
||||||
|
}
|
||||||
|
|
||||||
|
// InitCommands injects default commands into a Commands registry.
|
||||||
|
func InitCommands(c *Commands) {
|
||||||
c.Add(Command{
|
c.Add(Command{
|
||||||
Prefix: "/help",
|
Prefix: "/help",
|
||||||
Handler: func(channel *Channel, msg CommandMsg) error {
|
Handler: func(channel *Channel, msg CommandMsg) error {
|
||||||
|
@ -217,6 +222,4 @@ func init() {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
defaultCommands = &c
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ type help struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCommandsHelp creates a help container from a commands container.
|
// NewCommandsHelp creates a help container from a commands container.
|
||||||
func NewCommandsHelp(c []*Command) *help {
|
func NewCommandsHelp(c []*Command) fmt.Stringer {
|
||||||
lookup := map[string]struct{}{}
|
lookup := map[string]struct{}{}
|
||||||
h := help{
|
h := help{
|
||||||
items: []helpItem{},
|
items: []helpItem{},
|
||||||
|
|
7
host.go
7
host.go
|
@ -14,6 +14,7 @@ import (
|
||||||
type Host struct {
|
type Host struct {
|
||||||
listener *sshd.SSHListener
|
listener *sshd.SSHListener
|
||||||
channel *chat.Channel
|
channel *chat.Channel
|
||||||
|
commands *chat.Commands
|
||||||
|
|
||||||
motd string
|
motd string
|
||||||
auth *Auth
|
auth *Auth
|
||||||
|
@ -26,6 +27,12 @@ func NewHost(listener *sshd.SSHListener) *Host {
|
||||||
listener: listener,
|
listener: listener,
|
||||||
channel: ch,
|
channel: ch,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make our own commands registry instance.
|
||||||
|
commands := chat.Commands{}
|
||||||
|
chat.InitCommands(&commands)
|
||||||
|
ch.SetCommands(commands)
|
||||||
|
|
||||||
go ch.Serve()
|
go ch.Serve()
|
||||||
return &h
|
return &h
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue