DataHoarder
e2885687b2
All checks were successful
continuous-integration/drone/push Build is passing
125 lines
3.4 KiB
Go
125 lines
3.4 KiB
Go
package index
|
|
|
|
import (
|
|
"errors"
|
|
"git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/sidechain"
|
|
"git.gammaspectra.live/P2Pool/p2pool-observer/utils"
|
|
"net/url"
|
|
"slices"
|
|
"strings"
|
|
)
|
|
|
|
type MinerWebHook struct {
|
|
Miner uint64 `json:"miner"`
|
|
Type WebHookType `json:"type"`
|
|
Url string `json:"url"`
|
|
Settings map[string]string `json:"settings"`
|
|
Consensus *sidechain.Consensus `json:"-"`
|
|
}
|
|
|
|
type WebHookType string
|
|
|
|
const (
|
|
WebHookSlack WebHookType = "slack"
|
|
WebHookDiscord WebHookType = "discord"
|
|
WebHookTelegram WebHookType = "telegram"
|
|
WebHookMatrixHookshot WebHookType = "matrix-hookshot"
|
|
WebHookCustom WebHookType = "custom"
|
|
)
|
|
|
|
var disallowedCustomHookHosts = []string{
|
|
"hooks.slack.com",
|
|
"discord.com",
|
|
"api.telegram.org",
|
|
}
|
|
|
|
var disallowedCustomHookPorts = []string{}
|
|
|
|
func (w *MinerWebHook) ScanFromRow(consensus *sidechain.Consensus, row RowScanInterface) error {
|
|
var settingsBuf []byte
|
|
|
|
w.Consensus = consensus
|
|
w.Settings = make(map[string]string)
|
|
|
|
if err := row.Scan(&w.Miner, &w.Type, &w.Url, &settingsBuf); err != nil {
|
|
return err
|
|
} else if err = utils.UnmarshalJSON(settingsBuf, &w.Settings); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (w *MinerWebHook) Verify() error {
|
|
uri, err := url.Parse(w.Url)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
switch w.Type {
|
|
case WebHookSlack:
|
|
if uri.Scheme != "https" {
|
|
return errors.New("invalid URL scheme, expected https")
|
|
}
|
|
if uri.Host != "hooks.slack.com" {
|
|
return errors.New("invalid hook host, expected hooks.slack.com")
|
|
}
|
|
if uri.Port() != "" {
|
|
return errors.New("unexpected port")
|
|
}
|
|
if !strings.HasPrefix(uri.Path, "/services/") {
|
|
return errors.New("invalid hook path start")
|
|
}
|
|
case WebHookDiscord:
|
|
if uri.Scheme != "https" {
|
|
return errors.New("invalid URL scheme, expected https")
|
|
}
|
|
if uri.Host != "discord.com" {
|
|
return errors.New("invalid hook host, expected discord.com")
|
|
}
|
|
if uri.Port() != "" {
|
|
return errors.New("unexpected port")
|
|
}
|
|
if !strings.HasPrefix(uri.Path, "/api/webhooks/") {
|
|
return errors.New("invalid hook path start")
|
|
}
|
|
case WebHookTelegram:
|
|
if uri.Scheme != "https" {
|
|
return errors.New("invalid URL scheme, expected https")
|
|
}
|
|
if uri.Host != "api.telegram.org" {
|
|
return errors.New("invalid hook host, expected api.telegram.org")
|
|
}
|
|
if uri.Port() != "" {
|
|
return errors.New("unexpected port")
|
|
}
|
|
if !strings.HasPrefix(uri.Path, "/bot") {
|
|
return errors.New("invalid hook path start")
|
|
}
|
|
if !strings.HasSuffix(uri.Path, "/sendMessage") {
|
|
return errors.New("invalid hook path end")
|
|
}
|
|
case WebHookMatrixHookshot:
|
|
if uri.Scheme != "https" {
|
|
return errors.New("invalid URL scheme, expected https")
|
|
}
|
|
if slices.Contains(disallowedCustomHookHosts, strings.ToLower(uri.Hostname())) {
|
|
return errors.New("disallowed hook host")
|
|
}
|
|
if uri.Port() != "" {
|
|
return errors.New("unexpected port")
|
|
}
|
|
case WebHookCustom:
|
|
if uri.Scheme != "https" && uri.Scheme != "http" {
|
|
return errors.New("invalid URL scheme, expected http or https")
|
|
}
|
|
if slices.Contains(disallowedCustomHookHosts, strings.ToLower(uri.Hostname())) {
|
|
return errors.New("disallowed hook host")
|
|
}
|
|
if slices.Contains(disallowedCustomHookPorts, strings.ToLower(uri.Port())) {
|
|
return errors.New("disallowed hook port")
|
|
}
|
|
default:
|
|
return errors.New("unsupported hook type")
|
|
}
|
|
return nil
|
|
}
|