Switch UserPerms to cmap and fix panic

This commit is contained in:
kayos@tcp.direct 2022-07-11 22:36:36 -07:00
parent 61ef265c6c
commit 32f2b078c3
Signed by: kayos
GPG Key ID: 4B841471B4BEE979
4 changed files with 16 additions and 20 deletions

2
go.mod
View File

@ -6,3 +6,5 @@ require (
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de
github.com/orcaman/concurrent-map v1.0.0
)
require github.com/dvyukov/go-fuzz v0.0.0-20220220162807-a217d9bdbece // indirect

2
go.sum
View File

@ -2,6 +2,8 @@ github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de h1:FxWPpzIjnTlhP
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de/go.mod h1:DCaWoUhZrYW9p1lxo/cm8EmUOOzAPSEZNGF2DK1dJgw=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dvyukov/go-fuzz v0.0.0-20220220162807-a217d9bdbece h1:6BGhEtGBmkgr8TKLjMBBMpvM/fK0GHj4prrkK1tYPcA=
github.com/dvyukov/go-fuzz v0.0.0-20220220162807-a217d9bdbece/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/orcaman/concurrent-map v1.0.0 h1:I/2A2XPCb4IuQWcQhBhSwGfiuybl/J0ev9HDbW65HOY=
github.com/orcaman/concurrent-map v1.0.0/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI=

View File

@ -7,7 +7,8 @@ package girc
import (
"encoding/json"
"strings"
"sync"
cmap "github.com/orcaman/concurrent-map"
)
// CMode represents a single step of a given mode change.
@ -395,50 +396,41 @@ func (s *state) userPrefixes() string {
// UserPerms contains all of the permissions for each channel the user is
// in.
type UserPerms struct {
mu sync.RWMutex
channels map[string]Perms
channels cmap.ConcurrentMap
}
// Copy returns a deep copy of the channel permissions.
func (p *UserPerms) Copy() (perms *UserPerms) {
np := &UserPerms{
channels: make(map[string]Perms),
channels: cmap.New(),
}
for key := range p.channels {
np.channels[key] = p.channels[key]
for tuple := range p.channels.IterBuffered() {
np.channels.Set(tuple.Key, tuple.Val)
}
return np
}
// MarshalJSON implements json.Marshaler.
func (p *UserPerms) MarshalJSON() ([]byte, error) {
p.mu.Lock()
out, err := json.Marshal(&p.channels)
p.mu.Unlock()
return out, err
}
// Lookup looks up the users permissions for a given channel. ok is false
// if the user is not in the given channel.
func (p *UserPerms) Lookup(channel string) (perms Perms, ok bool) {
p.mu.RLock()
defer p.mu.RUnlock()
perms, ok = p.channels[ToRFC1459(channel)]
var permsi interface{}
permsi, ok = p.channels.Get(ToRFC1459(channel))
perms = permsi.(Perms)
return perms, ok
}
func (p *UserPerms) set(channel string, perms Perms) {
p.mu.Lock()
p.channels[ToRFC1459(channel)] = perms
p.mu.Unlock()
p.channels.Set(ToRFC1459(channel), perms)
}
func (p *UserPerms) remove(channel string) {
p.mu.Lock()
delete(p.channels, ToRFC1459(channel))
p.mu.Unlock()
p.channels.Remove(ToRFC1459(channel))
}
// Perms contains all channel-based user permissions. The minimum op, and

View File

@ -459,7 +459,7 @@ func (s *state) createUser(src *Source) (u *User, ok bool) {
FirstSeen: time.Now(),
LastActive: time.Now(),
Network: s.client.NetworkName(),
Perms: &UserPerms{channels: make(map[string]Perms)},
Perms: &UserPerms{channels: cmap.New()},
}
s.users.Set(src.ID(), u)