Refactoring

- Add extra code paths where `ctx` can be passed and used.
- Remove useless `id` path to get comment note.
- Add extra checks in note API.
- Use `ctx.ParamsInt64` to get the ID from the request.
- Handle `GetXXX` more gracefully by returning 404 when appropiate.
This commit is contained in:
Gusted 2023-01-13 15:50:11 +01:00
parent f8a1dba197
commit b89242ee66
No known key found for this signature in database
GPG Key ID: FD821B732837125F
9 changed files with 63 additions and 51 deletions

View File

@ -1347,17 +1347,17 @@ func FixCommentTypeLabelWithOutsideLabels(ctx context.Context) (int64, error) {
return res.RowsAffected()
}
func (c *Comment) GetIRI() string {
err := c.LoadIssue(db.DefaultContext)
func (c *Comment) GetIRI(ctx context.Context) string {
err := c.LoadIssue(ctx)
if err != nil {
return ""
}
err = c.Issue.LoadRepo(db.DefaultContext)
err = c.Issue.LoadRepo(ctx)
if err != nil {
return ""
}
if strings.Contains(c.Issue.Repo.OwnerName, "@") {
return c.OldTitle
}
return setting.AppURL + "api/v1/activitypub/note/" + c.Issue.Repo.OwnerName + "/" + c.Issue.Repo.Name + "/" + strconv.FormatInt(c.Issue.Index, 10) + "/" + strconv.FormatInt(c.ID, 10)
return setting.AppURL + "api/v1/activitypub/note/" + c.Issue.Repo.OwnerName + "/" + c.Issue.Repo.Name + "/" + strconv.FormatInt(c.ID, 10)
}

View File

@ -2398,8 +2398,8 @@ func DeleteOrphanedIssues(ctx context.Context) error {
return nil
}
func (issue *Issue) GetIRI() string {
err := issue.LoadRepo(db.DefaultContext)
func (issue *Issue) GetIRI(ctx context.Context) string {
err := issue.LoadRepo(ctx)
if err != nil {
log.Error(fmt.Sprintf("loadRepo: %v", err))
}

View File

@ -4,7 +4,7 @@
package activitypub
import (
"strconv"
"net/http"
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/modules/context"
@ -13,7 +13,7 @@ import (
// 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
// swagger:operation GET /activitypub/note/{username}/{reponame}/{noteid} activitypub activitypubNote
// ---
// summary: Returns the Note object for a comment to an issue or PR
// produces:
@ -29,11 +29,6 @@ func Note(ctx *context.APIContext) {
// 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
@ -42,19 +37,34 @@ func Note(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/ActivityPub"
// "204":
// "$ref": "#/responses/empty"
// "404":
// "$ref": "#/responses/notFound"
index, err := strconv.ParseInt(ctx.Params("noteid"), 10, 64)
comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64("noteid"))
if err != nil {
ctx.ServerError("ParseInt", err)
if issues_model.IsErrCommentNotExist(err) {
ctx.NotFound(err)
} else {
ctx.Error(http.StatusInternalServerError, "GetCommentByID", err)
}
return
}
// TODO: index can be spoofed!!!
comment, err := issues_model.GetCommentByID(ctx, index)
if err != nil {
ctx.ServerError("GetCommentByID", err)
// Ensure the comment comes from the specified repository.
if comment.Issue.RepoID != ctx.Repo.Repository.ID {
ctx.Status(http.StatusNotFound)
return
}
note, err := activitypub.Note(comment)
// Only allow comments and not events.
if comment.Type != issues_model.CommentTypeComment {
ctx.Status(http.StatusNoContent)
return
}
note, err := activitypub.Note(ctx, comment)
if err != nil {
ctx.ServerError("Note", err)
return

View File

@ -4,8 +4,6 @@
package activitypub
import (
"strconv"
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/services/activitypub"
@ -37,18 +35,20 @@ func Ticket(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/ActivityPub"
// "404":
// "$ref": "#/responses/notFound"
index, err := strconv.ParseInt(ctx.Params("id"), 10, 64)
issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64("id"))
if err != nil {
ctx.ServerError("ParseInt", err)
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound()
} else {
ctx.ServerError("GetIssueByIndex", err)
}
return
}
issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, index)
if err != nil {
ctx.ServerError("GetIssueByIndex", err)
return
}
ticket, err := activitypub.Ticket(issue)
ticket, err := activitypub.Ticket(ctx, issue)
if err != nil {
ctx.ServerError("Ticket", err)
return

View File

@ -657,7 +657,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("/note/{username}/{reponame}/{noteid}", repoAssignment(), activitypub.Note)
})
}
m.Get("/signing-key.gpg", misc.SigningKey)

View File

@ -4,9 +4,9 @@
package activitypub
import (
"context"
"strconv"
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/modules/forgefed"
@ -14,20 +14,20 @@ import (
)
// Construct a Note object from a comment
func Note(comment *issues_model.Comment) (*ap.Note, error) {
err := comment.LoadPoster(db.DefaultContext)
func Note(ctx context.Context, comment *issues_model.Comment) (*ap.Note, error) {
err := comment.LoadPoster(ctx)
if err != nil {
return nil, err
}
err = comment.LoadIssue(db.DefaultContext)
err = comment.LoadIssue(ctx)
if err != nil {
return nil, err
}
note := ap.Note{
Type: ap.NoteType,
ID: ap.IRI(comment.GetIRI()),
ID: ap.IRI(comment.GetIRI(ctx)),
AttributedTo: ap.IRI(comment.Poster.GetIRI()),
Context: ap.IRI(comment.Issue.GetIRI()),
Context: ap.IRI(comment.Issue.GetIRI(ctx)),
To: ap.ItemCollection{ap.IRI("https://www.w3.org/ns/activitystreams#Public")},
}
note.Content = ap.NaturalLanguageValuesNew()
@ -39,8 +39,8 @@ func Note(comment *issues_model.Comment) (*ap.Note, error) {
}
// Construct a Ticket object from an issue
func Ticket(issue *issues_model.Issue) (*forgefed.Ticket, error) {
iri := issue.GetIRI()
func Ticket(ctx context.Context, issue *issues_model.Issue) (*forgefed.Ticket, error) {
iri := issue.GetIRI(ctx)
ticket := forgefed.TicketNew()
ticket.Type = forgefed.TicketType
ticket.ID = ap.IRI(iri)
@ -53,13 +53,13 @@ func Ticket(issue *issues_model.Issue) (*forgefed.Ticket, error) {
return nil, err
}
err = issue.LoadRepo(db.DefaultContext)
err = issue.LoadRepo(ctx)
if err != nil {
return nil, err
}
ticket.Context = ap.IRI(issue.Repo.GetIRI())
err = issue.LoadPoster(db.DefaultContext)
err = issue.LoadPoster(ctx)
if err != nil {
return nil, err
}

View File

@ -82,7 +82,7 @@ func CreateIssueComment(ctx context.Context, doer *user_model.User, repo *repo_m
if strings.Contains(repo.OwnerName, "@") {
// Federated comment
note, err := activitypub.Note(comment)
note, err := activitypub.Note(ctx, comment)
if err != nil {
return nil, err
}

View File

@ -29,7 +29,7 @@ func NewIssue(repo *repo_model.Repository, issue *issues_model.Issue, labelIDs [
if strings.Contains(repo.OwnerName, "@") {
// Federated issue
ticket, err := activitypub.Ticket(issue)
ticket, err := activitypub.Ticket(db.DefaultContext, issue)
if err != nil {
return err
}

View File

@ -23,7 +23,7 @@
},
"basePath": "{{AppSubUrl | JSEscape | Safe}}/api/v1",
"paths": {
"/activitypub/note/{username}/{reponame}/{id}/{noteid}": {
"/activitypub/note/{username}/{reponame}/{noteid}": {
"get": {
"produces": [
"application/activity+json"
@ -48,13 +48,6 @@
"in": "path",
"required": true
},
{
"type": "string",
"description": "ID number of the issue or PR",
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "ID number of the comment",
@ -66,6 +59,12 @@
"responses": {
"200": {
"$ref": "#/responses/ActivityPub"
},
"204": {
"$ref": "#/responses/empty"
},
"404": {
"$ref": "#/responses/notFound"
}
}
}
@ -238,6 +237,9 @@
"responses": {
"200": {
"$ref": "#/responses/ActivityPub"
},
"404": {
"$ref": "#/responses/notFound"
}
}
}