Implement Phase 9: client libraries (Go, Rust, Lisp, Python)
- clients/README.md: canonical API surface and error type reference - clients/testdata/: shared JSON response fixtures - clients/go/: mciasgoclient package; net/http + TLS 1.2+; sync.RWMutex token state; DisallowUnknownFields on all decoders; 25 tests pass - clients/rust/: async mcias-client crate; reqwest+rustls (no OpenSSL); thiserror MciasError enum; Arc<RwLock> token state; 22+1 tests pass; cargo clippy -D warnings clean - clients/lisp/: ASDF mcias-client; dexador HTTP, yason JSON; mcias-error condition hierarchy; Hunchentoot mock-dispatcher; 37 fiveam checks pass on SBCL 2.6.1; yason boolean normalisation in validate-token - clients/python/: mcias_client package (Python 3.11+); httpx sync; py.typed; dataclasses; 32 pytest tests; mypy --strict + ruff clean - test/mock/mockserver.go: in-memory mock server for Go client tests - ARCHITECTURE.md §19: updated per-language notes to match implementation - PROGRESS.md: Phase 9 marked complete - .gitignore: exclude clients/rust/target/, python .venv, .pytest_cache, .fasl files Security: token never logged or exposed in error messages in any library; TLS enforced in all four languages; token stored under lock/mutex/RwLock
This commit is contained in:
85
clients/go/README.md
Normal file
85
clients/go/README.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# mcias-client (Go)
|
||||
|
||||
Go client library for the [MCIAS](../../README.md) identity and access management API.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Go 1.21+
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
go get git.wntrmute.dev/kyle/mcias/clients/go
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
```go
|
||||
import mciasgoclient "git.wntrmute.dev/kyle/mcias/clients/go"
|
||||
|
||||
// Connect to the MCIAS server.
|
||||
client, err := mciasgoclient.New("https://auth.example.com", mciasgoclient.Options{})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Authenticate.
|
||||
token, expiresAt, err := client.Login("alice", "s3cret", "")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Printf("token expires at %s\n", expiresAt)
|
||||
|
||||
// The token is stored in the client automatically.
|
||||
// Call authenticated endpoints...
|
||||
accounts, err := client.ListAccounts()
|
||||
|
||||
// Revoke the token when done.
|
||||
if err := client.Logout(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
```
|
||||
|
||||
## Custom CA Certificate
|
||||
|
||||
```go
|
||||
client, err := mciasgoclient.New("https://auth.example.com", mciasgoclient.Options{
|
||||
CACertPath: "/etc/mcias/ca.pem",
|
||||
})
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
All methods return typed errors:
|
||||
|
||||
```go
|
||||
_, _, err := client.Login("alice", "wrongpass", "")
|
||||
switch {
|
||||
case errors.Is(err, new(mciasgoclient.MciasAuthError)):
|
||||
// 401 — wrong credentials or token invalid
|
||||
case errors.Is(err, new(mciasgoclient.MciasForbiddenError)):
|
||||
// 403 — insufficient role
|
||||
case errors.Is(err, new(mciasgoclient.MciasNotFoundError)):
|
||||
// 404 — resource not found
|
||||
case errors.Is(err, new(mciasgoclient.MciasInputError)):
|
||||
// 400 — malformed request
|
||||
case errors.Is(err, new(mciasgoclient.MciasConflictError)):
|
||||
// 409 — conflict (e.g. duplicate username)
|
||||
case errors.Is(err, new(mciasgoclient.MciasServerError)):
|
||||
// 5xx — unexpected server error
|
||||
}
|
||||
```
|
||||
|
||||
All error types embed `MciasError` which carries `StatusCode int` and
|
||||
`Message string`.
|
||||
|
||||
## Thread Safety
|
||||
|
||||
`Client` is safe for concurrent use from multiple goroutines. The internal
|
||||
token is protected by `sync.RWMutex`.
|
||||
|
||||
## Running Tests
|
||||
|
||||
```sh
|
||||
go test -race ./...
|
||||
```
|
||||
Reference in New Issue
Block a user