From 30b431da49a3aa80a960aeb9e4e86a00e7a0d72a Mon Sep 17 00:00:00 2001 From: Anthony Wang Date: Mon, 25 Jul 2022 15:43:20 -0500 Subject: [PATCH] Set ap.ItemTyperFunc to correctly unmarshal JSON --- cmd/serv.go | 2 +- modules/activitypub/authorize_interaction.go | 27 +++++-------- modules/activitypub/repo.go | 16 ++++---- modules/activitypub/user.go | 2 +- routers/api/v1/activitypub/repo.go | 42 +++++++------------- routers/web/admin/auths.go | 2 +- 6 files changed, 37 insertions(+), 54 deletions(-) diff --git a/cmd/serv.go b/cmd/serv.go index b00c3962f..023744132 100644 --- a/cmd/serv.go +++ b/cmd/serv.go @@ -90,7 +90,7 @@ var ( "git-receive-pack": perm.AccessModeWrite, lfsAuthenticateVerb: perm.AccessModeNone, } - alphaDashDotPattern = regexp.MustCompile(`[^\w-\.]`) + alphaDashDotPattern = regexp.MustCompile(`[^\w-\.@]`) ) func fail(userMessage, logMessage string, args ...interface{}) error { diff --git a/modules/activitypub/authorize_interaction.go b/modules/activitypub/authorize_interaction.go index af783d895..61a63f7c2 100644 --- a/modules/activitypub/authorize_interaction.go +++ b/modules/activitypub/authorize_interaction.go @@ -8,8 +8,8 @@ import ( "net/http" "net/url" + "code.gitea.io/gitea/models/forgefed" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/json" ap "github.com/go-ap/activitypub" ) @@ -26,37 +26,32 @@ func AuthorizeInteraction(c *context.Context) { return } - var object map[string]interface{} - err = json.Unmarshal(resp, &object) + ap.ItemTyperFunc = forgefed.GetItemByType + object, err := ap.UnmarshalJSON(resp) if err != nil { - c.ServerError("Unmarshal", err) + c.ServerError("UnmarshalJSON", err) return } - switch object["type"] { - case "Person": - var person ap.Person - err = person.UnmarshalJSON(resp) + + switch object.GetType() { + case ap.PersonType: if err != nil { c.ServerError("UnmarshalJSON", err) return } - err = FederatedUserNew(c, person) + err = FederatedUserNew(c, object.(ap.Person)) if err != nil { c.ServerError("FederatedUserNew", err) return } - name, err := personIRIToName(person.GetLink()) + name, err := personIRIToName(object.GetLink()) if err != nil { c.ServerError("personIRIToName", err) return } c.Redirect(name) - /*case "organization": - // Do something idk - case "repository": - FederatedRepoNew() // TODO - case "ticket": - // TODO*/ + case forgefed.RepositoryType: + err = FederatedRepoNew(object.(forgefed.Repository)) } c.Status(http.StatusOK) diff --git a/modules/activitypub/repo.go b/modules/activitypub/repo.go index a52a4d155..821cfd896 100644 --- a/modules/activitypub/repo.go +++ b/modules/activitypub/repo.go @@ -5,17 +5,19 @@ package activitypub import ( - "code.gitea.io/gitea/models" - repo_model "code.gitea.io/gitea/models/repo" + //"code.gitea.io/gitea/models" + "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/repository" - ap "github.com/go-ap/activitypub" + ap "github.com/go-ap/activitypub"*/ ) -func FederatedRepoNew(user *user_model.User, name string, iri ap.IRI) (*repo_model.Repository, error) { +func FederatedRepoNew(repo forgefed.Repository) error { // TODO: also handle forks - return repository.CreateRepository(user, user, models.CreateRepoOptions{ - Name: name, - }) + /*_, err := repository.CreateRepository(user, user, models.CreateRepoOptions{ + Name: repo.Name.String(), + })*/ + return nil } diff --git a/modules/activitypub/user.go b/modules/activitypub/user.go index 5e1a8583b..8681c7276 100644 --- a/modules/activitypub/user.go +++ b/modules/activitypub/user.go @@ -48,7 +48,7 @@ func FederatedUserNew(ctx context.Context, person ap.Person) error { user := &user_model.User{ Name: name, - FullName: person.Name.String(), + FullName: person.Name.String(), // May not exist!! Email: email, Avatar: avatar, LoginType: auth.Federated, diff --git a/routers/api/v1/activitypub/repo.go b/routers/api/v1/activitypub/repo.go index 34dc5f223..73a85605a 100644 --- a/routers/api/v1/activitypub/repo.go +++ b/routers/api/v1/activitypub/repo.go @@ -12,7 +12,6 @@ import ( "code.gitea.io/gitea/models/forgefed" "code.gitea.io/gitea/modules/activitypub" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" @@ -96,51 +95,40 @@ func RepoInbox(ctx *context.APIContext) { return } - var activity map[string]interface{} - err = json.Unmarshal(body, activity) + ap.ItemTyperFunc = forgefed.GetItemByType + var activity ap.Activity + err = activity.UnmarshalJSON(body) if err != nil { - ctx.ServerError("Unmarshal", err) + ctx.ServerError("UnmarshalJSON", err) return } // Make sure keyID matches the user doing the activity _, keyID, _ := getKeyID(ctx.Req) - actor, ok := activity["actor"] - if ok && !strings.HasPrefix(keyID, actor.(string)) { + if activity.Actor != nil && !strings.HasPrefix(keyID, activity.Actor.GetID().String()) { ctx.ServerError("Actor does not match HTTP signature keyID", nil) return } - attributedTo, ok := activity["attributedTo"] - if ok && !strings.HasPrefix(keyID, attributedTo.(string)) { + if activity.AttributedTo != nil && !strings.HasPrefix(keyID, activity.AttributedTo.GetID().String()) { ctx.ServerError("AttributedTo does not match HTTP signature keyID", nil) return } // Process activity - switch activity["type"].(ap.ActivityVocabularyType) { + switch activity.Type { case ap.CreateType: - // Create activity, extract the object - object, ok := activity["object"].(map[string]interface{}) - if ok { - ctx.ServerError("Create activity does not contain object", err) - return - } - objectBinary, err := json.Marshal(object) - if err != nil { - ctx.ServerError("Marshal", err) + if activity.Object == nil { + ctx.ServerError("Activity does not contain object", err) return } - switch object["type"].(ap.ActivityVocabularyType) { + switch activity.Object.(ap.Object).Type { case forgefed.RepositoryType: // Fork created by remote instance - var repository forgefed.Repository - repository.UnmarshalJSON(objectBinary) - activitypub.ForkFromCreate(ctx, repository) + activitypub.ForkFromCreate(ctx, activity.Object.(forgefed.Repository)) case forgefed.TicketType: // New issue or pull request - var ticket forgefed.Ticket - ticket.UnmarshalJSON(objectBinary) + ticket := activity.Object.(forgefed.Ticket) if ticket.Origin != nil { // New pull request activitypub.PullRequest(ctx, ticket) @@ -150,12 +138,10 @@ func RepoInbox(ctx *context.APIContext) { } case ap.NoteType: // New comment - var note ap.Note - note.UnmarshalJSON(objectBinary) - activitypub.Comment(ctx, note) + activitypub.Comment(ctx, activity.Object.(ap.Note)) } default: - log.Info("Incoming unsupported ActivityStreams type: %s", activity["type"]) + log.Info("Incoming unsupported ActivityStreams type: %s", activity.Type) ctx.PlainText(http.StatusNotImplemented, "ActivityStreams type not supported") return } diff --git a/routers/web/admin/auths.go b/routers/web/admin/auths.go index 7ea8a5280..dd6edbd0f 100644 --- a/routers/web/admin/auths.go +++ b/routers/web/admin/auths.go @@ -39,7 +39,7 @@ const ( ) var ( - separatorAntiPattern = regexp.MustCompile(`[^\w-\.]`) + separatorAntiPattern = regexp.MustCompile(`[^\w-\.@]`) langCodePattern = regexp.MustCompile(`^[a-z]{2}-[A-Z]{2}$`) )