mirror of
https://github.com/ergochat/ergo.git
synced 2024-12-22 18:52:41 +01:00
Merge pull request #377 from slingamn/kickfail
fix another three bugs that were reported today
This commit is contained in:
commit
a273ef624c
@ -241,12 +241,7 @@ func (channel *Channel) Names(client *Client, rb *ResponseBuffer) {
|
|||||||
rb.Add(nil, client.server.name, RPL_ENDOFNAMES, client.nick, channel.name, client.t("End of NAMES list"))
|
rb.Add(nil, client.server.name, RPL_ENDOFNAMES, client.nick, channel.name, client.t("End of NAMES list"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClientIsAtLeast returns whether the client has at least the given channel privilege.
|
func channelUserModeIsAtLeast(clientModes *modes.ModeSet, permission modes.Mode) bool {
|
||||||
func (channel *Channel) ClientIsAtLeast(client *Client, permission modes.Mode) bool {
|
|
||||||
channel.stateMutex.RLock()
|
|
||||||
clientModes := channel.members[client]
|
|
||||||
channel.stateMutex.RUnlock()
|
|
||||||
|
|
||||||
if clientModes == nil {
|
if clientModes == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -264,6 +259,14 @@ func (channel *Channel) ClientIsAtLeast(client *Client, permission modes.Mode) b
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClientIsAtLeast returns whether the client has at least the given channel privilege.
|
||||||
|
func (channel *Channel) ClientIsAtLeast(client *Client, permission modes.Mode) bool {
|
||||||
|
channel.stateMutex.RLock()
|
||||||
|
clientModes := channel.members[client]
|
||||||
|
channel.stateMutex.RUnlock()
|
||||||
|
return channelUserModeIsAtLeast(clientModes, permission)
|
||||||
|
}
|
||||||
|
|
||||||
func (channel *Channel) ClientPrefixes(client *Client, isMultiPrefix bool) string {
|
func (channel *Channel) ClientPrefixes(client *Client, isMultiPrefix bool) string {
|
||||||
channel.stateMutex.RLock()
|
channel.stateMutex.RLock()
|
||||||
defer channel.stateMutex.RUnlock()
|
defer channel.stateMutex.RUnlock()
|
||||||
@ -277,24 +280,26 @@ func (channel *Channel) ClientPrefixes(client *Client, isMultiPrefix bool) strin
|
|||||||
|
|
||||||
func (channel *Channel) ClientHasPrivsOver(client *Client, target *Client) bool {
|
func (channel *Channel) ClientHasPrivsOver(client *Client, target *Client) bool {
|
||||||
channel.stateMutex.RLock()
|
channel.stateMutex.RLock()
|
||||||
defer channel.stateMutex.RUnlock()
|
|
||||||
|
|
||||||
clientModes := channel.members[client]
|
clientModes := channel.members[client]
|
||||||
targetModes := channel.members[target]
|
targetModes := channel.members[target]
|
||||||
result := false
|
channel.stateMutex.RUnlock()
|
||||||
for _, mode := range modes.ChannelPrivModes {
|
|
||||||
if clientModes.HasMode(mode) {
|
if clientModes.HasMode(modes.ChannelFounder) {
|
||||||
result = true
|
// founder can kick anyone
|
||||||
// admins cannot kick other admins
|
return true
|
||||||
if mode == modes.ChannelAdmin && targetModes.HasMode(modes.ChannelAdmin) {
|
} else if clientModes.HasMode(modes.ChannelAdmin) {
|
||||||
result = false
|
// admins cannot kick other admins
|
||||||
}
|
return !channelUserModeIsAtLeast(targetModes, modes.ChannelAdmin)
|
||||||
break
|
} else if clientModes.HasMode(modes.ChannelOperator) {
|
||||||
} else if targetModes.HasMode(mode) {
|
// operators *can* kick other operators
|
||||||
break
|
return !channelUserModeIsAtLeast(targetModes, modes.ChannelAdmin)
|
||||||
}
|
} else if clientModes.HasMode(modes.Halfop) {
|
||||||
|
// halfops cannot kick other halfops
|
||||||
|
return !channelUserModeIsAtLeast(targetModes, modes.Halfop)
|
||||||
|
} else {
|
||||||
|
// voice and unprivileged cannot kick anyone
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (channel *Channel) hasClient(client *Client) bool {
|
func (channel *Channel) hasClient(client *Client) bool {
|
||||||
@ -952,10 +957,6 @@ func (channel *Channel) Kick(client *Client, target *Client, comment string, rb
|
|||||||
rb.Add(nil, client.server.name, ERR_NOTONCHANNEL, channel.name, client.t("You're not on that channel"))
|
rb.Add(nil, client.server.name, ERR_NOTONCHANNEL, channel.name, client.t("You're not on that channel"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !channel.ClientIsAtLeast(client, modes.ChannelOperator) {
|
|
||||||
rb.Add(nil, client.server.name, ERR_CANNOTSENDTOCHAN, channel.name, client.t("Cannot send to channel"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !channel.hasClient(target) {
|
if !channel.hasClient(target) {
|
||||||
rb.Add(nil, client.server.name, ERR_USERNOTINCHANNEL, client.nick, channel.name, client.t("They aren't on that channel"))
|
rb.Add(nil, client.server.name, ERR_USERNOTINCHANNEL, client.nick, channel.name, client.t("They aren't on that channel"))
|
||||||
return
|
return
|
||||||
|
@ -555,19 +555,21 @@ func chathistoryHandler(server *Server, client *Client, msg ircmsg.IrcMessage, r
|
|||||||
newRb := NewResponseBuffer(client)
|
newRb := NewResponseBuffer(client)
|
||||||
newRb.Label = rb.Label // same label, new batch
|
newRb.Label = rb.Label // same label, new batch
|
||||||
// TODO: send `WARN CHATHISTORY MAX_MESSAGES_EXCEEDED` when appropriate
|
// TODO: send `WARN CHATHISTORY MAX_MESSAGES_EXCEEDED` when appropriate
|
||||||
if !success {
|
if hist == nil {
|
||||||
newRb.Add(nil, server.name, "ERR", "CHATHISTORY", "NEED_MORE_PARAMS")
|
|
||||||
} else if hist == nil {
|
|
||||||
newRb.Add(nil, server.name, "ERR", "CHATHISTORY", "NO_SUCH_CHANNEL")
|
newRb.Add(nil, server.name, "ERR", "CHATHISTORY", "NO_SUCH_CHANNEL")
|
||||||
} else if len(items) == 0 {
|
} else if len(items) == 0 {
|
||||||
newRb.Add(nil, server.name, "ERR", "CHATHISTORY", "NO_TEXT_TO_SEND")
|
newRb.Add(nil, server.name, "ERR", "CHATHISTORY", "NO_TEXT_TO_SEND")
|
||||||
|
} else if !success {
|
||||||
|
newRb.Add(nil, server.name, "ERR", "CHATHISTORY", "NEED_MORE_PARAMS")
|
||||||
}
|
}
|
||||||
newRb.Send(true)
|
newRb.Send(true)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
target := msg.Params[0]
|
target := msg.Params[0]
|
||||||
channel = server.channels.Get(target)
|
channel = server.channels.Get(target)
|
||||||
if channel != nil {
|
if channel != nil && channel.hasClient(client) {
|
||||||
|
// "If [...] the user does not have permission to view the requested content, [...]
|
||||||
|
// NO_SUCH_CHANNEL SHOULD be returned"
|
||||||
hist = &channel.history
|
hist = &channel.history
|
||||||
} else {
|
} else {
|
||||||
targetClient := server.clients.Get(target)
|
targetClient := server.clients.Get(target)
|
||||||
@ -1019,7 +1021,7 @@ func historyHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *R
|
|||||||
target := msg.Params[0]
|
target := msg.Params[0]
|
||||||
var hist *history.Buffer
|
var hist *history.Buffer
|
||||||
channel := server.channels.Get(target)
|
channel := server.channels.Get(target)
|
||||||
if channel != nil {
|
if channel != nil && channel.hasClient(client) {
|
||||||
hist = &channel.history
|
hist = &channel.history
|
||||||
} else {
|
} else {
|
||||||
if strings.ToLower(target) == "me" {
|
if strings.ToLower(target) == "me" {
|
||||||
@ -1036,7 +1038,11 @@ func historyHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *R
|
|||||||
}
|
}
|
||||||
|
|
||||||
if hist == nil {
|
if hist == nil {
|
||||||
rb.Add(nil, server.name, ERR_NOSUCHCHANNEL, client.Nick(), target, client.t("No such channel"))
|
if channel == nil {
|
||||||
|
rb.Add(nil, server.name, ERR_NOSUCHCHANNEL, client.Nick(), target, client.t("No such channel"))
|
||||||
|
} else {
|
||||||
|
rb.Add(nil, server.name, ERR_NOTONCHANNEL, client.Nick(), target, client.t("You're not on that channel"))
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,11 +204,11 @@ func (channel *Channel) ApplyChannelModeChanges(client *Client, isSamode bool, c
|
|||||||
switch change.Op {
|
switch change.Op {
|
||||||
case modes.Add:
|
case modes.Add:
|
||||||
channel.setKey(change.Arg)
|
channel.setKey(change.Arg)
|
||||||
|
applied = append(applied, change)
|
||||||
case modes.Remove:
|
case modes.Remove:
|
||||||
channel.setKey("")
|
channel.setKey("")
|
||||||
|
applied = append(applied, change)
|
||||||
}
|
}
|
||||||
applied = append(applied, change)
|
|
||||||
|
|
||||||
case modes.InviteOnly, modes.Moderated, modes.NoOutside, modes.OpOnlyTopic, modes.RegisteredOnly, modes.Secret, modes.ChanRoleplaying:
|
case modes.InviteOnly, modes.Moderated, modes.NoOutside, modes.OpOnlyTopic, modes.RegisteredOnly, modes.Secret, modes.ChanRoleplaying:
|
||||||
if change.Op == modes.List {
|
if change.Op == modes.List {
|
||||||
|
Loading…
Reference in New Issue
Block a user