fix(client): resolve race condition in Process event handler
Move lock acquisition to the top of Process() instead of per-case. Previously UserAdded and UserRemoved read the privileges map without holding any lock, causing data races with concurrent Fetch/IsAllowed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -104,13 +104,14 @@ func (h *PrivilegeHandler) Setup() []goamqp.Setup {
|
|||||||
|
|
||||||
// Process privilege-related events and update the internal state
|
// Process privilege-related events and update the internal state
|
||||||
func (h *PrivilegeHandler) Process(msg interface{}, _ goamqp.Headers) (interface{}, error) {
|
func (h *PrivilegeHandler) Process(msg interface{}, _ goamqp.Headers) (interface{}, error) {
|
||||||
|
h.Lock()
|
||||||
|
defer h.Unlock()
|
||||||
|
|
||||||
switch ev := msg.(type) {
|
switch ev := msg.(type) {
|
||||||
case *UserAdded:
|
case *UserAdded:
|
||||||
if priv, exists := h.privileges[ev.Email]; exists {
|
if priv, exists := h.privileges[ev.Email]; exists {
|
||||||
priv[ev.CompanyID] = &CompanyPrivileges{}
|
priv[ev.CompanyID] = &CompanyPrivileges{}
|
||||||
} else {
|
} else {
|
||||||
h.Lock()
|
|
||||||
defer h.Unlock()
|
|
||||||
h.privileges[ev.Email] = map[string]*CompanyPrivileges{
|
h.privileges[ev.Email] = map[string]*CompanyPrivileges{
|
||||||
ev.CompanyID: {},
|
ev.CompanyID: {},
|
||||||
}
|
}
|
||||||
@@ -118,19 +119,13 @@ func (h *PrivilegeHandler) Process(msg interface{}, _ goamqp.Headers) (interface
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
case *UserRemoved:
|
case *UserRemoved:
|
||||||
if priv, exists := h.privileges[ev.Email]; exists {
|
if priv, exists := h.privileges[ev.Email]; exists {
|
||||||
h.Lock()
|
|
||||||
defer h.Unlock()
|
|
||||||
delete(priv, ev.CompanyID)
|
delete(priv, ev.CompanyID)
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
case *PrivilegeAdded:
|
case *PrivilegeAdded:
|
||||||
h.Lock()
|
|
||||||
defer h.Unlock()
|
|
||||||
h.setPrivileges(ev.Email, ev.CompanyID, ev.Privilege, true)
|
h.setPrivileges(ev.Email, ev.CompanyID, ev.Privilege, true)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
case *PrivilegeRemoved:
|
case *PrivilegeRemoved:
|
||||||
h.Lock()
|
|
||||||
defer h.Unlock()
|
|
||||||
h.setPrivileges(ev.Email, ev.CompanyID, ev.Privilege, false)
|
h.setPrivileges(ev.Email, ev.CompanyID, ev.Privilege, false)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
default:
|
default:
|
||||||
|
|||||||
Reference in New Issue
Block a user