authz_client / test (push) Successful in 58s
Unbound Release / Check Preconditions (push) Successful in 22s
Unbound Release / Create Tag (push) Skipped
authz_client / vulnerabilities (push) Successful in 47s
Unbound Release / Generate Changelog and Handle PR (push) Successful in 32s
Unbound Release / Create Release (push) Successful in 24s
Release / release (push) Successful in 58s
pre-commit / pre-commit (push) Successful in 2m17s
47 lines
2.0 KiB
Markdown
47 lines
2.0 KiB
Markdown
# 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
|
|
privileges := handler.Get(email, companyID)
|
|
if privileges.Invoicing {
|
|
// User has invoicing privileges
|
|
}
|
|
```
|
|
|
|
### 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 update events from the authz-service (`Setup()`), keeping the local privilege cache up-to-date. Each routing key gets its own queue, so events for one company arrive in any order — `Process` must never discard state it didn't itself record. `User.Added` therefore creates the company entry only when it is missing: a `Privilege.Added` processed ahead of it would otherwise be overwritten, and nothing re-reads the privilege until the next `Fetch()`. The converse doesn't hold yet — `setPrivileges` still creates an entry for a company it never saw a `User.Added` for, so a `Privilege.*` delivered after `User.Removed` resurrects an all-false membership. 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.
|