diff --git a/models/forgefed/activity.go b/models/forgefed/activity.go index 0820bf5ea6..491a938bd5 100644 --- a/models/forgefed/activity.go +++ b/models/forgefed/activity.go @@ -26,9 +26,13 @@ func (s *ForgeLike) UnmarshalJSON(data []byte) error { func (s ForgeLike) Validate() []string { var result []string result = append(result, validation.ValidateNotEmpty(string(s.Type), "type")...) + result = append(result, validation.ValidateOneOf(string(s.Type), []any{"Like"})...) result = append(result, validation.ValidateNotEmpty(s.Actor.GetID().String(), "actor")...) result = append(result, validation.ValidateNotEmpty(s.Object.GetID().String(), "object")...) result = append(result, validation.ValidateNotEmpty(s.StartTime.String(), "startTime")...) + if s.StartTime.IsZero() { + result = append(result, "StartTime was invalid.") + } return result } diff --git a/models/forgefed/activity_test.go b/models/forgefed/activity_test.go index cc82c1b8b4..982ed82eec 100644 --- a/models/forgefed/activity_test.go +++ b/models/forgefed/activity_test.go @@ -7,6 +7,7 @@ import ( "reflect" "testing" + "code.gitea.io/gitea/modules/validation" ap "github.com/go-ap/activitypub" ) @@ -82,3 +83,37 @@ func Test_StarUnmarshalJSON(t *testing.T) { }) } } + +func TestAcivityValidation(t *testing.T) { + sut := new(ForgeLike) + sut.UnmarshalJSON([]byte(`{"type":"Like", + "actor":"https://repo.prod.meissa.de/api/activitypub/user-id/1", + "object":"https://codeberg.org/api/activitypub/repository-id/1", + "startTime": "2014-12-31T23:00:00-08:00"}`)) + if res, _ := validation.IsValid(sut); !res { + t.Errorf("sut expected to be valid: %v\n", sut.Validate()) + } + + sut.UnmarshalJSON([]byte(`{"actor":"https://repo.prod.meissa.de/api/activitypub/user-id/1", + "object":"https://codeberg.org/api/activitypub/repository-id/1", + "startTime": "2014-12-31T23:00:00-08:00"}`)) + if sut.Validate()[0] != "Field type may not be empty" { + t.Errorf("validation error expected but was: %v\n", sut.Validate()) + } + + sut.UnmarshalJSON([]byte(`{"type":"bad-type", + "actor":"https://repo.prod.meissa.de/api/activitypub/user-id/1", + "object":"https://codeberg.org/api/activitypub/repository-id/1", + "startTime": "2014-12-31T23:00:00-08:00"}`)) + if sut.Validate()[0] != "Value bad-type is not contained in allowed values [[Like]]" { + t.Errorf("validation error expected but was: %v\n", sut.Validate()) + } + + sut.UnmarshalJSON([]byte(`{"type":"Like", + "actor":"https://repo.prod.meissa.de/api/activitypub/user-id/1", + "object":"https://codeberg.org/api/activitypub/repository-id/1", + "startTime": "not a date"}`)) + if sut.Validate()[0] != "StartTime was invalid." { + t.Errorf("validation error expected but was: %v\n", sut.Validate()) + } +} diff --git a/routers/api/v1/activitypub/repository.go b/routers/api/v1/activitypub/repository.go index 1d94560127..765ab01fcc 100644 --- a/routers/api/v1/activitypub/repository.go +++ b/routers/api/v1/activitypub/repository.go @@ -21,6 +21,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/validation" "code.gitea.io/gitea/modules/web" "github.com/google/uuid" @@ -85,7 +86,11 @@ func RepositoryInbox(ctx *context.APIContext) { log.Info("RepositoryInbox: repo: %v", repository) activity := web.GetForm(ctx).(*forgefed.ForgeLike) - log.Info("RepositoryInbox: activity:%v", activity) + if res, err := validation.IsValid(activity); !res { + ctx.ServerError("Validate activity", err) + return + } + log.Info("RepositoryInbox: activity validated:%v", activity) // parse actorID (person) actorUri := activity.Actor.GetID().String()