diff --git a/routers/api/v1/activitypub/follow.go b/routers/api/v1/activitypub/follow.go index e2ebe14852..ca04486853 100644 --- a/routers/api/v1/activitypub/follow.go +++ b/routers/api/v1/activitypub/follow.go @@ -6,6 +6,7 @@ package activitypub import ( "context" + "errors" "strings" user_model "code.gitea.io/gitea/models/user" @@ -47,9 +48,9 @@ func follow(ctx context.Context, follow ap.Follow) error { // Process an incoming Undo follow activity func unfollow(ctx context.Context, unfollow ap.Undo) error { // Object contains the follow - follow, err := ap.To[ap.Follow](unfollow.Object) - if err != nil { - return err + follow, ok := unfollow.Object.(*ap.Follow) + if !ok { + return errors.New("could not cast object to follow") } // Actor is the user performing the undo follow diff --git a/routers/api/v1/activitypub/reqsignature.go b/routers/api/v1/activitypub/reqsignature.go index 345a4877e0..644bf16cb8 100644 --- a/routers/api/v1/activitypub/reqsignature.go +++ b/routers/api/v1/activitypub/reqsignature.go @@ -112,13 +112,16 @@ func checkActivityAndKeyID(activity ap.Activity, keyID string) error { 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 - }) + if activity.Type == ap.UndoType { + 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 + }) + } + return nil } diff --git a/routers/api/v1/activitypub/star.go b/routers/api/v1/activitypub/star.go index 30959b25c1..8f653dbe47 100644 --- a/routers/api/v1/activitypub/star.go +++ b/routers/api/v1/activitypub/star.go @@ -6,6 +6,7 @@ package activitypub import ( "context" + "errors" "strings" repo_model "code.gitea.io/gitea/models/repo" @@ -29,9 +30,9 @@ func star(ctx context.Context, like ap.Like) (err error) { // 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 + like, ok := unlike.Object.(*ap.Like) + if !ok { + return errors.New("could not cast object to like") } user, err := activitypub.PersonIRIToUser(ctx, like.Actor.GetLink()) if err != nil { diff --git a/services/activitypub/activities.go b/services/activitypub/activities.go index 177ae30e5c..5a8fd3894b 100644 --- a/services/activitypub/activities.go +++ b/services/activitypub/activities.go @@ -16,7 +16,6 @@ import ( func Follow(actorUser, followUser *user_model.User) (follow *ap.Follow) { object := ap.PersonNew(ap.IRI(followUser.LoginName)) 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 @@ -24,11 +23,8 @@ func Follow(actorUser, followUser *user_model.User) (follow *ap.Follow) { // Create Undo Follow activity 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.Type = ap.UndoType + unfollow = ap.UndoNew("", Follow(actorUser, followUser)) + unfollow.Actor = ap.PersonNew(ap.IRI(actorUser.GetIRI())) unfollow.To = ap.ItemCollection{ap.Item(ap.IRI(followUser.LoginName + "/inbox"))} return } @@ -40,3 +36,11 @@ func Star(user *user_model.User, repo *repo_model.Repository) (like *ap.Like) { like.To = ap.ItemCollection{ap.IRI(repo.GetIRI() + "/inbox")} return } + +// Create Undo Like activity +func Unstar(user *user_model.User, repo *repo_model.Repository) (unstar *ap.Undo) { + unstar = ap.UndoNew("", Star(user, repo)) + unstar.Actor = ap.PersonNew(ap.IRI(user.GetIRI())) + unstar.To = ap.ItemCollection{ap.IRI(repo.GetIRI() + "/inbox")} + return +} diff --git a/services/repository/star.go b/services/repository/star.go index 748a910384..7ff98a175b 100644 --- a/services/repository/star.go +++ b/services/repository/star.go @@ -5,11 +5,13 @@ package repository import ( "context" - "strings" + "code.gitea.io/gitea/models/auth" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/services/activitypub" + + ap "github.com/go-ap/activitypub" ) // StarRepo or unstar repository. @@ -18,13 +20,23 @@ func StarRepo(ctx context.Context, userID, repoID int64, star bool) error { if err != nil { return err } - if strings.Contains(repo.Name, "@") { + err = repo.GetOwner(ctx) + if err != nil { + return err + } + if repo.Owner.LoginType == auth.Federated { // Federated repo user, err := user_model.GetUserByID(ctx, userID) if err != nil { return err } - err = activitypub.Send(user, activitypub.Star(user, repo)) + var activity *ap.Activity + if star { + activity = activitypub.Star(user, repo) + } else { + activity = activitypub.Unstar(user, repo) + } + err = activitypub.Send(user, activity) if err != nil { return err }