11 Commits

Author SHA1 Message Date
releaser 45512115c5 chore(release): prepare for v0.5.0 (#295)
Release / release (push) Successful in 40s
authz_client / vulnerabilities (push) Successful in 1m23s
authz_client / test (push) Successful in 2m1s
pre-commit / pre-commit (push) Successful in 4m10s
## [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)

<!-- generated by git-cliff -->

---

**Note:** Please use **Squash Merge** when merging this PR.

Reviewed-on: #295
Co-authored-by: Unbound Releaser <releaser@unbound.se>
Co-committed-by: Unbound Releaser <releaser@unbound.se>
2026-03-12 07:39:47 +00:00
argoyle fe0abd62c8 feat(client): add API key authentication for /authz endpoint (#294)
Release / release (push) Successful in 1m15s
authz_client / vulnerabilities (push) Successful in 2m9s
authz_client / test (push) Successful in 2m21s
pre-commit / pre-commit (push) Successful in 4m46s
## Summary

- Add `WithAPIKey(key string)` option to `PrivilegeHandler`
- When set, `Fetch()` sends `Authorization: Bearer <key>` header
- Backward compatible: no key = no header (existing behavior)

## Test plan

- [x] Unit test verifying Authorization header is sent
- [x] Unit test verifying no header without key
- [x] Existing tests still pass

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Reviewed-on: #294
2026-03-12 07:32:12 +00:00
renovate a54cf45a4b chore(deps): update pre-commit hook golangci/golangci-lint to v2.11.3 (#292)
Release / release (push) Successful in 1m21s
authz_client / vulnerabilities (push) Successful in 2m9s
authz_client / test (push) Successful in 4m40s
pre-commit / pre-commit (push) Successful in 7m39s
2026-03-10 11:12:34 +00:00
renovate f9a5ef7085 chore(deps): update pre-commit hook golangci/golangci-lint to v2.11.2 (#290)
pre-commit / pre-commit (push) Successful in 4m44s
Release / release (push) Successful in 1m2s
authz_client / vulnerabilities (push) Failing after 2h42m46s
authz_client / test (push) Failing after 2h42m53s
2026-03-07 22:09:47 +00:00
renovate 200e7cf963 chore(deps): update pre-commit hook golangci/golangci-lint to v2.11.1 (#288)
Release / release (push) Successful in 57s
authz_client / vulnerabilities (push) Successful in 1m46s
authz_client / test (push) Successful in 2m49s
pre-commit / pre-commit (push) Successful in 5m49s
2026-03-06 15:11:17 +00:00
renovate 110f6206f9 chore(deps): update dependency go to v1.26.1 (#286)
Release / release (push) Successful in 1m13s
authz_client / vulnerabilities (push) Successful in 1m36s
authz_client / test (push) Successful in 2m27s
pre-commit / pre-commit (push) Successful in 10m39s
2026-03-06 01:18:10 +00:00
renovate c53d80792c chore(deps): update pre-commit hook golangci/golangci-lint to v2.10.1 (#283)
Release / release (push) Successful in 1m31s
authz_client / vulnerabilities (push) Successful in 2m39s
authz_client / test (push) Successful in 3m54s
pre-commit / pre-commit (push) Successful in 8m34s
2026-02-17 17:01:30 +00:00
renovate ebc0c3bb8e chore(deps): update pre-commit hook golangci/golangci-lint to v2.10.0 (#282)
Release / release (push) Failing after 41s
authz_client / vulnerabilities (push) Successful in 17m19s
authz_client / test (push) Successful in 18m59s
pre-commit / pre-commit (push) Successful in 52m24s
2026-02-17 15:01:11 +00:00
renovate cb59762fc9 chore(deps): update pre-commit hook golangci/golangci-lint to v2.9.0 (#281)
authz_client / vulnerabilities (push) Successful in 2m12s
Release / release (push) Successful in 1m55s
authz_client / test (push) Successful in 4m10s
pre-commit / pre-commit (push) Successful in 17m58s
2026-02-11 07:13:35 +00:00
renovate a82466cb27 chore(deps): update dependency go to v1.26.0 (#280)
Release / release (push) Successful in 1m22s
authz_client / vulnerabilities (push) Successful in 4m20s
authz_client / test (push) Successful in 4m30s
pre-commit / pre-commit (push) Successful in 9m2s
2026-02-11 06:19:26 +00:00
renovate 29eab978f7 chore(deps): update dependency go to v1.25.7 (#279)
Release / release (push) Failing after 58s
authz_client / test (push) Successful in 4m30s
authz_client / vulnerabilities (push) Successful in 3m54s
pre-commit / pre-commit (push) Successful in 12m54s
2026-02-04 16:16:32 +00:00
6 changed files with 81 additions and 12 deletions
+1 -1
View File
@@ -30,7 +30,7 @@ repos:
- id: go-test - id: go-test
- id: gofumpt - id: gofumpt
- repo: https://github.com/golangci/golangci-lint - repo: https://github.com/golangci/golangci-lint
rev: v2.8.0 rev: v2.11.3
hooks: hooks:
- id: golangci-lint-full - id: golangci-lint-full
- repo: https://github.com/gitleaks/gitleaks - repo: https://github.com/gitleaks/gitleaks
+1 -1
View File
@@ -1,3 +1,3 @@
{ {
"version": "v0.4.1" "version": "v0.5.0"
} }
+24
View File
@@ -2,6 +2,30 @@
All notable changes to this project will be documented in this file. 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 ## [0.4.1] - 2026-01-09
### ⚙️ Miscellaneous Tasks ### ⚙️ Miscellaneous Tasks
+21 -9
View File
@@ -28,6 +28,7 @@ type PrivilegeHandler struct {
*sync.RWMutex *sync.RWMutex
client *http.Client client *http.Client
baseURL string baseURL string
apiKey string
privileges map[string]map[string]*CompanyPrivileges 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. // New creates a new PrivilegeHandler. Pass OptsFuncs to configure.
func New(opts ...OptsFunc) *PrivilegeHandler { func New(opts ...OptsFunc) *PrivilegeHandler {
handler := &PrivilegeHandler{ handler := &PrivilegeHandler{
@@ -57,7 +65,16 @@ func New(opts ...OptsFunc) *PrivilegeHandler {
// Fetch the initial set of privileges from an authz-service // Fetch the initial set of privileges from an authz-service
func (h *PrivilegeHandler) Fetch() error { 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 { if err != nil {
return err return err
} }
@@ -87,13 +104,14 @@ func (h *PrivilegeHandler) Setup() []goamqp.Setup {
// Process privilege-related events and update the internal state // Process privilege-related events and update the internal state
func (h *PrivilegeHandler) Process(msg interface{}, _ goamqp.Headers) (interface{}, error) { func (h *PrivilegeHandler) Process(msg interface{}, _ goamqp.Headers) (interface{}, error) {
h.Lock()
defer h.Unlock()
switch ev := msg.(type) { switch ev := msg.(type) {
case *UserAdded: case *UserAdded:
if priv, exists := h.privileges[ev.Email]; exists { if priv, exists := h.privileges[ev.Email]; exists {
priv[ev.CompanyID] = &CompanyPrivileges{} priv[ev.CompanyID] = &CompanyPrivileges{}
} else { } else {
h.Lock()
defer h.Unlock()
h.privileges[ev.Email] = map[string]*CompanyPrivileges{ h.privileges[ev.Email] = map[string]*CompanyPrivileges{
ev.CompanyID: {}, ev.CompanyID: {},
} }
@@ -101,19 +119,13 @@ func (h *PrivilegeHandler) Process(msg interface{}, _ goamqp.Headers) (interface
return nil, nil return nil, nil
case *UserRemoved: case *UserRemoved:
if priv, exists := h.privileges[ev.Email]; exists { if priv, exists := h.privileges[ev.Email]; exists {
h.Lock()
defer h.Unlock()
delete(priv, ev.CompanyID) delete(priv, ev.CompanyID)
} }
return nil, nil return nil, nil
case *PrivilegeAdded: case *PrivilegeAdded:
h.Lock()
defer h.Unlock()
h.setPrivileges(ev.Email, ev.CompanyID, ev.Privilege, true) h.setPrivileges(ev.Email, ev.CompanyID, ev.Privilege, true)
return nil, nil return nil, nil
case *PrivilegeRemoved: case *PrivilegeRemoved:
h.Lock()
defer h.Unlock()
h.setPrivileges(ev.Email, ev.CompanyID, ev.Privilege, false) h.setPrivileges(ev.Email, ev.CompanyID, ev.Privilege, false)
return nil, nil return nil, nil
default: default:
+33
View File
@@ -251,6 +251,39 @@ func TestPrivilegeHandler_IsAllowed_Return_True_If_Privilege_Exists(t *testing.T
assert.True(t, result) 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) { func TestPrivilegeHandler_Fetch_Error_Response(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(500) w.WriteHeader(500)
+1 -1
View File
@@ -2,7 +2,7 @@ module gitea.unbound.se/shiny/authz_client
go 1.22.12 go 1.22.12
toolchain go1.25.6 toolchain go1.26.1
require ( require (
github.com/sparetimecoders/goamqp v0.3.3 github.com/sparetimecoders/goamqp v0.3.3