initial commit

This commit is contained in:
Cadey Ratio 2020-01-11 13:38:50 -05:00
commit c2b7e8e5a8
12 changed files with 654 additions and 0 deletions

1
.dockerignore Normal file
View File

@ -0,0 +1 @@
.env

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
.env
bin/
var/

130
cmd/mi/main.go Normal file
View File

@ -0,0 +1,130 @@
package main
import (
"context"
"flag"
"net/url"
"os"
"os/signal"
"time"
"github.com/facebookarchive/flagenv"
_ "github.com/joho/godotenv/autoload"
r "gopkg.in/rethinkdb/rethinkdb-go.v6"
"within.website/ln"
)
var (
// Twitter
twitterAPIKey = flag.String("twitter-api-key", "", "Twitter API key")
twitterAPISecret = flag.String("twitter-api-secret", "", "Twitter API secret")
twitterConsumerToken = flag.String("twitter-consumer-token", "", "Twitter consumer Token")
twitterConsumerSecret = flag.String("twitter-consumer-secret", "", "Twitter consumer Secret")
// Mastodon
mastodonInstance = flag.String("mastodon-instance", "", "Mastodon instance to connect to")
mastodonAppID = flag.String("mastodon-app-id", "", "Mastodon app ID")
mastodonAppSecret = flag.String("mastodon-app-secret", "", "Mastodon app secret")
mastodonToken = flag.String("mastodon-token", "", "Mastodon API token")
mastodonAccount = flag.String("mastodon-account", "", "Mastodon account")
/*
// Gitea
giteaInstance = flag.String("gitea-instance", "", "Gitea instance to use")
giteaAPIToken = flag.String("gitea-api-token", "", "Gitea API token")
// Github
githubToken = flag.String("github-token", "", "Github API token")
*/
// Reddit
redditAppID = flag.String("reddit-app-id", "", "Reddit app ID")
redditAppSecret = flag.String("reddit-app-secret", "", "Reddit app Secret")
redditUsername = flag.String("reddit-username", "", "Reddit username")
redditPassword = flag.String("reddit-password", "", "Reddit password")
// RethinkDB
rethinkDBURL = flag.String("rethinkdb-url", "rethinkdb2://admin@127.0.0.1:28015/mi", "RethinkDB URL")
// Patreon
patreonClientID = flag.String("patreon-client-id", "", "Patreon client ID")
patreonClientSecret = flag.String("patreon-client-secret", "", "Patreon client secret")
patreonAccessToken = flag.String("patreon-access-token", "", "Patreon access token")
patreonRefreshToken = flag.String("patreon-refresh-token", "", "Patreon refresh token")
// Blog
blogURL = flag.String("blog-url", "https://christine.website/blog.json", "JSONFeed to monitor for new posts")
// Port
port = flag.String("port", "5000", "HTTP port")
)
func main() {
flagenv.Parse()
flag.Parse()
ctx := context.Background()
ctx = ln.WithF(ctx, ln.F{
"mastodon_instance": *mastodonInstance,
})
r.SetTags("rethinkdb", "json")
u, err := url.Parse(*rethinkDBURL)
if err != nil {
ln.FatalErr(ctx, err)
}
pw, _ := u.User.Password()
db := u.Path[1:]
session, err := r.Connect(r.ConnectOpts{
Address: u.Host,
Database: db,
Username: u.User.Username(),
Password: pw,
})
if err != nil {
ln.FatalErr(ctx, err)
}
mastodonClient, err := makeMastodon()
if err != nil {
ln.FatalErr(ctx, err)
}
redditBot, err := makeReddit()
if err != nil {
ln.FatalErr(ctx, err)
}
twitterClient, err := makeTwitter()
if err != nil {
ln.FatalErr(ctx, err)
}
mi := &Mi{
session: session,
mastodonClient: mastodonClient,
twitterClient: twitterClient,
redditBot: redditBot,
}
ctx, cancel := context.WithCancel(ctx)
go func(cf func()) {
var signalChan chan os.Signal
signalChan = make(chan os.Signal, 1)
signal.Notify(signalChan, os.Interrupt)
<-signalChan
cf()
}(cancel)
go mi.StreamMastodon(ctx)
go mi.StreamReddit(ctx)
go mi.StreamMastodonToTwitter(ctx)
<-ctx.Done()
ln.Log(ctx, ln.Info("cleaning up"))
time.Sleep(500 * time.Millisecond)
}

139
cmd/mi/mastodon.go Normal file
View File

@ -0,0 +1,139 @@
package main
import (
"context"
"encoding/json"
"github.com/McKael/madon"
"github.com/jaytaylor/html2text"
r "gopkg.in/rethinkdb/rethinkdb-go.v6"
"within.website/ln"
"within.website/ln/opname"
)
func makeMastodon() (*madon.Client, error) {
c, err := madon.RestoreApp("mi", *mastodonInstance, *mastodonAppID, *mastodonAppSecret, &madon.UserToken{AccessToken: *mastodonToken})
if err != nil {
return nil, err
}
return c, nil
}
func (mi *Mi) StreamMastodon(ctx context.Context) error {
evChan := make(chan madon.StreamEvent, 10)
stop := make(chan bool)
done := make(chan bool)
ctx = opname.With(context.Background(), "user-stream")
err := mi.mastodonClient.StreamListener("user", "", evChan, stop, done)
if err != nil {
ln.FatalErr(ctx, err)
}
ln.Log(ctx, ln.Info("streaming user toots to rethinkdb"))
for {
select {
case <-done:
ln.Fatal(ctx, ln.Action("got done?"))
case <-ctx.Done():
stop <- true
case ev := <-evChan:
s, ok := ev.Data.(madon.Status)
if !ok {
continue
}
if s.Reblog != nil {
continue
}
err := r.Table("mastodon").Insert(s).Exec(mi.session)
if err != nil {
ln.Error(ctx, err)
stop <- true
}
ln.Log(ctx, ln.Info("got toot"), ln.F{
"toot_url": s.URL,
"toot_creator": s.Account.Username,
})
}
}
}
type MastodonStatus struct {
ID float64 `json:"id"`
InReplyToID *float64 `json:"in_reply_to_id"`
Account struct {
Acct string `json:"acct"`
} `json:"account"`
URL string `json:"url"`
Content string `json:"content"`
}
type NewStatus struct {
NewVal *MastodonStatus `json:"new_val"`
OldVal *MastodonStatus `json:"old_val"`
}
func (mi *Mi) StreamMastodonToTwitter(ctx context.Context) {
res, err := r.Table("mastodon").Changes().Run(mi.session)
if err != nil {
ln.FatalErr(ctx, err)
}
defer res.Close()
ln.Log(ctx, ln.Info("streaming mastodon to twitter"))
for {
data, ok := res.NextResponse()
if !ok {
ln.FatalErr(ctx, res.Err())
}
select {
case <-ctx.Done():
break
default:
}
var ns NewStatus
err := json.Unmarshal(data, &ns)
if err != nil {
ln.FatalErr(ctx, err)
}
st := ns.NewVal
if st.Account.Acct != *mastodonAccount {
continue
}
if st.InReplyToID != nil {
continue
}
text, err := html2text.FromString(st.Content, html2text.Options{OmitLinks: true})
if len(text) > 200 {
text = text[:200] + "... read more here: " + st.URL
}
if err != nil {
ln.Error(ctx, err, ln.F{"url": st.URL})
continue
}
tweet, _, err := mi.twitterClient.Statuses.Update(text, nil)
if err != nil {
ln.Error(ctx, err, ln.F{
"text": text,
"url": st.URL,
})
continue
}
ln.Log(ctx, ln.Info("sent tweet from mastodon"), ln.F{
"tweet_id": tweet.ID,
})
}
}

17
cmd/mi/mi.go Normal file
View File

@ -0,0 +1,17 @@
package main
import (
"github.com/McKael/madon"
"github.com/dghubble/go-twitter/twitter"
"github.com/turnage/graw/reddit"
"gopkg.in/mxpv/patreon-go.v1"
r "gopkg.in/rethinkdb/rethinkdb-go.v6"
)
type Mi struct {
session *r.Session
mastodonClient *madon.Client
twitterClient *twitter.Client
redditBot reddit.Bot
patreonClient *patreon.Client
}

38
cmd/mi/patreon.go Normal file
View File

@ -0,0 +1,38 @@
package main
import (
"context"
"time"
"golang.org/x/oauth2"
"gopkg.in/mxpv/patreon-go.v1"
)
func makePatreon() (*patreon.Client, error) {
config := oauth2.Config{
ClientID: *patreonClientID,
ClientSecret: *patreonClientSecret,
Endpoint: oauth2.Endpoint{
AuthURL: patreon.AuthorizationURL,
TokenURL: patreon.AccessTokenURL,
},
Scopes: []string{"users", "pledges-to-me", "my-campaign"},
}
token := oauth2.Token{
AccessToken: *patreonAccessToken,
RefreshToken: *patreonRefreshToken,
// Must be non-nil, otherwise token will not be expired
Expiry: time.Now().Add(-24 * time.Hour),
}
tc := config.Client(context.Background(), &token)
client := patreon.NewClient(tc)
_, err := client.FetchUser()
if err != nil {
return nil, err
}
return client, nil
}

7
cmd/mi/posse.go Normal file
View File

@ -0,0 +1,7 @@
package main
type Post struct {
Title string
URL string
Tags []string
}

141
cmd/mi/reddit.go Normal file
View File

@ -0,0 +1,141 @@
package main
import (
"context"
"runtime"
"strings"
"github.com/turnage/graw/reddit"
"github.com/turnage/graw/streams"
r "gopkg.in/rethinkdb/rethinkdb-go.v6"
"within.website/ln"
)
func makeReddit() (reddit.Bot, error) {
cfg := reddit.BotConfig{
Agent: "mi:life_logging_bot:0.0.1 by /u/shadowh511",
App: reddit.App{
ID: *redditAppID,
Secret: *redditAppSecret,
Username: *redditUsername,
Password: *redditPassword,
},
}
bot, err := reddit.NewBot(cfg)
if err != nil {
return nil, err
}
return bot, nil
}
func (mi *Mi) StreamReddit(ctx context.Context) {
kill := make(chan bool)
errs := make(chan error, 5)
posts, comments, err := streams.User(mi.redditBot, kill, errs, *redditUsername)
if err != nil {
ln.FatalErr(ctx, err)
}
postReplies, err := streams.PostReplies(mi.redditBot, kill, errs)
if err != nil {
ln.FatalErr(ctx, err)
}
commentReplies, err := streams.CommentReplies(mi.redditBot, kill, errs)
if err != nil {
ln.FatalErr(ctx, err)
}
ln.Log(ctx, ln.Info("streaming reddit posts"))
for {
select {
case <-ctx.Done():
kill <- true
kill <- true
kill <- true
runtime.Goexit()
case <-errs:
ln.Error(ctx, err)
case p := <-posts:
ln.Log(ctx, ln.Info("got reddit post"), ln.F{
"from": p.Author,
"link": p.Permalink,
})
data := map[string]interface{}{
"id": p.Name,
"permalink": p.Permalink,
"created_at": p.CreatedUTC,
"author": p.Author,
"body": p.SelfText,
"url": p.URL,
}
err := r.Table("reddit_posts").Insert(data).Exec(mi.session)
if err != nil {
ln.Error(ctx, err)
}
case c := <-comments:
ln.Log(ctx, ln.Info("got reddit comment"), ln.F{
"id": c.ID,
"author": c.Author,
"thread": strings.Join(strings.Split(c.Permalink, "/")[:6], "/") + "/",
})
data := map[string]interface{}{
"id": c.ID,
"author": c.Author,
"parent_id": c.ParentID,
"body": c.Body,
"thread": strings.Join(strings.Split(c.Permalink, "/")[:6], "/") + "/",
}
err := r.Table("reddit_comments").Insert(data).Exec(mi.session)
if err != nil {
ln.Error(ctx, err)
}
case pr := <-postReplies:
ln.Log(ctx, ln.Info("got reddit post reply"), ln.F{
"id": pr.ID,
"author": pr.Author,
"thread": strings.Join(strings.Split(pr.Context, "/")[:6], "/") + "/",
})
data := map[string]interface{}{
"id": pr.ID,
"author": pr.Author,
"parent_id": pr.ParentID,
"body": pr.Body,
"thread": strings.Join(strings.Split(pr.Context, "/")[:6], "/") + "/",
}
err := r.Table("reddit_comments").Insert(data).Exec(mi.session)
if err != nil {
ln.Error(ctx, err)
}
case cr := <-commentReplies:
ln.Log(ctx, ln.Info("got reddit comment reply"), ln.F{
"id": cr.ID,
"author": cr.Author,
"thread": strings.Join(strings.Split(cr.Context, "/")[:6], "/") + "/",
})
data := map[string]interface{}{
"id": cr.ID,
"author": cr.Author,
"parent_id": cr.ParentID,
"body": cr.Body,
"thread": strings.Join(strings.Split(cr.Context, "/")[:6], "/") + "/",
}
err := r.Table("reddit_comments").Insert(data).Exec(mi.session)
if err != nil {
ln.Error(ctx, err)
}
}
}
}

23
cmd/mi/twitter.go Normal file
View File

@ -0,0 +1,23 @@
package main
import (
"github.com/dghubble/go-twitter/twitter"
"github.com/dghubble/oauth1"
)
func makeTwitter() (*twitter.Client, error) {
config := oauth1.NewConfig(*twitterConsumerToken, *twitterConsumerSecret)
token := oauth1.NewToken(*twitterAPIKey, *twitterAPISecret)
// http.Client will automatically authorize Requests
httpClient := config.Client(oauth1.NoContext, token)
// twitter client
client := twitter.NewClient(httpClient)
_, _, err := client.Accounts.VerifyCredentials(nil)
if err != nil {
return nil, err
}
return client, nil
}

26
go.mod Normal file
View File

@ -0,0 +1,26 @@
module within.website/mi
go 1.13
require (
github.com/McKael/madon v2.3.0+incompatible
github.com/dghubble/go-twitter v0.0.0-20190719072343-39e5462e111f
github.com/dghubble/oauth1 v0.6.0
github.com/facebookarchive/flagenv v0.0.0-20160425205200-fcd59fca7456
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 // indirect
github.com/facebookgo/flagenv v0.0.0-20160425205200-fcd59fca7456
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 // indirect
github.com/gorilla/websocket v1.4.1 // indirect
github.com/jaytaylor/html2text v0.0.0-20190408195923-01ec452cbe43
github.com/joho/godotenv v1.3.0
github.com/kr/pretty v0.1.0
github.com/olekukonko/tablewriter v0.0.4 // indirect
github.com/sendgrid/rest v2.4.1+incompatible // indirect
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
github.com/turnage/graw v0.0.0-20191224200831-a592320d5bc9
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
gopkg.in/mxpv/patreon-go.v1 v1.0.0-20171031001022-1d2f253ac700
gopkg.in/rethinkdb/rethinkdb-go.v6 v6.0.0
within.website/ln v0.7.0
)

108
go.sum Normal file
View File

@ -0,0 +1,108 @@
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/McKael/madon v2.3.0+incompatible h1:xMUA+Fy4saDV+8tN3MMnwJUoYWC//5Fy8LeOqJsRNIM=
github.com/McKael/madon v2.3.0+incompatible/go.mod h1:+issnvJjN1rpjAHZwXRB/x30uHh/NoQR7QaojJK/lSI=
github.com/cenkalti/backoff v2.0.0+incompatible h1:5IIPUHhlnUZbcHQsQou5k1Tn58nJkeJL9U+ig5CHJbY=
github.com/cenkalti/backoff v2.0.0+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1qxKWjE/Bpp46npY=
github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dghubble/go-twitter v0.0.0-20190719072343-39e5462e111f h1:M2wB039zeS1/LZtN/3A7tWyfctiOBL4ty5PURBmDdWU=
github.com/dghubble/go-twitter v0.0.0-20190719072343-39e5462e111f/go.mod h1:xfg4uS5LEzOj8PgZV7SQYRHbG7jPUnelEiaAVJxmhJE=
github.com/dghubble/oauth1 v0.6.0 h1:m1yC01Ohc/eF38jwZ8JUjL1a+XHHXtGQgK+MxQbmSx0=
github.com/dghubble/oauth1 v0.6.0/go.mod h1:8pFdfPkv/jr8mkChVbNVuJ0suiHe278BtWI4Tk1ujxk=
github.com/dghubble/sling v1.3.0 h1:pZHjCJq4zJvc6qVQ5wN1jo5oNZlNE0+8T/h0XeXBUKU=
github.com/dghubble/sling v1.3.0/go.mod h1:XXShWaBWKzNLhu2OxikSNFrlsvowtz4kyRuXUG7oQKY=
github.com/facebookarchive/flagenv v0.0.0-20160425205200-fcd59fca7456 h1:1NzATV1A9LeTWAuAJGd7vE/wYSO08EJQTrwKcBBR6Cw=
github.com/facebookarchive/flagenv v0.0.0-20160425205200-fcd59fca7456/go.mod h1:Lbo+w7sC1xznzryrqUDoBBT2nLKV9JnDOzdiVMHYX/8=
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 h1:0JZ+dUmQeA8IIVUMzysrX4/AKuQwWhV2dYQuPZdvdSQ=
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=
github.com/facebookgo/flagenv v0.0.0-20160425205200-fcd59fca7456 h1:CkmB2l68uhvRlwOTPrwnuitSxi/S3Cg4L5QYOcL9MBc=
github.com/facebookgo/flagenv v0.0.0-20160425205200-fcd59fca7456/go.mod h1:zFhibDvPDWmtk4dAQ05sRobtyoffEHygEt3wSNuAzz8=
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A=
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 h1:E2s37DuLxFhQDg5gKsWoLBOB0n+ZW8s599zru8FJ2/Y=
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
github.com/jaytaylor/html2text v0.0.0-20190408195923-01ec452cbe43 h1:jTkyeF7NZ5oIr0ESmcrpiDgAfoidCBF4F5kJhjtaRwE=
github.com/jaytaylor/html2text v0.0.0-20190408195923-01ec452cbe43/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8=
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg=
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sendgrid/rest v2.4.1+incompatible h1:HDib/5xzQREPq34lN3YMhQtMkdXxS/qLp5G3k9a5++4=
github.com/sendgrid/rest v2.4.1+incompatible/go.mod h1:kXX7q3jZtJXK5c5qK83bSGMdV6tsOE70KbHoqJls4lE=
github.com/sirupsen/logrus v1.0.6 h1:hcP1GmhGigz/O7h1WVUM5KklBp1JoNS9FggWKdj/j3s=
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo=
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf/go.mod h1:RJID2RhlZKId02nZ62WenDCkgHFerpIOmW0iT7GKmXM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/turnage/graw v0.0.0-20191224200831-a592320d5bc9 h1:hGzA+rD6+ZhT23x6lG6Pk6tG3gI95gvNu0X5MzwoYkQ=
github.com/turnage/graw v0.0.0-20191224200831-a592320d5bc9/go.mod h1:aAkq4I/q1izZSSwHvzhDn9NA+eGxgTSuibwP3MZRlQY=
github.com/turnage/redditproto v0.0.0-20151223012412-afedf1b6eddb h1:qR56NGRvs2hTUbkn6QF8bEJzxPIoMw3Np3UigBeJO5A=
github.com/turnage/redditproto v0.0.0-20151223012412-afedf1b6eddb/go.mod h1:GyqJdEoZSNoxKDb7Z2Lu/bX63jtFukwpaTP9ZIS5Ei0=
golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac h1:7d7lG9fHOLdL6jZPtnV4LpI41SbohIJ1Atq7U991dMg=
golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d h1:g9qWBGx4puODJTMVyoPrpoxPFgVGd+z1DZwjfRu4d0I=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180828065106-d99a578cf41b h1:cmOZLU2i7CLArKNViO+ZCQ47wqYFyKEIpbGWp+b6Uoc=
golang.org/x/sys v0.0.0-20180828065106-d99a578cf41b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fatih/pool.v2 v2.0.0 h1:xIFeWtxifuQJGk/IEPKsTduEKcKvPmhoiVDGpC40nKg=
gopkg.in/fatih/pool.v2 v2.0.0/go.mod h1:8xVGeu1/2jr2wm5V9SPuMht2H5AEmf5aFMGSQixtjTY=
gopkg.in/mxpv/patreon-go.v1 v1.0.0-20171031001022-1d2f253ac700 h1:ymnLBRNALxuok6al+nlPJxfSa3yc2SZc5N21svHQtys=
gopkg.in/mxpv/patreon-go.v1 v1.0.0-20171031001022-1d2f253ac700/go.mod h1:IZaw6NfbSsGszLfPbo9LLlxLIx17eMHWe4cxpM8wUMk=
gopkg.in/rethinkdb/rethinkdb-go.v6 v6.0.0 h1:x+tVYhL4QUktgB8Dvspq0ZmnPYMO/5tYEvhX5KBm47M=
gopkg.in/rethinkdb/rethinkdb-go.v6 v6.0.0/go.mod h1:Z9NgaOLdqIZS9v3EFLP/S0VdloWSW+2zEN6dllUSCVQ=
within.website/ln v0.7.0 h1:cZUc53cZF/+hWuEAv1VbqlYJ5czuPFHKfH0hLKmlIUA=
within.website/ln v0.7.0/go.mod h1:ifURKqsCJekcsdUE+hyCdcuhQqQ+9v9DfA++ZqYxZFE=

21
tools/paseto-key-gen.go Normal file
View File

@ -0,0 +1,21 @@
//+build ignore
package main
import (
"crypto/ed25519"
"encoding/hex"
"fmt"
)
func main() {
publicKey, privateKey, err := ed25519.GenerateKey(nil)
if err != nil {
panic(err)
}
fmt.Printf(
"PASETO_PUBLIC_KEY=%s\nPASETO_PRIVATE_KEY=%s\n",
hex.EncodeToString(publicKey),
hex.EncodeToString([]byte(privateKey)),
)
}