And create activities work-ish
All checks were successful
/ docker (push) Successful in 4m18s

This commit is contained in:
Melody Becker 2025-05-16 21:31:17 +02:00
parent 8ec486cfc1
commit 440399f8d2
8 changed files with 171 additions and 9 deletions

View file

@ -17,7 +17,7 @@ import (
"git.mstar.dev/mstar/linstrom/storage-new/models"
)
type ActivityCreateOut struct {
type ActivityCreate struct {
Context any `json:"@context,omitempty"`
Id string `json:"id"`
Type string `json:"type"`
@ -56,7 +56,7 @@ func activityCreate(w http.ResponseWriter, r *http.Request) {
// Does not set the context for the activity, in case the activity is embedded
// in another activity or object. That's the responsibility of the handler
// getting the final result
func CreateFromStorage(ctx context.Context, id string) (*ActivityCreateOut, error) {
func CreateFromStorage(ctx context.Context, id string) (*ActivityCreate, error) {
// log := log.Ctx(ctx)
a := dbgen.Activity
activity, err := a.Where(a.Type.Eq(string(models.ActivityCreate))).
@ -71,7 +71,7 @@ func CreateFromStorage(ctx context.Context, id string) (*ActivityCreateOut, erro
if err != nil {
return nil, err
}
out := ActivityCreateOut{
out := ActivityCreate{
Id: config.GlobalConfig.General.GetFullPublicUrl() + "/api/activitypub/create/" + id,
Type: "Create",
Actor: note.AttributedTo,

View file

@ -12,6 +12,7 @@ import (
webutils "git.mstar.dev/mstar/goutils/http"
"git.mstar.dev/mstar/goutils/other"
"github.com/mitchellh/mapstructure"
"github.com/rs/zerolog/hlog"
"gorm.io/gorm"
@ -668,4 +669,88 @@ func handleReject(w http.ResponseWriter, r *http.Request, object map[string]any)
}
}
func handleCreate(w http.ResponseWriter, r *http.Request, object map[string]any) {}
func handleCreate(w http.ResponseWriter, r *http.Request, object map[string]any) {
log := hlog.FromRequest(r)
activity := ActivityCreate{}
err := mapstructure.Decode(object, &activity)
if err != nil {
log.Error().
Err(err).
Any("raw", object).
Msg("Failed to marshal create activity to proper type")
webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError)
return
}
actingUser, err := activitypub.ImportRemoteAccountByAPUrl(activity.Actor)
if err != nil {
log.Error().
Err(err).
Str("actor", activity.Actor).
Msg("Failed to import remote actor for note")
webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError)
return
}
switch val := activity.Object.(type) {
case string:
activitypub.ImportRemoteNote(val)
return
case map[string]any:
default:
webutils.ProblemDetails(
w,
http.StatusBadRequest,
"/errors/bad-request-data",
"bad request data",
other.IntoPointer("Bad object data for create activity. Must be a struct or string"),
nil,
)
return
}
obj := activity.Object.(map[string]any)
// Dumb hack since published timestamp is still a string at this point
tmpTime, err := time.Parse(time.RFC3339, obj["published"].(string))
if err != nil {
delete(obj, "published")
} else {
obj["published"] = tmpTime
}
objectNote := ObjectNote{}
err = mapstructure.Decode(obj, &objectNote)
if err != nil {
log.Error().
Err(err).
Any("raw", activity.Object).
Msg("Failed to unmarshal create object into note")
webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError)
return
}
if objectNote.Type != "Note" {
webutils.ProblemDetails(
w,
http.StatusBadRequest,
"/errors/bad-request-data",
"bad request data",
other.IntoPointer("Bad object data for create activity. object.type must be 'Note'"),
nil,
)
return
}
dbNote := models.Note{
ID: objectNote.Id,
CreatedAt: objectNote.Published,
Creator: *actingUser,
CreatorId: actingUser.ID,
Remote: true,
RawContent: objectNote.Content,
OriginId: actingUser.ServerId,
}
if objectNote.Summary != nil {
dbNote.ContentWarning = sql.NullString{Valid: true, String: *objectNote.Summary}
}
err = dbgen.Note.Create(&dbNote)
if err != nil {
log.Error().Err(err).Any("note", dbNote).Msg("Failed to create note in db")
webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError)
return
}
}

View file

@ -17,7 +17,7 @@ import (
"git.mstar.dev/mstar/linstrom/storage-new/dbgen"
)
type ObjectNoteOut struct {
type ObjectNote struct {
// Context should be set, if needed, by the endpoint handler
Context any `json:"@context,omitempty"`
@ -73,12 +73,12 @@ func objectNote(w http.ResponseWriter, r *http.Request) {
}
}
func NoteFromStorage(ctx context.Context, id string) (*ObjectNoteOut, error) {
func NoteFromStorage(ctx context.Context, id string) (*ObjectNote, error) {
note, err := dbgen.Note.Where(dbgen.Note.ID.Eq(id)).Preload(dbgen.Note.Creator).First()
if err != nil {
return nil, err
}
data := &ObjectNoteOut{
data := &ObjectNote{
Id: config.GlobalConfig.General.GetFullPublicUrl() + "/api/activitypub/note/" + id,
Type: "Note",
Published: note.CreatedAt,

View file

@ -71,6 +71,13 @@ func users(w http.ResponseWriter, r *http.Request) {
}
return
}
// FIXME: Remove this later
// (or rather move to dedicated module in storage for old migration stuff),
// temporary fix for old data. User creation locations are fixed already
err = storage.EnsureLocalUserIdHasLinks(userId)
if err != nil {
log.Warn().Err(err).Msg("Failed to create links for local user")
}
apUrl := activitypub.UserIdToApUrl(user.ID)
var keyBytes string