From 3e44a44f5040981341e11b53d71283b95e2004d2 Mon Sep 17 00:00:00 2001 From: Aaron Bieber Date: Tue, 18 Feb 2020 20:20:01 -0700 Subject: [PATCH] add ability to check federation status of homeservers --- README.md | 1 + plugins/federation.go | 110 ++++++++++++++++++++++++++++++++++++++++++ plugins/plugins.go | 1 + 3 files changed, 112 insertions(+) create mode 100644 plugins/federation.go diff --git a/README.md b/README.md index 86cb956..7007d0d 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ |Beat|`(?i)^\.beat$|^what time is it\?$|^beat( )?time:?\??$`|Print the current [beat time](https://en.wikipedia.org/wiki/Swatch_Internet_Time).| |Beer|`(?i)^beer: `|Queries [OpenDataSoft](https://public-us.opendatasoft.com/explore/dataset/open-beer-database/table/)'s beer database for a given beer.| |BotSnack|`(?i)botsnack`|Consumes a botsnack. This pleases mcchunkie and brings balance to the universe.| +|Feder|`(?i)^feder: (.*)$`|check the Matrix federation status of a given URL.| |HighFive|`o/|\o`|Everyone loves highfives.| |Hi|`(?i)^hi|hi$`|Friendly bots say hi.| |LoveYou|`(?i)i love you`|Spreading love where ever we can by responding when someone shows us love.| diff --git a/plugins/federation.go b/plugins/federation.go new file mode 100644 index 0000000..cb26fc3 --- /dev/null +++ b/plugins/federation.go @@ -0,0 +1,110 @@ +package plugins + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "log" + "net/http" + "net/url" + "regexp" + + "github.com/matrix-org/gomatrix" +) + +// ServiceInfo represents the version info from a response +type ServiceInfo struct { + Name string `json:"name"` + Version string `json:"version"` +} + +// FedResp represents a federation statuse response +type FedResp struct { + Status bool `json:"FederationOK"` + Info ServiceInfo `json:"Version"` +} + +// Feder responds to federation check requests +type Feder struct { +} + +// Descr describes this plugin +func (h *Feder) Descr() string { + return "check the Matrix federation status of a given URL." +} + +// Re returns the federation check matching string +func (h *Feder) Re() string { + return `(?i)^feder: (.*)$` +} + +func (h *Feder) fix(msg string) string { + re := regexp.MustCompile(h.Re()) + return re.ReplaceAllString(msg, "$1") +} + +// Match determines if we should call the response for Feder +func (h *Feder) Match(user, msg string) bool { + re := regexp.MustCompile(h.Re()) + return re.MatchString(msg) +} + +func (h *Feder) get(hserver string) (*FedResp, error) { + u := "https://federationtester.matrix.org/api/report?server_name=" + u = fmt.Sprintf("%s%s", u, url.PathEscape(hserver)) + resp, err := http.Get(u) + if err != nil { + return nil, err + } + + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + var fresp = &FedResp{} + err = json.Unmarshal([]byte(body), fresp) + if err != nil { + return nil, err + } + + return fresp, nil +} + +// SetStore we don't need a store here. +func (h *Feder) SetStore(s PluginStore) {} + +// RespondText to looking up of federation check requests +func (h *Feder) RespondText(c *gomatrix.Client, ev *gomatrix.Event, user, post string) { + homeServer := h.fix(post) + if homeServer != "" { + u, err := url.Parse(fmt.Sprintf("https://%s", homeServer)) + if err != nil { + SendText(c, ev.RoomID, "that's not a real host name.") + return + } + + homeServer = u.Hostname() + + log.Printf("%s: responding to '%s'", h.Name(), ev.Sender) + fed, err := h.get(homeServer) + if err != nil { + SendText(c, ev.RoomID, fmt.Sprintf("sorry %s, I can't look up the federation status (%s)", ev.Sender, err)) + } + + stat := "broken" + if fed.Status { + stat = "OK" + } + SendText(c, ev.RoomID, fmt.Sprintf("%s is running %s (%s) and is %s.", + homeServer, fed.Info.Name, fed.Info.Version, stat)) + + } +} + +// Name Feder! +func (h *Feder) Name() string { + return "Feder" +} diff --git a/plugins/plugins.go b/plugins/plugins.go index b84832c..f9b8dba 100644 --- a/plugins/plugins.go +++ b/plugins/plugins.go @@ -73,6 +73,7 @@ var Plugs = Plugins{ &Beat{}, &Beer{}, &BotSnack{}, + &Feder{}, &HighFive{}, &Hi{}, &LoveYou{},