mirror of https://gitlab.com/ngerakines/tavern.git
159 lines
4.2 KiB
Go
159 lines
4.2 KiB
Go
package fed
|
|
|
|
import (
|
|
"crypto/rsa"
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/yukimochi/httpsig"
|
|
"go.uber.org/zap"
|
|
|
|
"github.com/ngerakines/tavern/common"
|
|
"github.com/ngerakines/tavern/g"
|
|
"github.com/ngerakines/tavern/storage"
|
|
)
|
|
|
|
type ActivityClient struct {
|
|
HTTPClient common.HTTPClient
|
|
Logger *zap.Logger
|
|
}
|
|
|
|
func (client ActivityClient) Get(location string) (string, storage.Payload, error) {
|
|
client.Logger.Debug("Sending activity request", zap.String("url", location))
|
|
return ldJsonGet(client.HTTPClient, location)
|
|
}
|
|
|
|
func (client ActivityClient) GetSigned(location string, localActor storage.LocalActor) (string, storage.Payload, error) {
|
|
client.Logger.Debug("Sending signed activity request", zap.String("url", location))
|
|
|
|
sigConfig := []httpsig.Algorithm{httpsig.RSA_SHA256}
|
|
headersToSign := []string{httpsig.RequestTarget, "date"}
|
|
signer, _, err := httpsig.NewSigner(sigConfig, headersToSign, httpsig.Signature)
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
|
|
privateKey, err := localActor.User.GetPrivateKey()
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
|
|
return ldJsonGetSigned(client.HTTPClient, location, signer, localActor.Actor.GetKeyID(), privateKey)
|
|
}
|
|
|
|
func (client ActivityClient) GetSignedWithKey(location, keyID string, privateKey *rsa.PrivateKey) (string, storage.Payload, error) {
|
|
client.Logger.Debug("Sending signed activity request", zap.String("url", location))
|
|
|
|
sigConfig := []httpsig.Algorithm{httpsig.RSA_SHA256}
|
|
headersToSign := []string{httpsig.RequestTarget, "date"}
|
|
signer, _, err := httpsig.NewSigner(sigConfig, headersToSign, httpsig.Signature)
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
|
|
return ldJsonGetSigned(client.HTTPClient, location, signer, keyID, privateKey)
|
|
}
|
|
|
|
func ldJsonGet(client common.HTTPClient, location string) (string, storage.Payload, error) {
|
|
request, err := http.NewRequest("GET", location, nil)
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
request.Header.Add("Accept", "application/ld+json")
|
|
request.Header.Set("User-Agent", g.UserAgent())
|
|
|
|
resp, err := client.Do(request)
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
return "", nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
|
}
|
|
body, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1*1024*1024))
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
|
|
p, err := storage.PayloadFromBytes(body)
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
|
|
return string(body), p, nil
|
|
}
|
|
|
|
func JRDJsonGet(client common.HTTPClient, location string) (string, storage.Payload, error) {
|
|
request, err := http.NewRequest("GET", location, nil)
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
request.Header.Add("Accept", "application/jrd+json")
|
|
request.Header.Set("User-Agent", g.UserAgent())
|
|
|
|
resp, err := client.Do(request)
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
return "", nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
|
}
|
|
body, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1*1024*1024))
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
|
|
p, err := storage.PayloadFromBytes(body)
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
|
|
return string(body), p, nil
|
|
}
|
|
|
|
func ldJsonGetSigned(client common.HTTPClient, location string, signer httpsig.Signer, keyID string, privateKey *rsa.PrivateKey) (string, storage.Payload, error) {
|
|
request, err := http.NewRequest("GET", location, nil)
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
request.Header.Add("Accept", "application/ld+json")
|
|
request.Header.Add("date", time.Now().UTC().Format(http.TimeFormat))
|
|
request.Header.Set("User-Agent", g.UserAgent())
|
|
|
|
if err = signer.SignRequest(privateKey, keyID, request); err != nil {
|
|
return "", nil, err
|
|
}
|
|
|
|
resp, err := client.Do(request)
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
return "", nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
|
}
|
|
body, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1*1024*1024))
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
|
|
p, err := storage.PayloadFromBytes(body)
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
|
|
return string(body), p, nil
|
|
}
|
|
|
|
func ObjectThread(p storage.Payload) string {
|
|
context, _ := storage.JSONString(p, "context")
|
|
return context
|
|
}
|