Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
09766ebe8b | ||
|
|
e0d1ce3b31 | ||
|
|
5100d53c76 | ||
|
|
01f30cfd2b | ||
|
|
9d1b981644 | ||
|
|
3347d598a4 | ||
|
|
6bdf6e1cd3 | ||
|
|
f5e9eb52a7 | ||
|
|
85d29c1196 | ||
|
|
37d9282f7e | ||
|
|
5c2477eded | ||
|
|
bfd5fd4c16 | ||
|
|
dfc666ebb0 | ||
|
|
75f87fd618 | ||
|
|
752f80ea96 | ||
|
|
08269c034b | ||
|
|
89fa8928dc | ||
|
|
6fccd2010c | ||
|
|
4296334275 | ||
|
|
daa836e97d | ||
|
|
f9a89b64be | ||
|
|
775d25cb59 | ||
|
|
ef992cb9db | ||
|
|
c3b8a3f1ce | ||
|
|
45512115c5 | ||
|
|
fe0abd62c8 | ||
|
|
a54cf45a4b | ||
|
|
f9a5ef7085 | ||
|
|
200e7cf963 | ||
|
|
110f6206f9 | ||
|
|
c53d80792c | ||
|
|
ebc0c3bb8e | ||
|
|
cb59762fc9 | ||
|
|
a82466cb27 | ||
|
|
29eab978f7 | ||
|
|
f3166426b6 | ||
|
|
3171c53393
|
||
|
|
7af8e00b4c | ||
|
|
0c0f321b33
|
||
|
|
87805f1552 | ||
|
|
74ee30bccc | ||
|
|
646e4f31c4 | ||
|
|
881fac379f | ||
|
|
2c2bd2798f | ||
|
|
204b108ece | ||
|
|
fa795a58cf | ||
|
|
60650b9c04 | ||
|
|
60d9eea9c9
|
||
|
|
dd571f8d85 | ||
|
|
1f822b2957 | ||
|
|
5b49b36a32 | ||
|
|
a06bae1da9 | ||
|
|
90084cc3a4 | ||
|
|
7825fa17a6 | ||
|
|
73f854ba06
|
||
|
|
5b3527439f | ||
|
|
681afe2626
|
||
|
|
2e1eb327e0 | ||
|
|
622d907e03 | ||
|
|
4b38ce4f0f | ||
|
|
b82e15c49b | ||
|
|
f0ea0d7d26 | ||
|
|
26de10c2b9 | ||
|
|
3865b1b5f7 | ||
|
|
cd84a51f91
|
||
|
|
eab39dc818 | ||
|
|
524cad9180 | ||
|
|
b339804535 | ||
|
|
d2ed9ed12a | ||
|
|
f521fb29c9 | ||
|
|
123dd2a4c2 | ||
|
|
c5943b41ec | ||
|
|
5644b061c0 | ||
|
|
8330219579 | ||
|
|
425013f115 | ||
|
|
7f3b78b000 | ||
|
|
ab8a9809d5 | ||
|
|
9ef9084ffa | ||
|
|
e48c5b3bb9 | ||
|
|
4421bcfbeb | ||
|
|
18748ceaad | ||
|
|
14d32b3b51 | ||
|
|
d571e92a0b | ||
|
|
d355edd642 | ||
|
|
abd34b334a | ||
|
|
da73907913 | ||
|
|
becde50685 | ||
|
|
a84a14a0d3 | ||
|
|
707e26b420 | ||
|
|
ffa2eca348 | ||
|
|
76fc782c96 | ||
|
|
4d3147c65c | ||
|
|
6643990160 | ||
|
|
20d69f9c19 | ||
|
|
d327307539 | ||
|
|
5dce8a0f2b | ||
|
|
6f6272cb02 | ||
|
|
7eddad8d4b | ||
|
|
1fd3ae5123
|
||
|
|
247c04a710 | ||
|
|
37f6c63025 | ||
|
|
215a9ed976 | ||
|
|
006ebd101e | ||
|
|
600653518c | ||
|
|
c95cd1c80a | ||
|
|
881a6f0e3c | ||
|
|
84939fa04b | ||
|
|
0821cbb6eb | ||
|
|
0cb8363ab1 | ||
|
|
8a440bd28c | ||
|
|
13461b43e3 | ||
|
|
49100894e9 | ||
|
|
7818f97a7c | ||
|
|
66c429bde1 | ||
|
|
585fa5dfa4 | ||
|
|
82cca9b09c | ||
|
|
bcbddac138 | ||
|
|
e62257d933 | ||
|
|
f45918bac8 | ||
|
|
77ac58202a | ||
|
|
257a97f191 | ||
|
|
32e8127273 | ||
|
|
223f65396d | ||
|
|
01d4a4bc9f | ||
|
|
1038cff1d9 | ||
|
|
f961bf91f7 | ||
|
|
721cb1be91 | ||
|
|
2f570a0638 | ||
|
|
ee52c50e76 | ||
|
|
675ac0338f | ||
|
|
f708a18960 | ||
|
|
a8ba5635e3 | ||
|
|
4efc6572ee
|
||
|
|
05c59fa4a5 | ||
|
|
52ea18c616 | ||
|
|
9dd2b5aaa8 | ||
|
|
af93e418f4
|
||
|
|
46e26efe67 | ||
|
|
f65e3868e3 | ||
|
|
003407ecaa | ||
|
|
50849e8682 | ||
|
|
3e8b3d00e5 | ||
|
|
a5ac3c3500
|
||
|
|
2502c85497 | ||
|
|
ed60a0ccb3 | ||
|
|
047e09823d | ||
|
|
a0326a1594 | ||
|
|
fe5a401bfc | ||
|
|
c12617975f | ||
|
|
64a3a6e533 | ||
|
|
c46753598d | ||
|
|
30637a081d | ||
|
|
44bebba3c1 | ||
|
|
830e1307bd | ||
|
|
f094014c90 |
No files matched your search
@@ -0,0 +1,81 @@
|
||||
name: authz_client
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- uses: actions/setup-go@v7
|
||||
with:
|
||||
go-version: 'stable'
|
||||
- name: Run tests
|
||||
run: go test -race -coverprofile=coverage.txt ./...
|
||||
|
||||
- name: Check coverage
|
||||
id: coverage
|
||||
run: |
|
||||
go install github.com/vladopajic/go-test-coverage/v2@latest
|
||||
go-test-coverage --config ./.testcoverage.yml --github-action-output
|
||||
- name: Download baseline coverage
|
||||
if: gitea.event_name == 'pull_request'
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: coverage-baseline
|
||||
path: ./baseline
|
||||
continue-on-error: true
|
||||
- name: Compare coverage
|
||||
if: gitea.event_name == 'pull_request'
|
||||
run: |
|
||||
CURRENT="${{ steps.coverage.outputs.total-coverage }}"
|
||||
if [ -f ./baseline/coverage.txt ]; then
|
||||
BASE=$(cat ./baseline/coverage.txt)
|
||||
echo "Base coverage: ${BASE}%"
|
||||
echo "Current coverage: ${CURRENT}%"
|
||||
if [ "$(echo "$CURRENT < $BASE" | bc -l)" -eq 1 ]; then
|
||||
echo "::error::Coverage decreased from ${BASE}% to ${CURRENT}%"
|
||||
exit 1
|
||||
fi
|
||||
echo "Coverage maintained or improved: ${BASE}% -> ${CURRENT}%"
|
||||
else
|
||||
echo "No baseline coverage found, skipping comparison"
|
||||
echo "Current coverage: ${CURRENT}%"
|
||||
fi
|
||||
- name: Save coverage baseline
|
||||
if: gitea.ref == 'refs/heads/main'
|
||||
run: echo "${{ steps.coverage.outputs.total-coverage }}" > coverage.txt
|
||||
- name: Upload coverage baseline
|
||||
if: gitea.ref == 'refs/heads/main'
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: coverage-baseline
|
||||
path: coverage.txt
|
||||
retention-days: 90
|
||||
- name: Post coverage comment
|
||||
if: gitea.event_name == 'pull_request'
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
GITEA_URL: ${{ gitea.server_url }}
|
||||
run: |
|
||||
COVERAGE="${{ steps.coverage.outputs.total-coverage }}"
|
||||
curl -X POST "${GITEA_URL}/api/v1/repos/${{ gitea.repository }}/issues/${{ gitea.event.pull_request.number }}/comments" \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"body\": \"## Coverage Report\n\nTotal coverage: **${COVERAGE}%**\"}"
|
||||
|
||||
vulnerabilities:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- uses: actions/setup-go@v7
|
||||
with:
|
||||
go-version: 'stable'
|
||||
- name: Check vulnerabilities
|
||||
run: |
|
||||
go install golang.org/x/vuln/cmd/govulncheck@latest
|
||||
govulncheck ./...
|
||||
@@ -0,0 +1,25 @@
|
||||
name: pre-commit
|
||||
permissions: read-all
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
pre-commit:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
SKIP: no-commit-to-branch
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- uses: actions/setup-go@v7
|
||||
with:
|
||||
go-version: stable
|
||||
- uses: actions/setup-python@v7
|
||||
with:
|
||||
python-version: '3.14'
|
||||
- name: Install goimports
|
||||
run: go install golang.org/x/tools/cmd/goimports@latest
|
||||
- uses: pre-commit/action@v3.0.1
|
||||
@@ -0,0 +1,9 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
release:
|
||||
uses: unboundsoftware/shared-workflows/.gitea/workflows/Release.yml@main
|
||||
@@ -1,2 +1,4 @@
|
||||
.idea
|
||||
.claude
|
||||
/release
|
||||
coverage.txt
|
||||
@@ -1,38 +0,0 @@
|
||||
include:
|
||||
- template: 'Workflows/MergeRequest-Pipelines.gitlab-ci.yml'
|
||||
- project: unboundsoftware/ci-templates
|
||||
file: Defaults.gitlab-ci.yml
|
||||
- project: unboundsoftware/ci-templates
|
||||
file: Release.gitlab-ci.yml
|
||||
- project: unboundsoftware/ci-templates
|
||||
file: Pre-Commit-Go.gitlab-ci.yml
|
||||
|
||||
image: amd64/golang:1.25.1@sha256:70de49a6a9bfd1bde2b332fde29d04a8cc65047464fa97ddb94251b05e572bc0
|
||||
|
||||
stages:
|
||||
- deps
|
||||
- test
|
||||
|
||||
deps:
|
||||
stage: deps
|
||||
script:
|
||||
- go mod download
|
||||
|
||||
test:
|
||||
stage: test
|
||||
dependencies:
|
||||
- deps
|
||||
script:
|
||||
- CGO_ENABLED=1 go test -mod=readonly -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=$(go list ./... | tr '\n' , | sed 's/,$//') ./...
|
||||
- go tool cover -html=coverage.txt -o coverage.html
|
||||
- go tool cover -func=coverage.txt
|
||||
- curl -Os https://uploader.codecov.io/latest/linux/codecov
|
||||
- chmod +x codecov
|
||||
- ./codecov -t ${CODECOV_TOKEN} -R $CI_PROJECT_DIR -C $CI_COMMIT_SHA -r $CI_PROJECT_PATH
|
||||
|
||||
vulnerabilities:
|
||||
stage: test
|
||||
image: amd64/golang:1.25.1@sha256:70de49a6a9bfd1bde2b332fde29d04a8cc65047464fa97ddb94251b05e572bc0
|
||||
script:
|
||||
- go install golang.org/x/vuln/cmd/govulncheck@latest
|
||||
- govulncheck ./...
|
||||
+5
-12
@@ -10,15 +10,8 @@ repos:
|
||||
args:
|
||||
- --allow-multiple-documents
|
||||
- id: check-added-large-files
|
||||
- repo: https://gitlab.com/devopshq/gitlab-ci-linter
|
||||
rev: v1.0.6
|
||||
hooks:
|
||||
- id: gitlab-ci-linter
|
||||
args:
|
||||
- --project
|
||||
- unboundsoftware/shiny/authz_client
|
||||
- repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook
|
||||
rev: v9.22.0
|
||||
rev: v9.26.0
|
||||
hooks:
|
||||
- id: commitlint
|
||||
stages: [ commit-msg ]
|
||||
@@ -30,17 +23,17 @@ repos:
|
||||
- id: go-imports
|
||||
args:
|
||||
- -local
|
||||
- gitlab.com/unboundsoftware/shiny/authz_client
|
||||
- gitea.unbound.se/shiny/authz_client
|
||||
- repo: https://github.com/lietu/go-pre-commit
|
||||
rev: v0.1.0
|
||||
rev: v1.0.0
|
||||
hooks:
|
||||
- id: go-test
|
||||
- id: gofumpt
|
||||
- repo: https://github.com/golangci/golangci-lint
|
||||
rev: v2.4.0
|
||||
rev: v2.13.2
|
||||
hooks:
|
||||
- id: golangci-lint-full
|
||||
- repo: https://github.com/gitleaks/gitleaks
|
||||
rev: v8.28.0
|
||||
rev: v8.30.1
|
||||
hooks:
|
||||
- id: gitleaks
|
||||
@@ -0,0 +1,13 @@
|
||||
# Coverage configuration for go-test-coverage
|
||||
# https://github.com/vladopajic/go-test-coverage
|
||||
|
||||
profile: coverage.txt
|
||||
|
||||
threshold:
|
||||
file: 0
|
||||
package: 0
|
||||
total: 0
|
||||
|
||||
exclude:
|
||||
paths:
|
||||
- _test\.go$
|
||||
+350
-30
@@ -1,3 +1,146 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [0.7.0] - 2026-09-16
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- [**breaking**] Order privilege events by sequence number and merge snapshots by position (#333)
|
||||
|
||||
## [0.6.1] - 2026-09-16
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- Keep existing privileges when User.Added is processed late (#331)
|
||||
|
||||
## [0.6.0] - 2026-09-14
|
||||
|
||||
### 🚀 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
|
||||
|
||||
### 🚀 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
|
||||
|
||||
- *(deps)* Update actions/setup-python action to v6
|
||||
- Migrate module path to gitea.unbound.se
|
||||
|
||||
## [0.4.0] - 2026-01-09
|
||||
|
||||
### 🚀 Features
|
||||
|
||||
- Migrate from GitLab CI to Gitea Actions
|
||||
|
||||
### 🚜 Refactor
|
||||
|
||||
- Update module path to new repository location
|
||||
|
||||
### 📚 Documentation
|
||||
|
||||
- Add CLAUDE.md for Claude Code integration
|
||||
|
||||
### 🧪 Testing
|
||||
|
||||
- Add concurrent fetch and read tests for privileges
|
||||
|
||||
### ⚙️ Miscellaneous Tasks
|
||||
|
||||
- *(deps)* Update golang:1.25.3 docker digest to 9ac0edc
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.6.1
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.29.0
|
||||
- *(deps)* Update dependency go to v1.25.4
|
||||
- *(deps)* Update golang docker tag to v1.25.4
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.6.2
|
||||
- *(deps)* Update golang:1.25.4 docker digest to efe81fa
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.29.1
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.30.0
|
||||
- *(deps)* Update dependency go to v1.25.5
|
||||
- *(deps)* Update golang docker tag to v1.25.5
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.7.0
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.7.1
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.7.2
|
||||
- *(deps)* Update golang:1.25.5 docker digest to 0c27bcf
|
||||
- *(deps)* Update golang:1.25.5 docker digest to ad03ba9
|
||||
- *(deps)* Update actions/setup-go action to v6
|
||||
- *(deps)* Update actions/checkout action to v6
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.8.0
|
||||
- Add pre-commit and release workflows
|
||||
|
||||
## [0.3.1] - 2025-11-02
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- Change to write lock for thread safety in json unmarshal
|
||||
|
||||
### ⚙️ Miscellaneous Tasks
|
||||
|
||||
- *(deps)* Update golang:1.25.1 docker digest to 53f7808
|
||||
- *(deps)* Update pre-commit hook lietu/go-pre-commit to v1
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.5.0
|
||||
- *(deps)* Update golang:1.25.1 docker digest to 12640a4
|
||||
- *(deps)* Update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.23.0
|
||||
- *(deps)* Update dependency go to v1.25.2
|
||||
- *(deps)* Update golang docker tag to v1.25.2
|
||||
- *(deps)* Update dependency go to v1.25.3
|
||||
- *(deps)* Update golang docker tag to v1.25.3
|
||||
- Add default configuration for git-cliff
|
||||
- *(deps)* Update golang:1.25.3 docker digest to 69d1009
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.6.0
|
||||
|
||||
## [0.3.0] - 2025-09-06
|
||||
|
||||
### 🚀 Features
|
||||
@@ -10,6 +153,49 @@
|
||||
- *(deps)* Update module github.com/sparetimecoders/goamqp to v0.3.3
|
||||
- *(deps)* Update module github.com/stretchr/testify to v1.11.0
|
||||
- *(deps)* Update module github.com/stretchr/testify to v1.11.1
|
||||
|
||||
### ⚙️ Miscellaneous Tasks
|
||||
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.1.0
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.1.1
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.1.2
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.1.4
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.1.5
|
||||
- *(deps)* Update golang:1.24.2 docker digest to bf7899c
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.25.0
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.25.1
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.1.6
|
||||
- *(deps)* Update dependency go to v1.24.3
|
||||
- *(deps)* Update golang docker tag to v1.24.3
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.26.0
|
||||
- *(deps)* Update golang:1.24.3 docker digest to f255a7d
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.27.0
|
||||
- *(deps)* Update dependency go to v1.24.4
|
||||
- *(deps)* Update golang docker tag to v1.24.4
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.27.1
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.27.2
|
||||
- *(deps)* Update golang:1.24.4 docker digest to 3494bbe
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.2.0
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.2.1
|
||||
- *(deps)* Update golang:1.24.4 docker digest to 9f820b6
|
||||
- *(deps)* Update dependency go to v1.24.5
|
||||
- *(deps)* Update golang docker tag to v1.24.5
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.2.2
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.28.0
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.3.0
|
||||
- *(deps)* Update golang:1.24.5 docker digest to 0a156a4
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.3.1
|
||||
- *(deps)* Update dependency go to v1.24.6
|
||||
- *(deps)* Update golang docker tag to v1.24.6
|
||||
- *(deps)* Update pre-commit hook pre-commit/pre-commit-hooks to v6
|
||||
- *(deps)* Update golang:1.24.6 docker digest to 958bfd1
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.4.0
|
||||
- *(deps)* Update golang docker tag to v1.25.0
|
||||
- *(deps)* Update dependency go to v1.25.0
|
||||
- *(deps)* Update golang:1.25.0 docker digest to f6b9e1a
|
||||
- *(deps)* Update dependency go to v1.25.1
|
||||
- *(deps)* Update golang docker tag to v1.25.1
|
||||
|
||||
## [0.2.0] - 2025-04-11
|
||||
|
||||
### 🚀 Features
|
||||
@@ -26,6 +212,82 @@
|
||||
### 🚜 Refactor
|
||||
|
||||
- *(ci)* Remove pre-commit job and add new template
|
||||
|
||||
### ⚙️ Miscellaneous Tasks
|
||||
|
||||
- *(deps)* Update pre-commit hook pre-commit/pre-commit-hooks to v5
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.20.1
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.21.0
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.21.1
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.21.2
|
||||
- *(deps)* Pin golang docker tag to ad5c126
|
||||
- *(deps)* Pin unbound/pre-commit docker tag to 92fce44
|
||||
- *(deps)* Update golang docker tag to v1.23.3
|
||||
- *(deps)* Update unbound/pre-commit docker digest to 596abf5
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v1.62.0
|
||||
- *(deps)* Update golang:1.23.3 docker digest to 8956c08
|
||||
- *(deps)* Update unbound/pre-commit docker digest to e78425c
|
||||
- *(deps)* Update golang:1.23.3 docker digest to 3694e36
|
||||
- *(deps)* Update golang:1.23.3 docker digest to b2ca381
|
||||
- *(deps)* Update golang:1.23.3 docker digest to 2660218
|
||||
- *(deps)* Update golang:1.23.3 docker digest to c2d828f
|
||||
- *(deps)* Update golang:1.23.3 docker digest to 73f06be
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v1.62.2
|
||||
- *(deps)* Update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.19.0
|
||||
- *(deps)* Update golang:1.23.3 docker digest to ee5f0ad
|
||||
- *(deps)* Update golang:1.23.3 docker digest to b4aabba
|
||||
- *(deps)* Update golang:1.23.3 docker digest to 2b01164
|
||||
- *(deps)* Update golang:1.23.3 docker digest to 017ec6b
|
||||
- *(deps)* Update golang docker tag to v1.23.4
|
||||
- *(deps)* Update golang:1.23.4 docker digest to 574185e
|
||||
- *(deps)* Update golang:1.23.4 docker digest to 7003184
|
||||
- *(deps)* Update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.20.0
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.21.3
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.21.4
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.22.0
|
||||
- *(deps)* Update golang:1.23.4 docker digest to 7ea4c9d
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.22.1
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v1.63.0
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v1.63.1
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v1.63.2
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v1.63.3
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v1.63.4
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.23.0
|
||||
- *(deps)* Update golang:1.23.4 docker digest to 3b1a7de
|
||||
- *(deps)* Update golang:1.23.4 docker digest to 08e1417
|
||||
- *(deps)* Update golang:1.23.4 docker digest to 585103a
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.23.1
|
||||
- *(deps)* Update golang:1.23.4 docker digest to 5305905
|
||||
- *(deps)* Update golang:1.23.4 docker digest to 9820aca
|
||||
- *(deps)* Update golang docker tag to v1.23.5
|
||||
- *(deps)* Update golang:1.23.5 docker digest to 8c10f21
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.23.2
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.23.3
|
||||
- *(deps)* Update golang:1.23.5 docker digest to e213430
|
||||
- *(deps)* Update golang docker tag to v1.23.6
|
||||
- *(deps)* Update golang:1.23.6 docker digest to 958bd2e
|
||||
- *(deps)* Update golang:1.23.6 docker digest to 9271129
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v1.64.2
|
||||
- *(deps)* Update golang docker tag to v1.24.0
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v1.64.4
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v1.64.5
|
||||
- *(deps)* Update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.21.0
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.24.0
|
||||
- *(deps)* Update golang:1.24.0 docker digest to 4a3f101
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v1.64.6
|
||||
- *(deps)* Update golang docker tag to v1.24.1
|
||||
- *(deps)* Update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.22.0
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v1.64.7
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v1.64.8
|
||||
- *(deps)* Update golang:1.24.1 docker digest to 5ecf333
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.24.2
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.0.1
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.0.2
|
||||
- *(deps)* Update golang docker tag to v1.24.2
|
||||
- *(deps)* Update golang:1.24.2 docker digest to aebb7df
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.24.3
|
||||
|
||||
## [0.1.4] - 2024-10-05
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
@@ -33,30 +295,67 @@
|
||||
- *(deps)* Update module github.com/stretchr/testify to v1.9.0
|
||||
- *(deps)* Update module github.com/sparetimecoders/goamqp to v0.3.1
|
||||
|
||||
### 💼 Other
|
||||
|
||||
- *(deps)* Bump github.com/sparetimecoders/goamqp from 0.2.1 to 0.3.0
|
||||
|
||||
### ⚙️ Miscellaneous Tasks
|
||||
|
||||
- Update to Go 1.21.6
|
||||
- Update to Go 1.22.0
|
||||
- *(deps)* Update node.js to v20
|
||||
- *(deps)* Update pre-commit hook devopshq/gitlab-ci-linter to v1.0.6
|
||||
- *(deps)* Update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.11.0
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v1.56.2
|
||||
- *(deps)* Update pre-commit hook lietu/go-pre-commit to v0.1.0
|
||||
- *(deps)* Update pre-commit hook pre-commit/pre-commit-hooks to v4.5.0
|
||||
- *(deps)* Update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.12.0
|
||||
- *(deps)* Update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.13.0
|
||||
- *(deps)* Update golang docker tag to v1.22.1
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v1.57.0
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v1.57.1
|
||||
- Add gitleaks to pre-commit setup
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.18.2
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v1.57.2
|
||||
- *(deps)* Update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.14.0
|
||||
- *(deps)* Update golang docker tag to v1.22.2
|
||||
- *(deps)* Update pre-commit hook pre-commit/pre-commit-hooks to v4.6.0
|
||||
- *(deps)* Update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.15.0
|
||||
- *(deps)* Update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.16.0
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v1.58.0
|
||||
- *(deps)* Update golang docker tag to v1.22.3
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v1.58.1
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v1.58.2
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v1.59.0
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.18.3
|
||||
- *(deps)* Update golang docker tag to v1.22.4
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v1.59.1
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.18.4
|
||||
- *(deps)* Update golang docker tag to v1.22.5
|
||||
- *(deps)* Update golang docker tag to v1.22.6
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v1.60.1
|
||||
- *(deps)* Update golang docker tag to v1.23.0
|
||||
- Update golangci-lint to use full version
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v1.60.2
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v1.60.3
|
||||
- *(deps)* Update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.17.0
|
||||
- *(deps)* Update golang docker tag to v1.23.1
|
||||
- *(deps)* Update pre-commit hook golangci/golangci-lint to v1.61.0
|
||||
- *(deps)* Update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.18.0
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.19.1
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.19.2
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.19.3
|
||||
- *(deps)* Update golang docker tag to v1.23.2
|
||||
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.20.0
|
||||
- Add release flow
|
||||
- Remove old release job
|
||||
|
||||
### Build
|
||||
|
||||
- *(deps)* Bump github.com/sparetimecoders/goamqp from 0.2.1 to 0.3.0
|
||||
|
||||
## [0.1.3] - 2023-12-26
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- Prohibit concurrent read/write
|
||||
|
||||
### 💼 Other
|
||||
|
||||
- *(deps)* Bump github.com/sparetimecoders/goamqp from 0.1.4 to 0.1.5
|
||||
- *(deps)* Bump github.com/sparetimecoders/goamqp from 0.1.5 to 0.2.0
|
||||
- *(deps)* Bump github.com/sparetimecoders/goamqp from 0.2.0 to 0.2.1
|
||||
|
||||
### ⚙️ Miscellaneous Tasks
|
||||
|
||||
- Update Go version
|
||||
@@ -68,31 +367,31 @@
|
||||
- Use 1.21.1 in go.mod for Dependabot
|
||||
- Update to go 1.21.3 and remove patch level
|
||||
- Update version of Go
|
||||
|
||||
### Build
|
||||
|
||||
- *(deps)* Bump github.com/sparetimecoders/goamqp from 0.1.4 to 0.1.5
|
||||
- *(deps)* Bump github.com/sparetimecoders/goamqp from 0.1.5 to 0.2.0
|
||||
- *(deps)* Bump github.com/sparetimecoders/goamqp from 0.2.0 to 0.2.1
|
||||
|
||||
## [0.1.2] - 2023-06-04
|
||||
|
||||
### 💼 Other
|
||||
|
||||
- *(deps)* Bump github.com/stretchr/testify from 1.8.2 to 1.8.3
|
||||
- *(deps)* Bump github.com/stretchr/testify from 1.8.3 to 1.8.4
|
||||
|
||||
### ⚙️ Miscellaneous Tasks
|
||||
|
||||
- Update pre-commit and fix golangci-lint
|
||||
- Update golangci-lint
|
||||
|
||||
### Build
|
||||
|
||||
- *(deps)* Bump github.com/stretchr/testify from 1.8.2 to 1.8.3
|
||||
- *(deps)* Bump github.com/stretchr/testify from 1.8.3 to 1.8.4
|
||||
|
||||
## [0.1.1] - 2023-05-11
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- Run builds with Go 1.19.2 to fix vulnerabilities
|
||||
|
||||
### 💼 Other
|
||||
|
||||
- *(deps)* Bump github.com/stretchr/testify from 1.8.0 to 1.8.1
|
||||
- *(deps)* Bump github.com/sparetimecoders/goamqp from 0.1.1 to 0.1.2
|
||||
- *(deps)* Bump github.com/sparetimecoders/goamqp from 0.1.2 to 0.1.3
|
||||
- *(deps)* Bump github.com/stretchr/testify from 1.8.1 to 1.8.2
|
||||
- *(deps)* Bump github.com/sparetimecoders/goamqp from 0.1.3 to 0.1.4
|
||||
|
||||
### ⚙️ Miscellaneous Tasks
|
||||
|
||||
- Add vulnerability-check
|
||||
@@ -106,13 +405,32 @@
|
||||
- Update Go verion for vulnerabilities scan
|
||||
- Update to Go 1.20.3
|
||||
- Update Go version and fix gitlabci lint
|
||||
|
||||
### Build
|
||||
|
||||
- *(deps)* Bump github.com/stretchr/testify from 1.8.0 to 1.8.1
|
||||
- *(deps)* Bump github.com/sparetimecoders/goamqp from 0.1.1 to 0.1.2
|
||||
- *(deps)* Bump github.com/sparetimecoders/goamqp from 0.1.2 to 0.1.3
|
||||
- *(deps)* Bump github.com/stretchr/testify from 1.8.1 to 1.8.2
|
||||
- *(deps)* Bump github.com/sparetimecoders/goamqp from 0.1.3 to 0.1.4
|
||||
|
||||
## [0.1.0] - 2022-07-20
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- Pipeline
|
||||
|
||||
### 💼 Other
|
||||
### ⚙️ Miscellaneous Tasks
|
||||
|
||||
- Add dependabot config
|
||||
- *(deps)* Bump gitlab.com/sparetimecoders/goamqp from 0.3.1 to 0.3.2
|
||||
- *(deps)* Bump github.com/stretchr/testify from 1.4.0 to 1.7.0
|
||||
- Remove dependabot-standalone
|
||||
- Change to codecov binary instead of bash uploader
|
||||
- *(deps)* Bump gitlab.com/sparetimecoders/goamqp from 0.3.2 to 0.4.0
|
||||
- Switch to moved goamqp
|
||||
|
||||
### Build
|
||||
|
||||
- Add params to codecov
|
||||
- *(deps)* Bump github.com/stretchr/testify from 1.7.0 to 1.7.1
|
||||
@@ -122,12 +440,6 @@
|
||||
- *(deps)* Bump github.com/stretchr/testify from 1.7.4 to 1.7.5
|
||||
- *(deps)* Bump github.com/stretchr/testify from 1.7.5 to 1.8.0
|
||||
|
||||
### ⚙️ Miscellaneous Tasks
|
||||
|
||||
- Add dependabot config
|
||||
- Remove dependabot-standalone
|
||||
- Change to codecov binary instead of bash uploader
|
||||
- Switch to moved goamqp
|
||||
## [0.0.8] - 2021-05-15
|
||||
|
||||
### ⚙️ Miscellaneous Tasks
|
||||
@@ -139,6 +451,7 @@
|
||||
- Rename master -> main
|
||||
- Group imports
|
||||
- Update to latest version of goamqp
|
||||
|
||||
## [0.0.7] - 2020-04-12
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
@@ -146,6 +459,7 @@
|
||||
- Update to Go 1.14 to fix test errors
|
||||
- Use go mod download
|
||||
- Sort companies before comparing since map-iteration is not stable
|
||||
|
||||
## [0.0.6] - 2020-04-12
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
@@ -156,21 +470,25 @@
|
||||
|
||||
- Add tests
|
||||
- Modify event structure
|
||||
|
||||
## [0.0.5] - 2019-12-31
|
||||
|
||||
### 🚀 Features
|
||||
|
||||
- Add handling of removed privilege
|
||||
|
||||
## [0.0.4] - 2019-12-08
|
||||
|
||||
### 🚀 Features
|
||||
|
||||
- Add name and registration number to event
|
||||
|
||||
## [0.0.3] - 2019-11-22
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- Print unexpected messages
|
||||
|
||||
## [0.0.2] - 2019-11-06
|
||||
|
||||
### 🚀 Features
|
||||
@@ -180,3 +498,5 @@
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- Rename module
|
||||
|
||||
<!-- generated by git-cliff -->
|
||||
@@ -0,0 +1,51 @@
|
||||
# authz_client
|
||||
|
||||
Shared Go library for authorization service client integration.
|
||||
|
||||
## Shared Documentation
|
||||
|
||||
@../docs/claude/architecture.md
|
||||
@../docs/claude/go-services.md
|
||||
@../docs/claude/conventions.md
|
||||
|
||||
## Library Information
|
||||
|
||||
### Purpose
|
||||
|
||||
Provides a client for the authz-service, handling privilege management for users across companies. Used by all microservices that need to check user permissions.
|
||||
|
||||
### Usage
|
||||
|
||||
```go
|
||||
import client "gitea.unbound.se/shiny/authz_client"
|
||||
|
||||
// Create handler with options
|
||||
handler := client.New(client.WithBaseURL("http://authz-service"))
|
||||
|
||||
// Check user privileges
|
||||
allowed := handler.IsAllowed(email, companyID, func(p client.CompanyPrivileges) bool {
|
||||
return p.Invoicing
|
||||
})
|
||||
```
|
||||
|
||||
### Privileges
|
||||
|
||||
The `CompanyPrivileges` struct contains permission flags:
|
||||
- `Admin` - Administrative access
|
||||
- `Company` - Company management
|
||||
- `Consumer` - Consumer/customer access
|
||||
- `Time` - Time tracking
|
||||
- `Invoicing` - Invoice management
|
||||
- `Accounting` - Accounting access
|
||||
- `Supplier` - Supplier management
|
||||
- `Salary` - Salary/payroll access
|
||||
|
||||
### Event Handling
|
||||
|
||||
Registers per-replica (transient) go-messaging-amqp consumers for privilege events from authz-service (`Setup()`). Each routing key gets its own queue, so events arrive in any order. `Process` orders them by the `sequenceNo` authz-service's event store stamps on every event: all four events come from authz-service's `Company` aggregate, so the global sequence number orders them within a company. Each (email, company) keeps the sequence number of the last fact about membership and about each privilege; an event only overrides older facts. `User.Removed` stamps every privilege, so a late grant can't come back. An event without `sequenceNo` fails closed: additions are dropped, and removals apply and block every later event for those facts until the next snapshot. An event with a negative or implausibly large `sequenceNo` is dropped. Tests that seed the handler must set `SequenceNo`.
|
||||
|
||||
### Startup
|
||||
|
||||
Call `Fetch()` **after** `conn.Start` (consumers bound), never before: events published between the snapshot and the binding would otherwise be lost. authz-service only serves a snapshot whose read view has applied every stored event. It sends that position in the `X-Authz-Sequence` header and answers 503 while the read view lags (backlog, backfill, reset); `Fetch` retries 503 for about a minute. `Fetch` merges the snapshot as facts at that sequence number (newer event facts win, pairs missing from the snapshot are removed) and drops later events at or below it. A snapshot older than one already merged is ignored, so concurrent or repeated fetches are safe. A snapshot without the header merges at 0 and logs a warning (rollout window only).
|
||||
|
||||
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.
|
||||
@@ -1,4 +1 @@
|
||||
# Shiny authz-client
|
||||
|
||||
[](https://gitlab.com/unboundsoftware/shiny/authz_client/commits/main)
|
||||
[](https://codecov.io/gl/unboundsoftware:shiny/authz_client)
|
||||
@@ -1,16 +1,31 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"math"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/sparetimecoders/goamqp"
|
||||
goamqp "codeberg.org/messaging/go-messaging-amqp"
|
||||
spec "codeberg.org/messaging/messaging"
|
||||
)
|
||||
|
||||
// SequenceHeader carries the global sequence number of the authz-service read view the
|
||||
// /authz snapshot was read at.
|
||||
const SequenceHeader = "X-Authz-Sequence"
|
||||
|
||||
// pending marks a fact cleared by an event without a sequence number. No event can
|
||||
// override it; only a snapshot can.
|
||||
const pending = math.MaxInt
|
||||
|
||||
// CompanyPrivileges contains the privileges for a combination of email address and company id
|
||||
type CompanyPrivileges struct {
|
||||
Admin bool `json:"admin"`
|
||||
@@ -23,12 +38,84 @@ type CompanyPrivileges struct {
|
||||
Salary bool `json:"salary"`
|
||||
}
|
||||
|
||||
// field returns the flag for privilege, or nil for an unknown privilege.
|
||||
func (c *CompanyPrivileges) field(privilege Privilege) *bool {
|
||||
switch privilege {
|
||||
case PrivilegeAdmin:
|
||||
return &c.Admin
|
||||
case PrivilegeCompany:
|
||||
return &c.Company
|
||||
case PrivilegeConsumer:
|
||||
return &c.Consumer
|
||||
case PrivilegeTime:
|
||||
return &c.Time
|
||||
case PrivilegeInvoicing:
|
||||
return &c.Invoicing
|
||||
case PrivilegeAccounting:
|
||||
return &c.Accounting
|
||||
case PrivilegeSupplier:
|
||||
return &c.Supplier
|
||||
case PrivilegeSalary:
|
||||
return &c.Salary
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// companyState is what the handler knows about one email in one company. Every
|
||||
// privilege event for a company comes from authz-service's Company aggregate, so
|
||||
// its global sequence number orders the events for the pair. The four routing
|
||||
// keys arrive on separate queues in any order; a fact is only overwritten by a
|
||||
// fact with a higher sequence number.
|
||||
type companyState struct {
|
||||
privileges CompanyPrivileges
|
||||
// privilegeSeq is the sequence number of the last fact about each privilege.
|
||||
privilegeSeq map[Privilege]int
|
||||
// member is whether the user belongs to the company, as of memberSeq. A
|
||||
// User.Removed stamps every privilege with its sequence number, so a grant
|
||||
// older than the removal can't come back.
|
||||
member bool
|
||||
memberSeq int
|
||||
}
|
||||
|
||||
func newCompanyState() *companyState {
|
||||
return &companyState{privilegeSeq: map[Privilege]int{}}
|
||||
}
|
||||
|
||||
// clearPending turns facts cleared without a sequence number into unordered facts, so
|
||||
// the snapshot being merged replaces them.
|
||||
func (s *companyState) clearPending() {
|
||||
if s.memberSeq == pending {
|
||||
s.memberSeq = 0
|
||||
}
|
||||
for p, seq := range s.privilegeSeq {
|
||||
if seq == pending {
|
||||
s.privilegeSeq[p] = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// maxSeq is the highest sequence number of any fact in the state.
|
||||
func (s *companyState) maxSeq() int {
|
||||
m := s.memberSeq
|
||||
for _, seq := range s.privilegeSeq {
|
||||
m = max(m, seq)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// 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
|
||||
client *http.Client
|
||||
baseURL string
|
||||
apiKey string
|
||||
state map[string]map[string]*companyState
|
||||
// floor is the sequence number of the newest snapshot. Its effects are all in
|
||||
// the state, so an event at or below it is stale.
|
||||
floor int
|
||||
// retries is how many times Fetch retries a snapshot authz-service isn't ready to serve.
|
||||
retries int
|
||||
retryDelay time.Duration
|
||||
}
|
||||
|
||||
// OptsFunc is used to configure the PrivilegeHandler
|
||||
@@ -41,13 +128,22 @@ 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{
|
||||
RWMutex: &sync.RWMutex{},
|
||||
client: &http.Client{},
|
||||
client: &http.Client{Timeout: 30 * time.Second},
|
||||
baseURL: "http://authz-service",
|
||||
privileges: map[string]map[string]*CompanyPrivileges{},
|
||||
state: map[string]map[string]*companyState{},
|
||||
retries: 60,
|
||||
retryDelay: time.Second,
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(handler)
|
||||
@@ -55,101 +151,250 @@ func New(opts ...OptsFunc) *PrivilegeHandler {
|
||||
return handler
|
||||
}
|
||||
|
||||
// Fetch the initial set of privileges from an authz-service
|
||||
// Fetch a snapshot of all privileges from an authz-service and merge it into the state.
|
||||
//
|
||||
// Call it after the AMQP connection has started: authz-service only serves a snapshot
|
||||
// that includes every stored event, so together with the bound queues no event is
|
||||
// missed. While its read view is behind it answers 503, and Fetch retries. The snapshot
|
||||
// is applied as facts at its sequence number: a fact from an event newer than the
|
||||
// snapshot is kept, everything else is replaced, and a pair missing from the snapshot is
|
||||
// removed. A snapshot older than one already merged is ignored.
|
||||
func (h *PrivilegeHandler) Fetch() error {
|
||||
resp, err := h.client.Get(fmt.Sprintf("%s/authz", h.baseURL))
|
||||
for attempt := 0; ; attempt++ {
|
||||
err := h.fetch()
|
||||
if !errors.Is(err, errNotReady) || attempt >= h.retries {
|
||||
return err
|
||||
}
|
||||
time.Sleep(h.retryDelay)
|
||||
}
|
||||
}
|
||||
|
||||
var errNotReady = errors.New("fetch privileges: authz-service read view not ready")
|
||||
|
||||
func (h *PrivilegeHandler) fetch() error {
|
||||
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
|
||||
}
|
||||
defer func() { _ = resp.Body.Close() }()
|
||||
|
||||
if resp.StatusCode == http.StatusServiceUnavailable {
|
||||
return errNotReady
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("fetch privileges: unexpected status %s", resp.Status)
|
||||
}
|
||||
|
||||
buff, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
h.RLock()
|
||||
defer h.RUnlock()
|
||||
err = json.Unmarshal(buff, &h.privileges)
|
||||
if err != nil {
|
||||
var snapshot map[string]map[string]CompanyPrivileges
|
||||
if err := json.Unmarshal(buff, &snapshot); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
seq := 0
|
||||
if v := resp.Header.Get(SequenceHeader); v != "" {
|
||||
seq, err = strconv.Atoi(v)
|
||||
if err != nil || seq < 0 {
|
||||
return fmt.Errorf("fetch privileges: invalid %s header %q", SequenceHeader, v)
|
||||
}
|
||||
} else {
|
||||
// ponytail: only during the rollout window, before authz-service sends the header.
|
||||
slog.Warn("authz snapshot has no sequence number; events older than it can revert it", "header", SequenceHeader)
|
||||
}
|
||||
|
||||
h.Lock()
|
||||
defer h.Unlock()
|
||||
h.merge(snapshot, seq)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *PrivilegeHandler) merge(snapshot map[string]map[string]CompanyPrivileges, seq int) {
|
||||
if seq < h.floor {
|
||||
// A newer snapshot is already merged; this one could only bring back removed state.
|
||||
slog.Warn("ignoring authz snapshot older than the one already merged", "seq", seq, "floor", h.floor)
|
||||
return
|
||||
}
|
||||
for email, companies := range h.state {
|
||||
for companyID, s := range companies {
|
||||
s.clearPending()
|
||||
if _, exists := snapshot[email][companyID]; exists {
|
||||
continue
|
||||
}
|
||||
if s.maxSeq() <= seq {
|
||||
// Nothing newer than the snapshot; the floor keeps stale events out.
|
||||
delete(companies, companyID)
|
||||
continue
|
||||
}
|
||||
removeUser(s, seq, false)
|
||||
}
|
||||
if len(companies) == 0 {
|
||||
delete(h.state, email)
|
||||
}
|
||||
}
|
||||
for email, companies := range snapshot {
|
||||
for companyID, privileges := range companies {
|
||||
s := h.company(email, companyID)
|
||||
if s.memberSeq <= seq {
|
||||
s.member = true
|
||||
s.memberSeq = seq
|
||||
}
|
||||
for _, p := range AllPrivilege {
|
||||
if s.privilegeSeq[p] <= seq {
|
||||
*s.privileges.field(p) = *privileges.field(p)
|
||||
s.privilegeSeq[p] = seq
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
h.floor = max(h.floor, seq)
|
||||
}
|
||||
|
||||
func (h *PrivilegeHandler) Setup() []goamqp.Setup {
|
||||
return []goamqp.Setup{
|
||||
goamqp.TransientEventStreamConsumer("User.Added", h.Process, UserAdded{}),
|
||||
goamqp.TransientEventStreamConsumer("User.Removed", h.Process, UserRemoved{}),
|
||||
goamqp.TransientEventStreamConsumer("Privilege.Added", h.Process, PrivilegeAdded{}),
|
||||
goamqp.TransientEventStreamConsumer("Privilege.Removed", h.Process, PrivilegeRemoved{}),
|
||||
goamqp.TransientEventStreamConsumer("User.Added", process[UserAdded](h)),
|
||||
goamqp.TransientEventStreamConsumer("User.Removed", process[UserRemoved](h)),
|
||||
goamqp.TransientEventStreamConsumer("Privilege.Added", process[PrivilegeAdded](h)),
|
||||
goamqp.TransientEventStreamConsumer("Privilege.Removed", process[PrivilegeRemoved](h)),
|
||||
}
|
||||
}
|
||||
|
||||
// Process privilege-related events and update the internal state
|
||||
func (h *PrivilegeHandler) Process(msg interface{}, _ goamqp.Headers) (interface{}, error) {
|
||||
// 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.
|
||||
//
|
||||
// Events are applied by sequence number, not by arrival order. An event without a
|
||||
// sequence number can't be ordered, so it fails closed: a removal is applied and an
|
||||
// addition is dropped.
|
||||
func (h *PrivilegeHandler) Process(msg any) 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: {},
|
||||
}
|
||||
if h.stale(ev.SequenceNo, true, ev) {
|
||||
return nil
|
||||
}
|
||||
return nil, nil
|
||||
s := h.company(ev.Email, ev.CompanyID)
|
||||
if ev.SequenceNo > s.memberSeq {
|
||||
s.member = true
|
||||
s.memberSeq = ev.SequenceNo
|
||||
}
|
||||
return nil
|
||||
case *UserRemoved:
|
||||
if priv, exists := h.privileges[ev.Email]; exists {
|
||||
h.Lock()
|
||||
defer h.Unlock()
|
||||
delete(priv, ev.CompanyID)
|
||||
if h.stale(ev.SequenceNo, false, ev) {
|
||||
return nil
|
||||
}
|
||||
return nil, nil
|
||||
removeUser(h.company(ev.Email, ev.CompanyID), ev.SequenceNo, ev.SequenceNo == 0)
|
||||
return nil
|
||||
case *PrivilegeAdded:
|
||||
h.Lock()
|
||||
defer h.Unlock()
|
||||
h.setPrivileges(ev.Email, ev.CompanyID, ev.Privilege, true)
|
||||
return nil, nil
|
||||
if h.stale(ev.SequenceNo, true, ev) {
|
||||
return nil
|
||||
}
|
||||
h.setPrivilege(ev.Email, ev.CompanyID, ev.Privilege, ev.SequenceNo, true)
|
||||
return nil
|
||||
case *PrivilegeRemoved:
|
||||
h.Lock()
|
||||
defer h.Unlock()
|
||||
h.setPrivileges(ev.Email, ev.CompanyID, ev.Privilege, false)
|
||||
return nil, nil
|
||||
if h.stale(ev.SequenceNo, false, ev) {
|
||||
return nil
|
||||
}
|
||||
h.setPrivilege(ev.Email, ev.CompanyID, ev.Privilege, ev.SequenceNo, false)
|
||||
return nil
|
||||
default:
|
||||
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))
|
||||
slog.Error("unexpected privilege message type", "type", reflect.TypeOf(msg).String())
|
||||
return fmt.Errorf("unexpected event type: '%s'", reflect.TypeOf(msg))
|
||||
}
|
||||
}
|
||||
|
||||
func (h *PrivilegeHandler) setPrivileges(email, companyId string, privilege Privilege, set bool) {
|
||||
if priv, exists := h.privileges[email]; exists {
|
||||
if c, exists := priv[companyId]; exists {
|
||||
switch privilege {
|
||||
case PrivilegeAdmin:
|
||||
c.Admin = set
|
||||
case PrivilegeCompany:
|
||||
c.Company = set
|
||||
case PrivilegeConsumer:
|
||||
c.Consumer = set
|
||||
case PrivilegeTime:
|
||||
c.Time = set
|
||||
case PrivilegeInvoicing:
|
||||
c.Invoicing = set
|
||||
case PrivilegeAccounting:
|
||||
c.Accounting = set
|
||||
case PrivilegeSupplier:
|
||||
c.Supplier = set
|
||||
case PrivilegeSalary:
|
||||
c.Salary = set
|
||||
}
|
||||
} else {
|
||||
priv[companyId] = &CompanyPrivileges{}
|
||||
h.setPrivileges(email, companyId, privilege, set)
|
||||
// stale reports whether an event must be skipped: an addition without a sequence
|
||||
// number, or any event already covered by the latest snapshot.
|
||||
func (h *PrivilegeHandler) stale(seq int, addition bool, ev any) bool {
|
||||
if seq < 0 || seq >= pending {
|
||||
slog.Error("dropping privilege event with invalid sequence number", "type", reflect.TypeOf(ev).String(), "seq", seq)
|
||||
return true
|
||||
}
|
||||
if seq == 0 {
|
||||
if addition {
|
||||
slog.Warn("dropping privilege addition without sequence number", "type", reflect.TypeOf(ev).String())
|
||||
}
|
||||
} else {
|
||||
h.privileges[email] = map[string]*CompanyPrivileges{}
|
||||
h.setPrivileges(email, companyId, privilege, set)
|
||||
return addition
|
||||
}
|
||||
return seq <= h.floor
|
||||
}
|
||||
|
||||
func (h *PrivilegeHandler) company(email, companyID string) *companyState {
|
||||
companies, exists := h.state[email]
|
||||
if !exists {
|
||||
companies = map[string]*companyState{}
|
||||
h.state[email] = companies
|
||||
}
|
||||
s, exists := companies[companyID]
|
||||
if !exists {
|
||||
s = newCompanyState()
|
||||
companies[companyID] = s
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// removeUser removes the user at seq, overriding every fact older than seq. An
|
||||
// unordered removal (all) overrides every fact and marks them pending, so no event can
|
||||
// bring them back before the next snapshot.
|
||||
func removeUser(s *companyState, seq int, all bool) {
|
||||
stamp := seq
|
||||
if all {
|
||||
stamp = pending
|
||||
}
|
||||
if all || s.memberSeq < seq {
|
||||
s.member = false
|
||||
s.memberSeq = max(s.memberSeq, stamp)
|
||||
}
|
||||
for _, p := range AllPrivilege {
|
||||
if all || s.privilegeSeq[p] < seq {
|
||||
*s.privileges.field(p) = false
|
||||
s.privilegeSeq[p] = max(s.privilegeSeq[p], stamp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (h *PrivilegeHandler) setPrivilege(email, companyID string, privilege Privilege, seq int, set bool) {
|
||||
if !privilege.IsValid() {
|
||||
return
|
||||
}
|
||||
s := h.company(email, companyID)
|
||||
if seq != 0 && seq <= s.privilegeSeq[privilege] {
|
||||
return
|
||||
}
|
||||
*s.privileges.field(privilege) = set
|
||||
if seq == 0 {
|
||||
// Only an unordered removal gets here; keep it until the next snapshot.
|
||||
seq = pending
|
||||
}
|
||||
s.privilegeSeq[privilege] = max(s.privilegeSeq[privilege], seq)
|
||||
// authz-service's aggregate adds the user when a privilege is granted.
|
||||
if set && seq > s.memberSeq {
|
||||
s.member = true
|
||||
s.memberSeq = seq
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,12 +402,10 @@ func (h *PrivilegeHandler) setPrivileges(email, companyId string, privilege Priv
|
||||
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 {
|
||||
if predicate(*v) {
|
||||
result = append(result, k)
|
||||
}
|
||||
result := []string{}
|
||||
for k, s := range h.state[email] {
|
||||
if s.member && predicate(s.privileges) {
|
||||
result = append(result, k)
|
||||
}
|
||||
}
|
||||
return result
|
||||
@@ -172,11 +415,8 @@ func (h *PrivilegeHandler) CompaniesByUser(email string, predicate func(privileg
|
||||
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)
|
||||
}
|
||||
if s, exists := h.state[email][companyID]; exists && s.member {
|
||||
return predicate(s.privileges)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
+814
-84
File diff suppressed because it is too large.
Load diff
+84
@@ -0,0 +1,84 @@
|
||||
# git-cliff ~ default configuration file
|
||||
# https://git-cliff.org/docs/configuration
|
||||
#
|
||||
# Lines starting with "#" are comments.
|
||||
# Configuration options are organized into tables and keys.
|
||||
# See documentation for more information on available options.
|
||||
|
||||
[changelog]
|
||||
# template for the changelog header
|
||||
header = """
|
||||
# Changelog\n
|
||||
All notable changes to this project will be documented in this file.\n
|
||||
"""
|
||||
# template for the changelog body
|
||||
# https://keats.github.io/tera/docs/#introduction
|
||||
body = """
|
||||
{% if version %}\
|
||||
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
|
||||
{% else %}\
|
||||
## [unreleased]
|
||||
{% endif %}\
|
||||
{% for group, commits in commits | group_by(attribute="group") %}
|
||||
### {{ group | striptags | trim | upper_first }}
|
||||
{% for commit in commits %}
|
||||
- {% if commit.scope %}*({{ commit.scope }})* {% endif %}\
|
||||
{% if commit.breaking %}[**breaking**] {% endif %}\
|
||||
{{ commit.message | upper_first }}\
|
||||
{% endfor %}
|
||||
{% endfor %}\n
|
||||
"""
|
||||
# template for the changelog footer
|
||||
footer = """
|
||||
<!-- generated by git-cliff -->
|
||||
"""
|
||||
# remove the leading and trailing s
|
||||
trim = true
|
||||
# postprocessors
|
||||
postprocessors = [
|
||||
# { pattern = '<REPO>', replace = "https://github.com/orhun/git-cliff" }, # replace repository URL
|
||||
]
|
||||
# render body even when there are no releases to process
|
||||
# render_always = true
|
||||
# output file path
|
||||
# output = "test.md"
|
||||
|
||||
[git]
|
||||
# parse the commits based on https://www.conventionalcommits.org
|
||||
conventional_commits = true
|
||||
# filter out the commits that are not conventional
|
||||
filter_unconventional = true
|
||||
# process each line of a commit as an individual commit
|
||||
split_commits = false
|
||||
# regex for preprocessing the commit messages
|
||||
commit_preprocessors = [
|
||||
# Replace issue numbers
|
||||
#{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](<REPO>/issues/${2}))"},
|
||||
# Check spelling of the commit with https://github.com/crate-ci/typos
|
||||
# If the spelling is incorrect, it will be automatically fixed.
|
||||
#{ pattern = '.*', replace_command = 'typos --write-changes -' },
|
||||
]
|
||||
# regex for parsing and grouping commits
|
||||
commit_parsers = [
|
||||
{ message = "^feat", group = "<!-- 0 -->🚀 Features" },
|
||||
{ message = "^fix", group = "<!-- 1 -->🐛 Bug Fixes" },
|
||||
{ message = "^doc", group = "<!-- 3 -->📚 Documentation" },
|
||||
{ message = "^perf", group = "<!-- 4 -->⚡ Performance" },
|
||||
{ message = "^refactor", group = "<!-- 2 -->🚜 Refactor" },
|
||||
{ message = "^style", group = "<!-- 5 -->🎨 Styling" },
|
||||
{ message = "^test", group = "<!-- 6 -->🧪 Testing" },
|
||||
{ message = "^chore\\(release\\): prepare for", skip = true },
|
||||
{ message = "^chore|^ci", group = "<!-- 7 -->⚙️ Miscellaneous Tasks" },
|
||||
{ body = ".*security", group = "<!-- 8 -->🛡️ Security" },
|
||||
{ message = "^revert", group = "<!-- 9 -->◀️ Revert" },
|
||||
]
|
||||
# filter out the commits that are not matched by commit parsers
|
||||
filter_commits = false
|
||||
# sort the tags topologically
|
||||
topo_order = false
|
||||
# sort the commits inside sections by oldest/newest order
|
||||
sort_commits = "oldest"
|
||||
|
||||
[bump]
|
||||
# Before 1.0.0, a breaking change bumps the minor version instead of the major.
|
||||
breaking_always_bump_major = false
|
||||
@@ -1,15 +1,18 @@
|
||||
package client
|
||||
|
||||
// UserAdded is the event sent when a new user is added to a company
|
||||
// UserAdded is the event sent when a new user is added to a company.
|
||||
// SequenceNo is authz-service's global event sequence number; it orders the events.
|
||||
type UserAdded struct {
|
||||
Email string `json:"email"`
|
||||
CompanyID string `json:"companyId"`
|
||||
Email string `json:"email"`
|
||||
CompanyID string `json:"companyId"`
|
||||
SequenceNo int `json:"sequenceNo"`
|
||||
}
|
||||
|
||||
// UserRemoved is the event sent when a user is removed from a company
|
||||
type UserRemoved struct {
|
||||
Email string `json:"email"`
|
||||
CompanyID string `json:"companyId"`
|
||||
Email string `json:"email"`
|
||||
CompanyID string `json:"companyId"`
|
||||
SequenceNo int `json:"sequenceNo"`
|
||||
}
|
||||
|
||||
// Privilege is an enumeration of all available privileges
|
||||
@@ -51,14 +54,16 @@ func (e Privilege) String() string {
|
||||
|
||||
// PrivilegeAdded is the event sent when a new privilege is added
|
||||
type PrivilegeAdded struct {
|
||||
Email string `json:"email"`
|
||||
CompanyID string `json:"companyId"`
|
||||
Privilege Privilege `json:"privilege"`
|
||||
Email string `json:"email"`
|
||||
CompanyID string `json:"companyId"`
|
||||
Privilege Privilege `json:"privilege"`
|
||||
SequenceNo int `json:"sequenceNo"`
|
||||
}
|
||||
|
||||
// PrivilegeRemoved is the event sent when a privilege is removed
|
||||
type PrivilegeRemoved struct {
|
||||
Email string `json:"email"`
|
||||
CompanyID string `json:"companyId"`
|
||||
Privilege Privilege `json:"privilege"`
|
||||
Email string `json:"email"`
|
||||
CompanyID string `json:"companyId"`
|
||||
Privilege Privilege `json:"privilege"`
|
||||
SequenceNo int `json:"sequenceNo"`
|
||||
}
|
||||
@@ -1,19 +1,31 @@
|
||||
module gitlab.com/unboundsoftware/shiny/authz_client
|
||||
module gitea.unbound.se/shiny/authz_client
|
||||
|
||||
go 1.22.12
|
||||
|
||||
toolchain go1.25.1
|
||||
go 1.26.2
|
||||
|
||||
require (
|
||||
github.com/sparetimecoders/goamqp v0.3.3
|
||||
github.com/stretchr/testify v1.11.1
|
||||
codeberg.org/messaging/go-messaging-amqp v0.0.5
|
||||
codeberg.org/messaging/messaging v0.0.5
|
||||
github.com/stretchr/testify v1.12.1
|
||||
)
|
||||
|
||||
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/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rabbitmq/amqp091-go v1.10.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/prometheus/client_golang v1.23.2 // indirect
|
||||
github.com/prometheus/client_model v0.6.2 // indirect
|
||||
github.com/prometheus/common v0.66.1 // indirect
|
||||
github.com/prometheus/procfs v0.16.1 // indirect
|
||||
github.com/rabbitmq/amqp091-go v1.15.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
|
||||
)
|
||||
@@ -1,20 +1,72 @@
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
codeberg.org/messaging/go-messaging-amqp v0.0.5 h1:zzcJ+FVWgBPKyTkq9RXF11yvnhs8IN5BALBC+mps1zA=
|
||||
codeberg.org/messaging/go-messaging-amqp v0.0.5/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/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw=
|
||||
github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o=
|
||||
github.com/sparetimecoders/goamqp v0.3.3 h1:z/nfTPmrjeU/rIVuNOgsVLCimp3WFoNFvS3ZzXRJ6HE=
|
||||
github.com/sparetimecoders/goamqp v0.3.3/go.mod h1:W9NRCpWLE+Vruv2dcRSbszNil2O826d2Nv6kAkETW5o=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE=
|
||||
github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/nats-io/nats.go v1.52.0 h1:n3avV4VBsCgsdwh71TppsTwtv+QdPs7ntSKM8qJLGsc=
|
||||
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.15.0 h1:LEQL4/yp48/Wigt6A6XOu18RQRo8ZHtB5I/KZJn+gkw=
|
||||
github.com/rabbitmq/amqp091-go v1.15.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/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/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
Reference in new issue
Block a user