forked from External/ergo
fix #1688
* Add ACCEPT-tracking functionality (authorizing users to send DMs despite +R or other applicable restrictions) * Sending a DM automatically accepts the recipient * Add explicit ACCEPT command
This commit is contained in:
parent
03092769e7
commit
c5579a6a34
10 changed files with 250 additions and 35 deletions
76
irc/accept.go
Normal file
76
irc/accept.go
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
package irc
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/ergochat/ergo/irc/utils"
|
||||
)
|
||||
|
||||
// tracks ACCEPT relationships, i.e., `accepter` is willing to receive DMs from
|
||||
// `accepted` despite some restriction (currently the only relevant restriction
|
||||
// is that `accepter` is +R and `accepted` is not logged in)
|
||||
|
||||
type AcceptManager struct {
|
||||
sync.RWMutex
|
||||
|
||||
// maps recipient -> whitelist of permitted senders:
|
||||
// this is what we actually check
|
||||
clientToAccepted map[*Client]utils.HashSet[*Client]
|
||||
// this is the reverse mapping, it's needed so we can
|
||||
// clean up the forward mapping during (*Client).destroy():
|
||||
clientToAccepters map[*Client]utils.HashSet[*Client]
|
||||
}
|
||||
|
||||
func (am *AcceptManager) Initialize() {
|
||||
am.clientToAccepted = make(map[*Client]utils.HashSet[*Client])
|
||||
am.clientToAccepters = make(map[*Client]utils.HashSet[*Client])
|
||||
}
|
||||
|
||||
func (am *AcceptManager) MaySendTo(sender, recipient *Client) (result bool) {
|
||||
am.RLock()
|
||||
defer am.RUnlock()
|
||||
return am.clientToAccepted[recipient].Has(sender)
|
||||
}
|
||||
|
||||
func (am *AcceptManager) Accept(accepter, accepted *Client) {
|
||||
am.Lock()
|
||||
defer am.Unlock()
|
||||
|
||||
var m utils.HashSet[*Client]
|
||||
|
||||
m = am.clientToAccepted[accepter]
|
||||
if m == nil {
|
||||
m = make(utils.HashSet[*Client])
|
||||
am.clientToAccepted[accepter] = m
|
||||
}
|
||||
m.Add(accepted)
|
||||
|
||||
m = am.clientToAccepters[accepted]
|
||||
if m == nil {
|
||||
m = make(utils.HashSet[*Client])
|
||||
am.clientToAccepters[accepted] = m
|
||||
}
|
||||
m.Add(accepter)
|
||||
}
|
||||
|
||||
func (am *AcceptManager) Unaccept(accepter, accepted *Client) {
|
||||
am.Lock()
|
||||
defer am.Unlock()
|
||||
|
||||
delete(am.clientToAccepted[accepter], accepted)
|
||||
delete(am.clientToAccepters[accepted], accepter)
|
||||
}
|
||||
|
||||
func (am *AcceptManager) Remove(client *Client) {
|
||||
am.Lock()
|
||||
defer am.Unlock()
|
||||
|
||||
for accepter := range am.clientToAccepters[client] {
|
||||
delete(am.clientToAccepted[accepter], client)
|
||||
}
|
||||
for accepted := range am.clientToAccepted[client] {
|
||||
delete(am.clientToAccepters[accepted], client)
|
||||
}
|
||||
delete(am.clientToAccepters, client)
|
||||
delete(am.clientToAccepted, client)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue