fix(client): resolve race condition in Process event handler
authz_client / vulnerabilities (pull_request) Successful in 1m38s
authz_client / test (pull_request) Successful in 1m50s
pre-commit / pre-commit (pull_request) Successful in 5m11s

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:
2026-03-12 08:26:10 +01:00
parent 9cdb09add4
commit e24a339046
+3 -8
View File
@@ -104,13 +104,14 @@ func (h *PrivilegeHandler) Setup() []goamqp.Setup {
// Process privilege-related events and update the internal state
func (h *PrivilegeHandler) Process(msg interface{}, _ goamqp.Headers) (interface{}, error) {
h.Lock()
defer h.Unlock()
switch ev := msg.(type) {
case *UserAdded:
if priv, exists := h.privileges[ev.Email]; exists {
priv[ev.CompanyID] = &CompanyPrivileges{}
} else {
h.Lock()
defer h.Unlock()
h.privileges[ev.Email] = map[string]*CompanyPrivileges{
ev.CompanyID: {},
}
@@ -118,19 +119,13 @@ func (h *PrivilegeHandler) Process(msg interface{}, _ goamqp.Headers) (interface
return nil, nil
case *UserRemoved:
if priv, exists := h.privileges[ev.Email]; exists {
h.Lock()
defer h.Unlock()
delete(priv, ev.CompanyID)
}
return nil, nil
case *PrivilegeAdded:
h.Lock()
defer h.Unlock()
h.setPrivileges(ev.Email, ev.CompanyID, ev.Privilege, true)
return nil, nil
case *PrivilegeRemoved:
h.Lock()
defer h.Unlock()
h.setPrivileges(ev.Email, ev.CompanyID, ev.Privilege, false)
return nil, nil
default: