Files
authz_client/client.go
T
2019-11-05 21:24:54 +01:00

123 lines
3.1 KiB
Go

package client
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
// CompanyPrivileges contains the privileges for a combination of email address and company id
type CompanyPrivileges struct {
Admin bool `json:"admin"`
Company bool `json:"company"`
Consumer bool `json:"consumer"`
Time bool `json:"time"`
Invoicing bool `json:"invoicing"`
Accounting bool `json:"accounting"`
Supplier bool `json:"supplier"`
}
// PrivilegeAdded is the event sent when a new privilege is added
type PrivilegeAdded struct {
Email string `json:"email"`
CompanyID string `json:"companyId"`
Admin bool `json:"admin"`
Company bool `json:"company"`
Consumer bool `json:"consumer"`
Time bool `json:"time"`
Invoicing bool `json:"invoicing"`
Accounting bool `json:"accounting"`
Supplier bool `json:"supplier"`
}
// PrivilegeHandler processes PrivilegeAdded-events and fetches the initial set of privileges from an authz-service
type PrivilegeHandler struct {
client *http.Client
baseURL string
privileges map[string]map[string]CompanyPrivileges
}
// OptsFunc is used to configure the PrivilegeHandler
type OptsFunc func(handler *PrivilegeHandler)
// WithBaseURL sets the base URL to the authz-service
func WithBaseURL(url string) OptsFunc {
return func(handler *PrivilegeHandler) {
handler.baseURL = url
}
}
// New creates a new PrivilegeHandler. Pass OptsFuncs to configure.
func New(opts ...OptsFunc) *PrivilegeHandler {
handler := &PrivilegeHandler{
client: &http.Client{},
baseURL: "http://authz-service",
privileges: map[string]map[string]CompanyPrivileges{},
}
for _, opt := range opts {
opt(handler)
}
return handler
}
// Fetch the initial set of privileges from an authz-service
func (h *PrivilegeHandler) Fetch() error {
resp, err := h.client.Get(fmt.Sprintf("%s/authz", h.baseURL))
if err != nil {
return err
}
buff, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
err = json.Unmarshal(buff, &h.privileges)
if err != nil {
return err
}
return nil
}
// Process privilege-related events and update the internal state
func (h *PrivilegeHandler) Process(msg interface{}) bool {
if ev, ok := msg.(*PrivilegeAdded); ok {
h.setPrivileges(ev)
return true
}
return false
}
func (h *PrivilegeHandler) setPrivileges(ev *PrivilegeAdded) {
if priv, exists := h.privileges[ev.Email]; exists {
priv[ev.CompanyID] = CompanyPrivileges{
Admin: ev.Admin,
Company: ev.Company,
Consumer: ev.Consumer,
Time: ev.Time,
Invoicing: ev.Invoicing,
Accounting: ev.Accounting,
Supplier: ev.Supplier,
}
} else {
h.privileges[ev.Email] = map[string]CompanyPrivileges{
ev.CompanyID: {},
}
h.setPrivileges(ev)
}
}
// 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 {
var result []string
if p, exists := h.privileges[email]; exists {
for k, v := range p {
if predicate(v) {
result = append(result, k)
}
}
}
return result
}