dev vouch dev on at. thats about it atvouch.dev
9
fork

Configure Feed

Select the types of activity you want to include in your feed.

appview: add auth service

+452
+1
appview/auth/.gitignore
··· 1 + atvouch-auth
+180
appview/auth/auth.go
··· 1 + package main 2 + 3 + import ( 4 + "context" 5 + "fmt" 6 + "net/http" 7 + "os" 8 + "strings" 9 + "time" 10 + 11 + "github.com/bluesky-social/indigo/atproto/identity" 12 + "github.com/bluesky-social/indigo/atproto/syntax" 13 + es256k "github.com/ericvolp12/jwt-go-secp256k1" 14 + "github.com/gin-gonic/gin" 15 + "github.com/golang-jwt/jwt" 16 + lru "github.com/hashicorp/golang-lru/arc/v2" 17 + "gitlab.com/yawning/secp256k1-voi/secec" 18 + "golang.org/x/time/rate" 19 + ) 20 + 21 + type KeyCacheEntry struct { 22 + UserDID string 23 + Key any 24 + ExpiresAt time.Time 25 + } 26 + 27 + type Auth struct { 28 + KeyCache *lru.ARCCache[string, KeyCacheEntry] 29 + KeyCacheTTL time.Duration 30 + ServiceDID string 31 + Dir *identity.CacheDirectory 32 + } 33 + 34 + func NewAuth( 35 + keyCacheSize int, 36 + keyCacheTTL time.Duration, 37 + requestsPerSecond int, 38 + serviceDID string, 39 + ) (*Auth, error) { 40 + keyCache, err := lru.NewARC[string, KeyCacheEntry](keyCacheSize) 41 + if err != nil { 42 + return nil, fmt.Errorf("Failed to create key cache: %v", err) 43 + } 44 + 45 + client := http.Client{} 46 + plcUrl := os.Getenv("ATPROTO_PLC_URL") 47 + if plcUrl == "" { 48 + plcUrl = "https://plc.directory" 49 + } 50 + 51 + baseDir := identity.BaseDirectory{ 52 + PLCURL: plcUrl, 53 + PLCLimiter: rate.NewLimiter(rate.Limit(float64(requestsPerSecond)), 1), 54 + HTTPClient: client, 55 + TryAuthoritativeDNS: true, 56 + // primary Bluesky PDS instance only supports HTTP resolution method 57 + SkipDNSDomainSuffixes: []string{".bsky.social"}, 58 + } 59 + dir := identity.NewCacheDirectory(&baseDir, keyCacheSize, keyCacheTTL, time.Minute*2, keyCacheTTL) 60 + 61 + return &Auth{ 62 + KeyCache: keyCache, 63 + KeyCacheTTL: keyCacheTTL, 64 + ServiceDID: serviceDID, 65 + Dir: &dir, 66 + }, nil 67 + } 68 + 69 + func (auth *Auth) GetClaimsFromAuthHeader(ctx context.Context, authHeader string, claims jwt.Claims) error { 70 + if authHeader == "" { 71 + return fmt.Errorf("No Authorization header provided") 72 + } 73 + 74 + authHeaderParts := strings.Split(authHeader, " ") 75 + if len(authHeaderParts) != 2 { 76 + return fmt.Errorf("Invalid Authorization header") 77 + } 78 + 79 + if authHeaderParts[0] != "Bearer" { 80 + return fmt.Errorf("Invalid Authorization header (expected Bearer)") 81 + } 82 + 83 + accessToken := authHeaderParts[1] 84 + 85 + parser := jwt.Parser{ 86 + ValidMethods: []string{es256k.SigningMethodES256K.Alg()}, 87 + } 88 + 89 + token, err := parser.ParseWithClaims(accessToken, claims, func(token *jwt.Token) (interface{}, error) { 90 + if claims, ok := token.Claims.(*jwt.StandardClaims); ok { 91 + // Get the user's key from PLC Directory 92 + userDID := claims.Issuer 93 + entry, ok := auth.KeyCache.Get(userDID) 94 + if ok && entry.ExpiresAt.After(time.Now()) { 95 + return entry.Key, nil 96 + } 97 + 98 + did, err := syntax.ParseDID(userDID) 99 + if err != nil { 100 + return nil, fmt.Errorf("Failed to parse user DID: %v", err) 101 + } 102 + 103 + // Get the user's key from PLC Directory 104 + id, err := auth.Dir.LookupDID(ctx, did) 105 + if err != nil { 106 + return nil, fmt.Errorf("Failed to lookup user DID: %v", err) 107 + } 108 + 109 + key, err := id.GetPublicKey("atproto") 110 + if err != nil { 111 + return nil, fmt.Errorf("Failed to get user public key: %v", err) 112 + } 113 + 114 + parsedPubkey, err := secec.NewPublicKey(key.UncompressedBytes()) 115 + if err != nil { 116 + return nil, fmt.Errorf("Failed to parse user public key: %v", err) 117 + } 118 + 119 + // Add the ECDSA key to the cache 120 + auth.KeyCache.Add(userDID, KeyCacheEntry{ 121 + Key: parsedPubkey, 122 + ExpiresAt: time.Now().Add(auth.KeyCacheTTL), 123 + }) 124 + 125 + return parsedPubkey, nil 126 + } 127 + 128 + return nil, fmt.Errorf("Invalid authorization token (failed to parse claims)") 129 + }) 130 + 131 + if err != nil { 132 + return fmt.Errorf("Failed to parse authorization token: %v", err) 133 + } 134 + 135 + if !token.Valid { 136 + return fmt.Errorf("Invalid authorization token") 137 + } 138 + 139 + return nil 140 + } 141 + 142 + func (auth *Auth) AuthenticateGinRequestViaJWT(c *gin.Context) { 143 + authHeader := c.GetHeader("Authorization") 144 + if authHeader == "" { 145 + c.Next() 146 + return 147 + } 148 + 149 + claims := jwt.StandardClaims{} 150 + 151 + err := auth.GetClaimsFromAuthHeader(c.Request.Context(), authHeader, &claims) 152 + if err != nil { 153 + c.JSON(http.StatusUnauthorized, gin.H{"error": fmt.Errorf("Failed to get claims from auth header: %v", err).Error()}) 154 + c.Abort() 155 + return 156 + } 157 + 158 + // Set claims Issuer to context as user DID 159 + c.Set("user_did", claims.Issuer) 160 + c.Set("audience", claims.Audience) 161 + c.Next() 162 + } 163 + 164 + // InvalidateCache removes the cached key and identity information for a given DID 165 + func (auth *Auth) InvalidateCache(did string) error { 166 + // Remove from KeyCache 167 + auth.KeyCache.Remove(did) 168 + 169 + // Parse DID and purge from CacheDirectory 170 + atid, err := syntax.ParseAtIdentifier(did) 171 + if err != nil { 172 + return fmt.Errorf("failed to parse DID: %w", err) 173 + } 174 + 175 + if err := auth.Dir.Purge(context.Background(), *atid); err != nil { 176 + return fmt.Errorf("failed to purge from directory: %w", err) 177 + } 178 + 179 + return nil 180 + }
+32
appview/auth/endpoints.go
··· 1 + package main 2 + 3 + import ( 4 + "net/http" 5 + 6 + "github.com/gin-gonic/gin" 7 + ) 8 + 9 + func GetUser(c *gin.Context) { 10 + userDID := c.GetString("user_did") 11 + audience := c.GetString("audience") 12 + c.JSON(http.StatusOK, gin.H{"did": userDID, "aud": audience}) 13 + } 14 + 15 + type InvalidateCacheRequest struct { 16 + DID string `json:"did" binding:"required"` 17 + } 18 + 19 + func (auth *Auth) InvalidateCacheHandler(c *gin.Context) { 20 + var req InvalidateCacheRequest 21 + if err := c.ShouldBindJSON(&req); err != nil { 22 + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) 23 + return 24 + } 25 + 26 + if err := auth.InvalidateCache(req.DID); err != nil { 27 + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 28 + return 29 + } 30 + 31 + c.JSON(http.StatusOK, gin.H{"status": "ok", "invalidated": req.DID}) 32 + }
+53
appview/auth/go.mod
··· 1 + module ln4.net/atvouch/auth 2 + 3 + go 1.24.2 4 + 5 + require ( 6 + github.com/bluesky-social/indigo v0.0.0-20250520232546-236dd575c91e 7 + github.com/ericvolp12/jwt-go-secp256k1 v0.0.2 8 + github.com/gin-gonic/gin v1.10.1 9 + github.com/golang-jwt/jwt v3.2.2+incompatible 10 + github.com/hashicorp/golang-lru/arc/v2 v2.0.7 11 + gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b 12 + golang.org/x/time v0.11.0 13 + ) 14 + 15 + require ( 16 + github.com/beorn7/perks v1.0.1 // indirect 17 + github.com/bytedance/sonic v1.11.6 // indirect 18 + github.com/bytedance/sonic/loader v0.1.1 // indirect 19 + github.com/carlmjohnson/versioninfo v0.22.5 // indirect 20 + github.com/cespare/xxhash/v2 v2.2.0 // indirect 21 + github.com/cloudwego/base64x v0.1.4 // indirect 22 + github.com/cloudwego/iasm v0.2.0 // indirect 23 + github.com/gabriel-vasile/mimetype v1.4.3 // indirect 24 + github.com/gin-contrib/sse v0.1.0 // indirect 25 + github.com/go-playground/locales v0.14.1 // indirect 26 + github.com/go-playground/universal-translator v0.18.1 // indirect 27 + github.com/go-playground/validator/v10 v10.20.0 // indirect 28 + github.com/goccy/go-json v0.10.2 // indirect 29 + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect 30 + github.com/json-iterator/go v1.1.12 // indirect 31 + github.com/klauspost/cpuid/v2 v2.2.7 // indirect 32 + github.com/leodido/go-urn v1.4.0 // indirect 33 + github.com/mattn/go-isatty v0.0.20 // indirect 34 + github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect 35 + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 36 + github.com/modern-go/reflect2 v1.0.2 // indirect 37 + github.com/mr-tron/base58 v1.2.0 // indirect 38 + github.com/pelletier/go-toml/v2 v2.2.2 // indirect 39 + github.com/prometheus/client_golang v1.17.0 // indirect 40 + github.com/prometheus/client_model v0.5.0 // indirect 41 + github.com/prometheus/common v0.45.0 // indirect 42 + github.com/prometheus/procfs v0.12.0 // indirect 43 + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect 44 + github.com/ugorji/go/codec v1.2.12 // indirect 45 + gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 // indirect 46 + golang.org/x/arch v0.8.0 // indirect 47 + golang.org/x/crypto v0.23.0 // indirect 48 + golang.org/x/net v0.25.0 // indirect 49 + golang.org/x/sys v0.22.0 // indirect 50 + golang.org/x/text v0.15.0 // indirect 51 + google.golang.org/protobuf v1.34.1 // indirect 52 + gopkg.in/yaml.v3 v3.0.1 // indirect 53 + )
+128
appview/auth/go.sum
··· 1 + github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= 2 + github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= 3 + github.com/bluesky-social/indigo v0.0.0-20250520232546-236dd575c91e h1:DVD+HxQsDCVJtAkjfIKZVaBNc3kayHaU+A2TJZkFdp4= 4 + github.com/bluesky-social/indigo v0.0.0-20250520232546-236dd575c91e/go.mod h1:ovyxp8AMO1Hoe838vMJUbqHTZaAR8ABM3g3TXu+A5Ng= 5 + github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= 6 + github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= 7 + github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= 8 + github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= 9 + github.com/carlmjohnson/versioninfo v0.22.5 h1:O00sjOLUAFxYQjlN/bzYTuZiS0y6fWDQjMRvwtKgwwc= 10 + github.com/carlmjohnson/versioninfo v0.22.5/go.mod h1:QT9mph3wcVfISUKd0i9sZfVrPviHuSF+cUtLjm2WSf8= 11 + github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= 12 + github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 13 + github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= 14 + github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= 15 + github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= 16 + github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= 17 + github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 18 + github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 19 + github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 20 + github.com/ericvolp12/jwt-go-secp256k1 v0.0.2 h1:puGwrNTY2vCt8eakkSEq2yeNxUD3zb2kPhv1OsF1hPs= 21 + github.com/ericvolp12/jwt-go-secp256k1 v0.0.2/go.mod h1:ntxzdN7EhBp8h+N78AtN2hjbVKHa7mijryYd9nPMyMo= 22 + github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= 23 + github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= 24 + github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= 25 + github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= 26 + github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ= 27 + github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= 28 + github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= 29 + github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= 30 + github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= 31 + github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= 32 + github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= 33 + github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= 34 + github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8= 35 + github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= 36 + github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= 37 + github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= 38 + github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= 39 + github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= 40 + github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= 41 + github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 42 + github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 43 + github.com/hashicorp/golang-lru/arc/v2 v2.0.7 h1:QxkVTxwColcduO+LP7eJO56r2hFiG8zEbfAAzRv52KQ= 44 + github.com/hashicorp/golang-lru/arc/v2 v2.0.7/go.mod h1:Pe7gBlGdc8clY5LJ0LpJXMt5AmgmWNH1g+oFFVUHOEc= 45 + github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= 46 + github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= 47 + github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 48 + github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 49 + github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= 50 + github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= 51 + github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= 52 + github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= 53 + github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 54 + github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 55 + github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 56 + github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 57 + github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= 58 + github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= 59 + github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= 60 + github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 61 + github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= 62 + github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= 63 + github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 64 + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 65 + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 66 + github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 67 + github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 68 + github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= 69 + github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= 70 + github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= 71 + github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= 72 + github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 73 + github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 74 + github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= 75 + github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= 76 + github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= 77 + github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= 78 + github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= 79 + github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= 80 + github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= 81 + github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= 82 + github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= 83 + github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= 84 + github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 85 + github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 86 + github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 87 + github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= 88 + github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 89 + github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 90 + github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 91 + github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 92 + github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 93 + github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 94 + github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= 95 + github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 96 + github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= 97 + github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= 98 + github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= 99 + github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= 100 + gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b h1:CzigHMRySiX3drau9C6Q5CAbNIApmLdat5jPMqChvDA= 101 + gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b/go.mod h1:/y/V339mxv2sZmYYR64O07VuCpdNZqCTwO8ZcouTMI8= 102 + gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 h1:qwDnMxjkyLmAFgcfgTnfJrmYKWhHnci3GjDqcZp1M3Q= 103 + gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02/go.mod h1:JTnUj0mpYiAsuZLmKjTx/ex3AtMowcCgnE7YNyCEP0I= 104 + golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= 105 + golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= 106 + golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= 107 + golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= 108 + golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= 109 + golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= 110 + golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= 111 + golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 112 + golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 113 + golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= 114 + golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 115 + golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= 116 + golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 117 + golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= 118 + golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= 119 + google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= 120 + google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 121 + gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 122 + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 123 + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 124 + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 125 + gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 126 + gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 127 + nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= 128 + rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
+58
appview/auth/main.go
··· 1 + package main 2 + 3 + import ( 4 + "fmt" 5 + "log" 6 + "log/slog" 7 + "net/url" 8 + "os" 9 + "time" 10 + 11 + "github.com/gin-gonic/gin" 12 + ) 13 + 14 + func main() { 15 + log.SetOutput(os.Stderr) 16 + if os.Getenv("DEBUG") == "1" { 17 + slog.SetLogLoggerLevel(slog.LevelDebug) 18 + } 19 + endpoint := os.Getenv("ATVOUCH_ENDPOINT") 20 + if endpoint == "" { 21 + log.Fatalln("ATVOUCH_ENDPOINT must be set to a non-empty value") 22 + } 23 + 24 + serviceURL, err := url.Parse(endpoint) 25 + if err != nil { 26 + log.Fatal(fmt.Errorf("error parsing service endpoint: %w", err)) 27 + } 28 + 29 + serviceWebDID := "did:web:" + serviceURL.Host 30 + log.Printf("service DID Web: %s", serviceWebDID) 31 + 32 + // Create a gin router with default middleware for logging and recovery 33 + router := gin.Default() 34 + 35 + // Plug in Authentication Middleware 36 + auther, err := NewAuth( 37 + 100_000, 38 + time.Hour*12, 39 + 5, 40 + serviceWebDID, 41 + ) 42 + if err != nil { 43 + log.Fatalf("Failed to create Auth: %v", err) 44 + } 45 + 46 + router.Use(auther.AuthenticateGinRequestViaJWT) 47 + router.GET("/user", GetUser) 48 + router.POST("/invalidate_cache", auther.InvalidateCacheHandler) 49 + 50 + port := os.Getenv("PORT") 51 + if port == "" { 52 + port = "8087" 53 + } 54 + 55 + addr := fmt.Sprintf("127.0.0.1:%s", port) 56 + log.Printf("Starting server on addr %s", addr) 57 + router.Run(addr) 58 + }