mirror of https://github.com/jlelse/GoBlog
Improve ActivityPub implementation using go-ap/client
This commit is contained in:
parent
12bdf3ff9c
commit
0c2e2b2e4d
121
activityPub.go
121
activityPub.go
|
@ -1,6 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
|
@ -14,11 +15,11 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
ap "github.com/go-ap/activitypub"
|
ap "github.com/go-ap/activitypub"
|
||||||
|
apc "github.com/go-ap/client"
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/go-fed/httpsig"
|
"github.com/go-fed/httpsig"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
@ -57,8 +58,8 @@ func (a *goBlog) initActivityPub() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
a.apPostSigner, _, err = httpsig.NewSigner(
|
a.apSigner, _, err = httpsig.NewSigner(
|
||||||
[]httpsig.Algorithm{httpsig.RSA_SHA256},
|
[]httpsig.Algorithm{httpsig.ED25519, httpsig.RSA_SHA512, httpsig.RSA_SHA256},
|
||||||
httpsig.DigestSha256,
|
httpsig.DigestSha256,
|
||||||
[]string{httpsig.RequestTarget, "date", "host", "digest"},
|
[]string{httpsig.RequestTarget, "date", "host", "digest"},
|
||||||
httpsig.Signature,
|
httpsig.Signature,
|
||||||
|
@ -67,6 +68,16 @@ func (a *goBlog) initActivityPub() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
// Init http client
|
||||||
|
a.apHttpClients = map[string]*apc.C{}
|
||||||
|
for blog, bc := range a.cfg.Blogs {
|
||||||
|
a.apHttpClients[blog] = apc.New(
|
||||||
|
apc.WithHTTPClient(a.httpClient),
|
||||||
|
apc.WithSignFn(func(r *http.Request) error {
|
||||||
|
return a.signRequest(r, a.apIri(bc))
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
// Init send queue
|
// Init send queue
|
||||||
a.initAPSendQueue()
|
a.initAPSendQueue()
|
||||||
// Send profile updates
|
// Send profile updates
|
||||||
|
@ -145,28 +156,13 @@ func (a *goBlog) apHandleInbox(w http.ResponseWriter, r *http.Request) {
|
||||||
a.serveError(w, r, "Inbox not found", http.StatusNotFound)
|
a.serveError(w, r, "Inbox not found", http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
blogIri := a.apIri(blog)
|
|
||||||
// Verify request
|
// Verify request
|
||||||
requestActor, requestKey, requestActorStatus, err := a.apVerifySignature(r, blogIri)
|
requestActor, err := a.apVerifySignature(r, blogName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Send 401 because signature could not be verified
|
// Send 401 because signature could not be verified
|
||||||
a.serveError(w, r, err.Error(), http.StatusUnauthorized)
|
a.serveError(w, r, err.Error(), http.StatusUnauthorized)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if requestActorStatus != 0 {
|
|
||||||
if requestActorStatus == http.StatusGone || requestActorStatus == http.StatusNotFound {
|
|
||||||
u, err := url.Parse(requestKey)
|
|
||||||
if err == nil {
|
|
||||||
u.Fragment = ""
|
|
||||||
u.RawFragment = ""
|
|
||||||
_ = a.db.apRemoveFollower(blogName, u.String())
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
a.serveError(w, r, "Error when trying to get request actor", http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Parse activity
|
// Parse activity
|
||||||
limit := int64(10 * 1000 * 1000) // 10 MB
|
limit := int64(10 * 1000 * 1000) // 10 MB
|
||||||
body, err := io.ReadAll(io.LimitReader(r.Body, limit))
|
body, err := io.ReadAll(io.LimitReader(r.Body, limit))
|
||||||
|
@ -198,7 +194,7 @@ func (a *goBlog) apHandleInbox(w http.ResponseWriter, r *http.Request) {
|
||||||
// Handle activity
|
// Handle activity
|
||||||
switch activity.GetType() {
|
switch activity.GetType() {
|
||||||
case ap.FollowType:
|
case ap.FollowType:
|
||||||
a.apAccept(blogName, blogIri, blog, activity)
|
a.apAccept(blogName, blog, activity)
|
||||||
case ap.UndoType:
|
case ap.UndoType:
|
||||||
if activity.Object.IsObject() {
|
if activity.Object.IsObject() {
|
||||||
objectActivity, err := ap.ToActivity(activity.Object)
|
objectActivity, err := ap.ToActivity(activity.Object)
|
||||||
|
@ -262,31 +258,30 @@ func (a *goBlog) apOnCreateUpdate(blog *configBlog, requestActor *ap.Actor, acti
|
||||||
// TODO: handle them
|
// TODO: handle them
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *goBlog) apVerifySignature(r *http.Request, blogIri string) (*ap.Actor, string, int, error) {
|
func (a *goBlog) apVerifySignature(r *http.Request, blog string) (*ap.Actor, error) {
|
||||||
verifier, err := httpsig.NewVerifier(r)
|
verifier, err := httpsig.NewVerifier(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Error with signature header etc.
|
// Error with signature header etc.
|
||||||
return nil, "", 0, err
|
return nil, err
|
||||||
}
|
}
|
||||||
keyID := verifier.KeyId()
|
actor, err := a.apGetRemoteActor(ap.IRI(verifier.KeyId()), blog)
|
||||||
actor, statusCode, err := a.apGetRemoteActor(keyID, blogIri)
|
if err != nil || actor == nil {
|
||||||
if err != nil || actor == nil || statusCode != 0 {
|
|
||||||
// Actor not found or something else bad
|
// Actor not found or something else bad
|
||||||
return nil, keyID, statusCode, err
|
return nil, errors.New("failed to get actor: " + err.Error())
|
||||||
}
|
}
|
||||||
if actor.PublicKey.PublicKeyPem == "" {
|
if actor.PublicKey.PublicKeyPem == "" {
|
||||||
return nil, keyID, 0, errors.New("actor has no public key")
|
return nil, errors.New("actor has no public key")
|
||||||
}
|
}
|
||||||
block, _ := pem.Decode([]byte(actor.PublicKey.PublicKeyPem))
|
block, _ := pem.Decode([]byte(actor.PublicKey.PublicKeyPem))
|
||||||
if block == nil {
|
if block == nil {
|
||||||
return nil, keyID, 0, errors.New("public key invalid")
|
return nil, errors.New("public key invalid")
|
||||||
}
|
}
|
||||||
pubKey, err := x509.ParsePKIXPublicKey(block.Bytes)
|
pubKey, err := x509.ParsePKIXPublicKey(block.Bytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Unable to parse public key
|
// Unable to parse public key
|
||||||
return nil, keyID, 0, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return actor, keyID, 0, verifier.Verify(pubKey, httpsig.RSA_SHA256)
|
return actor, verifier.Verify(pubKey, httpsig.RSA_SHA256)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleWellKnownHostMeta(w http.ResponseWriter, r *http.Request) {
|
func handleWellKnownHostMeta(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -329,46 +324,8 @@ func (a *goBlog) apShowFollowers(w http.ResponseWriter, r *http.Request) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *goBlog) apGetRemoteActor(iri, ownBlogIri string) (*ap.Actor, int, error) {
|
func (a *goBlog) apGetRemoteActor(iri ap.IRI, blog string) (*ap.Actor, error) {
|
||||||
req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, iri, strings.NewReader(""))
|
return a.apHttpClients[blog].Actor(context.Background(), iri)
|
||||||
if err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
req.Header.Set("Accept", contenttype.AS)
|
|
||||||
req.Header.Set(userAgent, appUserAgent)
|
|
||||||
// Sign request
|
|
||||||
req.Header.Set("Date", time.Now().UTC().Format("Mon, 02 Jan 2006 15:04:05")+" GMT")
|
|
||||||
req.Header.Set("Host", req.URL.Host)
|
|
||||||
a.apPostSignMutex.Lock()
|
|
||||||
err = a.apPostSigner.SignRequest(a.apPrivateKey, ownBlogIri+"#main-key", req, []byte(""))
|
|
||||||
a.apPostSignMutex.Unlock()
|
|
||||||
if err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
// Do request
|
|
||||||
resp, err := a.httpClient.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
if !apRequestIsSuccess(resp.StatusCode) {
|
|
||||||
return nil, resp.StatusCode, nil
|
|
||||||
}
|
|
||||||
// Parse response
|
|
||||||
limit := int64(10 * 1000 * 1000) // 10 MB
|
|
||||||
body, err := io.ReadAll(io.LimitReader(resp.Body, limit))
|
|
||||||
if err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
apObject, err := ap.UnmarshalJSON(body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
actor, err := ap.ToActor(apObject)
|
|
||||||
if err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
return actor, 0, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *database) apGetAllInboxes(blog string) (inboxes []string, err error) {
|
func (db *database) apGetAllInboxes(blog string) (inboxes []string, err error) {
|
||||||
|
@ -464,12 +421,12 @@ func (a *goBlog) apUndelete(p *post) {
|
||||||
a.apPost(p)
|
a.apPost(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *goBlog) apAccept(blogName, blogIri string, blog *configBlog, follow *ap.Activity) {
|
func (a *goBlog) apAccept(blogName string, blog *configBlog, follow *ap.Activity) {
|
||||||
newFollower := follow.Actor.GetID()
|
newFollower := follow.Actor.GetID()
|
||||||
log.Println("New follow request from follower id:", newFollower.String())
|
log.Println("New follow request from follower id:", newFollower.String())
|
||||||
// Get remote actor
|
// Get remote actor
|
||||||
follower, status, err := a.apGetRemoteActor(newFollower.String(), blogIri)
|
follower, err := a.apGetRemoteActor(newFollower, blogName)
|
||||||
if err != nil || status != 0 {
|
if err != nil || follower == nil {
|
||||||
// Couldn't retrieve remote actor info
|
// Couldn't retrieve remote actor info
|
||||||
log.Println("Failed to retrieve remote actor info:", newFollower)
|
log.Println("Failed to retrieve remote actor info:", newFollower)
|
||||||
return
|
return
|
||||||
|
@ -583,3 +540,21 @@ func (a *goBlog) loadActivityPubPrivateKey() error {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *goBlog) signRequest(r *http.Request, blogIri string) error {
|
||||||
|
if date := r.Header.Get("Date"); date == "" {
|
||||||
|
r.Header.Set("Date", time.Now().UTC().Format(time.RFC1123))
|
||||||
|
}
|
||||||
|
if host := r.Header.Get("Host"); host == "" {
|
||||||
|
r.Header.Set("Host", r.URL.Host)
|
||||||
|
}
|
||||||
|
var bodyBuf bytes.Buffer
|
||||||
|
if r.Body != nil {
|
||||||
|
if _, err := io.Copy(&bodyBuf, r.Body); err == nil {
|
||||||
|
r.Body = io.NopCloser(&bodyBuf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a.apSignMutex.Lock()
|
||||||
|
defer a.apSignMutex.Unlock()
|
||||||
|
return a.apSigner.SignRequest(a.apPrivateKey, blogIri+"#main-key", r, bodyBuf.Bytes())
|
||||||
|
}
|
||||||
|
|
|
@ -82,12 +82,7 @@ func (a *goBlog) apSendSigned(blogIri, to string, activity []byte) error {
|
||||||
r.Header.Set("Accept", contenttype.ASUTF8)
|
r.Header.Set("Accept", contenttype.ASUTF8)
|
||||||
r.Header.Set(contentType, contenttype.ASUTF8)
|
r.Header.Set(contentType, contenttype.ASUTF8)
|
||||||
// Sign request
|
// Sign request
|
||||||
r.Header.Set("Date", time.Now().UTC().Format("Mon, 02 Jan 2006 15:04:05")+" GMT")
|
if err = a.signRequest(r, blogIri); err != nil {
|
||||||
r.Header.Set("Host", r.URL.Host)
|
|
||||||
a.apPostSignMutex.Lock()
|
|
||||||
err = a.apPostSigner.SignRequest(a.apPrivateKey, blogIri+"#main-key", r, activity)
|
|
||||||
a.apPostSignMutex.Unlock()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Do request
|
// Do request
|
||||||
|
|
6
app.go
6
app.go
|
@ -9,6 +9,7 @@ import (
|
||||||
ts "git.jlel.se/jlelse/template-strings"
|
ts "git.jlel.se/jlelse/template-strings"
|
||||||
"github.com/dgraph-io/ristretto"
|
"github.com/dgraph-io/ristretto"
|
||||||
ct "github.com/elnormous/contenttype"
|
ct "github.com/elnormous/contenttype"
|
||||||
|
apc "github.com/go-ap/client"
|
||||||
"github.com/go-fed/httpsig"
|
"github.com/go-fed/httpsig"
|
||||||
"github.com/hacdias/indieauth/v2"
|
"github.com/hacdias/indieauth/v2"
|
||||||
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
|
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
|
||||||
|
@ -23,8 +24,9 @@ type goBlog struct {
|
||||||
// ActivityPub
|
// ActivityPub
|
||||||
apPrivateKey *rsa.PrivateKey
|
apPrivateKey *rsa.PrivateKey
|
||||||
apPubKeyBytes []byte
|
apPubKeyBytes []byte
|
||||||
apPostSigner httpsig.Signer
|
apSigner httpsig.Signer
|
||||||
apPostSignMutex sync.Mutex
|
apSignMutex sync.Mutex
|
||||||
|
apHttpClients map[string]*apc.C
|
||||||
webfingerResources map[string]*configBlog
|
webfingerResources map[string]*configBlog
|
||||||
webfingerAccts map[string]string
|
webfingerAccts map[string]string
|
||||||
// ActivityStreams
|
// ActivityStreams
|
||||||
|
|
8
go.mod
8
go.mod
|
@ -21,7 +21,8 @@ require (
|
||||||
github.com/elnormous/contenttype v1.0.3
|
github.com/elnormous/contenttype v1.0.3
|
||||||
github.com/emersion/go-sasl v0.0.0-20220912192320-0145f2c60ead
|
github.com/emersion/go-sasl v0.0.0-20220912192320-0145f2c60ead
|
||||||
github.com/emersion/go-smtp v0.15.0
|
github.com/emersion/go-smtp v0.15.0
|
||||||
github.com/go-ap/activitypub v0.0.0-20221207073405-5d6d22cbc42e
|
github.com/go-ap/activitypub v0.0.0-20221209114049-1ceafda50f9f
|
||||||
|
github.com/go-ap/client v0.0.0-20221209114704-ee9adde8b2c2
|
||||||
github.com/go-ap/jsonld v0.0.0-20221030091449-f2a191312c73
|
github.com/go-ap/jsonld v0.0.0-20221030091449-f2a191312c73
|
||||||
github.com/go-chi/chi/v5 v5.0.8
|
github.com/go-chi/chi/v5 v5.0.8
|
||||||
github.com/go-fed/httpsig v1.1.0
|
github.com/go-fed/httpsig v1.1.0
|
||||||
|
@ -73,6 +74,7 @@ require (
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078 // indirect
|
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078 // indirect
|
||||||
|
git.sr.ht/~mariusor/lw v0.0.0-20221202111053-2dd31f3348e7 // indirect
|
||||||
github.com/andybalholm/cascadia v1.3.1 // indirect
|
github.com/andybalholm/cascadia v1.3.1 // indirect
|
||||||
github.com/aymerick/douceur v0.2.0 // indirect
|
github.com/aymerick/douceur v0.2.0 // indirect
|
||||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
|
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
|
||||||
|
@ -94,6 +96,8 @@ require (
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/lestrrat-go/strftime v1.0.6 // indirect
|
github.com/lestrrat-go/strftime v1.0.6 // indirect
|
||||||
github.com/magiconair/properties v1.8.6 // indirect
|
github.com/magiconair/properties v1.8.6 // indirect
|
||||||
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
github.com/mmcdole/goxpp v0.0.0-20181012175147-0068e33feabf // indirect
|
github.com/mmcdole/goxpp v0.0.0-20181012175147-0068e33feabf // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
|
@ -102,6 +106,8 @@ require (
|
||||||
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
|
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
github.com/rs/xid v1.4.0 // indirect
|
||||||
|
github.com/rs/zerolog v1.28.0 // indirect
|
||||||
github.com/snabb/diagio v1.0.0 // indirect
|
github.com/snabb/diagio v1.0.0 // indirect
|
||||||
github.com/spf13/afero v1.9.2 // indirect
|
github.com/spf13/afero v1.9.2 // indirect
|
||||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||||
|
|
24
go.sum
24
go.sum
|
@ -46,6 +46,8 @@ git.jlel.se/jlelse/template-strings v0.0.0-20220211095702-c012e3b5045b h1:zrGLEe
|
||||||
git.jlel.se/jlelse/template-strings v0.0.0-20220211095702-c012e3b5045b/go.mod h1:UNLE8cup2GTHbsE89xezRwq3GhKspPI9NyckPbgJEmw=
|
git.jlel.se/jlelse/template-strings v0.0.0-20220211095702-c012e3b5045b/go.mod h1:UNLE8cup2GTHbsE89xezRwq3GhKspPI9NyckPbgJEmw=
|
||||||
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078 h1:cliQ4HHsCo6xi2oWZYKWW4bly/Ory9FuTpFPRxj/mAg=
|
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078 h1:cliQ4HHsCo6xi2oWZYKWW4bly/Ory9FuTpFPRxj/mAg=
|
||||||
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078/go.mod h1:g/V2Hjas6Z1UHUp4yIx6bATpNzJ7DYtD0FG3+xARWxs=
|
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078/go.mod h1:g/V2Hjas6Z1UHUp4yIx6bATpNzJ7DYtD0FG3+xARWxs=
|
||||||
|
git.sr.ht/~mariusor/lw v0.0.0-20221202111053-2dd31f3348e7 h1:AmTBSijBohJRKKqd+QYQE74qwf2IKZEGBB4pQMP4G6o=
|
||||||
|
git.sr.ht/~mariusor/lw v0.0.0-20221202111053-2dd31f3348e7/go.mod h1:qGYsPqQVVmTZb54m50roPeXPlabiTOpcmco8LFefWzY=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
||||||
|
@ -79,6 +81,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||||
|
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/cretz/bine v0.2.1-0.20221201125941-b9d31d9c7866 h1:8Cji9JDEuYibvDQrWHvc42r9/HxjlD2kahN67LECXFk=
|
github.com/cretz/bine v0.2.1-0.20221201125941-b9d31d9c7866 h1:8Cji9JDEuYibvDQrWHvc42r9/HxjlD2kahN67LECXFk=
|
||||||
|
@ -124,8 +127,10 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE
|
||||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||||
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
|
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
|
||||||
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||||
github.com/go-ap/activitypub v0.0.0-20221207073405-5d6d22cbc42e h1:Qb0THMsDaDvRqvAwUFzJmN6WRbweiHUOoy9nY6GCw2M=
|
github.com/go-ap/activitypub v0.0.0-20221209114049-1ceafda50f9f h1:UV5kupaU8AP8g8Bbsn53q87XCufW/E8wvnTHDKqjoR4=
|
||||||
github.com/go-ap/activitypub v0.0.0-20221207073405-5d6d22cbc42e/go.mod h1:1oVD0h0aPT3OEE1ZoSUoym/UGKzxe+e0y8K2AkQ1Hqs=
|
github.com/go-ap/activitypub v0.0.0-20221209114049-1ceafda50f9f/go.mod h1:1oVD0h0aPT3OEE1ZoSUoym/UGKzxe+e0y8K2AkQ1Hqs=
|
||||||
|
github.com/go-ap/client v0.0.0-20221209114704-ee9adde8b2c2 h1:w+9mmPPuyEBS3B5w0OBpFzcNhj6xepbN33rzOXM3n2A=
|
||||||
|
github.com/go-ap/client v0.0.0-20221209114704-ee9adde8b2c2/go.mod h1:P5qNxXHk44o9OEmHxmjCFjS5jLZa4BZv6h7lHrmC1MA=
|
||||||
github.com/go-ap/errors v0.0.0-20221205040414-01c1adfc98ea h1:ywGtLGVjJjMrq4mu35Qmu+NtlhlTk/gTayE6Bb4tQZk=
|
github.com/go-ap/errors v0.0.0-20221205040414-01c1adfc98ea h1:ywGtLGVjJjMrq4mu35Qmu+NtlhlTk/gTayE6Bb4tQZk=
|
||||||
github.com/go-ap/errors v0.0.0-20221205040414-01c1adfc98ea/go.mod h1:SaTNjEEkp0q+w3pUS1ccyEL/lUrHteORlDq/e21mCc8=
|
github.com/go-ap/errors v0.0.0-20221205040414-01c1adfc98ea/go.mod h1:SaTNjEEkp0q+w3pUS1ccyEL/lUrHteORlDq/e21mCc8=
|
||||||
github.com/go-ap/jsonld v0.0.0-20221030091449-f2a191312c73 h1:GMKIYXyXPGIp+hYiWOhfqK4A023HdgisDT4YGgf99mw=
|
github.com/go-ap/jsonld v0.0.0-20221030091449-f2a191312c73 h1:GMKIYXyXPGIp+hYiWOhfqK4A023HdgisDT4YGgf99mw=
|
||||||
|
@ -153,6 +158,7 @@ github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8=
|
||||||
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||||
github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo=
|
github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo=
|
||||||
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
|
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
|
||||||
|
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
|
@ -294,8 +300,13 @@ github.com/lopezator/migrator v0.3.1/go.mod h1:X+lHDMZ9Ci3/KdbypJcQYFFwipVrJsX4f
|
||||||
github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
|
github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
|
||||||
github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||||
github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs=
|
github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs=
|
||||||
|
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||||
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||||
|
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||||
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||||
github.com/mattn/go-sqlite3 v1.14.3/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI=
|
github.com/mattn/go-sqlite3 v1.14.3/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI=
|
||||||
github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
|
@ -337,6 +348,10 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
|
||||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||||
|
github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY=
|
||||||
|
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||||
|
github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY=
|
||||||
|
github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/samber/lo v1.36.0 h1:4LaOxH1mHnbDGhTVE0i1z8v/lWaQW8AIfOD3HU4mSaw=
|
github.com/samber/lo v1.36.0 h1:4LaOxH1mHnbDGhTVE0i1z8v/lWaQW8AIfOD3HU4mSaw=
|
||||||
github.com/samber/lo v1.36.0/go.mod h1:HLeWcJRRyLKp3+/XBJvOrerCQn9mhdKMHyd7IRlgeQ8=
|
github.com/samber/lo v1.36.0/go.mod h1:HLeWcJRRyLKp3+/XBJvOrerCQn9mhdKMHyd7IRlgeQ8=
|
||||||
|
@ -555,7 +570,10 @@ golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
|
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
|
||||||
|
|
Loading…
Reference in New Issue