domain/identity/webfinger/service.go (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | package webfinger import ( "encoding/json" "net/http" ihttp "alin.ovh/homestead/shared/http" "alin.ovh/x/log" "github.com/benpate/digit" ) type ResourceProvider interface { GetResource() string GetIdentityResource() digit.Resource } type Service struct { log *log.Logger providers []ResourceProvider corsOrigin string } type Option func(*Service) func WithCORSOrigin(origin string) Option { return func(s *Service) { s.corsOrigin = origin } } func New(logger *log.Logger, providers []ResourceProvider, opts ...Option) *Service { service := &Service{ log: logger, providers: providers, corsOrigin: "*", // Default to allow all origins } for _, opt := range opts { opt(service) } return service } func (s *Service) RegisterHandlers(mux *http.ServeMux) { mux.HandleFunc("/.well-known/webfinger", s.handleWebFinger) } func (s *Service) Handler() http.HandlerFunc { return s.handleWebFinger } func (s *Service) HandleFunc(w http.ResponseWriter, r *http.Request) ihttp.Error { resource := r.URL.Query().Get("resource") if resource == "" { return ihttp.BadRequest("Missing resource parameter", nil) } for _, provider := range s.providers { if resource == provider.GetResource() { w.Header().Add("Content-Type", "application/jrd+json") if s.corsOrigin != "" { w.Header().Add("Access-Control-Allow-Origin", s.corsOrigin) } if err := json.NewEncoder(w).Encode(provider.GetIdentityResource()); err != nil { return ihttp.InternalServerError("Failed to encode webfinger response", err) } return nil } } return ihttp.NotFound("Resource not found") } func (s *Service) handleWebFinger(w http.ResponseWriter, r *http.Request) { if err := s.HandleFunc(w, r); err != nil { status := err.StatusCode() if status == 0 { status = http.StatusInternalServerError } http.Error(w, err.Error(), status) } } |