diff options
Diffstat (limited to 'activitypub/activity.go')
-rw-r--r-- | activitypub/activity.go | 360 |
1 files changed, 32 insertions, 328 deletions
diff --git a/activitypub/activity.go b/activitypub/activity.go index 88d9973..06e061b 100644 --- a/activitypub/activity.go +++ b/activitypub/activity.go @@ -1,20 +1,14 @@ package activitypub import ( - "encoding/json" "errors" "fmt" - "regexp" "strings" "github.com/FChannel0/FChannel-Server/config" "github.com/FChannel0/FChannel-Server/util" - "github.com/gofiber/fiber/v2" ) -// False positive for application/ld+ld, application/activity+ld, application/json+json -var activityRegexp = regexp.MustCompile("application\\/(ld|json|activity)((\\+(ld|json))|$)") - func AcceptActivity(header string) bool { accept := false if strings.Contains(header, ";") { @@ -27,169 +21,7 @@ func AcceptActivity(header string) bool { return accept } -func DeleteReportActivity(id string) error { - query := `delete from reported where id=$1` - - _, err := config.DB.Exec(query, id) - return err -} - -func GetActivityFromDB(id string) (Collection, error) { - var nColl Collection - var nActor Actor - var result []ObjectBase - - nColl.Actor = nActor - - query := `select actor, id, name, content, type, published, updated, attributedto, attachment, preview, actor, tripcode, sensitive from activitystream where id=$1 order by updated asc` - - rows, err := config.DB.Query(query, id) - if err != nil { - return nColl, err - } - - defer rows.Close() - for rows.Next() { - var post ObjectBase - var actor Actor - - if err := rows.Scan(&nColl.Actor.Id, &post.Id, &post.Name, &post.Content, &post.Type, &post.Published, &post.Updated, &post.AttributedTo, &post.Attachment[0].Id, &post.Preview.Id, &actor.Id, &post.TripCode, &post.Sensitive); err != nil { - return nColl, err - } - - post.Actor = actor.Id - - var postCnt int - var imgCnt int - var err error - - post.Replies, postCnt, imgCnt, err = post.GetReplies() - if err != nil { - return nColl, err - } - - post.Replies.TotalItems = postCnt - post.Replies.TotalImgs = imgCnt - - post.Attachment, err = post.Attachment[0].GetAttachment() - if err != nil { - return nColl, err - } - - post.Preview, err = post.Preview.GetPreview() - if err != nil { - return nColl, err - } - - result = append(result, post) - } - - nColl.OrderedItems = result - - return nColl, nil -} - -func GetActivityFromJson(ctx *fiber.Ctx) (Activity, error) { - - var respActivity ActivityRaw - var nActivity Activity - var nType string - - if err := json.Unmarshal(ctx.Body(), &respActivity); err != nil { - return nActivity, err - } - - if res, err := HasContextFromJson(respActivity.AtContextRaw.Context); err == nil && res { - var jObj ObjectBase - - if respActivity.Type == "Note" { - jObj, err = GetObjectFromJson(ctx.Body()) - if err != nil { - return nActivity, err - } - - nType = "Create" - } else { - jObj, err = GetObjectFromJson(respActivity.ObjectRaw) - if err != nil { - return nActivity, err - } - - nType = respActivity.Type - } - - actor, err := GetActorFromJson(respActivity.ActorRaw) - if err != nil { - return nActivity, err - } - - to, err := GetToFromJson(respActivity.ToRaw) - if err != nil { - return nActivity, err - } - - cc, err := GetToFromJson(respActivity.CcRaw) - if err != nil { - return nActivity, err - } - - nActivity.AtContext.Context = "https://www.w3.org/ns/activitystreams" - nActivity.Type = nType - nActivity.Actor = &actor - nActivity.Published = respActivity.Published - nActivity.Auth = respActivity.Auth - - if len(to) > 0 { - nActivity.To = to - } - - if len(cc) > 0 { - nActivity.Cc = cc - } - - nActivity.Name = respActivity.Name - nActivity.Object = &jObj - } else if err != nil { - return nActivity, err - } - - return nActivity, nil -} - -func HasContextFromJson(context []byte) (bool, error) { - var generic interface{} - - err := json.Unmarshal(context, &generic) - if err != nil { - return false, err - } - - hasContext := false - - switch generic.(type) { - case []interface{}: - var arrContext AtContextArray - err = json.Unmarshal(context, &arrContext.Context) - if len(arrContext.Context) > 0 { - if arrContext.Context[0] == "https://www.w3.org/ns/activitystreams" { - hasContext = true - } - } - break - - case string: - var arrContext AtContextString - err = json.Unmarshal(context, &arrContext.Context) - if arrContext.Context == "https://www.w3.org/ns/activitystreams" { - hasContext = true - } - break - } - - return hasContext, err -} - -func IsActivityLocal(activity Activity) (bool, error) { +func (activity Activity) IsLocal() (bool, error) { for _, e := range activity.To { if res, _ := GetActorFromDB(e); res.Id != "" { @@ -212,15 +44,15 @@ func IsActivityLocal(activity Activity) (bool, error) { return false, nil } -func ProcessActivity(activity Activity) error { +func (activity Activity) Process() error { activityType := activity.Type if activityType == "Create" { for _, e := range activity.To { - if res, err := GetActorFromDB(e); err == nil && res.Id != "" { + if res, err := GetActorFromDB(e); res.Id != "" { fmt.Println("actor is in the database") } else if err != nil { - return err + return util.MakeError(err, "Process") } else { fmt.Println("actor is NOT in the database") } @@ -235,7 +67,7 @@ func ProcessActivity(activity Activity) error { return nil } -func RejectActivity(activity Activity) Activity { +func (activity Activity) Reject() Activity { var accept Activity accept.AtContext.Context = activity.AtContext.Context accept.Type = "Reject" @@ -255,184 +87,56 @@ func RejectActivity(activity Activity) Activity { } func (activity Activity) Report(reason string) (bool, error) { - if res, err := activity.Object.IsLocal(); err == nil && !res { - // TODO: not local error - return false, nil - } else if err != nil { - return false, err - } - - activityCol, err := GetActivityFromDB(activity.Object.Id) - if err != nil { - return false, err + if isLocal, err := activity.Object.IsLocal(); !isLocal || err != nil { + return false, util.MakeError(err, "Report") } - query := `select count from reported where id=$1` - - rows, err := config.DB.Query(query, activity.Object.Id) + activityCol, err := activity.Object.GetCollection() if err != nil { - return false, err + return false, util.MakeError(err, "Report") } - defer rows.Close() - var count int - for rows.Next() { - if err := rows.Scan(&count); err != nil { - return false, err - } - } - - if count < 1 { - query = `insert into reported (id, count, board, reason) values ($1, $2, $3, $4)` - - _, err := config.DB.Exec(query, activity.Object.Object.Id, 1, activityCol.Actor.Id, reason) - if err != nil { - return false, err - } - } else { - count = count + 1 - query = `update reported set count=$1 where id=$2` - - _, err := config.DB.Exec(query, count, activity.Object.Id) - if err != nil { - return false, err - } + query := `insert into reported (id, count, board, reason) values ($1, $2, $3, $4)` + if _, err = config.DB.Exec(query, activity.Object.Object.Id, 1, activityCol.Actor.Id, reason); err != nil { + return false, util.MakeError(err, "Report") } return true, nil } -func (obj ObjectBase) WriteCache() error { - obj.Name = util.EscapeString(obj.Name) - obj.Content = util.EscapeString(obj.Content) - obj.AttributedTo = util.EscapeString(obj.AttributedTo) +func (activity Activity) SetFollower() (Activity, error) { + var query string - query := `select id from cacheactivitystream where id=$1` - - rows, err := config.DB.Query(query, obj.Id) - if err != nil { - return err - } - defer rows.Close() + alreadyFollow, err := activity.Actor.IsAlreadyFollower(activity.Object.Actor) - var id string - rows.Next() - err = rows.Scan(&id) if err != nil { - return err - } else if id != "" { - return nil // TODO: error? + return activity, util.MakeError(err, "SetFollower") } - if obj.Updated.IsZero() { - obj.Updated = obj.Published + activity.Type = "Reject" + if activity.Actor.Id == activity.Object.Actor { + return activity, nil } - query = `insert into cacheactivitystream (id, type, name, content, published, updated, attributedto, actor, tripcode, sensitive) values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)` - - _, err = config.DB.Exec(query, obj.Id, obj.Type, obj.Name, obj.Content, obj.Published, obj.Updated, obj.AttributedTo, obj.Actor, obj.TripCode, obj.Sensitive) - return err -} - -func (obj ObjectBase) WriteCacheWithAttachment(attachment ObjectBase) error { - obj.Name = util.EscapeString(obj.Name) - obj.Content = util.EscapeString(obj.Content) - obj.AttributedTo = util.EscapeString(obj.AttributedTo) - - query := `select id from cacheactivitystream where id=$1` - - rows, err := config.DB.Query(query, obj.Id) - if err != nil { - return err - } - defer rows.Close() - - var id string - rows.Next() - err = rows.Scan(&id) - if err != nil { - return err - } else if id != "" { - return nil // TODO: error? - } + if alreadyFollow { + query = `delete from follower where id=$1 and follower=$2` + activity.Summary = activity.Object.Actor + " Unfollow " + activity.Actor.Id - if obj.Updated.IsZero() { - obj.Updated = obj.Published - } - - query = `insert into cacheactivitystream (id, type, name, content, attachment, preview, published, updated, attributedto, actor, tripcode, sensitive) values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)` - - _, err = config.DB.Exec(query, obj.Id, obj.Type, obj.Name, obj.Content, attachment.Id, obj.Preview.Id, obj.Published, obj.Updated, obj.AttributedTo, obj.Actor, obj.TripCode, obj.Sensitive) - return err -} - -func (obj ObjectBase) WriteWithAttachment(attachment ObjectBase) { - - obj.Name = util.EscapeString(obj.Name) - obj.Content = util.EscapeString(obj.Content) - obj.AttributedTo = util.EscapeString(obj.AttributedTo) - - query := `insert into activitystream (id, type, name, content, attachment, preview, published, updated, attributedto, actor, tripcode, sensitive) values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)` - - _, e := config.DB.Exec(query, obj.Id, obj.Type, obj.Name, obj.Content, attachment.Id, obj.Preview.Id, obj.Published, obj.Updated, obj.AttributedTo, obj.Actor, obj.TripCode, obj.Sensitive) - - if e != nil { - fmt.Println("error inserting new activity with attachment") - panic(e) - } -} - -func (obj ObjectBase) WriteAttachmentCache() error { - var id string - - query := `select id from cacheactivitystream where id=$1` - if err := config.DB.QueryRow(query, obj.Id).Scan(&id); err != nil { - if obj.Updated.IsZero() { - obj.Updated = obj.Published + if _, err := config.DB.Exec(query, activity.Actor.Id, activity.Object.Actor); err != nil { + return activity, util.MakeError(err, "SetFollower") } - query = `insert into cacheactivitystream (id, type, name, href, published, updated, attributedTo, mediatype, size) values ($1, $2, $3, $4, $5, $6, $7, $8, $9)` - - _, err = config.DB.Exec(query, obj.Id, obj.Type, obj.Name, obj.Href, obj.Published, obj.Updated, obj.AttributedTo, obj.MediaType, obj.Size) - return err - } - - return nil -} - -func (obj ObjectBase) WriteAttachment() { - query := `insert into activitystream (id, type, name, href, published, updated, attributedTo, mediatype, size) values ($1, $2, $3, $4, $5, $6, $7, $8, $9)` - - _, e := config.DB.Exec(query, obj.Id, obj.Type, obj.Name, obj.Href, obj.Published, obj.Updated, obj.AttributedTo, obj.MediaType, obj.Size) - - if e != nil { - fmt.Println("error inserting new attachment") - panic(e) + activity.Type = "Accept" + return activity, util.MakeError(err, "SetFollower") } -} -func (obj NestedObjectBase) WritePreviewCache() error { - var id string + query = `insert into follower (id, follower) values ($1, $2)` + activity.Summary = activity.Object.Actor + " Follow " + activity.Actor.Id - query := `select id from cacheactivitystream where id=$1` - err := config.DB.QueryRow(query, obj.Id).Scan(&id) - if err != nil { - if obj.Updated.IsZero() { - obj.Updated = obj.Published - } - - query = `insert into cacheactivitystream (id, type, name, href, published, updated, attributedTo, mediatype, size) values ($1, $2, $3, $4, $5, $6, $7, $8, $9)` - - _, err = config.DB.Exec(query, obj.Id, obj.Type, obj.Name, obj.Href, obj.Published, obj.Updated, obj.AttributedTo, obj.MediaType, obj.Size) - return err + if _, err := config.DB.Exec(query, activity.Actor.Id, activity.Object.Actor); err != nil { + return activity, util.MakeError(err, "SetFollower") } - return nil -} - -func (obj NestedObjectBase) WritePreview() error { - query := `insert into activitystream (id, type, name, href, published, updated, attributedTo, mediatype, size) values ($1, $2, $3, $4, $5, $6, $7, $8, $9)` - - _, err := config.DB.Exec(query, obj.Id, obj.Type, obj.Name, obj.Href, obj.Published, obj.Updated, obj.AttributedTo, obj.MediaType, obj.Size) - return err + activity.Type = "Accept" + return activity, nil } |