mirror of
https://github.com/therootcompany/golib.git
synced 2026-03-31 18:18:00 +00:00
doc(csvauth): add programmatic usage section for tests and embedded apps
Document the API for creating credentials in code without a CSV file: - NewCredential params requirement (nil panics) - PurposeToken vs PurposeDefault lookup behavior - CacheCredential vs LoadCSV - Full test example for Bearer token auth
This commit is contained in:
parent
77c256a9c2
commit
bab1750c82
@ -135,6 +135,104 @@ req.SetBasicAuth(account.Name, account.Secret())
|
||||
}
|
||||
```
|
||||
|
||||
## Programmatic Usage (Tests, Embedded Apps)
|
||||
|
||||
You can set up credentials entirely in code, without a CSV file. This is useful
|
||||
for tests, embedded apps, or anywhere you want to avoid file I/O.
|
||||
|
||||
### Creating an Auth instance
|
||||
|
||||
`New` takes a 16-byte AES key. For tests, any 16 bytes will do:
|
||||
|
||||
```go
|
||||
key := make([]byte, 16) // all zeros is fine for tests
|
||||
auth := csvauth.New(key)
|
||||
```
|
||||
|
||||
### Creating credentials with NewCredential
|
||||
|
||||
`NewCredential` creates a credential with a derived (hashed or encrypted) secret.
|
||||
|
||||
**The `params` argument is required and must specify the algorithm.** Passing
|
||||
`nil` will panic with an index-out-of-range error. Valid values:
|
||||
|
||||
| Algorithm | Params |
|
||||
| --- | --- |
|
||||
| Plaintext | `[]string{"plain"}` |
|
||||
| AES-128-GCM (reversible) | `[]string{"aes-128-gcm"}` |
|
||||
| PBKDF2 (defaults) | `[]string{"pbkdf2"}` |
|
||||
| PBKDF2 (explicit) | `[]string{"pbkdf2", "1000", "16", "SHA-256"}` |
|
||||
| bcrypt (defaults) | `[]string{"bcrypt"}` |
|
||||
| bcrypt (explicit cost) | `[]string{"bcrypt", "12"}` |
|
||||
|
||||
```go
|
||||
cred := auth.NewCredential(
|
||||
csvauth.PurposeToken, // purpose: "token" or "login"
|
||||
"bot@example.com", // name (username or label)
|
||||
"my-secret-token", // plaintext secret
|
||||
[]string{"plain"}, // algorithm — REQUIRED, must not be nil
|
||||
[]string{"admin"}, // roles (nil for none)
|
||||
"", // extra JSON (empty string for none)
|
||||
)
|
||||
```
|
||||
|
||||
### Token auth vs Login auth
|
||||
|
||||
The `purpose` field controls how a credential is stored and looked up:
|
||||
|
||||
- **`"login"` (PurposeDefault)** — The credential is cached by **name**
|
||||
(username). `Authenticate("username", "password")` looks it up by name.
|
||||
|
||||
- **`"token"` (PurposeToken)** — The credential is cached by a **hash of the
|
||||
secret** in a separate tokens map. `Authenticate("", "the-token")` looks it
|
||||
up by hashing the provided secret and searching the tokens map.
|
||||
|
||||
**If you use `"login"` as the purpose for a Bearer token credential, it will
|
||||
never be found by `Authenticate("", secret)`** because login credentials are
|
||||
only searched by name, not by token hash. Token credentials _must_ use
|
||||
`PurposeToken` (`"token"`).
|
||||
|
||||
### CacheCredential vs LoadCSV
|
||||
|
||||
Both populate the same internal maps — they differ only in how credentials
|
||||
are provided:
|
||||
|
||||
- **`CacheCredential(c)`** — Add a single credential programmatically. Use
|
||||
this in tests or when building credentials in code.
|
||||
- **`LoadCSV(f, '\t')`** — Parse a TSV (or CSV) file of credentials. Use this
|
||||
in production when credentials live in a file.
|
||||
|
||||
### Full test example
|
||||
|
||||
```go
|
||||
func TestBearerAuth(t *testing.T) {
|
||||
key := make([]byte, 16)
|
||||
auth := csvauth.New(key)
|
||||
|
||||
secret := "test-api-token-abc123"
|
||||
|
||||
// Purpose MUST be "token" for Bearer-style auth
|
||||
cred := auth.NewCredential(
|
||||
csvauth.PurposeToken,
|
||||
"test-bot",
|
||||
secret,
|
||||
[]string{"plain"},
|
||||
nil,
|
||||
"",
|
||||
)
|
||||
auth.CacheCredential(*cred)
|
||||
|
||||
// Authenticate with empty name (Bearer token style)
|
||||
principal, err := auth.Authenticate("", secret)
|
||||
if err != nil {
|
||||
t.Fatalf("expected success, got: %v", err)
|
||||
}
|
||||
if principal.ID() != "test-bot" {
|
||||
t.Fatalf("expected 'test-bot', got %q", principal.ID())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Service Account
|
||||
|
||||
1. Use `csvauth store --purpose <account> [options] <username>` to store API credentials
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user