Rewrite createPullRequest and add createPersonFromIRI
This commit is contained in:
parent
c982b67626
commit
a666eefe8f
5 changed files with 98 additions and 52 deletions
|
@ -11,6 +11,7 @@ import (
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/context"
|
"code.gitea.io/gitea/modules/context"
|
||||||
"code.gitea.io/gitea/modules/forgefed"
|
"code.gitea.io/gitea/modules/forgefed"
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/services/activitypub"
|
"code.gitea.io/gitea/services/activitypub"
|
||||||
|
|
||||||
ap "github.com/go-ap/activitypub"
|
ap "github.com/go-ap/activitypub"
|
||||||
|
@ -51,7 +52,7 @@ func AuthorizeInteraction(ctx *context.Context) {
|
||||||
ctx.ServerError("PersonIRIToName", err)
|
ctx.ServerError("PersonIRIToName", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.Redirect(name)
|
ctx.Redirect(setting.AppSubURL + name)
|
||||||
case forgefed.RepositoryType:
|
case forgefed.RepositoryType:
|
||||||
// Federated repository
|
// Federated repository
|
||||||
err = forgefed.OnRepository(object, func(r *forgefed.Repository) error {
|
err = forgefed.OnRepository(object, func(r *forgefed.Repository) error {
|
||||||
|
@ -66,7 +67,7 @@ func AuthorizeInteraction(ctx *context.Context) {
|
||||||
ctx.ServerError("RepositoryIRIToName", err)
|
ctx.ServerError("RepositoryIRIToName", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.Redirect(username + "/" + reponame)
|
ctx.Redirect(setting.AppSubURL + username + "/" + reponame)
|
||||||
case forgefed.TicketType:
|
case forgefed.TicketType:
|
||||||
// Federated issue or pull request
|
// Federated issue or pull request
|
||||||
err = forgefed.OnTicket(object, func(t *forgefed.Ticket) error {
|
err = forgefed.OnTicket(object, func(t *forgefed.Ticket) error {
|
||||||
|
@ -81,7 +82,7 @@ func AuthorizeInteraction(ctx *context.Context) {
|
||||||
ctx.ServerError("TicketIRIToName", err)
|
ctx.ServerError("TicketIRIToName", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.Redirect(username + "/" + reponame + "/issues/" + strconv.FormatInt(idx, 10))
|
ctx.Redirect(setting.AppSubURL + username + "/" + reponame + "/issues/" + strconv.FormatInt(idx, 10))
|
||||||
default:
|
default:
|
||||||
ctx.ServerError("Not implemented", err)
|
ctx.ServerError("Not implemented", err)
|
||||||
return
|
return
|
||||||
|
|
|
@ -91,9 +91,8 @@ func createPerson(ctx context.Context, person *ap.Person) error {
|
||||||
return user_model.SetUserSetting(user.ID, user_model.UserActivityPubPubPem, person.PublicKey.PublicKeyPem)
|
return user_model.SetUserSetting(user.ID, user_model.UserActivityPubPubPem, person.PublicKey.PublicKeyPem)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new federated repo from a Repository object
|
func createPersonFromIRI(ctx context.Context, personIRI ap.IRI) error {
|
||||||
func createRepository(ctx context.Context, repository *forgefed.Repository) error {
|
ownerURL, err := url.Parse(personIRI.String())
|
||||||
ownerURL, err := url.Parse(repository.AttributedTo.GetLink().String())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -102,6 +101,7 @@ func createRepository(ctx context.Context, repository *forgefed.Repository) erro
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse person object
|
// Parse person object
|
||||||
ap.ItemTyperFunc = forgefed.GetItemByType
|
ap.ItemTyperFunc = forgefed.GetItemByType
|
||||||
ap.JSONItemUnmarshal = forgefed.JSONUnmarshalerFn
|
ap.JSONItemUnmarshal = forgefed.JSONUnmarshalerFn
|
||||||
|
@ -110,12 +110,17 @@ func createRepository(ctx context.Context, repository *forgefed.Repository) erro
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create federated user
|
// Create federated user
|
||||||
err = createPerson(ctx, object.(*ap.Person))
|
return createPerson(ctx, object.(*ap.Person))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new federated repo from a Repository object
|
||||||
|
func createRepository(ctx context.Context, repository *forgefed.Repository) error {
|
||||||
|
err := createPersonFromIRI(ctx, repository.AttributedTo.GetLink())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := activitypub.PersonIRIToUser(ctx, repository.AttributedTo.GetLink())
|
user, err := activitypub.PersonIRIToUser(ctx, repository.AttributedTo.GetLink())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -145,17 +150,8 @@ func createRepository(ctx context.Context, repository *forgefed.Repository) erro
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a ticket
|
func createRepositoryFromIRI(ctx context.Context, repoIRI ap.IRI) error {
|
||||||
func createTicket(ctx context.Context, ticket *forgefed.Ticket) error {
|
repoURL, err := url.Parse(repoIRI.String())
|
||||||
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -164,6 +160,7 @@ func createIssue(ctx context.Context, ticket *forgefed.Ticket) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse repository object
|
// Parse repository object
|
||||||
ap.ItemTyperFunc = forgefed.GetItemByType
|
ap.ItemTyperFunc = forgefed.GetItemByType
|
||||||
ap.JSONItemUnmarshal = forgefed.JSONUnmarshalerFn
|
ap.JSONItemUnmarshal = forgefed.JSONUnmarshalerFn
|
||||||
|
@ -172,10 +169,24 @@ func createIssue(ctx context.Context, ticket *forgefed.Ticket) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create federated repo
|
// Create federated repo
|
||||||
err = forgefed.OnRepository(object, func(r *forgefed.Repository) error {
|
return forgefed.OnRepository(object, func(r *forgefed.Repository) error {
|
||||||
return createRepository(ctx, r)
|
return createRepository(ctx, r)
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a ticket
|
||||||
|
func createTicket(ctx context.Context, ticket *forgefed.Ticket) error {
|
||||||
|
if ticket.Origin != nil && ticket.Target != nil {
|
||||||
|
return createPullRequest(ctx, ticket)
|
||||||
|
}
|
||||||
|
return createIssue(ctx, ticket)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create an issue
|
||||||
|
func createIssue(ctx context.Context, ticket *forgefed.Ticket) error {
|
||||||
|
err := createRepositoryFromIRI(ctx, ticket.Context.GetLink())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -194,53 +205,62 @@ func createIssue(ctx context.Context, ticket *forgefed.Ticket) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
issue := &issues_model.Issue{
|
issue := &issues_model.Issue{
|
||||||
Index: idx,
|
Index: idx, // This doesn't seem to work?
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
Repo: repo,
|
Repo: repo,
|
||||||
Title: ticket.Summary.String(),
|
Title: ticket.Summary.String(),
|
||||||
PosterID: user.ID,
|
PosterID: user.ID,
|
||||||
Poster: user,
|
Poster: user,
|
||||||
Content: ticket.Content.String(),
|
Content: ticket.Content.String(),
|
||||||
|
IsClosed: ticket.IsResolved,
|
||||||
}
|
}
|
||||||
return issue_service.NewIssue(repo, issue, nil, nil, nil)
|
return issue_service.NewIssue(repo, issue, nil, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a pull request
|
// Create a pull request
|
||||||
func createPullRequest(ctx context.Context, ticket *forgefed.Ticket) error {
|
func createPullRequest(ctx context.Context, ticket *forgefed.Ticket) error {
|
||||||
// TODO: Clean this up
|
err := createRepositoryFromIRI(ctx, ticket.Context.GetLink())
|
||||||
|
|
||||||
actorUser, err := activitypub.PersonIRIToUser(ctx, ticket.AttributedTo.GetLink())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: The IRI processing stuff should be moved to iri.go
|
user, err := activitypub.PersonIRIToUser(ctx, ticket.AttributedTo.GetLink())
|
||||||
originIRI := ticket.Origin.GetLink()
|
if err != nil {
|
||||||
originIRISplit := strings.Split(originIRI.String(), "/")
|
return err
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Extract origin and target repos
|
||||||
|
originUsername, originReponame, originBranch, err := activitypub.BranchIRIToName(ticket.Origin.GetLink())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
originRepo, err := repo_model.GetRepositoryByOwnerAndName(originUsername, originReponame)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
targetUsername, targetReponame, targetBranch, err := activitypub.BranchIRIToName(ticket.Target.GetLink())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
targetRepo, err := repo_model.GetRepositoryByOwnerAndName(targetUsername, targetReponame)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
idx, err := strconv.ParseInt(ticket.Name.String()[1:], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
prIssue := &issues_model.Issue{
|
||||||
|
Index: idx,
|
||||||
|
RepoID: targetRepo.ID,
|
||||||
|
Title: ticket.Summary.String(),
|
||||||
|
PosterID: user.ID,
|
||||||
|
Poster: user,
|
||||||
|
IsPull: true,
|
||||||
|
Content: ticket.Content.String(),
|
||||||
|
IsClosed: ticket.IsResolved,
|
||||||
|
}
|
||||||
pr := &issues_model.PullRequest{
|
pr := &issues_model.PullRequest{
|
||||||
HeadRepoID: originRepo.ID,
|
HeadRepoID: originRepo.ID,
|
||||||
BaseRepoID: targetRepo.ID,
|
BaseRepoID: targetRepo.ID,
|
||||||
|
@ -251,12 +271,16 @@ func createPullRequest(ctx context.Context, ticket *forgefed.Ticket) error {
|
||||||
MergeBase: "",
|
MergeBase: "",
|
||||||
Type: issues_model.PullRequestGitea,
|
Type: issues_model.PullRequestGitea,
|
||||||
}
|
}
|
||||||
|
|
||||||
return pull_service.NewPullRequest(ctx, targetRepo, prIssue, []int64{}, []string{}, pr, []int64{})
|
return pull_service.NewPullRequest(ctx, targetRepo, prIssue, []int64{}, []string{}, pr, []int64{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a comment
|
// Create a comment
|
||||||
func createComment(ctx context.Context, note *ap.Note) error {
|
func createComment(ctx context.Context, note *ap.Note) error {
|
||||||
|
err := createPersonFromIRI(ctx, note.AttributedTo.GetLink())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
actorUser, err := activitypub.PersonIRIToUser(ctx, note.AttributedTo.GetLink())
|
actorUser, err := activitypub.PersonIRIToUser(ctx, note.AttributedTo.GetLink())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -78,6 +78,8 @@ func verifyHTTPSignatures(ctx *gitea_context.APIContext) (authenticated bool, er
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 4. Create a federated user for the actor
|
// 4. Create a federated user for the actor
|
||||||
|
// TODO: This is a very bad place for creating federated users
|
||||||
|
// We end up creating way more users than necessary!
|
||||||
var person ap.Person
|
var person ap.Person
|
||||||
err = person.UnmarshalJSON(b)
|
err = person.UnmarshalJSON(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -65,9 +65,9 @@ func Ticket(ctx *context.APIContext) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ticket.Name = ap.NaturalLanguageValuesNew()
|
|
||||||
// Setting a NaturalLanguageValue to a number causes go-ap's JSON parsing to do weird things
|
// Setting a NaturalLanguageValue to a number causes go-ap's JSON parsing to do weird things
|
||||||
// Workaround: set it to #1 instead of 1
|
// Workaround: set it to #1 instead of 1
|
||||||
|
ticket.Name = ap.NaturalLanguageValuesNew()
|
||||||
err = ticket.Name.Set("en", ap.Content("#"+ctx.Params("id")))
|
err = ticket.Name.Set("en", ap.Content("#"+ctx.Params("id")))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("Set Name", err)
|
ctx.ServerError("Set Name", err)
|
||||||
|
|
|
@ -83,7 +83,7 @@ func RepositoryIRIToRepository(ctx context.Context, repoIRI ap.IRI) (*repo_model
|
||||||
func TicketIRIToName(ticketIRI ap.IRI) (string, string, int64, error) {
|
func TicketIRIToName(ticketIRI ap.IRI) (string, string, int64, error) {
|
||||||
ticketIRISplit := strings.Split(ticketIRI.String(), "/")
|
ticketIRISplit := strings.Split(ticketIRI.String(), "/")
|
||||||
if len(ticketIRISplit) < 5 {
|
if len(ticketIRISplit) < 5 {
|
||||||
return "", "", 0, errors.New("not a Ticket actor IRI")
|
return "", "", 0, errors.New("not a Ticket object IRI")
|
||||||
}
|
}
|
||||||
|
|
||||||
instance := ticketIRISplit[2]
|
instance := ticketIRISplit[2]
|
||||||
|
@ -100,3 +100,22 @@ func TicketIRIToName(ticketIRI ap.IRI) (string, string, int64, error) {
|
||||||
// Remote repo
|
// Remote repo
|
||||||
return username + "@" + instance, reponame, idx, nil
|
return username + "@" + instance, reponame, idx, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the owner, repo name, and idx of a Branch object IRI
|
||||||
|
func BranchIRIToName(ticketIRI ap.IRI) (string, string, string, error) {
|
||||||
|
ticketIRISplit := strings.Split(ticketIRI.String(), "/")
|
||||||
|
if len(ticketIRISplit) < 5 {
|
||||||
|
return "", "", "", errors.New("not a Branch object IRI")
|
||||||
|
}
|
||||||
|
|
||||||
|
instance := ticketIRISplit[2]
|
||||||
|
username := ticketIRISplit[len(ticketIRISplit)-3]
|
||||||
|
reponame := ticketIRISplit[len(ticketIRISplit)-2]
|
||||||
|
branch := ticketIRISplit[len(ticketIRISplit)-1]
|
||||||
|
if instance == setting.Domain {
|
||||||
|
// Local repo
|
||||||
|
return username, reponame, branch, nil
|
||||||
|
}
|
||||||
|
// Remote repo
|
||||||
|
return username + "@" + instance, reponame, branch, nil
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue