WIP: Adding relay support

Works but very rough code
This commit is contained in:
Farhan Khan 2022-01-09 21:16:34 -05:00
parent d2a8f39215
commit c120357259
9 changed files with 129 additions and 11 deletions

View File

@ -51,6 +51,14 @@ Fedilogue is configured by the `config.jsonc` file. Start by copying the `config
`config.jsonc` and edit the file with your use-case values. The configuration file is written in jsonc and `config.jsonc` and edit the file with your use-case values. The configuration file is written in jsonc and
has enclosed explanations that should be self-explanatory. has enclosed explanations that should be self-explanatory.
### Generate private and public key
```
cd fedilogue
mkdir -p keys
openssl genrsa -out keys/private.pem 3072
openssl rsa -in keys/private.pem -pubout -out public-key.pem
```
## Contact ## Contact
Ping me at [@fikran@thebag.social](https://thebag.social/@fikran) Ping me at [@fikran@thebag.social](https://thebag.social/@fikran)

View File

@ -1,7 +1,6 @@
package main package main
import ( import (
"gitlab.com/khanzf/fedilogue/shared"
"encoding/binary" "encoding/binary"
"encoding/json" "encoding/json"
"flag" "flag"
@ -9,6 +8,8 @@ import (
"io" "io"
"net" "net"
"os" "os"
"gitlab.com/khanzf/fedilogue/shared"
) )
func main() { func main() {
@ -18,6 +19,7 @@ func main() {
resumePtr := flag.String("resume", "", "Instance to Resume") resumePtr := flag.String("resume", "", "Instance to Resume")
addPtr := flag.String("add", "", "Instance to add") addPtr := flag.String("add", "", "Instance to add")
statusPtr := flag.Bool("status", false, "Check status") statusPtr := flag.Bool("status", false, "Check status")
followPtr := flag.String("follow", "", "Follow a target relay")
flag.Parse() flag.Parse()
/* Condition verification */ /* Condition verification */
@ -46,6 +48,13 @@ func main() {
totalflags++ totalflags++
commandMap.Type = "resume" commandMap.Type = "resume"
} }
if *followPtr != "" {
totalflags++
commandMap.Type = "follow"
commandMap.Endpoint = *followPtr
}
if totalflags > 1 { if totalflags > 1 {
fmt.Println("Incompatible arguments, exiting.") fmt.Println("Incompatible arguments, exiting.")
os.Exit(1) os.Exit(1)
@ -59,6 +68,7 @@ func main() {
fmt.Println(err) fmt.Println(err)
return return
} }
c, err := net.Dial("tcp", "127.0.0.1:5555") c, err := net.Dial("tcp", "127.0.0.1:5555")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
@ -130,5 +140,7 @@ func main() {
fmt.Fprintf(os.Stdout, "\t%s\t", runninginstance.CaptureType) fmt.Fprintf(os.Stdout, "\t%s\t", runninginstance.CaptureType)
fmt.Fprintf(os.Stdout, "%s\n", endpoint) fmt.Fprintf(os.Stdout, "%s\n", endpoint)
} }
case "follow":
fmt.Println("This is a follow test")
} }
} }

View File

@ -39,6 +39,7 @@ type Settings struct {
Externalaccounts []ExtAccount `"json:externalaccounts"` Externalaccounts []ExtAccount `"json:externalaccounts"`
MassFollowers []MassFollower `"json:massfollowers"` MassFollowers []MassFollower `"json:massfollowers"`
LogLevel int `"json:loglevel"` LogLevel int `"json:loglevel"`
Hostname string `"json:hostname"`
} }
var settings Settings var settings Settings

View File

@ -55,6 +55,8 @@
} }
], ],
"hostname": "myhostname",
/* /*
Log Level: Log Level:
* 0 = No logs * 0 = No logs

View File

@ -82,6 +82,10 @@ func handleClient(commandClient net.Conn) {
ri_mutex.Unlock() ri_mutex.Unlock()
} }
//ri_mutex.Unlock() //ri_mutex.Unlock()
case "follow":
logInfo("Follow handling...")
responseback.Message = "Trying to follow " + commandmap.Endpoint
go followInbox(commandmap.Endpoint)
case "suspend": case "suspend":
logFatal.Fatal("Suspend") logFatal.Fatal("Suspend")
case "resume": case "resume":

View File

@ -113,7 +113,7 @@ func main() {
} }
go startctl() go startctl()
//go webmain() go webmain()
runtime.Goexit() runtime.Goexit()
} }

View File

@ -4,6 +4,7 @@ import (
// "crypto/sha1" // "crypto/sha1"
"encoding/json" "encoding/json"
"fmt" "fmt"
// "html" // "html"
"io/ioutil" "io/ioutil"
"log" "log"
@ -23,6 +24,19 @@ type CreateObject struct {
Type string `json:"type"` Type string `json:"type"`
} }
// CreateObject - Used by post web receiver
type AnnounceObject struct {
ID string `json:"id"`
Actor string `json:"actor"`
To []string `json:"to"`
Type string `json:"type"`
Object string `json:"object"`
}
/*
{"@context": "https://www.w3.org/ns/activitystreams", "type": "Announce", "to": ["https://relay.101010.pl/followers"], "actor": "https://relay.101010.pl/actor", "object": "https://social.tchncs.de/users/keara/statuses/107594176486878867", "id": "https://relay.101010.pl/activities/7666bbe3-4448-4d99-919c-a618e0a912e9"}
*/
// RelayBase - The base object used by web receiver // RelayBase - The base object used by web receiver
type RelayBase struct { type RelayBase struct {
Actor string `json:"actor"` Actor string `json:"actor"`
@ -99,23 +113,27 @@ func webfinger(w http.ResponseWriter, r *http.Request) {
func inboxHandler() http.HandlerFunc { func inboxHandler() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
fmt.Println("Start of Inbox")
body, err := ioutil.ReadAll(r.Body) body, err := ioutil.ReadAll(r.Body)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
return return
} }
defer r.Body.Close()
var findtype RelayBase var findtype RelayBase
err = json.Unmarshal(body, &findtype) err = json.Unmarshal(body, &findtype)
if err != nil { if err != nil {
log.Fatal("Unable to unmarshal here, exiting...") logWarn("Unable to unmarshal here, exiting...")
return
} }
switch findtype.Type { switch findtype.Type {
case "Create": case "Create":
var createobject CreateObject var createobject CreateObject
err = json.Unmarshal(findtype.Object, &createobject) err = json.Unmarshal(body, &createobject)
if err != nil { if err != nil {
return return
} }
@ -123,18 +141,70 @@ func inboxHandler() http.HandlerFunc {
go check_activity(createobject.ID) go check_activity(createobject.ID)
slashend := strings.Index(createobject.ID[8:], "/") slashend := strings.Index(createobject.ID[8:], "/")
newinstance := createobject.ID[8 : 8+slashend] newinstance := createobject.ID[8 : 8+slashend]
log.Print("The at sign is: ", newinstance)
go CheckInstance(newinstance, "") go CheckInstance(newinstance, "")
case "Update":
case "Reject":
case "Add":
case "Remove":
case "Like": case "Like":
case "Announcement": case "Announce":
var announceobject AnnounceObject
err = json.Unmarshal(body, &announceobject)
if err != nil {
fmt.Println(err.Error())
return
}
check_activity(announceobject.Object)
matchset := re.FindStringSubmatch(announceobject.Object)
if matchset != nil {
newinstance := matchset[1]
go CheckInstance(newinstance, "")
}
case "Delete": case "Delete":
case "Undo": case "Undo":
default: default:
fmt.Println("Others --> " + findtype.Type) fmt.Println("Unknown Others --> " + findtype.Type)
}
w.Header().Set("Content-Type", "application/json")
fmt.Fprintf(w, "{}")
fmt.Println("End of Inbox")
} }
} }
func internalFetch(w http.ResponseWriter, r *http.Request) {
publicKeyBytes, err := ioutil.ReadFile("keys/public.pem")
publicKeyString := string(publicKeyBytes)
publicKeyString = strings.Replace(publicKeyString, "\n", "\\n", -11)
if err != nil {
log.Fatal(err)
}
staticjson := fmt.Sprintf(`{"@context":["https://www.w3.org/ns/activitystreams","https://%[1]s/schemas/litepub-0.1.jsonld",{"@language":"und"}],"endpoints":{"oauthAuthorizationEndpoint":"https://%[1]s/oauth/authorize","oauthRegistrationEndpoint":"https://%[1]s/api/v1/apps","oauthTokenEndpoint":"https://%[1]s/oauth/token","sharedInbox":"https://%[1]s/inbox","uploadMedia":"https://%[1]s/api/ap/upload_media"},"followers":"https://%[1]s/internal/fetch/followers","following":"https://%[1]s/internal/fetch/following","id":"https://%[1]s/internal/fetch","inbox":"https://%[1]s/internal/fetch/inbox","invisible":true,"manuallyApprovesFollowers":false,"name":"Pleroma","preferredUsername":"fedilogue","publicKey":{"id":"https://%[1]s/internal/fetch#main-key","owner":"https://%[1]s/internal/fetch","publicKeyPem":"%[2]s"},"summary":"Fedilogue Key or something.","type":"Application","url":"https://%[1]s/internal/fetch"}`, r.Host, publicKeyString)
fmt.Fprintf(w, staticjson)
}
func relay(w http.ResponseWriter, r *http.Request) {
fmt.Println("Requesting: ", r.Host, " /relay")
publicKeyBytes, err := ioutil.ReadFile("keys/public.pem")
publicKeyString := string(publicKeyBytes)
publicKeyString = strings.Replace(publicKeyString, "\n", "\\n", -11)
if err != nil {
log.Fatal(err)
}
staticjson := fmt.Sprintf(`{"@context":["https://www.w3.org/ns/activitystreams","https://%[1]s/schemas/litepub-0.1.jsonld",{"@language":"und"}],"alsoKnownAs":[],"attachment":[],"capabilities":{},"discoverable":false,"endpoints":{"oauthAuthorizationEndpoint":"https://%[1]s/oauth/authorize","oauthRegistrationEndpoint":"https://%[1]s/api/v1/apps","oauthTokenEndpoint":"https://%[1]s/oauth/token","sharedInbox":"https://%[1]s/inbox","uploadMedia":"https://%[1]s/api/ap/upload_media"},"featured":"https://%[1]s/relay/collections/featured","followers":"https://%[1]s/relay/followers","following":"https://%[1]s/relay/following","id":"https://%[1]s/relay","inbox":"https://%[1]s/relay/inbox","manuallyApprovesFollowers":false,"name":null,"outbox":"https://%[1]s/relay/outbox","preferredUsername":"relay","publicKey":{"id":"https://%[1]s/relay#main-key","owner":"https://%[1]s/relay","publicKeyPem":"%[2]s"},"summary":"","tag":[],"type":"Person","url":"https://%[1]s/relay"}`, r.Host, publicKeyString)
fmt.Fprintf(w, staticjson)
} }
func usersFedilogueFollowers(w http.ResponseWriter, r *http.Request) { func usersFedilogueFollowers(w http.ResponseWriter, r *http.Request) {
@ -201,7 +271,7 @@ func usersFedilogue(w http.ResponseWriter, r *http.Request) {
actorjsonmap["publicKey"] = publicKey actorjsonmap["publicKey"] = publicKey
actorjsonmap["summary"] = "" actorjsonmap["summary"] = ""
actorjsonmap["tag"] = tag actorjsonmap["tag"] = tag
actorjsonmap["type"] = "Person" actorjsonmap["type"] = "Application"
actorjsonmap["uri"] = "https://" + host + "/users/fedilogue" actorjsonmap["uri"] = "https://" + host + "/users/fedilogue"
actorjsonbin, err := json.Marshal(actorjsonmap) actorjsonbin, err := json.Marshal(actorjsonmap)
@ -216,17 +286,32 @@ func usersFedilogue(w http.ResponseWriter, r *http.Request) {
} }
func errorHandler(w http.ResponseWriter, r *http.Request) { func errorHandler(w http.ResponseWriter, r *http.Request) {
fmt.Println("404 --> ", r.URL.Path) for name, headers := range r.Header {
fmt.Println("ROW: ", name, " ", headers)
for _, h := range headers {
fmt.Fprintf(w, "%v: %v\n", name, h)
}
}
reqBody, err := ioutil.ReadAll(r.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("POST DATA: %s\n", reqBody)
} }
func webmain() { func webmain() {
http.HandleFunc("/.well-known/webfinger", webfinger) http.HandleFunc("/.well-known/webfinger", webfinger)
http.HandleFunc("/.well-known/host-meta", hostmeta) http.HandleFunc("/.well-known/host-meta", hostmeta)
http.HandleFunc("/inbox", inboxHandler()) http.HandleFunc("/inbox", inboxHandler())
http.HandleFunc("/internal/fetch", internalFetch)
http.HandleFunc("/relay", relay)
http.HandleFunc("/users/fedilogue", usersFedilogue) http.HandleFunc("/users/fedilogue", usersFedilogue)
http.HandleFunc("/users/fedilogue/followers", usersFedilogueFollowers) http.HandleFunc("/users/fedilogue/followers", usersFedilogueFollowers)
http.HandleFunc("/users/fedilogue/following", usersFedilogueFollowing) http.HandleFunc("/users/fedilogue/following", usersFedilogueFollowing)
http.HandleFunc("/", errorHandler) http.HandleFunc("/", errorHandler)
log.Print("Starting HTTP inbox on port 8080") log.Print("Starting HTTP inbox on port 127.0.0.1:8042")
log.Fatal(http.ListenAndServe(":8080", nil)) log.Fatal(http.ListenAndServe("127.0.0.1:8042", nil))
} }

2
go.mod
View File

@ -3,6 +3,7 @@ module gitlab.com/khanzf/fedilogue
go 1.17 go 1.17
require ( require (
github.com/go-fed/httpsig v1.1.0
github.com/jackc/pgx/v4 v4.14.1 github.com/jackc/pgx/v4 v4.14.1
github.com/microcosm-cc/bluemonday v1.0.16 github.com/microcosm-cc/bluemonday v1.0.16
muzzammil.xyz/jsonc v0.0.0-20201229145248-615b0916ca38 muzzammil.xyz/jsonc v0.0.0-20201229145248-615b0916ca38
@ -21,5 +22,6 @@ require (
github.com/jackc/puddle v1.2.0 // indirect github.com/jackc/puddle v1.2.0 // indirect
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect
golang.org/x/net v0.0.0-20210614182718-04defd469f4e // indirect golang.org/x/net v0.0.0-20210614182718-04defd469f4e // indirect
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 // indirect
golang.org/x/text v0.3.6 // indirect golang.org/x/text v0.3.6 // indirect
) )

4
go.sum
View File

@ -10,6 +10,8 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI=
github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
@ -155,8 +157,10 @@ golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
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-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
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/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=