aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony Wang2022-04-13 21:49:27 -0500
committerAnthony Wang2022-04-13 21:49:27 -0500
commit790ea2d6ba7b09878750eed92238f84f5426eafc (patch)
treecd30ea20386c9a1046cb35038005ebdb2927b90b
parent7931e210e5ce37c4f9aa16033fd8b64b52fcfeb5 (diff)
Implement outbox
-rw-r--r--modules/activitypub/client.go2
-rw-r--r--modules/activitypub/database.go23
-rw-r--r--modules/activitypub/fetch.go38
-rw-r--r--modules/activitypub/follow.go12
-rw-r--r--modules/activitypub/inbox.go19
-rw-r--r--modules/activitypub/outbox.go46
-rw-r--r--routers/api/v1/activitypub/reqsignature.go28
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
}