this repo has no description
1package middleware
2
3import (
4 "context"
5 "log"
6 "net/http"
7 "sync"
8 "time"
9
10 "github.com/bluesky-social/indigo/atproto/identity"
11 "github.com/icyphox/bild/auth"
12)
13
14type cachedIdent struct {
15 ident *identity.Identity
16 expiry time.Time
17}
18
19var (
20 identCache = make(map[string]cachedIdent)
21 cacheMutex sync.RWMutex
22)
23
24// Only use this middleware for routes that require a handle
25// /@{user}/...
26func AddDID(next http.Handler) http.Handler {
27 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
28 user := r.PathValue("user")
29
30 // Check cache first
31 cacheMutex.RLock()
32 if cached, ok := identCache[user]; ok && time.Now().Before(cached.expiry) {
33 cacheMutex.RUnlock()
34 ctx := context.WithValue(r.Context(), "did", cached.ident.DID.String())
35 r = r.WithContext(ctx)
36 next.ServeHTTP(w, r)
37 return
38 }
39 cacheMutex.RUnlock()
40
41 // Cache miss - resolve and cache
42 ident, err := auth.ResolveIdent(r.Context(), user)
43 if err != nil {
44 log.Println("error resolving identity", err)
45 http.Error(w, "error resolving identity", http.StatusNotFound)
46 return
47 }
48
49 cacheMutex.Lock()
50 identCache[user] = cachedIdent{
51 ident: ident,
52 expiry: time.Now().Add(24 * time.Hour),
53 }
54 cacheMutex.Unlock()
55
56 ctx := context.WithValue(r.Context(), "did", ident.DID.String())
57 r = r.WithContext(ctx)
58
59 next.ServeHTTP(w, r)
60 })
61}