diff --git a/app/activity_pub_service.go b/app/activity_pub_service.go index 2e18d13..23dfb7a 100644 --- a/app/activity_pub_service.go +++ b/app/activity_pub_service.go @@ -53,14 +53,20 @@ func (cfg *ActivityPubConfig) PrivateKey() *rsa.PrivateKey { } type ActivityPubService struct { - followersRepo repository.FollowerRepository - configRepo repository.ConfigRepository + followersRepo repository.FollowerRepository + configRepo repository.ConfigRepository + siteConfigServcie *SiteConfigService } -func NewActivityPubService(followersRepo repository.FollowerRepository, configRepo repository.ConfigRepository) *ActivityPubService { +func NewActivityPubService( + followersRepo repository.FollowerRepository, + configRepo repository.ConfigRepository, + siteConfigServcie *SiteConfigService, +) *ActivityPubService { return &ActivityPubService{ - followersRepo: followersRepo, - configRepo: configRepo, + followersRepo: followersRepo, + configRepo: configRepo, + siteConfigServcie: siteConfigServcie, } } @@ -104,6 +110,27 @@ func (svc *ActivityPubService) GetApConfig() (ActivityPubConfig, error) { return apConfig, nil } +func (svc *ActivityPubService) ActorUrl() string { + cfg, _ := svc.siteConfigServcie.GetSiteConfig() + return cfg.FullUrl +} +func (svc *ActivityPubService) MainKeyUri() string { + cfg, _ := svc.siteConfigServcie.GetSiteConfig() + return cfg.FullUrl + "#main-key" +} +func (svc *ActivityPubService) InboxUrl() string { + cfg, _ := svc.siteConfigServcie.GetSiteConfig() + return cfg.FullUrl + "/activitypub/inbox" +} +func (svc *ActivityPubService) OutboxUrl() string { + cfg, _ := svc.siteConfigServcie.GetSiteConfig() + return cfg.FullUrl + "/activitypub/outbox" +} +func (svc *ActivityPubService) FollowersUrl() string { + cfg, _ := svc.siteConfigServcie.GetSiteConfig() + return cfg.FullUrl + "/activitypub/followers" +} + func (s *ActivityPubService) AddFollower(follower string) error { return s.followersRepo.Add(follower) } @@ -157,7 +184,7 @@ func (s *ActivityPubService) GetActor(reqUrl string) (vocab.Actor, error) { req.Header.Set("Date", time.Now().Format(http.TimeFormat)) req.Header.Set("Host", parsedUrl.Host) - err = s.sign(apConfig.PrivateKey(), siteConfig.FullUrl+"/activitypub/actor#main-key", nil, req) + err = s.sign(apConfig.PrivateKey(), s.MainKeyUri(), nil, req) if err != nil { slog.Error("Signing error", "err", err) return vocab.Actor{}, err @@ -195,7 +222,7 @@ func (s *ActivityPubService) VerifySignature(r *http.Request, sender string) err s.configRepo.Get(config.ACT_PUB_CONF_NAME, &apConfig) s.configRepo.Get(config.SITE_CONFIG, &siteConfig) - slog.Info("verifying for", "sender", sender, "retriever", siteConfig.FullUrl+"/activitypub/actor") + slog.Info("verifying for", "sender", sender, "retriever", s.ActorUrl()) actor, err := s.GetActor(sender) // actor does not have a pub key -> don't verify @@ -264,7 +291,7 @@ func (s *ActivityPubService) sendObject(to vocab.Actor, data []byte) error { req.Header.Set("Accept", "application/ld+json") req.Header.Set("Date", time.Now().Format(http.TimeFormat)) req.Header.Set("Host", actorUrl.Host) - err = s.sign(apConfig.PrivateKey(), siteConfig.FullUrl+"/activitypub/actor#main-key", data, req) + err = s.sign(apConfig.PrivateKey(), s.MainKeyUri(), data, req) if err != nil { slog.Error("Signing error", "err", err) return err diff --git a/cmd/owl/main.go b/cmd/owl/main.go index 0c063db..a8457d4 100644 --- a/cmd/owl/main.go +++ b/cmd/owl/main.go @@ -66,7 +66,7 @@ func App(db infra.Database) *web.WebApp { webmentionService := app.NewWebmentionService( siteConfigService, interactionRepo, entryRepo, httpClient, eventBus, ) - apService := app.NewActivityPubService(followersRepo, configRepo) + apService := app.NewActivityPubService(followersRepo, configRepo, siteConfigService) // setup render functions render.SiteConfigService = siteConfigService diff --git a/web/activity_pub_handler.go b/web/activity_pub_handler.go index 4e7861a..36de33b 100644 --- a/web/activity_pub_handler.go +++ b/web/activity_pub_handler.go @@ -6,6 +6,7 @@ import ( "net/http" "net/url" "owl-blogs/app" + "strings" vocab "github.com/go-ap/activitypub" "github.com/go-ap/jsonld" @@ -63,7 +64,7 @@ func (s *ActivityPubServer) HandleWebfinger(ctx *fiber.Ctx) error { { Rel: "self", Type: "application/activity+json", - Href: siteConfig.FullUrl + "/activitypub/actor", + Href: s.apService.ActorUrl(), }, }, } @@ -73,24 +74,28 @@ func (s *ActivityPubServer) HandleWebfinger(ctx *fiber.Ctx) error { } func (s *ActivityPubServer) Router(router fiber.Router) { - router.Get("/actor", s.HandleActor) + // router.Get("/actor", s.HandleActor) router.Get("/outbox", s.HandleOutbox) router.Post("/inbox", s.HandleInbox) router.Get("/followers", s.HandleFollowers) } func (s *ActivityPubServer) HandleActor(ctx *fiber.Ctx) error { - siteConfig, _ := s.siteConfigService.GetSiteConfig() + accepts := strings.Contains(string(ctx.Request().Header.Peek("Accept")), "application/activity+json") + req_content := strings.Contains(string(ctx.Request().Header.Peek("Content-Type")), "application/activity+json") + if !accepts && !req_content { + return ctx.Next() + } apConfig, _ := s.apService.GetApConfig() - actor := vocab.PersonNew(vocab.IRI(siteConfig.FullUrl + "/activitypub/actor")) + actor := vocab.PersonNew(vocab.IRI(s.apService.ActorUrl())) actor.PreferredUsername = vocab.NaturalLanguageValues{{Value: vocab.Content(apConfig.PreferredUsername)}} - actor.Inbox = vocab.IRI(siteConfig.FullUrl + "/activitypub/inbox") - actor.Outbox = vocab.IRI(siteConfig.FullUrl + "/activitypub/outbox") - actor.Followers = vocab.IRI(siteConfig.FullUrl + "/activitypub/followers") + actor.Inbox = vocab.IRI(s.apService.InboxUrl()) + actor.Outbox = vocab.IRI(s.apService.OutboxUrl()) + actor.Followers = vocab.IRI(s.apService.FollowersUrl()) actor.PublicKey = vocab.PublicKey{ - ID: vocab.ID(siteConfig.FullUrl + "/activitypub/actor#main-key"), - Owner: vocab.IRI(siteConfig.FullUrl + "/activitypub/actor"), + ID: vocab.IRI(s.apService.MainKeyUri()), + Owner: vocab.IRI(s.apService.ActorUrl()), PublicKeyPem: apConfig.PublicKeyPem, } data, err := jsonld.WithContext( @@ -125,7 +130,7 @@ func (s *ActivityPubServer) HandleOutbox(ctx *fiber.Ctx) error { }) } - outbox := vocab.OrderedCollectionNew(vocab.IRI(siteConfig.FullUrl + "/activitypub/outbox")) + outbox := vocab.OrderedCollectionNew(vocab.IRI(s.apService.OutboxUrl())) outbox.TotalItems = uint(len(items)) outbox.OrderedItems = items @@ -205,9 +210,6 @@ func (s *ActivityPubServer) HandleInbox(ctx *fiber.Ctx) error { } func (s *ActivityPubServer) HandleFollowers(ctx *fiber.Ctx) error { - siteConfig, _ := s.siteConfigService.GetSiteConfig() - // apConfig, _ := s.apService.GetApConfig() - fs, err := s.apService.AllFollowers() if err != nil { return err @@ -218,7 +220,7 @@ func (s *ActivityPubServer) HandleFollowers(ctx *fiber.Ctx) error { followers.Append(vocab.IRI(f)) } followers.TotalItems = uint(len(fs)) - followers.ID = vocab.IRI(siteConfig.FullUrl + "/activitypub/followers") + followers.ID = vocab.IRI(s.apService.FollowersUrl()) data, err := jsonld.WithContext( jsonld.IRI(vocab.ActivityBaseURI), ).Marshal(followers) diff --git a/web/app.go b/web/app.go index 6d673f0..0deed3e 100644 --- a/web/app.go +++ b/web/app.go @@ -109,12 +109,15 @@ func NewWebApp( siteConfig.Post("/menus/create/", siteConfigMenusHandler.HandleCreate) siteConfig.Post("/menus/delete/", siteConfigMenusHandler.HandleDelete) + activityPubServer := NewActivityPubServer(siteConfigService, entryService, apService) + configRegister.Register(config.ACT_PUB_CONF_NAME, &app.ActivityPubConfig{}) + fiberApp.Use("/static", filesystem.New(filesystem.Config{ Root: http.FS(embedDirStatic), PathPrefix: "static", Browse: false, })) - fiberApp.Get("/", indexHandler.Handle) + fiberApp.Get("/", activityPubServer.HandleActor, indexHandler.Handle) fiberApp.Get("/lists/:list/", listHandler.Handle) // Media fiberApp.Get("/media/+", mediaHandler.Handle) @@ -135,8 +138,6 @@ func NewWebApp( fiberApp.Get("/sitemap.xml", NewSiteMapHandler(entryService, siteConfigService).Handle) // ActivityPub - activityPubServer := NewActivityPubServer(siteConfigService, entryService, apService) - configRegister.Register(config.ACT_PUB_CONF_NAME, &app.ActivityPubConfig{}) fiberApp.Get("/.well-known/webfinger", activityPubServer.HandleWebfinger) fiberApp.Route("/activitypub", activityPubServer.Router)