From f5a50ce45772ec6f65b99ad7f093252661ff8ed0 Mon Sep 17 00:00:00 2001 From: Anthony Wang Date: Sun, 27 Nov 2022 19:29:03 +0000 Subject: [PATCH] Add Note object endpoint --- modules/forgefed/repository.go | 1 + routers/api/v1/activitypub/note.go | 64 ++++++++++++++++++++++++++++++ routers/api/v1/activitypub/repo.go | 2 - routers/api/v1/api.go | 1 + services/activitypub/objects.go | 17 ++++++-- services/comments/comments.go | 6 ++- 6 files changed, 85 insertions(+), 6 deletions(-) create mode 100644 routers/api/v1/activitypub/note.go diff --git a/modules/forgefed/repository.go b/modules/forgefed/repository.go index 662e0eaa3..3d1319d27 100644 --- a/modules/forgefed/repository.go +++ b/modules/forgefed/repository.go @@ -29,6 +29,7 @@ type Repository struct { // RepositoryNew initializes a Repository type actor func RepositoryNew(id ap.ID) *Repository { a := ap.ActorNew(id, RepositoryType) + a.Type = RepositoryType o := Repository{Actor: *a} return &o } diff --git a/routers/api/v1/activitypub/note.go b/routers/api/v1/activitypub/note.go new file mode 100644 index 000000000..0033aa4aa --- /dev/null +++ b/routers/api/v1/activitypub/note.go @@ -0,0 +1,64 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package activitypub + +import ( + "strconv" + + issues_model "code.gitea.io/gitea/models/issues" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/services/activitypub" +) + +// Note function returns the Note object for a comment to an issue or PR +func Note(ctx *context.APIContext) { + // swagger:operation GET /activitypub/note/{username}/{reponame}/{id}/{noteid} activitypub activitypubNote + // --- + // summary: Returns the Note object for a comment to an issue or PR + // produces + // - application/activity+json + // parameters: + // - name: username + // in: path + // description: username of the user + // type: string + // required: true + // - name: reponame + // in: path + // description: name of the repo + // type: string + // required: true + // - name: id + // in: path + // description: ID number of the issue or PR + // type: string + // required: true + // - name: noteid + // in: path + // description: ID number of the comment + // type: string + // required: true + // responses: + // "200": + // "$ref": "#/responses/ActivityPub" + + index, err := strconv.ParseInt(ctx.Params("noteid"), 10, 64) + if err != nil { + ctx.ServerError("ParseInt", err) + return + } + // TODO: index can be spoofed!!! + comment, err := issues_model.GetCommentByID(ctx, index) + if err != nil { + ctx.ServerError("GetCommentByID", err) + return + } + note, err := activitypub.Note(comment) + if err != nil { + ctx.ServerError("Note", err) + return + } + response(ctx, note) +} diff --git a/routers/api/v1/activitypub/repo.go b/routers/api/v1/activitypub/repo.go index cab978dbd..9f7d93f22 100644 --- a/routers/api/v1/activitypub/repo.go +++ b/routers/api/v1/activitypub/repo.go @@ -41,7 +41,6 @@ func Repo(ctx *context.APIContext) { iri := ctx.Repo.Repository.GetIRI() repo := forgefed.RepositoryNew(ap.IRI(iri)) - repo.Type = forgefed.RepositoryType repo.Name = ap.NaturalLanguageValuesNew() err := repo.Name.Set("en", ap.Content(ctx.Repo.Repository.Name)) @@ -148,7 +147,6 @@ func RepoInbox(ctx *context.APIContext) { case ap.LikeType: err = star(ctx, activity) default: - log.Info("Incoming unsupported ActivityStreams type: %s", activity.Type) ctx.PlainText(http.StatusNotImplemented, "ActivityStreams type not supported") return } diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 06c80f789..6f8ac7c14 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -662,6 +662,7 @@ func Routes(ctx gocontext.Context) *web.Route { m.Get("/followers", activitypub.RepoFollowers) }, repoAssignment()) m.Get("/ticket/{username}/{reponame}/{id}", repoAssignment(), activitypub.Ticket) + m.Get("/note/{username}/{reponame}/{id}/{noteid}", repoAssignment(), activitypub.Note) }) } m.Get("/signing-key.gpg", misc.SigningKey) diff --git a/services/activitypub/objects.go b/services/activitypub/objects.go index aa6be99f4..ef4e7f3e2 100644 --- a/services/activitypub/objects.go +++ b/services/activitypub/objects.go @@ -15,15 +15,26 @@ import ( ) // Construct a Note object from a comment -func Note(comment *issues_model.Comment) *ap.Note { +func Note(comment *issues_model.Comment) (*ap.Note, error) { + err := comment.LoadPoster() + if err != nil { + return nil, err + } + err = comment.LoadIssue() + if err != nil { + return nil, err + } note := ap.Note{ Type: ap.NoteType, AttributedTo: ap.IRI(comment.Poster.GetIRI()), Context: ap.IRI(comment.Issue.GetIRI()), } note.Content = ap.NaturalLanguageValuesNew() - _ = note.Content.Set("en", ap.Content(comment.Content)) - return ¬e + err = note.Content.Set("en", ap.Content(comment.Content)) + if err != nil { + return nil, err + } + return ¬e, nil } // Construct a Ticket object from an issue diff --git a/services/comments/comments.go b/services/comments/comments.go index a28c4c7f5..8f478c018 100644 --- a/services/comments/comments.go +++ b/services/comments/comments.go @@ -32,7 +32,11 @@ func CreateIssueComment(doer *user_model.User, repo *repo_model.Repository, issu if strings.Contains(repo.OwnerName, "@") { // Federated comment - create := activitypub.Create(repo.OriginalURL + "/inbox", activitypub.Note(comment)) + note, err := activitypub.Note(comment) + if err != nil { + return nil, err + } + create := activitypub.Create(repo.OriginalURL + "/inbox", note) err = activitypub.Send(doer, create) if err != nil { return nil, err