mirror of https://github.com/jlelse/GoBlog
Improve ActivityPub and Webmention verification
This commit is contained in:
parent
32339e5c41
commit
1ef5b11310
|
@ -17,6 +17,7 @@ import (
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/go-fed/httpsig"
|
"github.com/go-fed/httpsig"
|
||||||
|
"github.com/spf13/cast"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (a *goBlog) initActivityPub() error {
|
func (a *goBlog) initActivityPub() error {
|
||||||
|
@ -167,17 +168,22 @@ func (a *goBlog) apHandleInbox(w http.ResponseWriter, r *http.Request) {
|
||||||
case "Create":
|
case "Create":
|
||||||
{
|
{
|
||||||
if object, ok := activity["object"].(map[string]interface{}); ok {
|
if object, ok := activity["object"].(map[string]interface{}); ok {
|
||||||
inReplyTo, hasReplyToString := object["inReplyTo"].(string)
|
inReplyTo := cast.ToString(object["inReplyTo"])
|
||||||
id, hasID := object["id"].(string)
|
objectId := cast.ToString(object["id"])
|
||||||
if hasReplyToString && hasID && len(inReplyTo) > 0 && len(id) > 0 && strings.Contains(inReplyTo, blogIri) {
|
objectUrl := cast.ToString(object["url"])
|
||||||
|
baseUrl := objectId
|
||||||
|
if objectUrl != "" {
|
||||||
|
baseUrl = objectUrl
|
||||||
|
}
|
||||||
|
if inReplyTo != "" && objectId != "" && strings.Contains(inReplyTo, blogIri) {
|
||||||
// It's an ActivityPub reply; save reply as webmention
|
// It's an ActivityPub reply; save reply as webmention
|
||||||
_ = a.createWebmention(id, inReplyTo)
|
_ = a.createWebmention(baseUrl, inReplyTo)
|
||||||
} else if content, hasContent := object["content"].(string); hasContent && hasID && len(id) > 0 {
|
} else if content, hasContent := object["content"].(string); hasContent && objectId != "" {
|
||||||
// May be a mention; find links to blog and save them as webmentions
|
// May be a mention; find links to blog and save them as webmentions
|
||||||
if links, err := allLinksFromHTMLString(content, id); err == nil {
|
if links, err := allLinksFromHTMLString(content, baseUrl); err == nil {
|
||||||
for _, link := range links {
|
for _, link := range links {
|
||||||
if strings.Contains(link, blogIri) {
|
if strings.Contains(link, blogIri) {
|
||||||
_ = a.createWebmention(id, link)
|
_ = a.createWebmention(baseUrl, link)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
9
http.go
9
http.go
|
@ -614,17 +614,22 @@ func noIndexHeader(next http.Handler) http.Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
type dynamicHandler struct {
|
type dynamicHandler struct {
|
||||||
router *chi.Mux
|
router *chi.Mux
|
||||||
mutex sync.RWMutex
|
mutex sync.RWMutex
|
||||||
|
initialized bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *dynamicHandler) swapHandler(h *chi.Mux) {
|
func (d *dynamicHandler) swapHandler(h *chi.Mux) {
|
||||||
d.mutex.Lock()
|
d.mutex.Lock()
|
||||||
d.router = h
|
d.router = h
|
||||||
|
d.initialized = true
|
||||||
d.mutex.Unlock()
|
d.mutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *dynamicHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (d *dynamicHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
for !d.initialized {
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
}
|
||||||
// Fix to use Path routing instead of RawPath routing in Chi
|
// Fix to use Path routing instead of RawPath routing in Chi
|
||||||
r.URL.RawPath = ""
|
r.URL.RawPath = ""
|
||||||
// Serve request
|
// Serve request
|
||||||
|
|
|
@ -72,7 +72,7 @@ func (a *goBlog) verifyMention(m *mention) error {
|
||||||
rec := httptest.NewRecorder()
|
rec := httptest.NewRecorder()
|
||||||
for a.d == nil {
|
for a.d == nil {
|
||||||
// Server not yet started
|
// Server not yet started
|
||||||
time.Sleep(10 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
}
|
}
|
||||||
a.d.ServeHTTP(rec, req.WithContext(context.WithValue(req.Context(), loggedInKey, true)))
|
a.d.ServeHTTP(rec, req.WithContext(context.WithValue(req.Context(), loggedInKey, true)))
|
||||||
resp = rec.Result()
|
resp = rec.Result()
|
||||||
|
@ -89,11 +89,11 @@ func (a *goBlog) verifyMention(m *mention) error {
|
||||||
_, err := a.db.exec("delete from webmentions where source = @source and target = @target", sql.Named("source", m.Source), sql.Named("target", m.Target))
|
_, err := a.db.exec("delete from webmentions where source = @source and target = @target", sql.Named("source", m.Source), sql.Named("target", m.Target))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(m.Content) > 500 {
|
if cr := []rune(m.Content); len(cr) > 500 {
|
||||||
m.Content = m.Content[0:497] + "…"
|
m.Content = string(cr[0:497]) + "…"
|
||||||
}
|
}
|
||||||
if len(m.Title) > 60 {
|
if tr := []rune(m.Title); len(tr) > 60 {
|
||||||
m.Title = m.Title[0:57] + "…"
|
m.Title = string(tr[0:57]) + "…"
|
||||||
}
|
}
|
||||||
newStatus := webmentionStatusVerified
|
newStatus := webmentionStatusVerified
|
||||||
if a.db.webmentionExists(m.Source, m.Target) {
|
if a.db.webmentionExists(m.Source, m.Target) {
|
||||||
|
@ -122,20 +122,25 @@ func (m *mention) verifyReader(body io.Reader) error {
|
||||||
}); !hasLink {
|
}); !hasLink {
|
||||||
return errors.New("target not found in source")
|
return errors.New("target not found in source")
|
||||||
}
|
}
|
||||||
// Set title
|
|
||||||
doc, err := goquery.NewDocumentFromReader(&gqBuffer)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if title := doc.Find("title"); title != nil {
|
|
||||||
m.Title = title.Text()
|
|
||||||
}
|
|
||||||
// Fill mention attributes
|
// Fill mention attributes
|
||||||
sourceURL, err := url.Parse(m.Source)
|
sourceURL, err := url.Parse(m.Source)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
m.Title = ""
|
||||||
|
m.Content = ""
|
||||||
|
m.Author = ""
|
||||||
m.fillFromData(microformats.Parse(&mfBuffer, sourceURL))
|
m.fillFromData(microformats.Parse(&mfBuffer, sourceURL))
|
||||||
|
// Set title when content is empty as well
|
||||||
|
if m.Title == "" && m.Content == "" {
|
||||||
|
doc, err := goquery.NewDocumentFromReader(&gqBuffer)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if title := doc.Find("title"); title != nil {
|
||||||
|
m.Title = title.Text()
|
||||||
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue