From 6e5348101cc9ef63cd0e2bfbd3b64609aeabf19d Mon Sep 17 00:00:00 2001 From: Juliusz Chroboczek Date: Mon, 30 Nov 2020 16:26:11 +0100 Subject: [PATCH] Propagate kick originators. --- diskwriter/diskwriter.go | 2 +- group/client.go | 2 +- group/group.go | 21 +++++++++- rtpconn/webclient.go | 89 +++++++++++++++++++++++++--------------- 4 files changed, 78 insertions(+), 36 deletions(-) diff --git a/diskwriter/diskwriter.go b/diskwriter/diskwriter.go index 889f40b..ad67491 100644 --- a/diskwriter/diskwriter.go +++ b/diskwriter/diskwriter.go @@ -81,7 +81,7 @@ func (client *Client) Close() error { return nil } -func (client *Client) Kick(message string) error { +func (client *Client) Kick(id, user, message string) error { err := client.Close() group.DelClient(client) return err diff --git a/group/client.go b/group/client.go index d8dd830..e0e2887 100644 --- a/group/client.go +++ b/group/client.go @@ -102,5 +102,5 @@ type Client interface { } type Kickable interface { - Kick(message string) error + Kick(id, user, message string) error } diff --git a/group/group.go b/group/group.go index a40d305..c113e7a 100644 --- a/group/group.go +++ b/group/group.go @@ -29,6 +29,23 @@ func (err UserError) Error() string { 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 func (err ProtocolError) Error() string { @@ -272,7 +289,7 @@ func AddClient(group string, c Client) (*Group, error) { g.mu.Lock() defer g.mu.Unlock() - if(!c.OverridePermissions(g)) { + if !c.OverridePermissions(g) { perms, err := g.description.GetPermission(group, c) if err != nil { return nil, err @@ -381,7 +398,7 @@ func (g *Group) Shutdown(message string) { g.Range(func(c Client) bool { cc, ok := c.(Kickable) if ok { - cc.Kick(message) + cc.Kick("", "", message) } return true }) diff --git a/rtpconn/webclient.go b/rtpconn/webclient.go index a001925..a600e78 100644 --- a/rtpconn/webclient.go +++ b/rtpconn/webclient.go @@ -17,22 +17,31 @@ import ( "sfu/group" ) -func errorToWSCloseMessage(err error) (string, []byte) { +func errorToWSCloseMessage(id string, err error) (*clientMessage, []byte) { var code int + var m *clientMessage var text string switch e := err.(type) { case *websocket.CloseError: code = websocket.CloseNormalClosure case group.ProtocolError: code = websocket.CloseProtocolError - text = string(e) - case group.UserError: + m = &clientMessage{ + Type: "usermessage", + Kind: "error", + Dest: id, + Priviledged: true, + Value: e.Error(), + } + text = e.Error() + case group.UserError, group.KickError: code = websocket.CloseNormalClosure - text = string(e) + m = errorMessage(id, err) + text = e.Error() default: code = websocket.CloseInternalServerErr } - return text, websocket.FormatCloseMessage(code, text) + return m, websocket.FormatCloseMessage(code, text) } func isWSNormalError(err error) bool { @@ -674,15 +683,9 @@ func StartClient(conn *websocket.Conn) (err error) { err = nil c.close(nil) } else { - m, e := errorToWSCloseMessage(err) - if m != "" { - c.write(clientMessage{ - Type: "usermessage", - Kind: "error", - Dest: c.id, - Priviledged: true, - Value: m, - }) + m, e := errorToWSCloseMessage(c.id, err) + if m != nil { + c.write(*m) } c.close(e) } @@ -741,7 +744,9 @@ type connectionFailedAction struct { type permissionsChangedAction struct{} type kickAction struct { - message string + id string + username string + message string } func clientLoop(c *webClient, ws *websocket.Conn) error { @@ -899,7 +904,9 @@ func clientLoop(c *webClient, ws *websocket.Conn) error { } } case kickAction: - return group.UserError(a.message) + return group.KickError{ + a.id, a.username, a.message, + } default: log.Printf("unexpected action %T", a) return errors.New("unexpected action") @@ -988,12 +995,12 @@ func setPermissions(g *group.Group, id string, perm string) error { return c.action(permissionsChangedAction{}) } -func (c *webClient) Kick(message string) error { - return c.action(kickAction{message}) +func (c *webClient) Kick(id, user, message string) error { + return c.action(kickAction{id, user, message}) } -func kickClient(g *group.Group, id string, message string) error { - client := g.GetClient(id) +func kickClient(g *group.Group, id, user, dest string, message string) error { + client := g.GetClient(dest) if client == nil { return group.UserError("no such user") } @@ -1003,7 +1010,7 @@ func kickClient(g *group.Group, id string, message string) error { 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 { @@ -1187,11 +1194,7 @@ func handleClientMessage(c *webClient, m clientMessage) error { if !c.permissions.Op { return c.error(group.UserError("not authorised")) } - message := m.Value - if message == "" { - message = "you have been kicked out" - } - err := kickClient(c.group, m.Dest, message) + err := kickClient(c.group, m.Id, m.Username, m.Dest, m.Value) if err != nil { return c.error(err) } @@ -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) { case group.UserError: - return c.write(clientMessage{ + return &clientMessage{ Type: "usermessage", Kind: "error", - Dest: c.id, + Dest: id, 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: - return err + return nil } } + +func (c *webClient) error(err error) error { + m := errorMessage(c.id, err) + if m == nil { + return err + } + return c.write(*m) +}