Compare commits
11 Commits
f3166426b6
...
v0.5.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 45512115c5 | |||
| fe0abd62c8 | |||
| a54cf45a4b | |||
| f9a5ef7085 | |||
| 200e7cf963 | |||
| 110f6206f9 | |||
| c53d80792c | |||
| ebc0c3bb8e | |||
| cb59762fc9 | |||
| a82466cb27 | |||
| 29eab978f7 |
@@ -30,7 +30,7 @@ repos:
|
||||
- id: go-test
|
||||
- id: gofumpt
|
||||
- repo: https://github.com/golangci/golangci-lint
|
||||
rev: v2.8.0
|
||||
rev: v2.11.3
|
||||
hooks:
|
||||
- id: golangci-lint-full
|
||||
- repo: https://github.com/gitleaks/gitleaks
|
||||
|
||||
@@ -2,6 +2,30 @@
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [0.5.0] - 2026-03-12
|
||||
|
||||
### 🚀 Features
|
||||
|
||||
- *(client)* Add API key authentication for /authz endpoint (#294)
|
||||
|
||||
### ⚙️ Miscellaneous Tasks
|
||||
|
||||
- *(deps)* Update golang:1.25.5 docker digest to 3a01526 (#271)
|
||||
- *(deps)* Update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.24.0 (#273)
|
||||
- *(deps)* Update dependency go to v1.25.6 (#274)
|
||||
- *(deps)* Update golang docker tag to v1.25.6 (#275)
|
||||
- Remove GitLab CI configuration
|
||||
- Add code coverage integration
|
||||
- *(deps)* Update dependency go to v1.25.7 (#279)
|
||||
- *(deps)* Update dependency go to v1.26.0 (#280)
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.9.0 (#281)
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.10.0 (#282)
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.10.1 (#283)
|
||||
- *(deps)* Update dependency go to v1.26.1 (#286)
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.11.1 (#288)
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.11.2 (#290)
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.11.3 (#292)
|
||||
|
||||
## [0.4.1] - 2026-01-09
|
||||
|
||||
### ⚙️ Miscellaneous Tasks
|
||||
|
||||
@@ -28,6 +28,7 @@ type PrivilegeHandler struct {
|
||||
*sync.RWMutex
|
||||
client *http.Client
|
||||
baseURL string
|
||||
apiKey string
|
||||
privileges map[string]map[string]*CompanyPrivileges
|
||||
}
|
||||
|
||||
@@ -41,6 +42,13 @@ func WithBaseURL(url string) OptsFunc {
|
||||
}
|
||||
}
|
||||
|
||||
// WithAPIKey sets an API key used as a Bearer token when fetching privileges
|
||||
func WithAPIKey(key string) OptsFunc {
|
||||
return func(handler *PrivilegeHandler) {
|
||||
handler.apiKey = key
|
||||
}
|
||||
}
|
||||
|
||||
// New creates a new PrivilegeHandler. Pass OptsFuncs to configure.
|
||||
func New(opts ...OptsFunc) *PrivilegeHandler {
|
||||
handler := &PrivilegeHandler{
|
||||
@@ -57,7 +65,16 @@ func New(opts ...OptsFunc) *PrivilegeHandler {
|
||||
|
||||
// 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))
|
||||
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/authz", h.baseURL), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if h.apiKey != "" {
|
||||
req.Header.Set("Authorization", "Bearer "+h.apiKey)
|
||||
}
|
||||
|
||||
resp, err := h.client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -87,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: {},
|
||||
}
|
||||
@@ -101,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:
|
||||
|
||||
@@ -251,6 +251,39 @@ func TestPrivilegeHandler_IsAllowed_Return_True_If_Privilege_Exists(t *testing.T
|
||||
assert.True(t, result)
|
||||
}
|
||||
|
||||
func TestPrivilegeHandler_Fetch_Sends_Authorization_Header_When_APIKey_Set(t *testing.T) {
|
||||
var receivedAuth string
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
receivedAuth = r.Header.Get("Authorization")
|
||||
_, _ = w.Write([]byte("{}"))
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
handler := New(
|
||||
WithBaseURL(server.URL),
|
||||
WithAPIKey("my-secret-key"),
|
||||
)
|
||||
|
||||
err := handler.Fetch()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "Bearer my-secret-key", receivedAuth)
|
||||
}
|
||||
|
||||
func TestPrivilegeHandler_Fetch_No_Authorization_Header_Without_APIKey(t *testing.T) {
|
||||
var receivedAuth string
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
receivedAuth = r.Header.Get("Authorization")
|
||||
_, _ = w.Write([]byte("{}"))
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
handler := New(WithBaseURL(server.URL))
|
||||
|
||||
err := handler.Fetch()
|
||||
assert.NoError(t, err)
|
||||
assert.Empty(t, receivedAuth)
|
||||
}
|
||||
|
||||
func TestPrivilegeHandler_Fetch_Error_Response(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(500)
|
||||
|
||||
Reference in New Issue
Block a user