This commit is contained in:
parent
03ca524c99
commit
82627e8467
1 changed files with 128 additions and 0 deletions
|
@ -7,6 +7,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
webutils "git.mstar.dev/mstar/goutils/http"
|
webutils "git.mstar.dev/mstar/goutils/http"
|
||||||
"git.mstar.dev/mstar/goutils/other"
|
"git.mstar.dev/mstar/goutils/other"
|
||||||
|
@ -83,6 +84,8 @@ func userInbox(w http.ResponseWriter, r *http.Request) {
|
||||||
switch objectType {
|
switch objectType {
|
||||||
case "Like":
|
case "Like":
|
||||||
handleLike(w, r, data)
|
handleLike(w, r, data)
|
||||||
|
case "Undo":
|
||||||
|
handleUndo(w, r, data)
|
||||||
default:
|
default:
|
||||||
webutils.ProblemDetailsStatusOnly(w, 500)
|
webutils.ProblemDetailsStatusOnly(w, 500)
|
||||||
}
|
}
|
||||||
|
@ -191,3 +194,128 @@ func handleLike(w http.ResponseWriter, r *http.Request, object map[string]any) {
|
||||||
webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError)
|
webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleUndo(w http.ResponseWriter, r *http.Request, object map[string]any) {
|
||||||
|
log := hlog.FromRequest(r)
|
||||||
|
_ = object["id"].(string)
|
||||||
|
_, ok := object["actor"].(string)
|
||||||
|
if !ok {
|
||||||
|
webutils.ProblemDetails(
|
||||||
|
w,
|
||||||
|
http.StatusBadRequest,
|
||||||
|
"/errors/bad-request-data",
|
||||||
|
"Bad activity data",
|
||||||
|
other.IntoPointer(`Request data needs to contain a field "actor" with a string value`),
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rawTarget, ok := object["object"]
|
||||||
|
if !ok {
|
||||||
|
webutils.ProblemDetails(
|
||||||
|
w,
|
||||||
|
http.StatusBadRequest,
|
||||||
|
"/errors/bad-request-data",
|
||||||
|
"Bad activity data",
|
||||||
|
other.IntoPointer(`Request data needs to contain a field "object"`),
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// TODO: I *think* undo is only actively used for likes, but could also be used for
|
||||||
|
// undoing create's and thus removing notes
|
||||||
|
var likeActivityId string
|
||||||
|
// I *think* the spec says that this must be an object. Not sure though
|
||||||
|
switch target := rawTarget.(type) {
|
||||||
|
case string:
|
||||||
|
likeActivityId = target
|
||||||
|
case map[string]any:
|
||||||
|
objType, ok := target["type"].(string)
|
||||||
|
if !ok || objType != "Like" {
|
||||||
|
webutils.ProblemDetails(
|
||||||
|
w,
|
||||||
|
http.StatusBadRequest,
|
||||||
|
"/errors/bad-request-data",
|
||||||
|
"Bad activity data",
|
||||||
|
other.IntoPointer(`Undone object is not of type like. If you receive this error for a valid undo for a different activity type,please contact the Linstrom developers with the activity type`),
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
likeActivityId, ok = target["id"].(string)
|
||||||
|
if !ok {
|
||||||
|
webutils.ProblemDetails(
|
||||||
|
w,
|
||||||
|
http.StatusBadRequest,
|
||||||
|
"/errors/bad-request-data",
|
||||||
|
"Bad activity data",
|
||||||
|
other.IntoPointer(`Missing id in undone object`),
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
webutils.ProblemDetails(
|
||||||
|
w,
|
||||||
|
http.StatusBadRequest,
|
||||||
|
"/errors/bad-request-data",
|
||||||
|
"Bad activity data",
|
||||||
|
other.IntoPointer(`Request data needs to contain a field "object" of type string or object`),
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// TODO: For above todo, get target resource via likeActivityId and remove approprietly
|
||||||
|
// Don't just assume it was a like being undone
|
||||||
|
act, err := dbgen.Activity.Where(dbgen.Activity.Id.Eq(likeActivityId), dbgen.Activity.Type.Eq("like")).
|
||||||
|
First()
|
||||||
|
switch err {
|
||||||
|
case gorm.ErrRecordNotFound:
|
||||||
|
return
|
||||||
|
case nil:
|
||||||
|
default:
|
||||||
|
log.Error().
|
||||||
|
Err(err).
|
||||||
|
Str("activity-id", likeActivityId).
|
||||||
|
Msg("Error while looking for find activity")
|
||||||
|
webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
reactionId := uint(other.Must(strconv.ParseUint(act.ObjectId, 10, 64)))
|
||||||
|
reaction, err := dbgen.Reaction.Where(dbgen.Reaction.ID.Eq(reactionId)).First()
|
||||||
|
switch err {
|
||||||
|
case gorm.ErrRecordNotFound:
|
||||||
|
return
|
||||||
|
case nil:
|
||||||
|
default:
|
||||||
|
log.Error().
|
||||||
|
Err(err).
|
||||||
|
Str("activity-id", likeActivityId).
|
||||||
|
Msg("Error while looking for find activity")
|
||||||
|
webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tx := dbgen.Q.Begin()
|
||||||
|
_, err = tx.Activity.Where(dbgen.Activity.Id.Eq(act.Id)).Delete()
|
||||||
|
if err != nil {
|
||||||
|
_ = tx.Rollback()
|
||||||
|
log.Error().Err(err).Str("activity-id", act.Id).Msg("Failed to delete activity on undo")
|
||||||
|
webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = tx.Reaction.Where(dbgen.Reaction.ID.Eq(reaction.ID)).Delete()
|
||||||
|
if err != nil {
|
||||||
|
_ = tx.Rollback()
|
||||||
|
log.Error().
|
||||||
|
Err(err).
|
||||||
|
Uint("reaction-id", reaction.ID).
|
||||||
|
Msg("Failed to delete reaction on undo")
|
||||||
|
webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = tx.Commit()
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("Failed to delete reaction and activity")
|
||||||
|
webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue