Changes
7 changed files (+169/-13)
-
-
@@ -28,7 +28,7 @@ require (github.com/ethantkoenig/rupture v1.0.1 github.com/felixge/fgprof v0.9.2 github.com/gliderlabs/ssh v0.3.4 github.com/go-ap/activitypub v0.0.0-00010101000000-000000000000 github.com/go-ap/activitypub v0.0.0-20220706134811-0c84d76ce535 github.com/go-ap/jsonld v0.0.0-20220615144122-1d862b15410d github.com/go-chi/chi/v5 v5.0.7 github.com/go-chi/cors v1.2.1
-
-
-
@@ -19,6 +19,8 @@ type Repository struct {Team ap.Item `jsonld:"team,omitempty"` // Forks OrderedCollection of repositories that are forks of this repository Forks ap.Item `jsonld:"forks,omitempty"` // ForkedFrom Identifies the repository which this repository was created as a fork ForkedFrom ap.Item `jsonld:"forkedFrom,omitempty"` } // RepositoryNew initializes a Repository type actor
-
@@ -42,6 +44,9 @@ func (r Repository) MarshalJSON() ([]byte, error) {if r.Forks != nil { ap.WriteItemJSONProp(&b, "forks", r.Forks) } if r.ForkedFrom != nil { ap.WriteItemJSONProp(&b, "forkedFrom", r.ForkedFrom) } ap.Write(&b, '}') return b, nil }
-
@@ -55,6 +60,7 @@ func (r *Repository) UnmarshalJSON(data []byte) error {r.Team = ap.JSONGetItem(val, "team") r.Forks = ap.JSONGetItem(val, "forks") r.ForkedFrom = ap.JSONGetItem(val, "forkedFrom") return ap.OnActor(&r.Actor, func(a *ap.Actor) error { return ap.LoadActor(val, a)
-
-
-
@@ -0,0 +1,68 @@// 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" //"code.gitea.io/gitea/models/forgefed" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/services/migrations" repo_service "code.gitea.io/gitea/services/repository" ap "github.com/go-ap/activitypub" ) func Fork(ctx context.Context, instance, username, reponame, destUsername string) { // Migrate repository code user, _ := user_model.GetUserByName(ctx, destUsername) _, err := migrations.MigrateRepository(ctx, user, destUsername, migrations.MigrateOptions{ CloneAddr: "https://" + instance + "/" + username + "/" + reponame + ".git", RepoName: reponame, }, nil) if err != nil { log.Warn("Couldn't create fork", err) } // Make the migrated repo a fork // Send a Create activity to the instance we are forking from create := ap.Create{Type: ap.CreateType} create.To = ap.ItemCollection{ap.IRI("https://" + instance + "/api/v1/activitypub/repo/" + username + "/" + reponame + "/inbox")} repo := ap.IRI(strings.TrimSuffix(setting.AppURL, "/") + "/api/v1/activitypub/repo/" + destUsername + "/" + reponame) // repo := forgefed.RepositoryNew(ap.IRI(strings.TrimSuffix(setting.AppURL, "/") + "/api/v1/activitypub/repo/" + destUsername + "/" + reponame)) // repo.ForkedFrom = forgefed.RepositoryNew(ap.IRI()) create.Object = repo Send(user, &create) } func ForkFromCreate(ctx context.Context, activity ap.Create) { // Don't create an actual copy of the remote repo! // https://gitea.com/Ta180m/gitea/issues/7 // Create the fork repoIRI := activity.Object.GetID() repoIRISplit := strings.Split(repoIRI.String(), "/") instance := repoIRISplit[2] username := repoIRISplit[7] reponame := repoIRISplit[8] // FederatedUserNew(username + "@" + instance, ) user, _ := user_model.GetUserByName(ctx, username+"@"+instance) // var repo forgefed.Repository // repo = activity.Object repo, _ := repo_model.GetRepositoryByOwnerAndName("Ta180m", reponame) // hardcoded for now :( _, err := repo_service.ForkRepository(ctx, user, user, repo_service.ForkRepoOptions{BaseRepo: repo, Name: reponame, Description: "this is a remote fork"}) log.Warn("Couldn't create copy of remote fork", err) // TODO: send back accept }
-
-
-
@@ -6,7 +6,6 @@ package activitypubimport ( "context" "fmt" "strconv" "strings"
-
@@ -35,15 +34,13 @@ func Comment(ctx context.Context, activity ap.Note) {contextSplit := strings.Split(context.String(), "/") username := contextSplit[3] reponame := contextSplit[4] fmt.Println(username) fmt.Println(reponame) repo, _ := repo_model.GetRepositoryByOwnerAndName(username, reponame) idx, _ := strconv.ParseInt(contextSplit[len(contextSplit)-1], 10, 64) issue, _ := issues.GetIssueByIndex(repo.ID, idx) issues.CreateCommentCtx(ctx, &issues.CreateCommentOptions{ Doer: actorUser, Repo: repo, Issue: issue, Doer: actorUser, Repo: repo, Issue: issue, Content: activity.Content.String(), }) }
-
-
-
@@ -0,0 +1,76 @@// 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" "fmt" "strings" 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/log" pull_service "code.gitea.io/gitea/services/pull" ap "github.com/go-ap/activitypub" ) func PullRequest(ctx context.Context, activity ap.Move) { actorIRI := activity.AttributedTo.GetLink() actorIRISplit := strings.Split(actorIRI.String(), "/") actorName := actorIRISplit[len(actorIRISplit)-1] + "@" + actorIRISplit[2] err := FederatedUserNew(actorName, actorIRI) if err != nil { log.Warn("Couldn't create new user", err) } actorUser, err := user_model.GetUserByName(ctx, actorName) if err != nil { log.Warn("Couldn't find actor", err) } // This code is really messy // The IRI processing stuff should be in a separate function originIRI := activity.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 := activity.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: "🎉", } pr := &issues_model.PullRequest{ HeadRepoID: originRepo.ID, BaseRepoID: targetRepo.ID, HeadBranch: originBranch, HeadCommitID: "73f228996f27fad2c7bb60435f912d943b66b0ee", // hardcoded for now BaseBranch: targetBranch, HeadRepo: originRepo, BaseRepo: targetRepo, MergeBase: "", Type: issues_model.PullRequestGitea, } err = pull_service.NewPullRequest(ctx, targetRepo, prIssue, []int64{}, []string{}, pr, []int64{}) fmt.Println(err) }
-
-
-
@@ -96,13 +96,21 @@ func RepoInbox(ctx *context.APIContext) {if err != nil { ctx.ServerError("Error reading request body", err) } var activity ap.Object activity.UnmarshalJSON(body) var activity ap.Activity activity.UnmarshalJSON(body) // This function doesn't support ForgeFed types!!! log.Warn("Debug", activity) if activity.Type == ap.NoteType { activitypub.Comment(ctx, activity) } else { switch activity.Type { case ap.NoteType: // activitypub.Comment(ctx, activity) case ap.CreateType: // if activity.Object.GetType() == forgefed.RepositoryType { // Fork created by remote instance activitypub.ForkFromCreate(ctx, activity) //} case ap.MoveType: // This should actually be forgefed.TicketType but that the UnmarshalJSON function above doesn't support ForgeFed! activitypub.PullRequest(ctx, activity) default: log.Warn("ActivityStreams type not supported", activity) }
-
-
-
@@ -65,6 +65,7 @@ func verifyHTTPSignatures(ctx *gitea_context.APIContext) (authenticated bool, erreturn } // 3. Verify the other actor's key // TODO: Verify attributedTo matches keyID algo := httpsig.Algorithm(setting.Federation.Algorithms[0]) authenticated = v.Verify(pubKey, algo) == nil return authenticated, err
-