Add support for deleted mentions

master
Jan-Lukas Else 2020-03-26 18:22:42 +01:00
parent 7c1e6baa3f
commit d747ceddf3
2 changed files with 61 additions and 16 deletions

View File

@ -14,6 +14,7 @@ import (
type Storage interface { type Storage interface {
CreateFile(path string, file string, message string) (err error) CreateFile(path string, file string, message string) (err error)
UpdateFile(path string, file string, message string) (err error) UpdateFile(path string, file string, message string) (err error)
DeleteFile(path string, message string) (err error)
} }
type Git struct { type Git struct {
@ -135,3 +136,30 @@ func (g Git) UpdateFile(filepath string, file string, message string) error {
} }
return g.push(repo) return g.push(repo)
} }
func (g Git) DeleteFile(filepath string, message string) (err error) {
repo, w, err := g.init()
if err != nil {
return errors.New("failed to initialize repo")
}
joinedPath := path.Join(g.filepath, filepath)
err = os.Remove(joinedPath)
if err != nil {
return errors.New("failed to delete file")
}
_, err = w.Add(filepath)
if err != nil {
return errors.New("failed to stage deletion")
}
_, err = w.Commit(message, &git.CommitOptions{
Author: &object.Signature{
Name: g.name,
Email: g.email,
When: time.Now(),
},
})
if err != nil {
return errors.New("failed to commit deletion")
}
return g.push(repo)
}

View File

@ -103,9 +103,14 @@ func HandleWebmention(w http.ResponseWriter, r *http.Request) {
return return
} }
if respCode < 200 || respCode >= 300 { if respCode < 200 || respCode >= 300 {
if respCode == 410 { if respCode == 410 || respCode == 404 {
// Delete mention, because source is gone // Delete mention, because source is gone
// TODO: Implement deletion go func() {
e := deleteWebmention(sourceUrl.String(), targetUrl.String())
if e != nil {
fmt.Print("Tried to delete webmention", sourceUrl.String(), "but failed:", e.Error())
}
}()
returnSuccess(targetUrl.String(), w, r) returnSuccess(targetUrl.String(), w, r)
return return
} else { } else {
@ -118,21 +123,27 @@ func HandleWebmention(w http.ResponseWriter, r *http.Request) {
// Check if source mentions target // Check if source mentions target
if !sourceMentionsTarget(sourceUrl.String(), targetUrl.String()) { if !sourceMentionsTarget(sourceUrl.String(), targetUrl.String()) {
err = errors.New("source doesn't mention target") err = errors.New("source doesn't mention target")
go func() {
// Try to delete webmention nevertheless
e := deleteWebmention(sourceUrl.String(), targetUrl.String())
if e != nil {
fmt.Print("Tried to delete webmention (source doesn't mention target) ", sourceUrl.String(), "but failed:", e.Error())
}
}()
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
_, _ = w.Write([]byte(err.Error())) _, _ = w.Write([]byte(err.Error()))
return return
} }
mention := &Mention{ go func() {
e := saveWebmention(&Mention{
Source: sourceUrl.String(), Source: sourceUrl.String(),
Target: targetUrl.String(), Target: targetUrl.String(),
Date: time.Now().Format(time.RFC3339), Date: time.Now().Format(time.RFC3339),
})
if e != nil {
fmt.Println("Failed to save webmention:", e.Error())
} }
err = saveWebmention(mention) }()
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte(err.Error()))
return
}
returnSuccess(targetUrl.String(), w, r) returnSuccess(targetUrl.String(), w, r)
go func() { go func() {
if SelectedNotificationServices != nil { if SelectedNotificationServices != nil {
@ -175,13 +186,19 @@ func saveWebmention(mention *Mention) (err error) {
return return
} }
func deleteWebmention(source string, target string) (err error) {
filePath := fmt.Sprintf("data/mentions/%x/%x.json", md5.Sum([]byte(strings.ReplaceAll(target, "/", ""))), md5.Sum([]byte(source)))
err = SelectedStorage.DeleteFile(filePath, "Delete webmention from "+source)
return
}
func returnSuccess(target string, w http.ResponseWriter, r *http.Request) { func returnSuccess(target string, w http.ResponseWriter, r *http.Request) {
w.Header().Add("Location", target)
if strings.Contains(r.Header.Get("Accept"), "text/html") { if strings.Contains(r.Header.Get("Accept"), "text/html") {
// Redirect browser // Redirect browser
w.Header().Add("Location", target)
w.WriteHeader(http.StatusSeeOther) w.WriteHeader(http.StatusSeeOther)
} else { } else {
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusCreated)
} }
// Purge CDN after 30 seconds // Purge CDN after 30 seconds
go func() { go func() {