mirror of https://github.com/jlelse/GoBlog
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
2.2 KiB
Go
82 lines
2.2 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/url"
|
|
"strings"
|
|
|
|
"github.com/carlmjohnson/requests"
|
|
"github.com/go-chi/chi/v5"
|
|
"go.goblog.app/app/pkgs/bodylimit"
|
|
)
|
|
|
|
func (a *goBlog) apRemoteFollow(w http.ResponseWriter, r *http.Request) {
|
|
blogName := chi.URLParam(r, "blog")
|
|
blog, ok := a.cfg.Blogs[blogName]
|
|
if !ok || blog == nil {
|
|
a.serveError(w, r, "Blog not found", http.StatusNotFound)
|
|
return
|
|
}
|
|
if user := r.FormValue("user"); user != "" {
|
|
// Parse instance
|
|
userParts := strings.Split(user, "@")
|
|
if len(userParts) < 2 {
|
|
a.serveError(w, r, "User must be of the form user@example.org or @user@example.org", http.StatusBadRequest)
|
|
return
|
|
}
|
|
user = userParts[len(userParts)-2]
|
|
instance := userParts[len(userParts)-1]
|
|
if user == "" || instance == "" {
|
|
a.serveError(w, r, "User or instance are empty", http.StatusBadRequest)
|
|
return
|
|
}
|
|
// Get webfinger
|
|
type webfingerLinkType struct {
|
|
Rel string `json:"rel"`
|
|
Template string `json:"template"`
|
|
}
|
|
type webfingerType struct {
|
|
Links []*webfingerLinkType `json:"links"`
|
|
}
|
|
webfinger := &webfingerType{}
|
|
pr, pw := io.Pipe()
|
|
go func() {
|
|
err := requests.
|
|
URL(fmt.Sprintf("https://%s/.well-known/webfinger?resource=acct:%s@%s", instance, user, instance)).
|
|
Client(a.httpClient).
|
|
ToWriter(pw).
|
|
Fetch(r.Context())
|
|
_ = pw.CloseWithError(err)
|
|
}()
|
|
err := json.NewDecoder(io.LimitReader(pr, 100*bodylimit.KB)).Decode(webfinger)
|
|
_ = pr.CloseWithError(err)
|
|
if err != nil {
|
|
a.serveError(w, r, "Failed to query webfinger", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
// Check webfinger and find template
|
|
template := ""
|
|
for _, link := range webfinger.Links {
|
|
if link.Rel == "http://ostatus.org/schema/1.0/subscribe" {
|
|
template = link.Template
|
|
break
|
|
}
|
|
}
|
|
if template == "" {
|
|
a.serveError(w, r, "Instance does not support subscribe schema version 1.0", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
// Build redirect
|
|
redirect := strings.ReplaceAll(template, "{uri}", url.PathEscape(a.apIri(blog)))
|
|
http.Redirect(w, r, redirect, http.StatusFound)
|
|
return
|
|
}
|
|
// Render remote follow form
|
|
a.render(w, r, a.renderActivityPubRemoteFollow, &renderData{
|
|
BlogString: blogName,
|
|
})
|
|
}
|