Changes
13 changed files (+158/-91)
-
-
@@ -27,6 +27,7 @@ import ("code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/references" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util"
-
@@ -2471,3 +2472,11 @@ func DeleteOrphanedIssues() error {} return nil } func (issue *Issue) GetIRI() string { _ = issue.LoadRepo(db.DefaultContext) if strings.Contains(issue.Repo.OwnerName, "@") { return issue.OriginalAuthor } return setting.AppURL + "api/v1/activitypub/ticket/" + issue.Repo.OwnerName + "/" + issue.Repo.Name + "/" + strconv.FormatInt(issue.Index, 10) }
-
-
-
@@ -802,3 +802,10 @@ func FixNullArchivedRepository() (int64, error) {IsArchived: false, }) } func (r *Repository) GetIRI() string { if strings.Contains(r.OwnerName, "@") { return r.OriginalURL } return setting.AppURL + "api/v1/activitypub/repo/" + r.OwnerName + "/" + r.Name }
-
-
-
@@ -1339,3 +1339,10 @@ func GetOrderByName() string {} return "name" } func (u *User) GetIRI() string { if u.LoginType == auth.Federated { return u.LoginName } return setting.AppURL + "api/v1/activitypub/user/" + u.Name }
-
-
-
@@ -62,35 +62,37 @@ func NotEmpty(i ap.Item) bool {if ap.IsNil(i) { return false } var notEmpty bool switch i.GetType() { case CommitType: OnCommit(i, func(c *Commit) error { notEmpty = ap.NotEmpty(c.Object) return nil }) c, err := ToCommit(i) if err != nil { return false } return ap.NotEmpty(c.Object) case BranchType: OnBranch(i, func(b *Branch) error { notEmpty = ap.NotEmpty(b.Object) return nil }) b, err := ToBranch(i) if err != nil { return false } return ap.NotEmpty(b.Object) case RepositoryType: OnRepository(i, func(r *Repository) error { notEmpty = ap.NotEmpty(r.Actor) return nil }) r, err := ToRepository(i) if err != nil { return false } return ap.NotEmpty(r.Actor) case PushType: OnPush(i, func(p *Push) error { notEmpty = ap.NotEmpty(p.Object) return nil }) p, err := ToPush(i) if err != nil { return false } return ap.NotEmpty(p.Object) case TicketType: OnTicket(i, func(t *Ticket) error { notEmpty = ap.NotEmpty(t.Object) return nil }) default: notEmpty = ap.NotEmpty(i) t, err := ToTicket(i) if err != nil { return false } return ap.NotEmpty(t.Object) } return notEmpty return ap.NotEmpty(i) }
-
-
-
@@ -42,7 +42,12 @@ func AuthorizeInteraction(ctx *context.Context) {switch object.GetType() { case ap.PersonType: // Federated user err = createPerson(ctx, object.(*ap.Person)) person, err := ap.ToActor(object) if err != nil { ctx.ServerError("ToActor", err) return } err = createPerson(ctx, person) if err != nil { ctx.ServerError("FederatedUserNew", err) return
-
-
-
@@ -67,7 +67,10 @@ func createPerson(ctx context.Context, person *ap.Person) error {} if person.Icon != nil { icon := person.Icon.(*ap.Image) icon, err := ap.ToObject(person.Icon) if err != nil { return err } iconURL, err := icon.URL.GetLink().URL() if err != nil { return err
-
@@ -112,7 +115,11 @@ func createPersonFromIRI(ctx context.Context, personIRI ap.IRI) error {} // Create federated user return createPerson(ctx, object.(*ap.Person)) person, err := ap.ToActor(object) if err != nil { return err } return createPerson(ctx, person) } // Create a new federated repo from a Repository object
-
@@ -133,7 +140,8 @@ func createRepository(ctx context.Context, repository *forgefed.Repository) erro} repo, err := repo_service.CreateRepository(user, user, repo_module.CreateRepoOptions{ Name: repository.Name.String(), Name: repository.Name.String(), OriginalURL: repository.GetLink().String(), }) if err != nil { return err
-
@@ -281,7 +289,7 @@ func createComment(ctx context.Context, note *ap.Note) error {return err } actorUser, err := activitypub.PersonIRIToUser(ctx, note.AttributedTo.GetLink()) user, err := activitypub.PersonIRIToUser(ctx, note.AttributedTo.GetLink()) if err != nil { return err }
-
@@ -299,7 +307,7 @@ func createComment(ctx context.Context, note *ap.Note) error {return err } _, err = issues_model.CreateCommentCtx(ctx, &issues_model.CreateCommentOptions{ Doer: actorUser, Doer: user, Repo: repo, Issue: issue, Content: note.Content.String(),
-
-
-
@@ -42,8 +42,8 @@ func Person(ctx *context.APIContext) {// "200": // "$ref": "#/responses/ActivityPub" link := setting.AppURL + "api/v1/activitypub/user/" + ctx.ContextUser.Name person := ap.PersonNew(ap.IRI(link)) iri := ctx.ContextUser.GetIRI() person := ap.PersonNew(ap.IRI(iri)) person.Name = ap.NaturalLanguageValuesNew() err := person.Name.Set("en", ap.Content(ctx.ContextUser.FullName))
-
@@ -68,14 +68,14 @@ func Person(ctx *context.APIContext) {URL: ap.IRI(ctx.ContextUser.AvatarFullLinkWithSize(2048)), } person.Inbox = ap.IRI(link + "/inbox") person.Outbox = ap.IRI(link + "/outbox") person.Following = ap.IRI(link + "/following") person.Followers = ap.IRI(link + "/followers") person.Liked = ap.IRI(link + "/liked") person.Inbox = ap.IRI(iri + "/inbox") person.Outbox = ap.IRI(iri + "/outbox") person.Following = ap.IRI(iri + "/following") person.Followers = ap.IRI(iri + "/followers") person.Liked = ap.IRI(iri + "/liked") person.PublicKey.ID = ap.IRI(link + "#main-key") person.PublicKey.Owner = ap.IRI(link) person.PublicKey.ID = ap.IRI(iri + "#main-key") person.PublicKey.Owner = ap.IRI(iri) publicKeyPem, err := activitypub.GetPublicKey(ctx.ContextUser) if err != nil { ctx.ServerError("GetPublicKey", err)
-
@@ -164,13 +164,13 @@ func PersonOutbox(ctx *context.APIContext) {// "200": // "$ref": "#/responses/ActivityPub" link := setting.AppURL + "api/v1/activitypub/user/" + ctx.ContextUser.Name iri := ctx.ContextUser.GetIRI() orderedCollection := ap.OrderedCollectionNew(ap.IRI(link + "/outbox")) orderedCollection.First = ap.IRI(link + "/outbox?page=1") orderedCollection := ap.OrderedCollectionNew(ap.IRI(iri + "/outbox")) orderedCollection.First = ap.IRI(iri + "/outbox?page=1") outbox := ap.OrderedCollectionPageNew(orderedCollection) outbox.First = ap.IRI(link + "/outbox?page=1") outbox.First = ap.IRI(iri + "/outbox?page=1") feed, err := activities.GetFeeds(ctx, activities.GetFeedsOptions{ RequestedUser: ctx.ContextUser,
-
@@ -183,12 +183,12 @@ func PersonOutbox(ctx *context.APIContext) {// Only specify next if this amount of feed corresponds to the calculated limit. if len(feed) == convert.ToCorrectPageSize(ctx.FormInt("limit")) { outbox.Next = ap.IRI(fmt.Sprintf("%s/outbox?page=%d", link, ctx.FormInt("page")+1)) outbox.Next = ap.IRI(fmt.Sprintf("%s/outbox?page=%d", iri, ctx.FormInt("page")+1)) } // Only specify previous page when there is one. if ctx.FormInt("page") > 1 { outbox.Prev = ap.IRI(fmt.Sprintf("%s/outbox?page=%d", link, ctx.FormInt("page")-1)) outbox.Prev = ap.IRI(fmt.Sprintf("%s/outbox?page=%d", iri, ctx.FormInt("page")-1)) } if err != nil {
-
@@ -249,7 +249,7 @@ func PersonFollowing(ctx *context.APIContext) {// "200": // "$ref": "#/responses/ActivityPub" link := setting.AppURL + "api/v1/activitypub/user/" + ctx.ContextUser.Name iri := ctx.ContextUser.GetIRI() users, _, err := user_model.GetUserFollowing(ctx, ctx.ContextUser, ctx.Doer, utils.GetListOptions(ctx)) if err != nil {
-
@@ -257,7 +257,7 @@ func PersonFollowing(ctx *context.APIContext) {return } following := ap.OrderedCollectionNew(ap.IRI(link + "/following")) following := ap.OrderedCollectionNew(ap.IRI(iri + "/following")) following.TotalItems = uint(len(users)) for _, user := range users {
-
@@ -290,7 +290,7 @@ func PersonFollowers(ctx *context.APIContext) {// "200": // "$ref": "#/responses/ActivityPub" link := setting.AppURL + "api/v1/activitypub/user/" + ctx.ContextUser.Name iri := ctx.ContextUser.GetIRI() users, _, err := user_model.GetUserFollowers(ctx, ctx.ContextUser, ctx.Doer, utils.GetListOptions(ctx)) if err != nil {
-
@@ -298,7 +298,7 @@ func PersonFollowers(ctx *context.APIContext) {return } followers := ap.OrderedCollectionNew(ap.IRI(link + "/followers")) followers := ap.OrderedCollectionNew(ap.IRI(iri + "/followers")) followers.TotalItems = uint(len(users)) for _, user := range users {
-
@@ -331,7 +331,7 @@ func PersonLiked(ctx *context.APIContext) {// "200": // "$ref": "#/responses/ActivityPub" link := setting.AppURL + "api/v1/activitypub/user/" + ctx.ContextUser.Name iri := ctx.ContextUser.GetIRI() repos, count, err := repo_model.SearchRepository(&repo_model.SearchRepoOptions{ Actor: ctx.Doer,
-
@@ -343,7 +343,7 @@ func PersonLiked(ctx *context.APIContext) {return } liked := ap.OrderedCollectionNew(ap.IRI(link + "/liked")) liked := ap.OrderedCollectionNew(ap.IRI(iri + "/liked")) liked.TotalItems = uint(count) for _, repo := range repos {
-
-
-
@@ -39,8 +39,8 @@ func Repo(ctx *context.APIContext) {// "200": // "$ref": "#/responses/ActivityPub" link := setting.AppURL + "api/v1/activitypub/repo/" + ctx.ContextUser.Name + "/" + ctx.Repo.Repository.Name repo := forgefed.RepositoryNew(ap.IRI(link)) iri := ctx.Repo.Repository.GetIRI() repo := forgefed.RepositoryNew(ap.IRI(iri)) repo.Name = ap.NaturalLanguageValuesNew() err := repo.Name.Set("en", ap.Content(ctx.Repo.Repository.Name))
-
@@ -58,10 +58,10 @@ func Repo(ctx *context.APIContext) {return } repo.Inbox = ap.IRI(link + "/inbox") repo.Outbox = ap.IRI(link + "/outbox") repo.Followers = ap.IRI(link + "/followers") repo.Team = ap.IRI(link + "/team") repo.Inbox = ap.IRI(iri + "/inbox") repo.Outbox = ap.IRI(iri + "/outbox") repo.Followers = ap.IRI(iri + "/followers") repo.Team = ap.IRI(iri + "/team") response(ctx, repo) }
-
-
-
@@ -43,12 +43,6 @@ func Ticket(ctx *context.APIContext) {// "200": // "$ref": "#/responses/ActivityPub" link := setting.AppURL + "api/v1/activitypub/ticket/" + ctx.ContextUser.Name + "/" + ctx.Repo.Repository.Name + "/" + ctx.Params("id") ticket := forgefed.TicketNew() ticket.Type = forgefed.TicketType ticket.ID = ap.IRI(link) repo, err := repo_model.GetRepositoryByOwnerAndNameCtx(ctx, ctx.ContextUser.Name, ctx.Repo.Repository.Name) if err != nil { ctx.ServerError("GetRepositoryByOwnerAndNameCtx", err)
-
@@ -64,6 +58,12 @@ func Ticket(ctx *context.APIContext) {ctx.ServerError("GetIssueByIndex", err) return } iri := issue.GetIRI() // TODO: move this to services/activitypub/objects.go ticket := forgefed.TicketNew() ticket.Type = forgefed.TicketType ticket.ID = ap.IRI(iri) // Setting a NaturalLanguageValue to a number causes go-ap's JSON parsing to do weird things // Workaround: set it to #1 instead of 1
-
-
-
@@ -12,42 +12,22 @@ import () // Create and send Follow activity func Follow(userID, followID int64) error { followUser, err := user_model.GetUserByID(followID) if err != nil { return err } actorUser, err := user_model.GetUserByID(userID) if err != nil { return err } func Follow(actorUser, followUser *user_model.User) *ap.Follow { object := ap.PersonNew(ap.IRI(followUser.LoginName)) follow := ap.FollowNew("", object) follow.Type = ap.FollowType follow.Actor = ap.PersonNew(ap.IRI(setting.AppURL + "api/v1/activitypub/user/" + actorUser.Name)) follow.To = ap.ItemCollection{ap.Item(ap.IRI(followUser.LoginName + "/inbox"))} return Send(actorUser, follow) return follow } // Create and send Undo Follow activity func Unfollow(userID, followID int64) error { followUser, err := user_model.GetUserByID(followID) if err != nil { return err } actorUser, err := user_model.GetUserByID(userID) if err != nil { return err } func Unfollow(actorUser, followUser *user_model.User) *ap.Undo { object := ap.PersonNew(ap.IRI(followUser.LoginName)) follow := ap.FollowNew("", object) follow.Actor = ap.PersonNew(ap.IRI(setting.AppURL + "api/v1/activitypub/user/" + actorUser.Name)) unfollow := ap.UndoNew("", follow) unfollow.Type = ap.UndoType unfollow.To = ap.ItemCollection{ap.Item(ap.IRI(followUser.LoginName + "/inbox"))} return Send(actorUser, unfollow) return unfollow }
-
-
-
@@ -0,0 +1,22 @@// 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 ( issues_model "code.gitea.io/gitea/models/issues" ap "github.com/go-ap/activitypub" ) func Note(comment *issues_model.Comment) ap.Note { 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 note }
-
-
-
@@ -5,12 +5,17 @@package comments import ( "strings" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/notification" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/services/activitypub" ap "github.com/go-ap/activitypub" ) // CreateIssueComment creates a plain issue comment.
-
@@ -27,6 +32,20 @@ func CreateIssueComment(doer *user_model.User, repo *repo_model.Repository, issureturn nil, err } if strings.Contains(repo.Owner.Name, "@") { // Federated comment // Refactor this to its own function in services/activitypub create := ap.Create{ Type: ap.CreateType, Object: activitypub.Note(comment), To: ap.ItemCollection{ap.Item(ap.IRI(repo.OriginalURL + "/inbox"))}, } err = activitypub.Send(doer, &create) if err != nil { return nil, err } } mentions, err := issues_model.FindAndUpdateIssueMentions(db.DefaultContext, issue, doer, comment.Content) if err != nil { return nil, err
-
-
-
@@ -295,9 +295,13 @@ func FollowUser(userID, followID int64) (err error) {} if followUser.LoginType == auth.Federated { // Following remote user err = activitypub.Follow(userID, followID) actorUser, err := user_model.GetUserByID(userID) if err != nil { return return err } err = activitypub.Send(actorUser, activitypub.Follow(actorUser, followUser)) if err != nil { return err } }
-
@@ -316,9 +320,13 @@ func UnfollowUser(userID, followID int64) (err error) {} if followUser.LoginType == auth.Federated { // Unfollowing remote user err = activitypub.Unfollow(userID, followID) actorUser, err := user_model.GetUserByID(userID) if err != nil { return return err } err = activitypub.Send(actorUser, activitypub.Unfollow(actorUser, followUser)) if err != nil { return err } }
-