20 Commits
Author SHA1 Message Date
releaser 9d1b981644 chore(release): prepare for v0.6.0 (#330)
Unbound Release / Check Preconditions (push) Successful in 26s
Unbound Release / Generate Changelog and Handle PR (push) Successful in 28s
Unbound Release / Create Tag (push) Skipped
authz_client / test (push) Skipped
authz_client / vulnerabilities (push) Skipped
Release / release (push) Successful in 1m5s
Unbound Release / Create Release (push) Successful in 30s
pre-commit / pre-commit (push) Successful in 3m3s
## [0.6.0] - 2026-09-11

### 🚀 Features

- [**breaking**] Consume privilege events with go-messaging-amqp (#327)

### ⚙️ Miscellaneous Tasks

- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.13.2 (#325)
- Bump the minor version for breaking changes before 1.0.0 (#328)

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

---

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

Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/330
Co-authored-by: Unbound Releaser <releaser@unbound.se>
2026-09-14 06:50:03 +00:00
argoyle 3347d598a4 chore: bump the minor version for breaking changes before 1.0.0 (#328)
authz_client / test (push) Skipped
Unbound Release / Check Preconditions (push) Successful in 31s
Unbound Release / Create Tag (push) Skipped
authz_client / vulnerabilities (push) Skipped
Release / release (push) Successful in 1m25s
pre-commit / pre-commit (push) Successful in 2m26s
Unbound Release / Create Release (push) Successful in 23s
Unbound Release / Generate Changelog and Handle PR (push) Successful in 39s
2026-09-11 21:05:52 +00:00
argoyle 6bdf6e1cd3 feat!: consume privilege events with go-messaging-amqp (#327)
Unbound Release / Create Tag (push) Skipped
Unbound Release / Check Preconditions (push) Successful in 29s
authz_client / vulnerabilities (push) Skipped
authz_client / test (push) Skipped
pre-commit / pre-commit (push) Successful in 2m36s
Unbound Release / Create Release (push) Successful in 40s
Unbound Release / Generate Changelog and Handle PR (push) Successful in 37s
Release / release (push) Successful in 2m24s
2026-09-11 21:00:41 +00:00
renovate f5e9eb52a7 chore(deps): update pre-commit hook golangci/golangci-lint to v2.13.2 (#325)
Unbound Release / Check Preconditions (push) Successful in 22s
Unbound Release / Create Tag (push) Skipped
authz_client / test (push) Skipped
Release / release (push) Successful in 4m57s
Unbound Release / Generate Changelog and Handle PR (push) Successful in 36s
authz_client / vulnerabilities (push) Skipped
pre-commit / pre-commit (push) Skipped
Unbound Release / Create Release (push) Successful in 24s
2026-08-31 00:08:45 +00:00
releaser 85d29c1196 chore(release): prepare for v0.5.1 (#324)
Unbound Release / Check Preconditions (push) Successful in 31s
Unbound Release / Create Tag (push) Skipped
Unbound Release / Generate Changelog and Handle PR (push) Successful in 29s
Unbound Release / Create Release (push) Successful in 31s
authz_client / test (push) Skipped
authz_client / vulnerabilities (push) Skipped
pre-commit / pre-commit (push) Skipped
Release / release (push) Successful in 6m25s
## [0.5.1] - 2026-08-21

### 🐛 Bug Fixes

- *(ci)* Use go-test-coverage binary directly to fix Gitea Actions (#303)
- *(deps)* Update module github.com/stretchr/testify to v1.12.0 (#319)
- *(deps)* Update module github.com/stretchr/testify to v1.12.1 (#321)

### ⚙️ Miscellaneous Tasks

- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.30.1 (#296)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.11.4 (#298)
- *(deps)* Update dependency go to v1.26.2 (#300)
- *(deps)* Update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.25.0 (#304)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.12.0 (#306)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.12.1 (#308)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.12.2 (#309)
- *(deps)* Update actions/checkout action to v7 (#311)
- *(deps)* Update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.26.0 (#313)
- *(deps)* Update actions/setup-go action to v7 (#315)
- *(deps)* Update actions/setup-python action to v7 (#317)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.13.1 (#322)

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

---

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

Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/324
Co-authored-by: Unbound Releaser <releaser@unbound.se>
2026-08-29 11:26:44 +00:00
renovate 37d9282f7e fix(deps): update module github.com/stretchr/testify to v1.12.1 (#321)
Unbound Release / Check Preconditions (push) Successful in 21s
Unbound Release / Create Tag (push) Skipped
Unbound Release / Generate Changelog and Handle PR (push) Successful in 39s
Release / release (push) Successful in 3m36s
authz_client / test (push) Skipped
authz_client / vulnerabilities (push) Skipped
pre-commit / pre-commit (push) Successful in 3m14s
Unbound Release / Create Release (push) Successful in 53s
2026-08-21 13:03:06 +00:00
renovate 5c2477eded chore(deps): update pre-commit hook golangci/golangci-lint to v2.13.1 (#322)
authz_client / test (push) Skipped
authz_client / vulnerabilities (push) Skipped
pre-commit / pre-commit (push) Successful in 2m8s
Unbound Release / Create Tag (push) Skipped
Unbound Release / Create Release (push) Successful in 24s
Unbound Release / Check Preconditions (push) Successful in 30s
Unbound Release / Generate Changelog and Handle PR (push) Successful in 48s
Release / release (push) Successful in 1m20s
2026-08-21 12:08:18 +00:00
renovate bfd5fd4c16 fix(deps): update module github.com/stretchr/testify to v1.12.0 (#319)
Unbound Release / Check Preconditions (push) Successful in 21s
Unbound Release / Create Tag (push) Skipped
authz_client / test (push) Skipped
authz_client / vulnerabilities (push) Skipped
pre-commit / pre-commit (push) Skipped
Unbound Release / Generate Changelog and Handle PR (push) Successful in 53s
Release / release (push) Successful in 47m10s
Unbound Release / Create Release (push) Successful in 24s
2026-08-17 09:09:30 +00:00
renovate dfc666ebb0 chore(deps): update actions/setup-python action to v7 (#317)
Unbound Release / Check Preconditions (push) Successful in 25s
Unbound Release / Create Tag (push) Skipped
authz_client / test (push) Skipped
authz_client / vulnerabilities (push) Skipped
pre-commit / pre-commit (push) Skipped
Unbound Release / Generate Changelog and Handle PR (push) Successful in 51s
Unbound Release / Create Release (push) Successful in 42s
Release / release (push) Successful in 19m15s
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [actions/setup-python](https://github.com/actions/setup-python) | action | major | `v6` → `v7` |

---

### Release Notes

<details>
<summary>actions/setup-python (actions/setup-python)</summary>

### [`v7.0.0`](https://github.com/actions/setup-python/releases/tag/v7.0.0)

[Compare Source](https://github.com/actions/setup-python/compare/v7.0.0...v7.0.0)

#### What's Changed

##### Enhancements

- Migrate to ESM and upgrade dependencies by [@&#8203;priyagupta108](https://github.com/priyagupta108) in [#&#8203;1330](https://github.com/actions/setup-python/pull/1330)
- Pin SHA commits and update docs with latest versions by [@&#8203;HarithaVattikuti](https://github.com/HarithaVattikuti) in [#&#8203;1338](https://github.com/actions/setup-python/pull/1338)
- Remove the pip-install input by [@&#8203;gowridurgad](https://github.com/gowridurgad) in [#&#8203;1336](https://github.com/actions/setup-python/pull/1336)

##### Bug Fix

- Fix to Classify stderr warning messages as warnings instead of errors in annotations by [@&#8203;lmvysakh](https://github.com/lmvysakh) in [#&#8203;1335](https://github.com/actions/setup-python/pull/1335)
- Validate and retry manifest fetch to prevent silent failures by [@&#8203;priyagupta108](https://github.com/priyagupta108) in [#&#8203;1332](https://github.com/actions/setup-python/pull/1332)

##### Dependency Upgrade

- Bump certifi from 2020.6.20 to 2024.7.4 in /**tests**/data by [@&#8203;dependabot](https://github.com/dependabot) in [#&#8203;1328](https://github.com/actions/setup-python/pull/1328)
- Remove EOL Python versions and Bumps numpy text fixture by [@&#8203;priya-kinthali](https://github.com/priya-kinthali) in [#&#8203;1333](https://github.com/actions/setup-python/pull/1333)
- Upgrade [@&#8203;actions/cache](https://github.com/actions/cache) to 6.2.0 by [@&#8203;philip-gai](https://github.com/philip-gai) in [#&#8203;1337](https://github.com/actions/setup-python/pull/1337)

#### New Contributors

- [@&#8203;lmvysakh](https://github.com/lmvysakh) made their first contribution in [#&#8203;1335](https://github.com/actions/setup-python/pull/1335)
- [@&#8203;philip-gai](https://github.com/philip-gai) made their first contribution in [#&#8203;1337](https://github.com/actions/setup-python/pull/1337)

**Full Changelog**: <https://github.com/actions/setup-python/compare/v6...v7.0.0>

### [`v7`](https://github.com/actions/setup-python/compare/v6.3.0...v7.0.0)

[Compare Source](https://github.com/actions/setup-python/compare/v6.3.0...v7.0.0)

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNTcuMiIsInVwZGF0ZWRJblZlciI6IjQzLjI1Ny4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/317

Co-authored-by: Renovate Bot <renovate@unbound.se>
2026-07-25 11:38:17 +00:00
renovate 75f87fd618 chore(deps): update actions/setup-go action to v7 (#315)
Release / release (push) Successful in 49s
authz_client / test (push) Successful in 1m4s
authz_client / vulnerabilities (push) Successful in 50s
pre-commit / pre-commit (push) Successful in 3m1s
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [actions/setup-go](https://github.com/actions/setup-go) | action | major | `v6` → `v7` |

---

### Release Notes

<details>
<summary>actions/setup-go (actions/setup-go)</summary>

### [`v7.0.0`](https://github.com/actions/setup-go/releases/tag/v7.0.0)

[Compare Source](https://github.com/actions/setup-go/compare/v7.0.0...v7.0.0)

##### What's Changed

- Migrate to ESM and upgrade dependencies by [@&#8203;priyagupta108](https://github.com/priyagupta108) in [#&#8203;763](https://github.com/actions/setup-go/pull/763)
- chore(deps): bump [@&#8203;actions/cache](https://github.com/actions/cache) to 6.2.0 by [@&#8203;philip-gai](https://github.com/philip-gai) in [#&#8203;771](https://github.com/actions/setup-go/pull/771)

##### New Contributors

- [@&#8203;philip-gai](https://github.com/philip-gai) made their first contribution in [#&#8203;771](https://github.com/actions/setup-go/pull/771)

**Full Changelog**: <https://github.com/actions/setup-go/compare/v6...v7.0.0>

### [`v7`](https://github.com/actions/setup-go/compare/v6.5.0...v7.0.0)

[Compare Source](https://github.com/actions/setup-go/compare/v6.5.0...v7.0.0)

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNDMuMiIsInVwZGF0ZWRJblZlciI6IjQzLjI0My4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/315
Co-authored-by: Renovate Bot <renovate@unbound.se>
Co-committed-by: Renovate Bot <renovate@unbound.se>
2026-07-19 18:55:40 +00:00
renovate 752f80ea96 chore(deps): update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.26.0 (#313)
authz_client / test (push) Successful in 1m43s
authz_client / vulnerabilities (push) Successful in 58s
Release / release (push) Successful in 48s
pre-commit / pre-commit (push) Successful in 4m5s
2026-06-27 23:27:40 +00:00
renovate 08269c034b chore(deps): update actions/checkout action to v7 (#311)
Release / release (push) Successful in 1m0s
authz_client / test (push) Successful in 2m6s
authz_client / vulnerabilities (push) Successful in 2m13s
pre-commit / pre-commit (push) Successful in 5m42s
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [actions/checkout](https://github.com/actions/checkout) | action | major | `v6` → `v7` |

---

### Release Notes

<details>
<summary>actions/checkout (actions/checkout)</summary>

### [`v7.0.0`](https://github.com/actions/checkout/blob/HEAD/CHANGELOG.md#v700)

[Compare Source](https://github.com/actions/checkout/compare/v7.0.0...v7.0.0)

- Block checking out fork PR for pull\_request\_target and workflow\_run by [@&#8203;aiqiaoy](https://github.com/aiqiaoy) in [#&#8203;2454](https://github.com/actions/checkout/pull/2454)
- Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the minor-actions-dependencies group across 1 directory by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2458](https://github.com/actions/checkout/pull/2458)
- Bump flatted from 3.3.1 to 3.4.2 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2460](https://github.com/actions/checkout/pull/2460)
- Bump js-yaml from 4.1.0 to 4.2.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2461](https://github.com/actions/checkout/pull/2461)
- Bump [@&#8203;actions/core](https://github.com/actions/core) and [@&#8203;actions/tool-cache](https://github.com/actions/tool-cache) and Remove uuid by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2459](https://github.com/actions/checkout/pull/2459)
- upgrade module to esm and update dependencies by [@&#8203;aiqiaoy](https://github.com/aiqiaoy) in [#&#8203;2463](https://github.com/actions/checkout/pull/2463)
- Bump the minor-npm-dependencies group across 1 directory with 3 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2462](https://github.com/actions/checkout/pull/2462)

### [`v7`](https://github.com/actions/checkout/blob/HEAD/CHANGELOG.md#v700)

[Compare Source](https://github.com/actions/checkout/compare/v6.0.3...v7.0.0)

- Block checking out fork PR for pull\_request\_target and workflow\_run by [@&#8203;aiqiaoy](https://github.com/aiqiaoy) in [#&#8203;2454](https://github.com/actions/checkout/pull/2454)
- Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the minor-actions-dependencies group across 1 directory by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2458](https://github.com/actions/checkout/pull/2458)
- Bump flatted from 3.3.1 to 3.4.2 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2460](https://github.com/actions/checkout/pull/2460)
- Bump js-yaml from 4.1.0 to 4.2.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2461](https://github.com/actions/checkout/pull/2461)
- Bump [@&#8203;actions/core](https://github.com/actions/core) and [@&#8203;actions/tool-cache](https://github.com/actions/tool-cache) and Remove uuid by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2459](https://github.com/actions/checkout/pull/2459)
- upgrade module to esm and update dependencies by [@&#8203;aiqiaoy](https://github.com/aiqiaoy) in [#&#8203;2463](https://github.com/actions/checkout/pull/2463)
- Bump the minor-npm-dependencies group across 1 directory with 3 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2462](https://github.com/actions/checkout/pull/2462)

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMjAuMCIsInVwZGF0ZWRJblZlciI6IjQzLjIyMC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/311
Co-authored-by: Renovate Bot <renovate@unbound.se>
Co-committed-by: Renovate Bot <renovate@unbound.se>
2026-06-21 15:45:38 +00:00
renovate 89fa8928dc chore(deps): update pre-commit hook golangci/golangci-lint to v2.12.2 (#309)
Release / release (push) Successful in 1m8s
authz_client / vulnerabilities (push) Successful in 1m36s
authz_client / test (push) Successful in 2m23s
pre-commit / pre-commit (push) Successful in 5m56s
2026-05-09 13:27:43 +00:00
renovate 6fccd2010c chore(deps): update pre-commit hook golangci/golangci-lint to v2.12.1 (#308)
Release / release (push) Failing after 1m1s
authz_client / vulnerabilities (push) Successful in 1m30s
authz_client / test (push) Successful in 2m18s
pre-commit / pre-commit (push) Successful in 5m13s
2026-05-04 17:07:50 +00:00
renovate 4296334275 chore(deps): update pre-commit hook golangci/golangci-lint to v2.12.0 (#306)
Release / release (push) Successful in 1m5s
authz_client / vulnerabilities (push) Successful in 1m56s
authz_client / test (push) Successful in 2m41s
pre-commit / pre-commit (push) Successful in 6m8s
2026-05-04 14:07:07 +00:00
renovate daa836e97d chore(deps): update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.25.0 (#304)
authz_client / test (push) Successful in 2m23s
authz_client / vulnerabilities (push) Successful in 1m32s
Release / release (push) Successful in 53s
pre-commit / pre-commit (push) Successful in 5m53s
2026-05-03 16:17:20 +00:00
argoyle f9a89b64be fix(ci): use go-test-coverage binary directly to fix Gitea Actions (#303)
authz_client / vulnerabilities (push) Successful in 1m37s
Release / release (push) Failing after 1m2s
authz_client / test (push) Successful in 2m44s
pre-commit / pre-commit (push) Failing after 14m25s
## Summary

- `vladopajic/go-test-coverage@v2` (v2.18.5+, released 2026-04-26/27) restructured its composite action to pass inputs via env-var mapping. Gitea `act_runner` doesn't expand `${{ }}` expressions inside docker-action `env:` blocks reliably, so the literal string `${{ inputs.config }}` reached the binary and broke the 'Check coverage' step.
- Replace the action with a direct `go install` + binary invocation (matching the established Frostmoln pattern).
- Use `--github-action-output` to expose `total-coverage` as a step output, replacing the manual `go tool cover -func | grep | awk` calculations.
- Baseline artifact now stores the percentage directly instead of the full coverage profile.
- Bump `go` directive in `go.mod` from 1.22.12 → 1.26.2 (matching toolchain) — we are the sole consumers of this module.

## Test plan

- [x] `prek run --all-files` passes
- [ ] CI passes on this PR
- [ ] After merge, baseline artifact format propagates on next push to main

Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/303
2026-04-29 06:06:22 +00:00
renovate 775d25cb59 chore(deps): update dependency go to v1.26.2 (#300)
authz_client / vulnerabilities (push) Successful in 1m46s
Release / release (push) Successful in 1m0s
authz_client / test (push) Successful in 2m10s
pre-commit / pre-commit (push) Successful in 6m1s
2026-04-10 00:13:25 +00:00
renovate ef992cb9db chore(deps): update pre-commit hook golangci/golangci-lint to v2.11.4 (#298)
Release / release (push) Successful in 1m6s
authz_client / vulnerabilities (push) Successful in 1m38s
authz_client / test (push) Successful in 2m18s
pre-commit / pre-commit (push) Successful in 6m1s
2026-03-22 18:11:14 +00:00
renovate c3b8a3f1ce chore(deps): update pre-commit hook gitleaks/gitleaks to v8.30.1 (#296)
authz_client / vulnerabilities (push) Successful in 2m10s
Release / release (push) Successful in 1m29s
authz_client / test (push) Successful in 3m0s
pre-commit / pre-commit (push) Successful in 7m11s
2026-03-12 16:09:43 +00:00
11 changed files with 259 additions and 110 deletions

No files matched your search

+15 -19
View File
@@ -10,19 +10,18 @@ jobs:
test: test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v7
- uses: actions/setup-go@v6 - uses: actions/setup-go@v7
with: with:
go-version: 'stable' go-version: 'stable'
- name: Run tests - name: Run tests
run: go test -race -coverprofile=coverage.txt ./... run: go test -race -coverprofile=coverage.txt ./...
- name: Check coverage - name: Check coverage
uses: vladopajic/go-test-coverage@v2 id: coverage
with: run: |
config: ./.testcoverage.yml go install github.com/vladopajic/go-test-coverage/v2@latest
go-test-coverage --config ./.testcoverage.yml --github-action-output
# Download baseline coverage from main branch (for PRs)
- name: Download baseline coverage - name: Download baseline coverage
if: gitea.event_name == 'pull_request' if: gitea.event_name == 'pull_request'
uses: actions/download-artifact@v3 uses: actions/download-artifact@v3
@@ -30,14 +29,12 @@ jobs:
name: coverage-baseline name: coverage-baseline
path: ./baseline path: ./baseline
continue-on-error: true continue-on-error: true
# Compare coverage against baseline (for PRs)
- name: Compare coverage - name: Compare coverage
if: gitea.event_name == 'pull_request' if: gitea.event_name == 'pull_request'
run: | run: |
CURRENT=$(go tool cover -func=coverage.txt | grep "^total:" | awk '{print $NF}' | tr -d '%') CURRENT="${{ steps.coverage.outputs.total-coverage }}"
if [ -f ./baseline/coverage.txt ]; then if [ -f ./baseline/coverage.txt ]; then
BASE=$(go tool cover -func=./baseline/coverage.txt | grep "^total:" | awk '{print $NF}' | tr -d '%') BASE=$(cat ./baseline/coverage.txt)
echo "Base coverage: ${BASE}%" echo "Base coverage: ${BASE}%"
echo "Current coverage: ${CURRENT}%" echo "Current coverage: ${CURRENT}%"
if [ "$(echo "$CURRENT < $BASE" | bc -l)" -eq 1 ]; then if [ "$(echo "$CURRENT < $BASE" | bc -l)" -eq 1 ]; then
@@ -49,8 +46,9 @@ jobs:
echo "No baseline coverage found, skipping comparison" echo "No baseline coverage found, skipping comparison"
echo "Current coverage: ${CURRENT}%" echo "Current coverage: ${CURRENT}%"
fi fi
- name: Save coverage baseline
# Upload coverage as baseline (only on main) if: gitea.ref == 'refs/heads/main'
run: echo "${{ steps.coverage.outputs.total-coverage }}" > coverage.txt
- name: Upload coverage baseline - name: Upload coverage baseline
if: gitea.ref == 'refs/heads/main' if: gitea.ref == 'refs/heads/main'
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
@@ -58,25 +56,23 @@ jobs:
name: coverage-baseline name: coverage-baseline
path: coverage.txt path: coverage.txt
retention-days: 90 retention-days: 90
# Post coverage to PR comment
- name: Post coverage comment - name: Post coverage comment
if: gitea.event_name == 'pull_request' if: gitea.event_name == 'pull_request'
env: env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
GITEA_URL: ${{ gitea.server_url }} GITEA_URL: ${{ gitea.server_url }}
run: | run: |
COVERAGE=$(go tool cover -func=coverage.txt | grep "^total:" | awk '{print $NF}') COVERAGE="${{ steps.coverage.outputs.total-coverage }}"
curl -X POST "${GITEA_URL}/api/v1/repos/${{ gitea.repository }}/issues/${{ gitea.event.pull_request.number }}/comments" \ curl -X POST "${GITEA_URL}/api/v1/repos/${{ gitea.repository }}/issues/${{ gitea.event.pull_request.number }}/comments" \
-H "Authorization: token ${GITEA_TOKEN}" \ -H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d "{\"body\": \"## Coverage Report\n\nTotal coverage: **${COVERAGE}**\"}" -d "{\"body\": \"## Coverage Report\n\nTotal coverage: **${COVERAGE}%**\"}"
vulnerabilities: vulnerabilities:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v7
- uses: actions/setup-go@v6 - uses: actions/setup-go@v7
with: with:
go-version: 'stable' go-version: 'stable'
- name: Check vulnerabilities - name: Check vulnerabilities
+3 -3
View File
@@ -13,11 +13,11 @@ jobs:
env: env:
SKIP: no-commit-to-branch SKIP: no-commit-to-branch
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v7
- uses: actions/setup-go@v6 - uses: actions/setup-go@v7
with: with:
go-version: stable go-version: stable
- uses: actions/setup-python@v6 - uses: actions/setup-python@v7
with: with:
python-version: '3.14' python-version: '3.14'
- name: Install goimports - name: Install goimports
+3 -3
View File
@@ -11,7 +11,7 @@ repos:
- --allow-multiple-documents - --allow-multiple-documents
- id: check-added-large-files - id: check-added-large-files
- repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook - repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook
rev: v9.24.0 rev: v9.26.0
hooks: hooks:
- id: commitlint - id: commitlint
stages: [ commit-msg ] stages: [ commit-msg ]
@@ -30,10 +30,10 @@ 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.11.3 rev: v2.13.2
hooks: hooks:
- id: golangci-lint-full - id: golangci-lint-full
- repo: https://github.com/gitleaks/gitleaks - repo: https://github.com/gitleaks/gitleaks
rev: v8.30.0 rev: v8.30.1
hooks: hooks:
- id: gitleaks - id: gitleaks
+1 -1
View File
@@ -1,3 +1,3 @@
{ {
"version": "v0.5.0" "version": "v0.6.0"
} }
+34
View File
@@ -2,6 +2,40 @@
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.6.0] - 2026-09-11
### 🚀 Features
- [**breaking**] Consume privilege events with go-messaging-amqp (#327)
### ⚙️ Miscellaneous Tasks
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.13.2 (#325)
- Bump the minor version for breaking changes before 1.0.0 (#328)
## [0.5.1] - 2026-08-29
### 🐛 Bug Fixes
- *(ci)* Use go-test-coverage binary directly to fix Gitea Actions (#303)
- *(deps)* Update module github.com/stretchr/testify to v1.12.0 (#319)
- *(deps)* Update module github.com/stretchr/testify to v1.12.1 (#321)
### ⚙️ Miscellaneous Tasks
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.30.1 (#296)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.11.4 (#298)
- *(deps)* Update dependency go to v1.26.2 (#300)
- *(deps)* Update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.25.0 (#304)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.12.0 (#306)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.12.1 (#308)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.12.2 (#309)
- *(deps)* Update actions/checkout action to v7 (#311)
- *(deps)* Update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.26.0 (#313)
- *(deps)* Update actions/setup-go action to v7 (#315)
- *(deps)* Update actions/setup-python action to v7 (#317)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.13.1 (#322)
## [0.5.0] - 2026-03-12 ## [0.5.0] - 2026-03-12
### 🚀 Features ### 🚀 Features
+1 -1
View File
@@ -43,4 +43,4 @@ The `CompanyPrivileges` struct contains permission flags:
### Event Handling ### Event Handling
Implements `goamqp` message handlers to receive privilege update events from the authz-service, keeping the local privilege cache up-to-date. Registers per-replica (transient) go-messaging-amqp consumers for privilege update events from the authz-service (`Setup()`), keeping the local privilege cache up-to-date. Don't combine `Setup()` with go-messaging-amqp's `WithReconnect`: a reconnect declares new per-replica queues, so revocations published during the outage are lost unless `Fetch()` runs again. Services exit on connection loss (`CloseListener`) and re-fetch on start.
+25 -11
View File
@@ -1,6 +1,7 @@
package client package client
import ( import (
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
@@ -8,7 +9,8 @@ import (
"reflect" "reflect"
"sync" "sync"
"github.com/sparetimecoders/goamqp" goamqp "codeberg.org/messaging/go-messaging-amqp"
spec "codeberg.org/messaging/messaging"
) )
// CompanyPrivileges contains the privileges for a combination of email address and company id // CompanyPrivileges contains the privileges for a combination of email address and company id
@@ -95,15 +97,27 @@ func (h *PrivilegeHandler) Fetch() error {
func (h *PrivilegeHandler) Setup() []goamqp.Setup { func (h *PrivilegeHandler) Setup() []goamqp.Setup {
return []goamqp.Setup{ return []goamqp.Setup{
goamqp.TransientEventStreamConsumer("User.Added", h.Process, UserAdded{}), goamqp.TransientEventStreamConsumer("User.Added", process[UserAdded](h)),
goamqp.TransientEventStreamConsumer("User.Removed", h.Process, UserRemoved{}), goamqp.TransientEventStreamConsumer("User.Removed", process[UserRemoved](h)),
goamqp.TransientEventStreamConsumer("Privilege.Added", h.Process, PrivilegeAdded{}), goamqp.TransientEventStreamConsumer("Privilege.Added", process[PrivilegeAdded](h)),
goamqp.TransientEventStreamConsumer("Privilege.Removed", h.Process, PrivilegeRemoved{}), goamqp.TransientEventStreamConsumer("Privilege.Removed", process[PrivilegeRemoved](h)),
}
}
// privilegeEvent is the set of events Process handles.
type privilegeEvent interface {
UserAdded | UserRemoved | PrivilegeAdded | PrivilegeRemoved
}
// process adapts Process to a typed go-messaging-amqp handler.
func process[T privilegeEvent](h *PrivilegeHandler) spec.EventHandler[T] {
return func(_ context.Context, event spec.ConsumableEvent[T]) error {
return h.Process(&event.Payload)
} }
} }
// 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 any) error {
h.Lock() h.Lock()
defer h.Unlock() defer h.Unlock()
@@ -116,21 +130,21 @@ func (h *PrivilegeHandler) Process(msg interface{}, _ goamqp.Headers) (interface
ev.CompanyID: {}, ev.CompanyID: {},
} }
} }
return nil, nil return nil
case *UserRemoved: case *UserRemoved:
if priv, exists := h.privileges[ev.Email]; exists { if priv, exists := h.privileges[ev.Email]; exists {
delete(priv, ev.CompanyID) delete(priv, ev.CompanyID)
} }
return nil, nil return nil
case *PrivilegeAdded: case *PrivilegeAdded:
h.setPrivileges(ev.Email, ev.CompanyID, ev.Privilege, true) h.setPrivileges(ev.Email, ev.CompanyID, ev.Privilege, true)
return nil, nil return nil
case *PrivilegeRemoved: case *PrivilegeRemoved:
h.setPrivileges(ev.Email, ev.CompanyID, ev.Privilege, false) h.setPrivileges(ev.Email, ev.CompanyID, ev.Privilege, false)
return nil, nil return nil
default: default:
fmt.Printf("Got unexpected message type (%s): '%+v'\n", reflect.TypeOf(msg).String(), msg) fmt.Printf("Got unexpected message type (%s): '%+v'\n", reflect.TypeOf(msg).String(), msg)
return nil, fmt.Errorf("unexpected event type: '%s'", reflect.TypeOf(msg)) return fmt.Errorf("unexpected event type: '%s'", reflect.TypeOf(msg))
} }
} }
+84 -47
View File
@@ -1,6 +1,7 @@
package client package client
import ( import (
"context"
"fmt" "fmt"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
@@ -8,28 +9,27 @@ import (
"sync" "sync"
"testing" "testing"
"github.com/sparetimecoders/goamqp" goamqp "codeberg.org/messaging/go-messaging-amqp"
spec "codeberg.org/messaging/messaging"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestPrivilegeHandler_Process_InvalidType(t *testing.T) { func TestPrivilegeHandler_Process_InvalidType(t *testing.T) {
handler := New(WithBaseURL("base")) handler := New(WithBaseURL("base"))
result, err := handler.Process("abc", goamqp.Headers{}) err := handler.Process("abc")
assert.Nil(t, result)
assert.EqualError(t, err, "unexpected event type: 'string'") assert.EqualError(t, err, "unexpected event type: 'string'")
} }
func TestPrivilegeHandler_Process_PrivilegeRemoved(t *testing.T) { func TestPrivilegeHandler_Process_PrivilegeRemoved(t *testing.T) {
handler := New(WithBaseURL("base")) handler := New(WithBaseURL("base"))
result, err := handler.Process(&PrivilegeAdded{ err := handler.Process(&PrivilegeAdded{
Email: "jim@example.org", Email: "jim@example.org",
CompanyID: "abc-123", CompanyID: "abc-123",
Privilege: PrivilegeAdmin, Privilege: PrivilegeAdmin,
}, goamqp.Headers{}) })
assert.Nil(t, result)
assert.NoError(t, err) assert.NoError(t, err)
companies := handler.CompaniesByUser("jim@example.org", func(privileges CompanyPrivileges) bool { companies := handler.CompaniesByUser("jim@example.org", func(privileges CompanyPrivileges) bool {
@@ -38,12 +38,11 @@ func TestPrivilegeHandler_Process_PrivilegeRemoved(t *testing.T) {
assert.Equal(t, []string{"abc-123"}, companies) assert.Equal(t, []string{"abc-123"}, companies)
result, err = handler.Process(&PrivilegeRemoved{ err = handler.Process(&PrivilegeRemoved{
Email: "jim@example.org", Email: "jim@example.org",
CompanyID: "abc-123", CompanyID: "abc-123",
Privilege: PrivilegeAdmin, Privilege: PrivilegeAdmin,
}, goamqp.Headers{}) })
assert.Nil(t, result)
assert.NoError(t, err) assert.NoError(t, err)
companies = handler.CompaniesByUser("jim@example.org", func(privileges CompanyPrivileges) bool { companies = handler.CompaniesByUser("jim@example.org", func(privileges CompanyPrivileges) bool {
@@ -56,18 +55,16 @@ func TestPrivilegeHandler_Process_PrivilegeRemoved(t *testing.T) {
func TestPrivilegeHandler_Process_UserAdded_And_UserRemoved(t *testing.T) { func TestPrivilegeHandler_Process_UserAdded_And_UserRemoved(t *testing.T) {
handler := New(WithBaseURL("base")) handler := New(WithBaseURL("base"))
result, err := handler.Process(&UserAdded{ err := handler.Process(&UserAdded{
Email: "jim@example.org", Email: "jim@example.org",
CompanyID: "abc-123", CompanyID: "abc-123",
}, goamqp.Headers{}) })
assert.Nil(t, result)
assert.NoError(t, err) assert.NoError(t, err)
result, err = handler.Process(&UserAdded{ err = handler.Process(&UserAdded{
Email: "jim@example.org", Email: "jim@example.org",
CompanyID: "abc-456", CompanyID: "abc-456",
}, goamqp.Headers{}) })
assert.Nil(t, result)
assert.NoError(t, err) assert.NoError(t, err)
companies := handler.CompaniesByUser("jim@example.org", func(privileges CompanyPrivileges) bool { companies := handler.CompaniesByUser("jim@example.org", func(privileges CompanyPrivileges) bool {
@@ -76,18 +73,16 @@ func TestPrivilegeHandler_Process_UserAdded_And_UserRemoved(t *testing.T) {
sort.Strings(companies) sort.Strings(companies)
assert.Equal(t, []string{"abc-123", "abc-456"}, companies) assert.Equal(t, []string{"abc-123", "abc-456"}, companies)
result, err = handler.Process(&UserRemoved{ err = handler.Process(&UserRemoved{
Email: "jim@example.org", Email: "jim@example.org",
CompanyID: "abc-123", CompanyID: "abc-123",
}, goamqp.Headers{}) })
assert.Nil(t, result)
assert.NoError(t, err) assert.NoError(t, err)
result, err = handler.Process(&UserRemoved{ err = handler.Process(&UserRemoved{
Email: "jim@example.org", Email: "jim@example.org",
CompanyID: "abc-456", CompanyID: "abc-456",
}, goamqp.Headers{}) })
assert.Nil(t, result)
assert.NoError(t, err) assert.NoError(t, err)
companies = handler.CompaniesByUser("jim@example.org", func(privileges CompanyPrivileges) bool { companies = handler.CompaniesByUser("jim@example.org", func(privileges CompanyPrivileges) bool {
@@ -109,11 +104,10 @@ func TestPrivilegeHandler_GetCompanies_Email_Not_Found(t *testing.T) {
func TestPrivilegeHandler_GetCompanies_No_Companies_Found(t *testing.T) { func TestPrivilegeHandler_GetCompanies_No_Companies_Found(t *testing.T) {
handler := New(WithBaseURL("base")) handler := New(WithBaseURL("base"))
result, err := handler.Process(&UserAdded{ err := handler.Process(&UserAdded{
Email: "jim@example.org", Email: "jim@example.org",
CompanyID: "abc-123", CompanyID: "abc-123",
}, goamqp.Headers{}) })
assert.Nil(t, result)
assert.NoError(t, err) assert.NoError(t, err)
companies := handler.CompaniesByUser("jim@example.org", func(privileges CompanyPrivileges) bool { companies := handler.CompaniesByUser("jim@example.org", func(privileges CompanyPrivileges) bool {
@@ -128,11 +122,10 @@ func TestPrivilegeHandler_GetCompanies_No_Companies_Found(t *testing.T) {
assert.Equal(t, []string{"abc-123"}, companies) assert.Equal(t, []string{"abc-123"}, companies)
result, err = handler.Process(&UserRemoved{ err = handler.Process(&UserRemoved{
Email: "jim@example.org", Email: "jim@example.org",
CompanyID: "abc-123", CompanyID: "abc-123",
}, goamqp.Headers{}) })
assert.Nil(t, result)
assert.NoError(t, err) assert.NoError(t, err)
companies = handler.CompaniesByUser("jim@example.org", func(privileges CompanyPrivileges) bool { companies = handler.CompaniesByUser("jim@example.org", func(privileges CompanyPrivileges) bool {
@@ -144,12 +137,11 @@ func TestPrivilegeHandler_GetCompanies_No_Companies_Found(t *testing.T) {
func TestPrivilegeHandler_GetCompanies_Company_With_Company_Access_Found(t *testing.T) { func TestPrivilegeHandler_GetCompanies_Company_With_Company_Access_Found(t *testing.T) {
handler := New(WithBaseURL("base")) handler := New(WithBaseURL("base"))
result, err := handler.Process(&PrivilegeAdded{ err := handler.Process(&PrivilegeAdded{
Email: "jim@example.org", Email: "jim@example.org",
CompanyID: "abc-123", CompanyID: "abc-123",
Privilege: PrivilegeCompany, Privilege: PrivilegeCompany,
}, goamqp.Headers{}) })
assert.Nil(t, result)
assert.NoError(t, err) assert.NoError(t, err)
companies := handler.CompaniesByUser("jim@example.org", func(privileges CompanyPrivileges) bool { companies := handler.CompaniesByUser("jim@example.org", func(privileges CompanyPrivileges) bool {
@@ -162,12 +154,11 @@ func TestPrivilegeHandler_GetCompanies_Company_With_Company_Access_Found(t *test
func TestPrivilegeHandler_GetCompanies_Company_With_Admin_Access_Found(t *testing.T) { func TestPrivilegeHandler_GetCompanies_Company_With_Admin_Access_Found(t *testing.T) {
handler := New(WithBaseURL("base")) handler := New(WithBaseURL("base"))
result, err := handler.Process(&PrivilegeAdded{ err := handler.Process(&PrivilegeAdded{
Email: "jim@example.org", Email: "jim@example.org",
CompanyID: "abc-123", CompanyID: "abc-123",
Privilege: PrivilegeConsumer, Privilege: PrivilegeConsumer,
}, goamqp.Headers{}) })
assert.Nil(t, result)
assert.NoError(t, err) assert.NoError(t, err)
companies := handler.CompaniesByUser("jim@example.org", func(privileges CompanyPrivileges) bool { companies := handler.CompaniesByUser("jim@example.org", func(privileges CompanyPrivileges) bool {
@@ -190,11 +181,11 @@ func TestPrivilegeHandler_IsAllowed_Return_False_If_No_Privileges(t *testing.T)
func TestPrivilegeHandler_IsAllowed_Return_True_If_Privilege_Exists(t *testing.T) { func TestPrivilegeHandler_IsAllowed_Return_True_If_Privilege_Exists(t *testing.T) {
handler := New(WithBaseURL("base")) handler := New(WithBaseURL("base"))
_, _ = handler.Process(&PrivilegeAdded{ _ = handler.Process(&PrivilegeAdded{
Email: "jim@example.org", Email: "jim@example.org",
CompanyID: "abc-123", CompanyID: "abc-123",
Privilege: PrivilegeTime, Privilege: PrivilegeTime,
}, goamqp.Headers{}) })
result := handler.IsAllowed("jim@example.org", "abc-123", func(privileges CompanyPrivileges) bool { result := handler.IsAllowed("jim@example.org", "abc-123", func(privileges CompanyPrivileges) bool {
return privileges.Time return privileges.Time
@@ -202,11 +193,11 @@ func TestPrivilegeHandler_IsAllowed_Return_True_If_Privilege_Exists(t *testing.T
assert.True(t, result) assert.True(t, result)
_, _ = handler.Process(&PrivilegeAdded{ _ = handler.Process(&PrivilegeAdded{
Email: "jim@example.org", Email: "jim@example.org",
CompanyID: "abc-123", CompanyID: "abc-123",
Privilege: PrivilegeInvoicing, Privilege: PrivilegeInvoicing,
}, goamqp.Headers{}) })
result = handler.IsAllowed("jim@example.org", "abc-123", func(privileges CompanyPrivileges) bool { result = handler.IsAllowed("jim@example.org", "abc-123", func(privileges CompanyPrivileges) bool {
return privileges.Invoicing return privileges.Invoicing
@@ -214,11 +205,11 @@ func TestPrivilegeHandler_IsAllowed_Return_True_If_Privilege_Exists(t *testing.T
assert.True(t, result) assert.True(t, result)
_, _ = handler.Process(&PrivilegeAdded{ _ = handler.Process(&PrivilegeAdded{
Email: "jim@example.org", Email: "jim@example.org",
CompanyID: "abc-123", CompanyID: "abc-123",
Privilege: PrivilegeAccounting, Privilege: PrivilegeAccounting,
}, goamqp.Headers{}) })
result = handler.IsAllowed("jim@example.org", "abc-123", func(privileges CompanyPrivileges) bool { result = handler.IsAllowed("jim@example.org", "abc-123", func(privileges CompanyPrivileges) bool {
return privileges.Accounting return privileges.Accounting
@@ -226,11 +217,11 @@ func TestPrivilegeHandler_IsAllowed_Return_True_If_Privilege_Exists(t *testing.T
assert.True(t, result) assert.True(t, result)
_, _ = handler.Process(&PrivilegeAdded{ _ = handler.Process(&PrivilegeAdded{
Email: "jim@example.org", Email: "jim@example.org",
CompanyID: "abc-123", CompanyID: "abc-123",
Privilege: PrivilegeSupplier, Privilege: PrivilegeSupplier,
}, goamqp.Headers{}) })
result = handler.IsAllowed("jim@example.org", "abc-123", func(privileges CompanyPrivileges) bool { result = handler.IsAllowed("jim@example.org", "abc-123", func(privileges CompanyPrivileges) bool {
return privileges.Supplier return privileges.Supplier
@@ -238,11 +229,11 @@ func TestPrivilegeHandler_IsAllowed_Return_True_If_Privilege_Exists(t *testing.T
assert.True(t, result) assert.True(t, result)
_, _ = handler.Process(&PrivilegeAdded{ _ = handler.Process(&PrivilegeAdded{
Email: "jim@example.org", Email: "jim@example.org",
CompanyID: "abc-123", CompanyID: "abc-123",
Privilege: PrivilegeSalary, Privilege: PrivilegeSalary,
}, goamqp.Headers{}) })
result = handler.IsAllowed("jim@example.org", "abc-123", func(privileges CompanyPrivileges) bool { result = handler.IsAllowed("jim@example.org", "abc-123", func(privileges CompanyPrivileges) bool {
return privileges.Salary return privileges.Salary
@@ -522,11 +513,11 @@ func TestPrivilegeHandler_Concurrent_Process_And_Read(t *testing.T) {
companyID := fmt.Sprintf("company-%d", i%10) companyID := fmt.Sprintf("company-%d", i%10)
go func(id string) { go func(id string) {
defer wg.Done() defer wg.Done()
_, _ = handler.Process(&PrivilegeAdded{ _ = handler.Process(&PrivilegeAdded{
Email: "jim@example.org", Email: "jim@example.org",
CompanyID: id, CompanyID: id,
Privilege: PrivilegeAdmin, Privilege: PrivilegeAdmin,
}, goamqp.Headers{}) })
}(companyID) }(companyID)
} }
@@ -598,11 +589,11 @@ func TestPrivilegeHandler_Concurrent_Multiple_Operations(t *testing.T) {
wg.Add(1) wg.Add(1)
go func(idx int) { go func(idx int) {
defer wg.Done() defer wg.Done()
_, _ = handler.Process(&PrivilegeAdded{ _ = handler.Process(&PrivilegeAdded{
Email: "jane@example.org", Email: "jane@example.org",
CompanyID: fmt.Sprintf("company-%d", idx%5), CompanyID: fmt.Sprintf("company-%d", idx%5),
Privilege: PrivilegeCompany, Privilege: PrivilegeCompany,
}, goamqp.Headers{}) })
}(i) }(i)
} }
@@ -648,3 +639,49 @@ func TestPrivilegeHandler_Concurrent_Multiple_Operations(t *testing.T) {
expectedJane := []string{"company-0", "company-1", "company-2", "company-3", "company-4"} expectedJane := []string{"company-0", "company-1", "company-2", "company-3", "company-4"}
assert.Equal(t, expectedJane, janeCompanies) assert.Equal(t, expectedJane, janeCompanies)
} }
func TestPrivilegeHandler_Setup(t *testing.T) {
handler := New(WithBaseURL("base"))
topology, err := goamqp.CollectTopology("some-service", handler.Setup()...)
assert.NoError(t, err)
wiring := map[string]string{}
for _, e := range topology.Endpoints {
assert.Equal(t, spec.DirectionConsume, e.Direction)
assert.True(t, e.Ephemeral, "%s must be a per-replica consumer", e.RoutingKey)
wiring[e.RoutingKey] = e.MessageType
}
// A key wired to the wrong type could turn a revocation into a grant.
assert.Equal(t, map[string]string{
"User.Added": "client.UserAdded",
"User.Removed": "client.UserRemoved",
"Privilege.Added": "client.PrivilegeAdded",
"Privilege.Removed": "client.PrivilegeRemoved",
}, wiring)
}
func TestPrivilegeHandler_process(t *testing.T) {
ctx := context.Background()
handler := New(WithBaseURL("base"))
admin := func(p CompanyPrivileges) bool { return p.Admin }
assert.NoError(t, process[UserAdded](handler)(ctx, spec.ConsumableEvent[UserAdded]{
Payload: UserAdded{Email: "jim@example.org", CompanyID: "abc-123"},
}))
assert.False(t, handler.IsAllowed("jim@example.org", "abc-123", admin))
assert.NoError(t, process[PrivilegeAdded](handler)(ctx, spec.ConsumableEvent[PrivilegeAdded]{
Payload: PrivilegeAdded{Email: "jim@example.org", CompanyID: "abc-123", Privilege: PrivilegeAdmin},
}))
assert.True(t, handler.IsAllowed("jim@example.org", "abc-123", admin))
assert.NoError(t, process[PrivilegeRemoved](handler)(ctx, spec.ConsumableEvent[PrivilegeRemoved]{
Payload: PrivilegeRemoved{Email: "jim@example.org", CompanyID: "abc-123", Privilege: PrivilegeAdmin},
}))
assert.False(t, handler.IsAllowed("jim@example.org", "abc-123", admin))
assert.NoError(t, process[UserRemoved](handler)(ctx, spec.ConsumableEvent[UserRemoved]{
Payload: UserRemoved{Email: "jim@example.org", CompanyID: "abc-123"},
}))
assert.Empty(t, handler.CompaniesByUser("jim@example.org", func(CompanyPrivileges) bool { return true }))
}
+4
View File
@@ -78,3 +78,7 @@ filter_commits = false
topo_order = false topo_order = false
# sort the commits inside sections by oldest/newest order # sort the commits inside sections by oldest/newest order
sort_commits = "oldest" sort_commits = "oldest"
[bump]
# Before 1.0.0, a breaking change bumps the minor version instead of the major.
breaking_always_bump_major = false
+22 -10
View File
@@ -1,19 +1,31 @@
module gitea.unbound.se/shiny/authz_client module gitea.unbound.se/shiny/authz_client
go 1.22.12 go 1.26.2
toolchain go1.26.1
require ( require (
github.com/sparetimecoders/goamqp v0.3.3 codeberg.org/messaging/go-messaging-amqp v0.0.4
github.com/stretchr/testify v1.11.1 codeberg.org/messaging/messaging v0.0.5
github.com/stretchr/testify v1.12.1
) )
require ( require (
github.com/davecgh/go-spew v1.1.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/google/uuid v1.6.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/pkg/errors v0.9.1 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.23.2 // indirect
github.com/rabbitmq/amqp091-go v1.10.0 // indirect github.com/prometheus/client_model v0.6.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect github.com/prometheus/common v0.66.1 // indirect
github.com/prometheus/procfs v0.16.1 // indirect
github.com/rabbitmq/amqp091-go v1.12.0 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/otel v1.44.0 // indirect
go.opentelemetry.io/otel/metric v1.44.0 // indirect
go.opentelemetry.io/otel/trace v1.44.0 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect
go.yaml.in/yaml/v3 v3.0.5 // indirect
golang.org/x/sys v0.45.0 // indirect
google.golang.org/protobuf v1.36.8 // indirect
) )
+67 -15
View File
@@ -1,20 +1,72 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= codeberg.org/messaging/go-messaging-amqp v0.0.4 h1:MwY/kU1lBdCL7ywKAg2k6aHuJf8f78MRZQSuyrNFvQ8=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= codeberg.org/messaging/go-messaging-amqp v0.0.4/go.mod h1:6bSCIkKH0V/oI7vaIq8ttINKYwov9c8ckZrwjfvp7kc=
codeberg.org/messaging/messaging v0.0.5 h1:/ueH90F4RNPUeeJIwdG9oVhDW7+XjCzwOYq8xc0kfQk=
codeberg.org/messaging/messaging v0.0.5/go.mod h1:xyWLUcfaVzcN6GWk9uaQsxPVUC2Vm2S89mYZGdiWTWg=
codeberg.org/messaging/messaging/tck v0.0.3 h1:a4Nr7ytFqEJloTOyVeAtMNgO9Fig1ZUirjW4FVlK0lc=
codeberg.org/messaging/messaging/tck v0.0.3/go.mod h1:RiOsKXGAhNQK2STBVYGjhN0CFtmcrsEne1qUe15n8Q4=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/sparetimecoders/goamqp v0.3.3 h1:z/nfTPmrjeU/rIVuNOgsVLCimp3WFoNFvS3ZzXRJ6HE= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/sparetimecoders/goamqp v0.3.3/go.mod h1:W9NRCpWLE+Vruv2dcRSbszNil2O826d2Nv6kAkETW5o= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/nats-io/nats.go v1.52.0 h1:n3avV4VBsCgsdwh71TppsTwtv+QdPs7ntSKM8qJLGsc=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/nats-io/nats.go v1.52.0/go.mod h1:26HypzazeOkyO3/mqd1zZd53STJN0EjCYF9Uy2ZOBno=
github.com/nats-io/nkeys v0.4.15 h1:JACV5jRVO9V856KOapQ7x+EY8Jo3qw1vJt/9Jpwzkk4=
github.com/nats-io/nkeys v0.4.15/go.mod h1:CpMchTXC9fxA5zrMo4KpySxNjiDVvr8ANOSZdiNfUrs=
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs=
github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA=
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
github.com/rabbitmq/amqp091-go v1.12.0 h1:V0v14Iqfs+MwHWihJt/nGS5Ulu0vw572b2Co3mwunkI=
github.com/rabbitmq/amqp091-go v1.12.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE=
github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU=
go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc=
go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc=
go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo=
go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58=
go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0=
go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk=
go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw=
go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg=
golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4=
golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA=
golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc=
google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=