Skip to content

Commit 8da3610

Browse files
committed
fix: Sign get actor, fix executeRelayActivity
1 parent 01f1a44 commit 8da3610

3 files changed

Lines changed: 34 additions & 5 deletions

File tree

api/decode.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ func decodeActivity(request *http.Request) (*models.Activity, *models.Actor, []b
2323
return nil, nil, nil, err
2424
}
2525
KeyID := verifier.KeyId()
26-
keyOwnerActor, err := models.NewActivityPubActorFromRemoteActor(KeyID, fmt.Sprintf("%s (golang net/http; Activity-Relay %s; %s)", GlobalConfig.ServerServiceName(), version, GlobalConfig.ServerHostname().Host), ActorCache)
26+
relayKeyID := RelayActor.PublicKey.ID
27+
relayPrivateKey := GlobalConfig.ActorKey()
28+
uaString := fmt.Sprintf("%s (golang net/http; Activity-Relay %s; %s)", GlobalConfig.ServerServiceName(), version, GlobalConfig.ServerHostname().Host)
29+
keyOwnerActor, err := models.NewActivityPubActorFromRemoteActor(KeyID, uaString, ActorCache, relayKeyID, relayPrivateKey)
2730
if err != nil {
2831
return nil, nil, nil, err
2932
}
@@ -56,7 +59,7 @@ func decodeActivity(request *http.Request) (*models.Activity, *models.Actor, []b
5659
if err != nil {
5760
return nil, nil, nil, err
5861
}
59-
remoteActor, err := models.NewActivityPubActorFromRemoteActor(activity.Actor, fmt.Sprintf("%s (golang net/http; Activity-Relay %s; %s)", GlobalConfig.ServerServiceName(), version, GlobalConfig.ServerHostname().Host), ActorCache)
62+
remoteActor, err := models.NewActivityPubActorFromRemoteActor(activity.Actor, uaString, ActorCache, relayKeyID, relayPrivateKey)
6063
if err != nil {
6164
return nil, nil, nil, err
6265
}
@@ -69,7 +72,7 @@ func fetchOriginalActivityFromURL(url string) (*models.Activity, *models.Actor,
6972
if err != nil {
7073
return nil, nil, err
7174
}
72-
remoteActor, err := models.NewActivityPubActorFromRemoteActor(remoteActivity.Actor, fmt.Sprintf("%s (golang net/http; Activity-Relay %s; %s)", GlobalConfig.ServerServiceName(), version, GlobalConfig.ServerHostname().Host), ActorCache)
75+
remoteActor, err := models.NewActivityPubActorFromRemoteActor(remoteActivity.Actor, fmt.Sprintf("%s (golang net/http; Activity-Relay %s; %s)", GlobalConfig.ServerServiceName(), version, GlobalConfig.ServerHostname().Host), ActorCache, RelayActor.PublicKey.ID, GlobalConfig.ActorKey())
7376
if err != nil {
7477
return &remoteActivity, nil, err
7578
}

api/resolver.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ func executeRejectRequest(activity *models.Activity, actor *models.Actor, err er
331331

332332
func executeRelayActivity(activity *models.Activity, actor *models.Actor, body []byte) error {
333333
actorID, _ := url.Parse(actor.ID)
334-
if !isActorSubscribed(actorID) {
334+
if !isActorSubscribersOrFollowers(actorID) {
335335
err := errors.New("to use the relay service, please follow in advance")
336336
return err
337337
}

models/models.go

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,35 @@
11
package models
22

33
import (
4+
"crypto/rsa"
45
"encoding/json"
56
"errors"
67
"io"
78
"net/http"
89
"net/url"
910
"time"
1011

12+
"github.com/go-fed/httpsig"
1113
"github.com/google/uuid"
1214
"github.com/patrickmn/go-cache"
1315
)
1416

17+
func signGETRequest(req *http.Request, keyID string, privateKey *rsa.PrivateKey) error {
18+
req.Header.Set("Host", req.URL.Host)
19+
req.Header.Set("Date", time.Now().UTC().Format("Mon, 02 Jan 2006 15:04:05")+" GMT")
20+
signer, _, err := httpsig.NewSigner(
21+
[]httpsig.Algorithm{httpsig.RSA_SHA256},
22+
httpsig.DigestSha256,
23+
[]string{httpsig.RequestTarget, "Host", "Date"},
24+
httpsig.Signature,
25+
60*60,
26+
)
27+
if err != nil {
28+
return err
29+
}
30+
return signer.SignRequest(privateKey, keyID, req, nil)
31+
}
32+
1533
// PublicKey : Activity Certificate.
1634
type PublicKey struct {
1735
ID string `json:"id,omitempty"`
@@ -85,7 +103,10 @@ func NewActivityPubActorFromRelayConfig(globalConfig *RelayConfig) Actor {
85103
}
86104

87105
// NewActivityPubActorFromRemoteActor : Retrieve Actor from remote instance.
88-
func NewActivityPubActorFromRemoteActor(url string, uaString string, cache *cache.Cache) (Actor, error) {
106+
// When keyID and privateKey are provided, the GET request is signed with
107+
// HTTP Signature so that instances requiring authenticated fetch (e.g.
108+
// GoToSocial) respond with 200 instead of 401.
109+
func NewActivityPubActorFromRemoteActor(url string, uaString string, cache *cache.Cache, keyID string, privateKey *rsa.PrivateKey) (Actor, error) {
89110
var actor = new(Actor)
90111
var err error
91112
cacheData, found := cache.Get(url)
@@ -100,6 +121,11 @@ func NewActivityPubActorFromRemoteActor(url string, uaString string, cache *cach
100121
req, _ := http.NewRequest("GET", url, nil)
101122
req.Header.Set("Accept", "application/activity+json")
102123
req.Header.Set("User-Agent", uaString)
124+
if privateKey != nil && keyID != "" {
125+
if err := signGETRequest(req, keyID, privateKey); err != nil {
126+
return *actor, err
127+
}
128+
}
103129
client := new(http.Client)
104130
resp, err := client.Do(req)
105131
if err != nil {

0 commit comments

Comments
 (0)