mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-04-29 20:46:58 +00:00
89 lines
1.9 KiB
Go
89 lines
1.9 KiB
Go
package hold
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/bluesky-social/indigo/atproto/identity"
|
|
"github.com/bluesky-social/indigo/atproto/syntax"
|
|
)
|
|
|
|
// handleCache provides caching for DID → handle resolution
|
|
// This reduces latency for pattern matching authorization checks
|
|
type handleCache struct {
|
|
mu sync.RWMutex
|
|
cache map[string]cacheEntry // did → handle
|
|
}
|
|
|
|
type cacheEntry struct {
|
|
handle string
|
|
expiresAt time.Time
|
|
}
|
|
|
|
const handleCacheTTL = 10 * time.Minute
|
|
|
|
var (
|
|
// Global handle cache instance
|
|
globalHandleCache = &handleCache{
|
|
cache: make(map[string]cacheEntry),
|
|
}
|
|
)
|
|
|
|
// get retrieves a cached handle for a DID
|
|
func (c *handleCache) get(did string) (string, bool) {
|
|
c.mu.RLock()
|
|
defer c.mu.RUnlock()
|
|
|
|
entry, ok := c.cache[did]
|
|
if !ok || time.Now().After(entry.expiresAt) {
|
|
return "", false
|
|
}
|
|
return entry.handle, true
|
|
}
|
|
|
|
// set stores a handle in the cache
|
|
func (c *handleCache) set(did, handle string) {
|
|
c.mu.Lock()
|
|
defer c.mu.Unlock()
|
|
|
|
c.cache[did] = cacheEntry{
|
|
handle: handle,
|
|
expiresAt: time.Now().Add(handleCacheTTL),
|
|
}
|
|
}
|
|
|
|
// resolveHandle resolves a DID to its current handle using ATProto identity resolution
|
|
// Results are cached for 10 minutes to reduce latency
|
|
func resolveHandle(did string) (string, error) {
|
|
// Check cache first
|
|
if handle, ok := globalHandleCache.get(did); ok {
|
|
return handle, nil
|
|
}
|
|
|
|
// Cache miss - resolve from network
|
|
ctx := context.Background()
|
|
directory := identity.DefaultDirectory()
|
|
|
|
didParsed, err := syntax.ParseDID(did)
|
|
if err != nil {
|
|
return "", fmt.Errorf("invalid DID: %w", err)
|
|
}
|
|
|
|
ident, err := directory.LookupDID(ctx, didParsed)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to resolve DID: %w", err)
|
|
}
|
|
|
|
handle := ident.Handle.String()
|
|
if handle == "" || handle == "handle.invalid" {
|
|
return "", fmt.Errorf("no valid handle found for DID")
|
|
}
|
|
|
|
// Cache the result
|
|
globalHandleCache.set(did, handle)
|
|
|
|
return handle, nil
|
|
}
|