75 lines
1.6 KiB
Go
75 lines
1.6 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
"time"
|
|
|
|
"git.juancwu.dev/juancwu/ficha"
|
|
)
|
|
|
|
type Meta struct {
|
|
UserID string `json:"user_id"`
|
|
Tier string `json:"tier"`
|
|
}
|
|
|
|
func main() {
|
|
key, err := ficha.GenerateKey()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
ring, err := ficha.NewKeyRing("k1", key)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
store := ficha.NewMemoryRevocationStore()
|
|
iss, err := ficha.NewIssuer(ring, store)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
ctx := context.Background()
|
|
tokenStr, err := iss.Issue(ctx,
|
|
[]string{"orders:read", "orders:write", "billing-manager"},
|
|
Meta{UserID: "u_42", Tier: "pro"},
|
|
15*time.Minute,
|
|
)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
fmt.Println("Token:", tokenStr)
|
|
|
|
tok, err := iss.Validate(ctx, tokenStr)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
fmt.Println("\nID: ", tok.ID())
|
|
fmt.Println("ExpiresAt: ", tok.ExpiresAt())
|
|
fmt.Println("Permissions:", tok.Permissions())
|
|
|
|
var meta Meta
|
|
if err := tok.UnmarshalData(&meta); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
fmt.Printf("Data: %+v\n", meta)
|
|
|
|
fmt.Println("\nChecks:")
|
|
fmt.Println(" Has(orders:read): ", tok.Has("orders:read"))
|
|
fmt.Println(" HasAll(read,write): ", tok.HasAll("orders:read", "orders:write"))
|
|
fmt.Println(" RequiresAll([]): ", tok.RequiresAll())
|
|
fmt.Println(" Composed matcher: ", tok.Check(ficha.All(
|
|
"orders:read",
|
|
ficha.Any("admin", "billing-manager"),
|
|
ficha.Not("readonly"),
|
|
)))
|
|
|
|
if err := iss.Revoke(ctx, tokenStr); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
fmt.Println("\nAfter revoke:")
|
|
if _, err := iss.Validate(ctx, tokenStr); err != nil {
|
|
fmt.Println(" Validate error:", err)
|
|
}
|
|
}
|