diff --git a/.gitignore b/.gitignore index d3d6d37..7240670 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ +config.json + data/* testdata diff --git a/README.md b/README.md index d8904ce..a0fab65 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,42 @@ Inspect how it's used on https://brainbaking.com/ - usually, a `` in your If you want to support the older pingback protocol, you can leverage webmenton.io's forward capabilities. Although I developed this primarily because webmention.io is _not_ reliable - you've been warned. +## Building and running + +Well, that's easy! + +1. Build: `go build` +2. Run: `./go-jamming` +3. ??? +4. Profit! + +## Configuration + +Place a `config.json` file in the same directory that looks like this: + +```json +{ + "port": 1337, + "host": "localhost", + "token": "sometoken", + "dataPath": "data", + "utcOffset": 60, + "allowedWebmentionSources": [ + "blah.com" + ], + "disallowedWebmentionDomains": [ + "youtube.com" + ] +} +``` + +- port, host: http server params +- token, allowedWebmentionSources: see below, used for authentication +- utcOffset: offset in minutes for date processing, starting from UTC time. +- dataPath: path to store all mentions as md5-encoded JSON filenames. + +If a config file is missing, or required keys are missing, a warning will be generated and default values will be used instead. See `common/config.go`. + ## What's in it? ### 1. Webmentions @@ -38,11 +74,11 @@ Accepted form format: target=https://aaronpk.example/post-by-aaron ``` -Will result in a `202 Accepted` - it handles things async. Stores in `.json` files in `data/domain`. +Will result in a `202 Accepted` - it handles things async. Stores in `.json` files in `[dataPath]/domain`. #### 1.2 `GET /webmention/:domain/:token` -Retrieves a JSON array with relevant webmentions stored for that domain. The token should match. See `config.js` to fiddle with it yourself. Environment variables are supported, although I haven't used them yet. +Retrieves a JSON array with relevant webmentions stored for that domain. The token should match. See configuration to fiddle with it yourself. Environment variables are supported, although I haven't used them yet. #### 1.3 `PUT /webmention/:domain/:token` @@ -95,8 +131,3 @@ Will result in a `200 OK` - that returns XML according to [The W3 pingback XML-R Happens automatically through `PUT /webmention/:domain/:token`! Links that are discovered as `rel="pingback"` that **do not** already have a webmention link will be processed as XML-RPC requests to be send. - -## TODOs - -- `published` date is not well-formatted and blindly taken over from feed -- Implement a Brid.gy-like system that converts links from domains in the config found on [public Mastodon timelines](https://docs.joinmastodon.org/methods/timelines/) into webmentions. (And check if it's ok to only use the public line) diff --git a/common/config.go b/common/config.go index f6df1f5..91bb649 100644 --- a/common/config.go +++ b/common/config.go @@ -1,21 +1,39 @@ package common import ( + "encoding/json" "errors" + "io/ioutil" "os" - "strconv" "strings" "github.com/rs/zerolog/log" ) type Config struct { - Port int - Token string - UtcOffset int - DataPath string - AllowedWebmentionSources []string - DisallowedWebmentionDomains []string + Port int `json:"port"` + Token string `json:"token"` + UtcOffset int `json:"utcOffset"` + DataPath string `json:"dataPath"` + AllowedWebmentionSources []string `json:"allowedWebmentionSources"` + DisallowedWebmentionDomains []string `json:"disallowedWebmentionDomains"` +} + +func (c *Config) missingKeys() []string { + keys := []string{} + if c.Port == 0 { + keys = append(keys, "port") + } + if c.Token == "" { + keys = append(keys, "token") + } + if c.DataPath == "" { + keys = append(keys, "dataPath") + } + if len(c.AllowedWebmentionSources) == 0 { + keys = append(keys, "allowedWebmentionSources") + } + return keys } func (c *Config) ContainsDisallowedDomain(url string) bool { @@ -53,23 +71,33 @@ func (c *Config) SetupDataDirs() { } func Configure() (c *Config) { - portstr := os.Getenv("PORT") - port, err := strconv.Atoi(portstr) + confData, err := ioutil.ReadFile("config.json") if err != nil { - port = 1337 - } - token := os.Getenv("TOKEN") - if token == "" { - token = "miauwkes" + log.Warn().Msg("No config.json file found, reverting to defaults...") + return defaultConfig() } - c = &Config{ - Port: port, - Token: token, + conf := &Config{} + err = json.Unmarshal(confData, conf) + if err != nil { + log.Warn().Msg("config.json malformed JSON, reverting to defaults...") + return defaultConfig() + } + someMissingKeys := conf.missingKeys() + if len(someMissingKeys) > 0 { + log.Warn().Str("keys", strings.Join(someMissingKeys, ", ")).Msg("config.json is missing required keys, reverting to defaults...") + return defaultConfig() + } + return conf +} + +func defaultConfig() *Config { + return &Config{ + Port: 1337, + Token: "miauwkes", UtcOffset: 60, DataPath: "data", AllowedWebmentionSources: []string{"brainbaking.com", "jefklakscodex.com"}, DisallowedWebmentionDomains: []string{"youtube.com"}, } - return }