Commit 6e534810 authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Propagate kick originators.

parent d98c9b95
...@@ -81,7 +81,7 @@ func (client *Client) Close() error { ...@@ -81,7 +81,7 @@ func (client *Client) Close() error {
return nil return nil
} }
func (client *Client) Kick(message string) error { func (client *Client) Kick(id, user, message string) error {
err := client.Close() err := client.Close()
group.DelClient(client) group.DelClient(client)
return err return err
......
...@@ -102,5 +102,5 @@ type Client interface { ...@@ -102,5 +102,5 @@ type Client interface {
} }
type Kickable interface { type Kickable interface {
Kick(message string) error Kick(id, user, message string) error
} }
...@@ -29,6 +29,23 @@ func (err UserError) Error() string { ...@@ -29,6 +29,23 @@ func (err UserError) Error() string {
return string(err) return string(err)
} }
type KickError struct {
Id string
Username string
Message string
}
func (err KickError) Error() string {
m := "kicked out"
if err.Message != "" {
m += "(" + err.Message + ")"
}
if err.Username != "" {
m += " by " + err.Username
}
return m
}
type ProtocolError string type ProtocolError string
func (err ProtocolError) Error() string { func (err ProtocolError) Error() string {
...@@ -272,7 +289,7 @@ func AddClient(group string, c Client) (*Group, error) { ...@@ -272,7 +289,7 @@ func AddClient(group string, c Client) (*Group, error) {
g.mu.Lock() g.mu.Lock()
defer g.mu.Unlock() defer g.mu.Unlock()
if(!c.OverridePermissions(g)) { if !c.OverridePermissions(g) {
perms, err := g.description.GetPermission(group, c) perms, err := g.description.GetPermission(group, c)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -381,7 +398,7 @@ func (g *Group) Shutdown(message string) { ...@@ -381,7 +398,7 @@ func (g *Group) Shutdown(message string) {
g.Range(func(c Client) bool { g.Range(func(c Client) bool {
cc, ok := c.(Kickable) cc, ok := c.(Kickable)
if ok { if ok {
cc.Kick(message) cc.Kick("", "", message)
} }
return true return true
}) })
......
...@@ -17,22 +17,31 @@ import ( ...@@ -17,22 +17,31 @@ import (
"sfu/group" "sfu/group"
) )
func errorToWSCloseMessage(err error) (string, []byte) { func errorToWSCloseMessage(id string, err error) (*clientMessage, []byte) {
var code int var code int
var m *clientMessage
var text string var text string
switch e := err.(type) { switch e := err.(type) {
case *websocket.CloseError: case *websocket.CloseError:
code = websocket.CloseNormalClosure code = websocket.CloseNormalClosure
case group.ProtocolError: case group.ProtocolError:
code = websocket.CloseProtocolError code = websocket.CloseProtocolError
text = string(e) m = &clientMessage{
case group.UserError: Type: "usermessage",
Kind: "error",
Dest: id,
Priviledged: true,
Value: e.Error(),
}
text = e.Error()
case group.UserError, group.KickError:
code = websocket.CloseNormalClosure code = websocket.CloseNormalClosure
text = string(e) m = errorMessage(id, err)
text = e.Error()
default: default:
code = websocket.CloseInternalServerErr code = websocket.CloseInternalServerErr
} }
return text, websocket.FormatCloseMessage(code, text) return m, websocket.FormatCloseMessage(code, text)
} }
func isWSNormalError(err error) bool { func isWSNormalError(err error) bool {
...@@ -674,15 +683,9 @@ func StartClient(conn *websocket.Conn) (err error) { ...@@ -674,15 +683,9 @@ func StartClient(conn *websocket.Conn) (err error) {
err = nil err = nil
c.close(nil) c.close(nil)
} else { } else {
m, e := errorToWSCloseMessage(err) m, e := errorToWSCloseMessage(c.id, err)
if m != "" { if m != nil {
c.write(clientMessage{ c.write(*m)
Type: "usermessage",
Kind: "error",
Dest: c.id,
Priviledged: true,
Value: m,
})
} }
c.close(e) c.close(e)
} }
...@@ -741,7 +744,9 @@ type connectionFailedAction struct { ...@@ -741,7 +744,9 @@ type connectionFailedAction struct {
type permissionsChangedAction struct{} type permissionsChangedAction struct{}
type kickAction struct { type kickAction struct {
message string id string
username string
message string
} }
func clientLoop(c *webClient, ws *websocket.Conn) error { func clientLoop(c *webClient, ws *websocket.Conn) error {
...@@ -899,7 +904,9 @@ func clientLoop(c *webClient, ws *websocket.Conn) error { ...@@ -899,7 +904,9 @@ func clientLoop(c *webClient, ws *websocket.Conn) error {
} }
} }
case kickAction: case kickAction:
return group.UserError(a.message) return group.KickError{
a.id, a.username, a.message,
}
default: default:
log.Printf("unexpected action %T", a) log.Printf("unexpected action %T", a)
return errors.New("unexpected action") return errors.New("unexpected action")
...@@ -988,12 +995,12 @@ func setPermissions(g *group.Group, id string, perm string) error { ...@@ -988,12 +995,12 @@ func setPermissions(g *group.Group, id string, perm string) error {
return c.action(permissionsChangedAction{}) return c.action(permissionsChangedAction{})
} }
func (c *webClient) Kick(message string) error { func (c *webClient) Kick(id, user, message string) error {
return c.action(kickAction{message}) return c.action(kickAction{id, user, message})
} }
func kickClient(g *group.Group, id string, message string) error { func kickClient(g *group.Group, id, user, dest string, message string) error {
client := g.GetClient(id) client := g.GetClient(dest)
if client == nil { if client == nil {
return group.UserError("no such user") return group.UserError("no such user")
} }
...@@ -1003,7 +1010,7 @@ func kickClient(g *group.Group, id string, message string) error { ...@@ -1003,7 +1010,7 @@ func kickClient(g *group.Group, id string, message string) error {
return group.UserError("this client is not kickable") return group.UserError("this client is not kickable")
} }
return c.Kick(message) return c.Kick(id, user, message)
} }
func handleClientMessage(c *webClient, m clientMessage) error { func handleClientMessage(c *webClient, m clientMessage) error {
...@@ -1187,11 +1194,7 @@ func handleClientMessage(c *webClient, m clientMessage) error { ...@@ -1187,11 +1194,7 @@ func handleClientMessage(c *webClient, m clientMessage) error {
if !c.permissions.Op { if !c.permissions.Op {
return c.error(group.UserError("not authorised")) return c.error(group.UserError("not authorised"))
} }
message := m.Value err := kickClient(c.group, m.Id, m.Username, m.Dest, m.Value)
if message == "" {
message = "you have been kicked out"
}
err := kickClient(c.group, m.Dest, message)
if err != nil { if err != nil {
return c.error(err) return c.error(err)
} }
...@@ -1298,17 +1301,39 @@ func (c *webClient) close(data []byte) error { ...@@ -1298,17 +1301,39 @@ func (c *webClient) close(data []byte) error {
} }
} }
func (c *webClient) error(err error) error { func errorMessage(id string, err error) *clientMessage {
switch e := err.(type) { switch e := err.(type) {
case group.UserError: case group.UserError:
return c.write(clientMessage{ return &clientMessage{
Type: "usermessage", Type: "usermessage",
Kind: "error", Kind: "error",
Dest: c.id, Dest: id,
Priviledged: true, Priviledged: true,
Value: string(e), Value: e.Error(),
}) }
case group.KickError:
message := e.Message
if message == "" {
message = "you have been kicked out"
}
return &clientMessage{
Type: "usermessage",
Kind: "error",
Id: e.Id,
Username: e.Username,
Dest: id,
Priviledged: true,
Value: message,
}
default: default:
return nil
}
}
func (c *webClient) error(err error) error {
m := errorMessage(c.id, err)
if m == nil {
return err return err
} }
return c.write(*m)
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment