Monorepo for Tangled tangled.org
5

Configure Feed

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

1package serviceauth 2 3import ( 4 "context" 5 "encoding/json" 6 "log/slog" 7 "net/http" 8 "strings" 9 10 "github.com/bluesky-social/indigo/atproto/auth" 11 "github.com/bluesky-social/indigo/atproto/syntax" 12 "tangled.org/core/idresolver" 13 "tangled.org/core/log" 14 xrpcerr "tangled.org/core/xrpc/errors" 15) 16 17const ActorDid string = "ActorDid" 18 19func DidWeb(hostname string) syntax.DID { 20 return syntax.DID("did:web:" + strings.ReplaceAll(hostname, ":", "%3A")) 21} 22 23type ServiceAuth struct { 24 logger *slog.Logger 25 resolver *idresolver.Resolver 26 audienceDid string 27} 28 29func NewServiceAuth(logger *slog.Logger, resolver *idresolver.Resolver, audienceDid string) *ServiceAuth { 30 return &ServiceAuth{ 31 logger: log.SubLogger(logger, "serviceauth"), 32 resolver: resolver, 33 audienceDid: audienceDid, 34 } 35} 36 37func (sa *ServiceAuth) VerifyServiceAuth(next http.Handler) http.Handler { 38 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 39 token := r.Header.Get("Authorization") 40 token = strings.TrimPrefix(token, "Bearer ") 41 42 s := auth.ServiceAuthValidator{ 43 Audience: sa.audienceDid, 44 Dir: sa.resolver.Directory(), 45 } 46 47 did, err := s.Validate(r.Context(), token, nil) 48 if err != nil { 49 sa.logger.Error("signature verification failed", "err", err) 50 writeError(w, xrpcerr.AuthError(err), http.StatusForbidden) 51 return 52 } 53 54 sa.logger.Debug("valid signature", ActorDid, did) 55 56 r = r.WithContext( 57 context.WithValue(r.Context(), ActorDid, did), 58 ) 59 60 next.ServeHTTP(w, r) 61 }) 62} 63 64// this is slightly different from http_util::write_error to follow the spec: 65// 66// the json object returned must include an "error" and a "message" 67func writeError(w http.ResponseWriter, e xrpcerr.XrpcError, status int) { 68 w.Header().Set("Content-Type", "application/json") 69 w.WriteHeader(status) 70 json.NewEncoder(w).Encode(e) 71}