Changes
12 changed files (+88/-64)
-
-
@@ -13,7 +13,7 @@ const ForgeFedNamespaceURI = "https://forgefed.org/ns"// GetItemByType instantiates a new ForgeFed object if the type matches // otherwise it defaults to existing activitypub package typer function. func GetItemByType(typ ap.ActivityVocabularyType) (ap.Item, error) { switch typ { switch typ { case CommitType: return CommitNew(), nil case BranchType:
-
-
-
@@ -50,18 +50,18 @@ func (p Push) MarshalJSON() ([]byte, error) {return b, nil } func (c *Push) UnmarshalJSON(data []byte) error { p := fastjson.Parser{} val, err := p.ParseBytes(data) func (p *Push) UnmarshalJSON(data []byte) error { ps := fastjson.Parser{} val, err := ps.ParseBytes(data) if err != nil { return err } c.Target = ap.JSONGetItem(val, "target") c.HashBefore = ap.JSONGetItem(val, "hashBefore") c.HashAfter = ap.JSONGetItem(val, "hashAfter") p.Target = ap.JSONGetItem(val, "target") p.HashBefore = ap.JSONGetItem(val, "hashBefore") p.HashAfter = ap.JSONGetItem(val, "hashAfter") return ap.OnObject(&c.Object, func(a *ap.Object) error { return ap.OnObject(&p.Object, func(a *ap.Object) error { return ap.LoadObject(val, a) }) }
-
-
-
@@ -1,11 +1,12 @@package forgefed import ( "encoding/json" "fmt" "reflect" "testing" "code.gitea.io/gitea/modules/json" ap "github.com/go-ap/activitypub" )
-
-
-
@@ -22,38 +22,42 @@ func AuthorizeInteraction(c *context.Context) {} resp, err := Fetch(uri) if err != nil { c.ServerError("Could not fetch remote URI", err) c.ServerError("Fetch", err) return } var object map[string]interface{} err = json.Unmarshal(resp, &object) if err != nil { c.ServerError("Could not unmarshal response into JSON", err) c.ServerError("Unmarshal", err) return } switch object["type"] { case "Person": var person ap.Person person.UnmarshalJSON(resp) err = person.UnmarshalJSON(resp) if err != nil { c.ServerError("UnmarshalJSON", err) return } err = FederatedUserNew(c, person) /*if err != nil { c.ServerError("Could not create new federated user", err) if err != nil { c.ServerError("FederatedUserNew", err) return }*/ } name, err := personIRIToName(person.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 "organization": // Do something idk case "repository": FederatedRepoNew() // TODO case "ticket": // TODO*/ } c.Status(http.StatusOK) } }
-
-
-
@@ -11,17 +11,15 @@ import ("code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/log" ap "github.com/go-ap/activitypub" ) // Create a comment func Comment(ctx context.Context, note ap.Note) { func Comment(ctx context.Context, note ap.Note) error { actorUser, err := personIRIToUser(ctx, note.AttributedTo.GetLink()) if err != nil { log.Warn("Couldn't find actor", err) return return err } // TODO: Move IRI processing stuff to iri.go
-
@@ -33,10 +31,11 @@ func Comment(ctx context.Context, note ap.Note) {idx, _ := strconv.ParseInt(contextSplit[len(contextSplit)-1], 10, 64) issue, _ := issues.GetIssueByIndex(repo.ID, idx) issues.CreateCommentCtx(ctx, &issues.CreateCommentOptions{ _, err = issues.CreateCommentCtx(ctx, &issues.CreateCommentOptions{ Doer: actorUser, Repo: repo, Issue: issue, Content: note.Content.String(), }) return err }
-
-
-
@@ -9,19 +9,17 @@ import ("strings" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" ap "github.com/go-ap/activitypub" ) // Process a Follow activity func Follow(ctx context.Context, follow ap.Follow) { func Follow(ctx context.Context, follow ap.Follow) error { // Actor is the user performing the follow actorIRI := follow.Actor.GetID() actorUser, err := personIRIToUser(ctx, actorIRI) if err != nil { log.Warn("Couldn't find actor user for follow", err) return return err } // Object is the user being followed
-
@@ -29,29 +27,30 @@ func Follow(ctx context.Context, follow ap.Follow) {objectUser, err := personIRIToUser(ctx, objectIRI) // Must be a local user if err != nil || strings.Contains(objectUser.Name, "@") { log.Warn("Couldn't find object user for follow", err) return return err } user_model.FollowUser(actorUser.ID, objectUser.ID) err = user_model.FollowUser(actorUser.ID, objectUser.ID) if err != nil { return err } // Send back an Accept activity accept := ap.AcceptNew(objectIRI, follow) accept.Actor = ap.Person{ID: objectIRI} accept.To = ap.ItemCollection{ap.IRI(actorIRI.String() + "/inbox")} accept.Object = follow Send(objectUser, accept) return Send(objectUser, accept) } // Process a Undo follow activity func Unfollow(ctx context.Context, unfollow ap.Undo) { func Unfollow(ctx context.Context, unfollow ap.Undo) error { follow := unfollow.Object.(*ap.Follow) // Actor is the user performing the undo follow actorIRI := follow.Actor.GetID() actorUser, err := personIRIToUser(ctx, actorIRI) if err != nil { log.Warn("Couldn't find actor user for follow", err) return return err } // Object is the user being unfollowed
-
@@ -59,9 +58,8 @@ func Unfollow(ctx context.Context, unfollow ap.Undo) {objectUser, err := personIRIToUser(ctx, objectIRI) // Must be a local user if err != nil || strings.Contains(objectUser.Name, "@") { log.Warn("Couldn't find object user for follow", err) return return err } user_model.UnfollowUser(actorUser.ID, objectUser.ID) return user_model.UnfollowUser(actorUser.ID, objectUser.ID) }
-
-
-
@@ -19,7 +19,7 @@ import (ap "github.com/go-ap/activitypub" ) func Fork(ctx context.Context, instance, username, reponame, destUsername string) { func Fork(ctx context.Context, instance, username, reponame, destUsername string) error { // TODO: Clean this up // Migrate repository code
-
@@ -42,10 +42,10 @@ func Fork(ctx context.Context, instance, username, reponame, destUsername string// repo.ForkedFrom = forgefed.RepositoryNew(ap.IRI()) create.Object = repo Send(user, &create) return Send(user, &create) } func ForkFromCreate(ctx context.Context, repository forgefed.Repository) { func ForkFromCreate(ctx context.Context, repository forgefed.Repository) error { // TODO: Clean this up // Don't create an actual copy of the remote repo!
-
@@ -66,5 +66,5 @@ func ForkFromCreate(ctx context.Context, repository forgefed.Repository) {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) return err }
-
-
-
@@ -28,11 +28,10 @@ func personIRIToName(personIRI ap.IRI) (string, error) {if instance == setting.Domain { // Local user return name, nil } else { // Remote user // Get name in username@instance.com format return name + "@" + instance, nil } // Remote user // Get name in username@instance.com format return name + "@" + instance, nil } // Returns the user corresponding to a Person actor IRI
-
@@ -63,10 +62,9 @@ func repositoryIRIToName(repoIRI ap.IRI) (string, string, error) {if instance == setting.Domain { // Local repo return username, reponame, nil } else { // Remote repo return username + "@" + instance, reponame, nil } // Remote repo return username + "@" + instance, reponame, nil } // Returns the repository corresponding to a Repository actor IRI
-
-
-
@@ -13,7 +13,7 @@ import (ap "github.com/go-ap/activitypub" ) func FederatedRepoNew(user *user_model.User, name string, IRI ap.IRI) (*repo_model.Repository, error) { func FederatedRepoNew(user *user_model.User, name string, iri ap.IRI) (*repo_model.Repository, error) { // TODO: also handle forks return repository.CreateRepository(user, user, models.CreateRepoOptions{ Name: name,
-
-
-
@@ -40,15 +40,14 @@ func Fetch(iri *url.URL) (b []byte, err error) {} // Send an activity func Send(user *user_model.User, activity *ap.Activity) { func Send(user *user_model.User, activity *ap.Activity) error { binary, err := jsonld.WithContext( jsonld.IRI(ap.ActivityBaseURI), jsonld.IRI(ap.SecurityContextURI), jsonld.IRI(forgefed.ForgeFedNamespaceURI), ).Marshal(activity) if err != nil { log.Warn("Marshal", err) return return err } for _, to := range activity.To {
-
@@ -57,4 +56,5 @@ func Send(user *user_model.User, activity *ap.Activity) {respBody, _ := io.ReadAll(io.LimitReader(resp.Body, setting.Federation.MaxSize)) log.Trace("Response from sending activity", string(respBody)) } return err }
-
-
-
@@ -129,14 +129,18 @@ func PersonInbox(ctx *context.APIContext) {// Process activity switch activity.Type { case ap.FollowType: activitypub.Follow(ctx, activity) err = activitypub.Follow(ctx, activity) case ap.UndoType: activitypub.Unfollow(ctx, activity) err = activitypub.Unfollow(ctx, activity) default: log.Info("Incoming unsupported ActivityStreams type: %s", activity.GetType()) ctx.PlainText(http.StatusNotImplemented, "ActivityStreams type not supported") return } if err != nil { ctx.ServerError("Could not process activity", err) return } ctx.Status(http.StatusNoContent) }
-
@@ -180,7 +184,11 @@ func PersonOutbox(ctx *context.APIContext) {object := ap.Note{Type: ap.NoteType, Content: ap.NaturalLanguageValuesNew()} object.Content.Set("en", ap.Content(action.GetRepoName())) create := ap.Create{Type: ap.CreateType, Object: object} outbox.OrderedItems.Append(create) err := outbox.OrderedItems.Append(create) if err != nil { ctx.ServerError("OrderedItems.Append", err) return } } }
-
@@ -194,7 +202,11 @@ func PersonOutbox(ctx *context.APIContext) {object := ap.Note{Type: ap.NoteType, Content: ap.NaturalLanguageValuesNew()} object.Content.Set("en", ap.Content("Starred "+star.Name)) create := ap.Create{Type: ap.CreateType, Object: object} outbox.OrderedItems.Append(create) err := outbox.OrderedItems.Append(create) if err != nil { ctx.ServerError("OrderedItems.Append", err) return } } outbox.TotalItems = uint(len(outbox.OrderedItems))
-
@@ -233,7 +245,11 @@ func PersonFollowing(ctx *context.APIContext) {for _, user := range users { // TODO: handle non-Federated users person := ap.PersonNew(ap.IRI(user.Website)) following.OrderedItems.Append(person) err := following.OrderedItems.Append(person) if err != nil { ctx.ServerError("OrderedItems.Append", err) return } } response(ctx, following)
-
@@ -270,7 +286,11 @@ func PersonFollowers(ctx *context.APIContext) {for _, user := range users { // TODO: handle non-Federated users person := ap.PersonNew(ap.IRI(user.Website)) followers.OrderedItems.Append(person) err := followers.OrderedItems.Append(person) if err != nil { ctx.ServerError("OrderedItems.Append", err) return } } response(ctx, followers)
-
@@ -311,7 +331,11 @@ func PersonLiked(ctx *context.APIContext) {for _, repo := range repos { // TODO: Handle remote starred repos repo := forgefed.RepositoryNew(ap.IRI(setting.AppURL + "api/v1/activitypub/repo/" + repo.OwnerName + "/" + repo.Name)) liked.OrderedItems.Append(repo) err := liked.OrderedItems.Append(repo) if err != nil { ctx.ServerError("OrderedItems.Append", err) return } } response(ctx, liked)
-
-
-
@@ -81,7 +81,7 @@ func verifyHTTPSignatures(ctx *gitea_context.APIContext) (authenticated bool, ervar person ap.Person person.UnmarshalJSON(b) err = activitypub.FederatedUserNew(ctx, person) return return authenticated, err } // ReqHTTPSignature function
-