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 {
CreateFile(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 {
@ -134,4 +135,31 @@ func (g Git) UpdateFile(filepath string, file string, message string) error {
return errors.New("failed to commit file")
}
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
}
if respCode < 200 || respCode >= 300 {
if respCode == 410 {
if respCode == 410 || respCode == 404 {
// 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)
return
} else {
@ -118,21 +123,27 @@ func HandleWebmention(w http.ResponseWriter, r *http.Request) {
// Check if source mentions target
if !sourceMentionsTarget(sourceUrl.String(), targetUrl.String()) {
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.Write([]byte(err.Error()))
return
}
mention := &Mention{
Source: sourceUrl.String(),
Target: targetUrl.String(),
Date: time.Now().Format(time.RFC3339),
}
err = saveWebmention(mention)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte(err.Error()))
return
}
go func() {
e := saveWebmention(&Mention{
Source: sourceUrl.String(),
Target: targetUrl.String(),
Date: time.Now().Format(time.RFC3339),
})
if e != nil {
fmt.Println("Failed to save webmention:", e.Error())
}
}()
returnSuccess(targetUrl.String(), w, r)
go func() {
if SelectedNotificationServices != nil {
@ -175,13 +186,19 @@ func saveWebmention(mention *Mention) (err error) {
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) {
w.Header().Add("Location", target)
if strings.Contains(r.Header.Get("Accept"), "text/html") {
// Redirect browser
w.Header().Add("Location", target)
w.WriteHeader(http.StatusSeeOther)
} else {
w.WriteHeader(http.StatusOK)
w.WriteHeader(http.StatusCreated)
}
// Purge CDN after 30 seconds
go func() {