From 2d74e4f555035753dd15fba0dca37e678e473ab0 Mon Sep 17 00:00:00 2001 From: Anthony Wang Date: Sun, 27 Nov 2022 01:40:15 +0000 Subject: [PATCH] Delete fork code and move createPullRequest to create.go --- models/activities/action_test.go | 4 +- .../v1/activitypub/authorize_interaction.go | 35 +------ routers/api/v1/activitypub/create.go | 93 ++++++++++++++++++- routers/api/v1/activitypub/fork.go | 51 ---------- routers/api/v1/activitypub/pull_request.go | 66 ------------- routers/api/v1/activitypub/repo.go | 11 +-- 6 files changed, 98 insertions(+), 162 deletions(-) delete mode 100644 routers/api/v1/activitypub/fork.go delete mode 100644 routers/api/v1/activitypub/pull_request.go diff --git a/models/activities/action_test.go b/models/activities/action_test.go index ac2a3043a..d97c0c33c 100644 --- a/models/activities/action_test.go +++ b/models/activities/action_test.go @@ -10,7 +10,7 @@ import ( activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" - issue_model "code.gitea.io/gitea/models/issues" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -31,7 +31,7 @@ func TestAction_GetRepoLink(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) - comment := unittest.AssertExistsAndLoadBean(t, &issue_model.Comment{ID: 2}) + comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2}) action := &activities_model.Action{RepoID: repo.ID, CommentID: comment.ID} setting.AppSubURL = "/suburl" expected := path.Join(setting.AppSubURL, owner.Name, repo.Name) diff --git a/routers/api/v1/activitypub/authorize_interaction.go b/routers/api/v1/activitypub/authorize_interaction.go index 3e1a94d85..a431bfb06 100644 --- a/routers/api/v1/activitypub/authorize_interaction.go +++ b/routers/api/v1/activitypub/authorize_interaction.go @@ -16,6 +16,7 @@ import ( ap "github.com/go-ap/activitypub" ) +// Fetch and load a remote object func AuthorizeInteraction(ctx *context.Context) { uri, err := url.Parse(ctx.Req.URL.Query().Get("uri")) if err != nil { @@ -40,10 +41,6 @@ func AuthorizeInteraction(ctx *context.Context) { switch object.GetType() { case ap.PersonType: // Federated user - if err != nil { - ctx.ServerError("UnmarshalJSON", err) - return - } err = createPerson(ctx, object.(*ap.Person)) if err != nil { ctx.ServerError("FederatedUserNew", err) @@ -71,35 +68,9 @@ func AuthorizeInteraction(ctx *context.Context) { } ctx.Redirect(username + "/" + reponame) case forgefed.TicketType: - // Federated ticket + // Federated issue or pull request err = forgefed.OnTicket(object, func(t *forgefed.Ticket) error { - // TODO: make sure federated user exists - // Also, refactor this code to reduce the chance of accidentally creating import cycles - repoURL, err := url.Parse(t.Context.GetLink().String()) - if err != nil { - return err - } - // Fetch repository object - resp, err := activitypub.Fetch(repoURL) - if err != nil { - return err - } - // Parse repository object - ap.ItemTyperFunc = forgefed.GetItemByType - ap.JSONItemUnmarshal = forgefed.JSONUnmarshalerFn - ap.NotEmptyChecker = forgefed.NotEmpty - object, err := ap.UnmarshalJSON(resp) - if err != nil { - return err - } - // Create federated repo - err = forgefed.OnRepository(object, func(r *forgefed.Repository) error { - return createRepository(ctx, r) - }) - if err != nil { - return err - } - return createIssue(ctx, t) + return createTicket(ctx, t) }) if err != nil { ctx.ServerError("ReceiveIssue", err) diff --git a/routers/api/v1/activitypub/create.go b/routers/api/v1/activitypub/create.go index eb9b6244c..a76fb8b89 100644 --- a/routers/api/v1/activitypub/create.go +++ b/routers/api/v1/activitypub/create.go @@ -12,7 +12,7 @@ import ( "strings" "code.gitea.io/gitea/models/auth" - issue_model "code.gitea.io/gitea/models/issues" + 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/forgefed" @@ -20,6 +20,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/services/activitypub" issue_service "code.gitea.io/gitea/services/issue" + pull_service "code.gitea.io/gitea/services/pull" repo_service "code.gitea.io/gitea/services/repository" user_service "code.gitea.io/gitea/services/user" @@ -120,6 +121,7 @@ func createRepository(ctx context.Context, repository *forgefed.Repository) erro return err } + // Check if repo exists _, err = repo_model.GetRepositoryByOwnerAndNameCtx(ctx, user.Name, repository.Name.String()) if err == nil { return nil @@ -143,8 +145,41 @@ func createRepository(ctx context.Context, repository *forgefed.Repository) erro return nil } +// Create a ticket +func createTicket(ctx context.Context, ticket *forgefed.Ticket) error { + if ticket.Origin != nil { + return createPullRequest(ctx, ticket) + } + return createIssue(ctx, ticket) +} + // Create an issue func createIssue(ctx context.Context, ticket *forgefed.Ticket) error { + repoURL, err := url.Parse(ticket.Context.GetLink().String()) + if err != nil { + return err + } + // Fetch repository object + resp, err := activitypub.Fetch(repoURL) + if err != nil { + return err + } + // Parse repository object + ap.ItemTyperFunc = forgefed.GetItemByType + ap.JSONItemUnmarshal = forgefed.JSONUnmarshalerFn + ap.NotEmptyChecker = forgefed.NotEmpty + object, err := ap.UnmarshalJSON(resp) + if err != nil { + return err + } + // Create federated repo + err = forgefed.OnRepository(object, func(r *forgefed.Repository) error { + return createRepository(ctx, r) + }) + if err != nil { + return err + } + // Construct issue user, err := activitypub.PersonIRIToUser(ctx, ap.IRI(ticket.AttributedTo.GetLink().String())) if err != nil { @@ -158,7 +193,7 @@ func createIssue(ctx context.Context, ticket *forgefed.Ticket) error { if err != nil { return err } - issue := &issue_model.Issue{ + issue := &issues_model.Issue{ ID: idx, RepoID: repo.ID, Repo: repo, @@ -170,6 +205,56 @@ func createIssue(ctx context.Context, ticket *forgefed.Ticket) error { return issue_service.NewIssue(repo, issue, nil, nil, nil) } +// Create a pull request +func createPullRequest(ctx context.Context, ticket *forgefed.Ticket) error { + // TODO: Clean this up + + actorUser, err := activitypub.PersonIRIToUser(ctx, ticket.AttributedTo.GetLink()) + if err != nil { + return err + } + + // TODO: The IRI processing stuff should be moved to iri.go + originIRI := ticket.Origin.GetLink() + originIRISplit := strings.Split(originIRI.String(), "/") + originInstance := originIRISplit[2] + originUsername := originIRISplit[3] + originReponame := originIRISplit[4] + originBranch := originIRISplit[len(originIRISplit)-1] + originRepo, _ := repo_model.GetRepositoryByOwnerAndName(originUsername+"@"+originInstance, originReponame) + + targetIRI := ticket.Target.GetLink() + targetIRISplit := strings.Split(targetIRI.String(), "/") + // targetInstance := targetIRISplit[2] + targetUsername := targetIRISplit[3] + targetReponame := targetIRISplit[4] + targetBranch := targetIRISplit[len(targetIRISplit)-1] + + targetRepo, _ := repo_model.GetRepositoryByOwnerAndName(targetUsername, targetReponame) + + prIssue := &issues_model.Issue{ + RepoID: targetRepo.ID, + Title: "Hello from test.exozy.me!", // Don't hardcode, get the title from the Ticket object + PosterID: actorUser.ID, + Poster: actorUser, + IsPull: true, + Content: "🎉", // TODO: Get content from Ticket object + } + + pr := &issues_model.PullRequest{ + HeadRepoID: originRepo.ID, + BaseRepoID: targetRepo.ID, + HeadBranch: originBranch, + BaseBranch: targetBranch, + HeadRepo: originRepo, + BaseRepo: targetRepo, + MergeBase: "", + Type: issues_model.PullRequestGitea, + } + + return pull_service.NewPullRequest(ctx, targetRepo, prIssue, []int64{}, []string{}, pr, []int64{}) +} + // Create a comment func createComment(ctx context.Context, note *ap.Note) error { actorUser, err := activitypub.PersonIRIToUser(ctx, note.AttributedTo.GetLink()) @@ -185,11 +270,11 @@ func createComment(ctx context.Context, note *ap.Note) error { if err != nil { return err } - issue, err := issue_model.GetIssueByIndex(repo.ID, idx) + issue, err := issues_model.GetIssueByIndex(repo.ID, idx) if err != nil { return err } - _, err = issue_model.CreateCommentCtx(ctx, &issue_model.CreateCommentOptions{ + _, err = issues_model.CreateCommentCtx(ctx, &issues_model.CreateCommentOptions{ Doer: actorUser, Repo: repo, Issue: issue, diff --git a/routers/api/v1/activitypub/fork.go b/routers/api/v1/activitypub/fork.go deleted file mode 100644 index 26a75c575..000000000 --- a/routers/api/v1/activitypub/fork.go +++ /dev/null @@ -1,51 +0,0 @@ -// 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 ( - "context" - - repo_model "code.gitea.io/gitea/models/repo" - user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/forgefed" - "code.gitea.io/gitea/services/activitypub" - repo_service "code.gitea.io/gitea/services/repository" - - ap "github.com/go-ap/activitypub" -) - -func fork(ctx context.Context, create ap.Create) error { - // Object is the new fork repository - repository, err := ap.To[forgefed.Repository](create.Object) - if err != nil { - return nil - } - - // TODO: Clean this up - actor, err := activitypub.PersonIRIToUser(ctx, create.Actor.GetLink()) - if err != nil { - return err - } - - // Don't create an actual copy of the remote repo! - // https://gitea.com/xy/gitea/issues/7 - - // Create the fork - repoIRI := repository.GetLink() - username, reponame, err := activitypub.RepositoryIRIToName(repoIRI) - if err != nil { - return err - } - - // FederatedUserNew(username + "@" + instance, ) - user, _ := user_model.GetUserByName(ctx, username) - - // var repo forgefed.Repository - // repo = activity.Object - repo, _ := repo_model.GetRepositoryByOwnerAndName(actor.Name, reponame) // hardcoded for now :( - - _, err = repo_service.ForkRepository(ctx, user, user, repo_service.ForkRepoOptions{BaseRepo: repo, Name: reponame, Description: "this is a remote fork"}) - return err -} diff --git a/routers/api/v1/activitypub/pull_request.go b/routers/api/v1/activitypub/pull_request.go deleted file mode 100644 index 3fa0a1ba1..000000000 --- a/routers/api/v1/activitypub/pull_request.go +++ /dev/null @@ -1,66 +0,0 @@ -// 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 ( - "context" - "strings" - - issues_model "code.gitea.io/gitea/models/issues" - repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/forgefed" - "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/services/activitypub" - pull_service "code.gitea.io/gitea/services/pull" -) - -func createPullRequest(ctx context.Context, ticket *forgefed.Ticket) error { - // TODO: Clean this up - - actorUser, err := activitypub.PersonIRIToUser(ctx, ticket.AttributedTo.GetLink()) - if err != nil { - log.Warn("Couldn't find ticket actor user", err) - } - - // TODO: The IRI processing stuff should be moved to iri.go - originIRI := ticket.Origin.GetLink() - originIRISplit := strings.Split(originIRI.String(), "/") - originInstance := originIRISplit[2] - originUsername := originIRISplit[3] - originReponame := originIRISplit[4] - originBranch := originIRISplit[len(originIRISplit)-1] - originRepo, _ := repo_model.GetRepositoryByOwnerAndName(originUsername+"@"+originInstance, originReponame) - - targetIRI := ticket.Target.GetLink() - targetIRISplit := strings.Split(targetIRI.String(), "/") - // targetInstance := targetIRISplit[2] - targetUsername := targetIRISplit[3] - targetReponame := targetIRISplit[4] - targetBranch := targetIRISplit[len(targetIRISplit)-1] - - targetRepo, _ := repo_model.GetRepositoryByOwnerAndName(targetUsername, targetReponame) - - prIssue := &issues_model.Issue{ - RepoID: targetRepo.ID, - Title: "Hello from test.exozy.me!", // Don't hardcode, get the title from the Ticket object - PosterID: actorUser.ID, - Poster: actorUser, - IsPull: true, - Content: "🎉", // TODO: Get content from Ticket object - } - - pr := &issues_model.PullRequest{ - HeadRepoID: originRepo.ID, - BaseRepoID: targetRepo.ID, - HeadBranch: originBranch, - BaseBranch: targetBranch, - HeadRepo: originRepo, - BaseRepo: targetRepo, - MergeBase: "", - Type: issues_model.PullRequestGitea, - } - - return pull_service.NewPullRequest(ctx, targetRepo, prIssue, []int64{}, []string{}, pr, []int64{}) -} diff --git a/routers/api/v1/activitypub/repo.go b/routers/api/v1/activitypub/repo.go index c948fe40e..c4dae70b3 100644 --- a/routers/api/v1/activitypub/repo.go +++ b/routers/api/v1/activitypub/repo.go @@ -127,16 +127,13 @@ func RepoInbox(ctx *context.APIContext) { switch o.Type { case forgefed.RepositoryType: // Fork created by remote instance - return fork(ctx, activity) + return forgefed.OnRepository(o, func(r *forgefed.Repository) error { + return createRepository(ctx, r) + }) case forgefed.TicketType: // New issue or pull request return forgefed.OnTicket(o, func(t *forgefed.Ticket) error { - if t.Origin != nil { - // New pull request - return createPullRequest(ctx, t) - } - // New issue - return createIssue(ctx, t) + return createTicket(ctx, t) }) case ap.NoteType: // New comment