Changes
8 changed files (+114/-41)
-
-
@@ -16,7 +16,6 @@ import ("code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/forgefed" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/routers/api/v1/utils" "code.gitea.io/gitea/services/activitypub"
-
@@ -117,21 +116,19 @@ func PersonInbox(ctx *context.APIContext) {// Make sure keyID matches the user doing the activity _, keyID, _ := getKeyID(ctx.Req) if activity.Actor != nil && !strings.HasPrefix(keyID, activity.Actor.GetLink().String()) { ctx.ServerError("Actor does not match HTTP signature keyID", nil) return } if activity.AttributedTo != nil && !strings.HasPrefix(keyID, activity.AttributedTo.GetLink().String()) { ctx.ServerError("AttributedTo does not match HTTP signature keyID", nil) err = checkActivityAndKeyID(activity, keyID) if err != nil { ctx.ServerError("keyID does not match activity", err) return } // TODO: Check activity.Object actor and attributedTo // Process activity switch activity.Type { case ap.FollowType: // Following a user err = follow(ctx, activity) case ap.UndoType: // Unfollowing a user err = unfollow(ctx, activity) case ap.CreateType: // TODO: this is kinda a hack
-
@@ -142,9 +139,7 @@ func PersonInbox(ctx *context.APIContext) {return createComment(ctx, n) }) default: log.Info("Incoming unsupported ActivityStreams type: %s", activity.GetType()) ctx.PlainText(http.StatusNotImplemented, "ActivityStreams type not supported") return err = fmt.Errorf("unsupported ActivityStreams activity type: %s", activity.GetType()) } if err != nil { ctx.ServerError("Could not process activity", err)
-
-
-
@@ -5,13 +5,13 @@package activitypub import ( "fmt" "io" "net/http" "strings" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/forgefed" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" ap "github.com/go-ap/activitypub" )
-
@@ -87,7 +87,7 @@ func RepoInbox(ctx *context.APIContext) {// "204": // "$ref": "#/responses/empty" body, err := io.ReadAll(ctx.Req.Body) body, err := io.ReadAll(io.LimitReader(ctx.Req.Body, setting.Federation.MaxSize)) if err != nil { ctx.ServerError("Error reading request body", err) return
-
@@ -105,17 +105,9 @@ func RepoInbox(ctx *context.APIContext) {// Make sure keyID matches the user doing the activity _, keyID, _ := getKeyID(ctx.Req) if activity.Actor != nil && !strings.HasPrefix(keyID, activity.Actor.GetLink().String()) { ctx.ServerError("Actor does not match HTTP signature keyID", nil) return } if activity.AttributedTo != nil && !strings.HasPrefix(keyID, activity.AttributedTo.GetLink().String()) { ctx.ServerError("AttributedTo does not match HTTP signature keyID", nil) return } if activity.Object == nil { ctx.ServerError("Activity does not contain object", err) err = checkActivityAndKeyID(activity, keyID) if err != nil { ctx.ServerError("keyID does not match activity", err) return }
-
@@ -139,18 +131,20 @@ func RepoInbox(ctx *context.APIContext) {return createComment(ctx, n) }) default: log.Info("Incoming unsupported ActivityStreams object type: %s", activity.Object.GetType()) ctx.PlainText(http.StatusNotImplemented, "ActivityStreams object type not supported") return err = fmt.Errorf("unsupported ActivityStreams object type: %s", activity.Object.GetType()) } case ap.LikeType: // Starring a repo err = star(ctx, activity) case ap.UndoType: // Unstarring a repo err = unstar(ctx, activity) default: ctx.PlainText(http.StatusNotImplemented, "ActivityStreams type not supported") return err = fmt.Errorf("unsupported ActivityStreams activity type: %s", activity.GetType()) } if err != nil { ctx.ServerError("Error when processing", err) ctx.ServerError("Could not process activity", err) return } ctx.Status(http.StatusNoContent)
-
-
-
@@ -7,6 +7,7 @@ import ("crypto" "crypto/x509" "encoding/pem" "errors" "fmt" "net/http" "net/url"
-
@@ -99,3 +100,25 @@ func ReqHTTPSignature() func(ctx *gitea_context.APIContext) {} } } // Check if the keyID matches the activity to prevent impersonation func checkActivityAndKeyID(activity ap.Activity, keyID string) error { if activity.Actor != nil && keyID != activity.Actor.GetLink().String() + "#main-key" { return errors.New("actor does not match HTTP signature keyID") } if activity.AttributedTo != nil && keyID != activity.AttributedTo.GetLink().String() + "#main-key" { return errors.New("attributedTo does not match HTTP signature keyID") } if activity.Object == nil { return errors.New("activity does not contain object") } return ap.OnActivity(activity.Object, func(a *ap.Activity) error { if a.Actor != nil && keyID != a.Actor.GetLink().String() + "#main-key" { return errors.New("actor does not match HTTP signature keyID") } if a.AttributedTo != nil && keyID != a.AttributedTo.GetLink().String() + "#main-key" { return errors.New("attributedTo does not match HTTP signature keyID") } return nil }) }
-
-
-
@@ -26,3 +26,20 @@ func star(ctx context.Context, like ap.Like) (err error) {} return repo_model.StarRepo(user.ID, repo.ID, true) } // Process an Undo Like activity to unstar a repository func unstar(ctx context.Context, unlike ap.Undo) (err error) { like, err := ap.To[ap.Like](unlike.Object) if err != nil { return err } user, err := activitypub.PersonIRIToUser(ctx, like.Actor.GetLink()) if err != nil { return } repo, err := activitypub.RepositoryIRIToRepository(ctx, like.Object.GetLink()) if err != nil || strings.Contains(repo.Name, "@") || repo.IsPrivate { return } return repo_model.StarRepo(user.ID, repo.ID, false) }
-
-
-
@@ -16,6 +16,7 @@ import ("code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/routers/api/v1/utils" repo_service "code.gitea.io/gitea/services/repository" ) // getStarredRepos returns the repos that the user with the specified userID has
-
@@ -151,7 +152,7 @@ func Star(ctx *context.APIContext) {// "204": // "$ref": "#/responses/empty" err := repo_model.StarRepo(ctx.Doer.ID, ctx.Repo.Repository.ID, true) err := repo_service.StarRepo(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID, true) if err != nil { ctx.Error(http.StatusInternalServerError, "StarRepo", err) return
-
@@ -179,7 +180,7 @@ func Unstar(ctx *context.APIContext) {// "204": // "$ref": "#/responses/empty" err := repo_model.StarRepo(ctx.Doer.ID, ctx.Repo.Repository.ID, false) err := repo_service.StarRepo(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID, false) if err != nil { ctx.Error(http.StatusInternalServerError, "StarRepo", err) return
-
-
-
@@ -287,9 +287,9 @@ func Action(ctx *context.Context) {case "unwatch": err = repo_model.WatchRepo(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID, false) case "star": err = repo_model.StarRepo(ctx.Doer.ID, ctx.Repo.Repository.ID, true) err = repo_service.StarRepo(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID, true) case "unstar": err = repo_model.StarRepo(ctx.Doer.ID, ctx.Repo.Repository.ID, false) err = repo_service.StarRepo(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID, false) case "accept_transfer": err = acceptOrRejectRepoTransfer(ctx, true) case "reject_transfer":
-
-
-
@@ -5,28 +5,38 @@package activitypub import ( repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/forgefed" ap "github.com/go-ap/activitypub" ) // Create Follow activity func Follow(actorUser, followUser *user_model.User) *ap.Follow { func Follow(actorUser, followUser *user_model.User) (follow *ap.Follow) { object := ap.PersonNew(ap.IRI(followUser.LoginName)) follow := ap.FollowNew("", object) follow = ap.FollowNew("", object) follow.Type = ap.FollowType follow.Actor = ap.PersonNew(ap.IRI(actorUser.GetIRI())) follow.To = ap.ItemCollection{ap.Item(ap.IRI(followUser.LoginName + "/inbox"))} return follow return } // Create Undo Follow activity func Unfollow(actorUser, followUser *user_model.User) *ap.Undo { func Unfollow(actorUser, followUser *user_model.User) (unfollow *ap.Undo) { object := ap.PersonNew(ap.IRI(followUser.LoginName)) follow := ap.FollowNew("", object) follow.Actor = ap.PersonNew(ap.IRI(actorUser.GetIRI())) unfollow := ap.UndoNew("", follow) unfollow = ap.UndoNew("", follow) unfollow.Type = ap.UndoType unfollow.To = ap.ItemCollection{ap.Item(ap.IRI(followUser.LoginName + "/inbox"))} return unfollow return } // Create Like activity func Star(user *user_model.User, repo *repo_model.Repository) (like *ap.Like) { like = ap.LikeNew("", forgefed.RepositoryNew(ap.IRI(repo.GetIRI()))) like.Actor = ap.PersonNew(ap.IRI(user.GetIRI())) like.To = ap.ItemCollection{ap.IRI(repo.GetIRI() + "/inbox")} return }
-
-
-
@@ -0,0 +1,33 @@// Copyright 2016 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT package repository import ( "context" "strings" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/services/activitypub" ) // StarRepo or unstar repository. func StarRepo(ctx context.Context, userID, repoID int64, star bool) error { repo, err := repo_model.GetRepositoryByID(ctx, repoID) if err != nil { return err } if strings.Contains(repo.Name, "@") { // Federated repo user, err := user_model.GetUserByID(ctx, userID) if err != nil { return err } err = activitypub.Send(user, activitypub.Star(user, repo)) if err != nil { return err } } return repo_model.StarRepo(userID, repoID, star) }
-