diff --git a/modules/activitypub/authorize_interaction.go b/modules/activitypub/authorize_interaction.go index 751f267ade..77fd16ceca 100644 --- a/modules/activitypub/authorize_interaction.go +++ b/modules/activitypub/authorize_interaction.go @@ -14,45 +14,45 @@ import ( ap "github.com/go-ap/activitypub" ) -func AuthorizeInteraction(c *context.Context) { - uri, err := url.Parse(c.Req.URL.Query().Get("uri")) +func AuthorizeInteraction(ctx *context.Context) { + uri, err := url.Parse(ctx.Req.URL.Query().Get("uri")) if err != nil { - c.ServerError("Could not parse URI", err) + ctx.ServerError("Could not parse URI", err) return } resp, err := Fetch(uri) if err != nil { - c.ServerError("Fetch", err) + ctx.ServerError("Fetch", err) return } ap.ItemTyperFunc = forgefed.GetItemByType object, err := ap.UnmarshalJSON(resp) if err != nil { - c.ServerError("UnmarshalJSON", err) + ctx.ServerError("UnmarshalJSON", err) return } switch object.GetType() { case ap.PersonType: if err != nil { - c.ServerError("UnmarshalJSON", err) + ctx.ServerError("UnmarshalJSON", err) return } - err = FederatedUserNew(c, object.(ap.Person)) + err = FederatedUserNew(ctx, object.(ap.Person)) if err != nil { - c.ServerError("FederatedUserNew", err) + ctx.ServerError("FederatedUserNew", err) return } name, err := personIRIToName(object.GetLink()) if err != nil { - c.ServerError("personIRIToName", err) + ctx.ServerError("personIRIToName", err) return } - c.Redirect(name) + ctx.Redirect(name) case forgefed.RepositoryType: - err = FederatedRepoNew(object.(forgefed.Repository)) + err = FederatedRepoNew(ctx, object.(forgefed.Repository)) } - c.Status(http.StatusOK) + ctx.Status(http.StatusOK) } diff --git a/modules/activitypub/iri.go b/modules/activitypub/iri.go index 235545cd20..592c269136 100644 --- a/modules/activitypub/iri.go +++ b/modules/activitypub/iri.go @@ -77,3 +77,15 @@ func repositoryIRIToRepository(ctx context.Context, repoIRI ap.IRI) (*repo_model // TODO: create remote repo if not exists return repo_model.GetRepositoryByOwnerAndName(username, reponame) } + +// Returns the IRI of the owner of a Repository actor IRI +func repositoryIRIToOwnerIRI(repoIRI ap.IRI) (ap.IRI, error) { + r := repoIRI.String() + rSplit := strings.Split(r, "/") + if len(rSplit) < 5 { + return "", errors.New("Not a Repository actor IRI") + } + username := rSplit[len(rSplit)-2] + reponame := rSplit[len(rSplit)-1] + return ap.IRI(strings.TrimSuffix(r, "repo/"+username+"/"+reponame)+"user/"+username), nil +} diff --git a/modules/activitypub/repo.go b/modules/activitypub/repo.go index 6f4f066f89..fd44445400 100644 --- a/modules/activitypub/repo.go +++ b/modules/activitypub/repo.go @@ -5,19 +5,36 @@ package activitypub import ( - //"code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/forgefed" - /*repo_model "code.gitea.io/gitea/models/repo" - user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/repository" + "context" - ap "github.com/go-ap/activitypub"*/ + "code.gitea.io/gitea/models" + repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/modules/forgefed" ) -func FederatedRepoNew(repo forgefed.Repository) error { - // TODO: also handle forks - /*_, err := repository.CreateRepository(user, user, models.CreateRepoOptions{ - Name: repo.Name.String(), - })*/ - return nil +// Create a new federated repo from a Repository object +func FederatedRepoNew(ctx context.Context, repository forgefed.Repository) error { + ownerIRI, err := repositoryIRIToOwnerIRI(repository.GetLink()) + if err != nil { + return err + } + user, err := personIRIToUser(ctx, ownerIRI) + if err != nil { + return err + } + + repo := repo_model.Repository{ + Name: repository.Name.String(), + } + if repository.ForkedFrom != nil { + repo.IsFork = true + forkedFrom, err := repositoryIRIToRepository(ctx, repository.ForkedFrom.GetLink()) + if err != nil { + return err + } + repo.ForkID = forkedFrom.ID + } + + // TODO: Check if repo already exists + return models.CreateRepository(ctx, user, user, &repo, false) } diff --git a/modules/activitypub/user.go b/modules/activitypub/user.go index 8681c72768..196c031977 100644 --- a/modules/activitypub/user.go +++ b/modules/activitypub/user.go @@ -15,6 +15,7 @@ import ( ap "github.com/go-ap/activitypub" ) +// Create a new federated user from a Person object func FederatedUserNew(ctx context.Context, person ap.Person) error { name, err := personIRIToName(person.GetLink()) if err != nil {