And follow requests work!

Who knew that Mastodon would set the accept target's object id to the
internal one?

But also, I am of the opinion that this is a bug on our side when
translating the activity to AP
This commit is contained in:
Melody Becker 2025-06-12 17:13:19 +02:00
parent 3c141e21fd
commit 9e23f82e55
Signed by: mstar
SSH key fingerprint: SHA256:9VAo09aaVNTWKzPW7Hq2LW+ox9OdwmTSHRoD4mlz1yI

View file

@ -387,6 +387,7 @@ func handleAccept(w http.ResponseWriter, r *http.Request, object map[string]any)
log := hlog.FromRequest(r)
rawTarget, ok := object["object"]
if !ok {
log.Debug().Msg("Rejecting accept, missing object")
_ = webutils.ProblemDetails(
w,
http.StatusBadRequest,
@ -397,7 +398,6 @@ func handleAccept(w http.ResponseWriter, r *http.Request, object map[string]any)
)
return true
}
// FIXME: Also handle other undo cases, such as follows
var targetObjectId string
// I *think* the spec says that this must be an object. Not sure though
switch target := rawTarget.(type) {
@ -406,7 +406,20 @@ func handleAccept(w http.ResponseWriter, r *http.Request, object map[string]any)
case map[string]any:
objType, ok := target["type"].(string)
// TODO: Ensure accept is only used for follows
if !ok || objType != "Follow" {
if !ok {
log.Debug().Msg("Rejecting accept, missing embedded object data")
_ = webutils.ProblemDetails(
w,
http.StatusBadRequest,
"/errors/bad-request-data",
"Bad activity data",
other.IntoPointer(`Target object must contain a type field`),
nil,
)
return true
}
if objType != "Follow" {
log.Debug().Msg("Rejecting accept, bad object type")
_ = webutils.ProblemDetails(
w,
http.StatusBadRequest,
@ -419,6 +432,7 @@ func handleAccept(w http.ResponseWriter, r *http.Request, object map[string]any)
}
targetObjectId, ok = target["id"].(string)
if !ok {
log.Debug().Msg("Rejecting accept, missing object id")
_ = webutils.ProblemDetails(
w,
http.StatusBadRequest,
@ -430,6 +444,7 @@ func handleAccept(w http.ResponseWriter, r *http.Request, object map[string]any)
return true
}
default:
log.Debug().Msg("Rejecting accept, missing object field")
_ = webutils.ProblemDetails(
w,
http.StatusBadRequest,
@ -440,22 +455,29 @@ func handleAccept(w http.ResponseWriter, r *http.Request, object map[string]any)
)
return true
}
internalIdMatch := objectIdRegex.FindStringSubmatch(targetObjectId)
if len(internalIdMatch) != 2 {
_ = webutils.ProblemDetails(
w,
http.StatusBadRequest,
"/errors/bad-request-data",
"Bad activity data",
other.IntoPointer(`Request data target object is not internal id`),
nil,
)
return true
var internalId string
if strings.HasPrefix(targetObjectId, "http") {
internalIdMatch := objectIdRegex.FindStringSubmatch(targetObjectId)
if len(internalIdMatch) != 2 {
log.Debug().Msg("Rejecting accept, objectIdRegex didn't match")
_ = webutils.ProblemDetails(
w,
http.StatusBadRequest,
"/errors/bad-request-data",
"Bad activity data",
other.IntoPointer(`Request data target object is not internal id`),
nil,
)
return true
}
internalId = internalIdMatch[1]
} else {
internalId = targetObjectId
}
internalId := internalIdMatch[1]
followActivity, err := dbgen.Activity.Where(dbgen.Activity.Id.Eq(internalId)).First()
switch err {
case gorm.ErrRecordNotFound:
log.Debug().Msg("Rejecting accept, target follow activity not found")
_ = webutils.ProblemDetailsStatusOnly(w, http.StatusNotFound)
return true
case nil: