fix: prohibit concurrent read/write
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user