package activitypub import ( "context" "encoding/json" "fmt" "net/http" webutils "git.mstar.dev/mstar/goutils/http" "github.com/rs/zerolog/hlog" "gorm.io/gorm" "git.mstar.dev/mstar/linstrom/activitypub" "git.mstar.dev/mstar/linstrom/config" "git.mstar.dev/mstar/linstrom/storage-new" "git.mstar.dev/mstar/linstrom/storage-new/dbgen" "git.mstar.dev/mstar/linstrom/storage-new/models" ) type ActivityCreateOut struct { Context any `json:"@context,omitempty"` Id string `json:"id"` Type string `json:"type"` Actor string `json:"actor"` Object any `json:"object"` } func activityCreate(w http.ResponseWriter, r *http.Request) { log := hlog.FromRequest(r) id := r.PathValue("id") activity, err := CreateFromStorage(r.Context(), id) switch err { case gorm.ErrRecordNotFound: webutils.ProblemDetailsStatusOnly(w, http.StatusNotFound) case nil: activity.Context = activitypub.BaseLdContext data, err := json.Marshal(activity) if err != nil { log.Error().Err(err).Any("activity", activity).Msg("Failed to marshal create activity") webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError) return } w.Header().Add("Content-Type", "application/activity+json") fmt.Fprint(w, string(data)) default: if storage.HandleReconnectError(err) { log.Error().Err(err).Msg("Connection failed, restart attempt started") } else { log.Error().Err(err).Msg("Failed to get create activity from db") } webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError) } } // Find a create activity from the db and format it for activitypub reads // 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) { // log := log.Ctx(ctx) a := dbgen.Activity activity, err := a.Where(a.Type.Eq(string(models.ActivityCreate))). Where(a.Id.Eq(id)). First() if err != nil { return nil, err } switch models.ActivitystreamsActivityTargetType(activity.ObjectType) { case models.ActivitystreamsActivityTargetNote: note, err := NoteFromStorage(ctx, activity.ObjectId) if err != nil { return nil, err } out := ActivityCreateOut{ Id: config.GlobalConfig.General.GetFullPublicUrl() + "/api/activitypub/create/" + id, Type: "Create", Actor: note.AttributedTo, Object: note, } return &out, nil case models.ActivitystreamsActivityTargetBoost: panic("Not implemented") case models.ActivitystreamsActivityTargetReaction: panic("Not implemented") case models.ActivitystreamsActivityTargetActivity: panic("Not implemented") case models.ActivitystreamsActivityTargetUser: panic("Not implemented") case models.ActivitystreamsActivityTargetUnknown: panic("Not implemented") default: panic("Not implemented") } }