diff --git a/client.go b/client.go index c195378..700955e 100644 --- a/client.go +++ b/client.go @@ -6,6 +6,7 @@ import ( "io" "net/http" "reflect" + "sync" "github.com/sparetimecoders/goamqp" ) @@ -23,6 +24,7 @@ type CompanyPrivileges struct { // PrivilegeHandler processes PrivilegeAdded-events and fetches the initial set of privileges from an authz-service type PrivilegeHandler struct { + *sync.RWMutex client *http.Client baseURL string privileges map[string]map[string]*CompanyPrivileges @@ -41,6 +43,7 @@ func WithBaseURL(url string) OptsFunc { // New creates a new PrivilegeHandler. Pass OptsFuncs to configure. func New(opts ...OptsFunc) *PrivilegeHandler { handler := &PrivilegeHandler{ + RWMutex: &sync.RWMutex{}, client: &http.Client{}, baseURL: "http://authz-service", privileges: map[string]map[string]*CompanyPrivileges{}, @@ -63,6 +66,8 @@ func (h *PrivilegeHandler) Fetch() error { return err } + h.RLock() + defer h.RUnlock() err = json.Unmarshal(buff, &h.privileges) if err != nil { return err @@ -77,6 +82,8 @@ func (h *PrivilegeHandler) Process(msg interface{}, _ goamqp.Headers) (interface 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: {}, } @@ -84,13 +91,19 @@ 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: @@ -130,6 +143,8 @@ func (h *PrivilegeHandler) setPrivileges(email, companyId string, privilege Priv // CompaniesByUser return a slice of company ids matching the provided email and predicate func func (h *PrivilegeHandler) CompaniesByUser(email string, predicate func(privileges CompanyPrivileges) bool) []string { + h.RLock() + defer h.RUnlock() var result []string if p, exists := h.privileges[email]; exists { for k, v := range p { @@ -143,6 +158,8 @@ func (h *PrivilegeHandler) CompaniesByUser(email string, predicate func(privileg // IsAllowed return true if the provided predicate return true for the privileges matching the provided email and companyID, return false otherwise func (h *PrivilegeHandler) IsAllowed(email, companyID string, predicate func(privileges CompanyPrivileges) bool) bool { + h.RLock() + defer h.RUnlock() if p, exists := h.privileges[email]; exists { if v, exists := p[companyID]; exists { return predicate(*v)