diff options
author | Anthony Wang | 2022-04-13 21:49:27 -0500 |
---|---|---|
committer | Anthony Wang | 2022-04-13 21:49:27 -0500 |
commit | 790ea2d6ba7b09878750eed92238f84f5426eafc (patch) | |
tree | cd30ea20386c9a1046cb35038005ebdb2927b90b | |
parent | 7931e210e5ce37c4f9aa16033fd8b64b52fcfeb5 (diff) |
Implement outbox
-rw-r--r-- | modules/activitypub/client.go | 2 | ||||
-rw-r--r-- | modules/activitypub/database.go | 23 | ||||
-rw-r--r-- | modules/activitypub/fetch.go | 38 | ||||
-rw-r--r-- | modules/activitypub/follow.go | 12 | ||||
-rw-r--r-- | modules/activitypub/inbox.go | 19 | ||||
-rw-r--r-- | modules/activitypub/outbox.go | 46 | ||||
-rw-r--r-- | routers/api/v1/activitypub/reqsignature.go | 28 |
7 files changed, 140 insertions, 28 deletions
diff --git a/modules/activitypub/client.go b/modules/activitypub/client.go index a11284dbc..0e4998234 100644 --- a/modules/activitypub/client.go +++ b/modules/activitypub/client.go @@ -24,7 +24,7 @@ import ( const ( // ActivityStreamsContentType const ActivityStreamsContentType = `application/ld+json; profile="https://www.w3.org/ns/activitystreams"` - httpsigExpirationTime = 60 + httpsigExpirationTime = 60 ) func containsRequiredHTTPHeaders(method string, headers []string) error { diff --git a/modules/activitypub/database.go b/modules/activitypub/database.go new file mode 100644 index 000000000..383186ced --- /dev/null +++ b/modules/activitypub/database.go @@ -0,0 +1,23 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package activitypub + +import ( + user_model "code.gitea.io/gitea/models/user" + + "github.com/go-fed/activity/streams/vocab" +) + +func databaseAddToInbox(activity vocab.ActivityStreamsActivity) { +} + +func databaseAddToOutbox(activity vocab.ActivityStreamsActivity) { +} + +func GetInbox(user user_model.User) { +} + +func GetOutbox(user user_model.User) { +} diff --git a/modules/activitypub/fetch.go b/modules/activitypub/fetch.go new file mode 100644 index 000000000..17f5b551d --- /dev/null +++ b/modules/activitypub/fetch.go @@ -0,0 +1,38 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package activitypub + +import ( + "fmt" + "io" + "net/http" + "net/url" + "time" + + "code.gitea.io/gitea/modules/httplib" +) + +func Fetch(iri *url.URL) (b []byte, err error) { + req := httplib.NewRequest(iri.String(), http.MethodGet) + req.Header("Accept", ActivityStreamsContentType) + req.Header("Accept-Charset", "utf-8") + clock, err := NewClock() + if err != nil { + return + } + req.Header("Date", fmt.Sprintf("%s GMT", clock.Now().UTC().Format(time.RFC1123))) + resp, err := req.Response() + if err != nil { + return + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + err = fmt.Errorf("url IRI fetch [%s] failed with status (%d): %s", iri, resp.StatusCode, resp.Status) + return + } + b, err = io.ReadAll(resp.Body) + return +} diff --git a/modules/activitypub/follow.go b/modules/activitypub/follow.go new file mode 100644 index 000000000..42d9022ce --- /dev/null +++ b/modules/activitypub/follow.go @@ -0,0 +1,12 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package activitypub + +import ( + "github.com/go-fed/activity/streams/vocab" +) + +func follow(activity vocab.ActivityStreamsActivity) { +} diff --git a/modules/activitypub/inbox.go b/modules/activitypub/inbox.go new file mode 100644 index 000000000..0dfdd2651 --- /dev/null +++ b/modules/activitypub/inbox.go @@ -0,0 +1,19 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package activitypub + +import ( + "github.com/go-fed/activity/streams/vocab" +) + +// Add an activity to a user's inbox +func AddToInbox(activity vocab.ActivityStreamsActivity) { + databaseAddToInbox(activity) + + // Probably should use callbacks here + if activity.GetJSONLDType().Name() == "Follow" { + follow(activity) + } +} diff --git a/modules/activitypub/outbox.go b/modules/activitypub/outbox.go new file mode 100644 index 000000000..6f5e197b1 --- /dev/null +++ b/modules/activitypub/outbox.go @@ -0,0 +1,46 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package activitypub + +import ( + "context" + "strings" + + user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/json" + + "github.com/go-fed/activity/streams" + "github.com/go-fed/activity/streams/vocab" +) + +// Add an activity to a user's outbox +func AddToOutbox(activity vocab.ActivityStreamsActivity) { + databaseAddToOutbox(activity) + + actorIRI := activity.GetActivityStreamsActor().Begin().GetIRI() + + s := strings.Split(actorIRI.String(), ",") + user, _ := user_model.GetUserByName(s[len(s)-1]) + + to := activity.GetActivityStreamsTo().Begin().GetIRI() + fetched, _ := Fetch(to) + var m map[string]interface{} + json.Unmarshal(fetched, &m) + + var person vocab.ActivityStreamsPerson + resolver, _ := streams.NewJSONResolver(func(c context.Context, p vocab.ActivityStreamsPerson) error { + person = p + return nil + }) + ctx := context.Background() + _ = resolver.Resolve(ctx, m) + inboxIRI := person.GetActivityStreamsInbox().GetIRI().String() + + client, _ := NewClient(user, actorIRI.String()+"#main-key") + + jsonmap, _ := streams.Serialize(activity) + body, _ := json.Marshal(jsonmap) + client.Post(body, inboxIRI) +} diff --git a/routers/api/v1/activitypub/reqsignature.go b/routers/api/v1/activitypub/reqsignature.go index b9f665da1..abf34b2c1 100644 --- a/routers/api/v1/activitypub/reqsignature.go +++ b/routers/api/v1/activitypub/reqsignature.go @@ -10,14 +10,11 @@ import ( "crypto/x509" "encoding/pem" "fmt" - "io" "net/http" "net/url" - "time" "code.gitea.io/gitea/modules/activitypub" gitea_context "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/httplib" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/setting" @@ -88,29 +85,6 @@ func getPublicKeyFromResponse(ctx context.Context, b []byte, keyID *url.URL) (p return } -func fetch(iri *url.URL) (b []byte, err error) { - req := httplib.NewRequest(iri.String(), http.MethodGet) - req.Header("Accept", activitypub.ActivityStreamsContentType) - req.Header("Accept-Charset", "utf-8") - clock, err := activitypub.NewClock() - if err != nil { - return - } - req.Header("Date", fmt.Sprintf("%s GMT", clock.Now().UTC().Format(time.RFC1123))) - resp, err := req.Response() - if err != nil { - return - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - err = fmt.Errorf("url IRI fetch [%s] failed with status (%d): %s", iri, resp.StatusCode, resp.Status) - return - } - b, err = io.ReadAll(resp.Body) - return -} - func verifyHTTPSignatures(ctx *gitea_context.APIContext) (authenticated bool, err error) { r := ctx.Req @@ -125,7 +99,7 @@ func verifyHTTPSignatures(ctx *gitea_context.APIContext) (authenticated bool, er return } // 2. Fetch the public key of the other actor - b, err := fetch(idIRI) + b, err := activitypub.Fetch(idIRI) if err != nil { return } |