From 1eec0012845315d643983eca6cbcb085649e877c Mon Sep 17 00:00:00 2001 From: Matt Baer Date: Sun, 11 Mar 2018 16:55:16 -0400 Subject: [PATCH 1/6] Add missing ADMIN_PASS and BROWSE_ITEMS info (in README) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 1050ad1..96f16ea 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,8 @@ DB_USER=dbuser DB_PASSWORD=pass DB_DB=htmlhouse PRIVATE_KEY=keys/dev PUBLIC_KEY= | `STATIC_DIR` | Relative dir where static files are stored | `static` | | `AUTO_APPROVE` | Automatically approves public posts | false | | `PREVIEWS_HOST` | Fully-qualified URL (without trailing slash) of screenshot server | None. | +| `ADMIN_PASS` | Password to perform admin functions via API | `uhoh` | +| `BROWSE_ITEMS` | Number of items to show on Browse page | 10 | | `TWITTER_KEY` | Twitter consumer key | `notreal` | | `TWITTER_SECRET` | Twitter consumer secret | `notreal` | | `TWITTER_TOKEN` | Twitter access token of the posting Twitter account | `notreal` | From 06d7569fa38a05afafe7a9e02fd3a47bd7d01dbc Mon Sep 17 00:00:00 2001 From: Matt Baer Date: Mon, 12 Mar 2018 11:00:52 -0400 Subject: [PATCH 2/6] Parse JWT keys correctly This now parses into rsa.{Public|Private}Key structs, as required by current jwt library. --- session.go | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/session.go b/session.go index 66a117d..4f5ad37 100644 --- a/session.go +++ b/session.go @@ -1,6 +1,7 @@ package htmlhouse import ( + "crypto/rsa" "fmt" jwt "github.com/dgrijalva/jwt-go" "github.com/juju/errgo" @@ -30,22 +31,32 @@ func newSessionInfo(houseID string) *sessionInfo { func newSessionManager(cfg *config) (sessionManager, error) { mgr := &defaultSessionManager{} - var err error - - mgr.signKey, err = ioutil.ReadFile(cfg.PrivateKey) + // Read and parse private key + signBytes, err := ioutil.ReadFile(cfg.PrivateKey) + if err != nil { + return mgr, errgo.Mask(err) + } + mgr.signKey, err = jwt.ParseRSAPrivateKeyFromPEM(signBytes) if err != nil { return mgr, errgo.Mask(err) } - mgr.verifyKey, err = ioutil.ReadFile(cfg.PublicKey) + // Read and parse public key + verifyBytes, err := ioutil.ReadFile(cfg.PublicKey) if err != nil { return mgr, errgo.Mask(err) } + mgr.verifyKey, err = jwt.ParseRSAPublicKeyFromPEM(verifyBytes) + if err != nil { + return mgr, errgo.Mask(err) + } + return mgr, nil } type defaultSessionManager struct { - verifyKey, signKey []byte + verifyKey *rsa.PublicKey + signKey *rsa.PrivateKey } func (m *defaultSessionManager) readToken(r *http.Request) (string, error) { From 597395f312f475ccffba2c4f38792c45016dc7a4 Mon Sep 17 00:00:00 2001 From: Matt Baer Date: Mon, 12 Mar 2018 11:03:55 -0400 Subject: [PATCH 3/6] Read API data in editor from top-level object There is no more meta object --- templates/editor.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/editor.html b/templates/editor.html index 4743b5e..4a71e58 100644 --- a/templates/editor.html +++ b/templates/editor.html @@ -125,7 +125,7 @@

HTMLhouse

data: {html: editor.getSession().getValue(), public: $publicCheck.checked ? "true" : ""}, success: function(data, status, xhr) { publishing = false; - {{if .ID}}if (data.meta.code == 200) { {{else}}if (data.meta.code == 201) { + {{if .ID}}if (data.code == 200) { {{else}}if (data.code == 201) { var houses = JSON.parse(H.get('neighborhood', '[]')); houses.push({id: data.data.id, token: xhr.getResponseHeader('Authorization')}); H.set('neighborhood', JSON.stringify(houses));{{end}} @@ -133,7 +133,7 @@

HTMLhouse

{{if .ID}}{{else}}H.remove('constructionSite');{{end}} window.location = '/' + data.data.id + '.html'; } else { - alert(data.meta.error_msg); + alert(data.error_msg); } }, error: function(jqXHR, status, error) { From 702d5234c051026dc9b3016b6f15b3c50a746c9d Mon Sep 17 00:00:00 2001 From: Matt Baer Date: Mon, 12 Mar 2018 11:10:55 -0400 Subject: [PATCH 4/6] Catch errors parsing PreviewsHost URI This prevents the app crashing if a bad URI is given. --- construction.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/construction.go b/construction.go index 9e6d69d..3f8165c 100644 --- a/construction.go +++ b/construction.go @@ -7,6 +7,7 @@ import ( "io/ioutil" "net/http" "net/url" + "os" "regexp" "strconv" "strings" @@ -90,6 +91,10 @@ func addPublicAccess(app *app, houseID, html string) error { data.Set("url", fmt.Sprintf("%s/%s.html", app.cfg.HostName, houseID)) u, err := url.ParseRequestURI(app.cfg.PreviewsHost) + if err != nil { + fmt.Fprintf(os.Stderr, "Error parsing request URI: %v\n", err) + return err + } u.Path = "/" urlStr := fmt.Sprintf("%v", u) From 2caebcfecffad6d472db7b11c2082b43d6d5f270 Mon Sep 17 00:00:00 2001 From: Matt Baer Date: Mon, 12 Mar 2018 11:20:56 -0400 Subject: [PATCH 5/6] Support blacklist for terms that prevent a public post This adds a BLACKLIST_TERMS configuration value that contains a comma-separated list of terms that indicate spam posts and will prevent a link from being showcased on the Browse page, tweeted out, etc. --- README.md | 1 + config.go | 11 +++++++++++ construction.go | 2 +- filter.go | 6 ++++++ 4 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 filter.go diff --git a/README.md b/README.md index 96f16ea..286e994 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ DB_USER=dbuser DB_PASSWORD=pass DB_DB=htmlhouse PRIVATE_KEY=keys/dev PUBLIC_KEY= | `PREVIEWS_HOST` | Fully-qualified URL (without trailing slash) of screenshot server | None. | | `ADMIN_PASS` | Password to perform admin functions via API | `uhoh` | | `BROWSE_ITEMS` | Number of items to show on Browse page | 10 | +| `BLACKLIST_TERMS` | Comma-separated list of terms to prevent a post from being made public | None. | | `TWITTER_KEY` | Twitter consumer key | `notreal` | | `TWITTER_SECRET` | Twitter consumer secret | `notreal` | | `TWITTER_TOKEN` | Twitter access token of the posting Twitter account | `notreal` | diff --git a/config.go b/config.go index 41e64b5..cbd6943 100644 --- a/config.go +++ b/config.go @@ -2,6 +2,8 @@ package htmlhouse import ( "github.com/danryan/env" + "regexp" + "strings" ) type config struct { @@ -23,6 +25,9 @@ type config struct { AdminPass string `env:"key=ADMIN_PASS default=uhoh"` BrowseItems int `env:"key=BROWSE_ITEMS default=10"` + BlacklistTerms string `env:"key=BLACKLIST_TERMS"` + BlacklistReg *regexp.Regexp + // Twitter configuration TwitterConsumerKey string `env:"key=TWITTER_KEY default=notreal"` TwitterConsumerSecret string `env:"key=TWITTER_SECRET default=notreal"` @@ -36,5 +41,11 @@ func newConfig() (*config, error) { return cfg, err } + // Process anything + termsReg := `(?i)\b` + cfg.BlacklistTerms + `\b` + termsReg = strings.Replace(termsReg, ",", `\b|\b`, -1) + cfg.BlacklistReg = regexp.MustCompile(termsReg) + + // Return result return cfg, nil } diff --git a/construction.go b/construction.go index 3f8165c..018b449 100644 --- a/construction.go +++ b/construction.go @@ -39,7 +39,7 @@ func createHouse(app *app, w http.ResponseWriter, r *http.Request) error { resUser := newSessionInfo(houseID) - if public { + if public && passesPublicFilter(app, html) { go addPublicAccess(app, houseID, html) } diff --git a/filter.go b/filter.go new file mode 100644 index 0000000..703f7e4 --- /dev/null +++ b/filter.go @@ -0,0 +1,6 @@ +package htmlhouse + +func passesPublicFilter(app *app, html string) bool { + spam := app.cfg.BlacklistReg.MatchString(html) + return !spam +} From 7893f07a808f00a65c41777ac77bcab3708cbd20 Mon Sep 17 00:00:00 2001 From: Matt Baer Date: Mon, 12 Mar 2018 11:28:20 -0400 Subject: [PATCH 6/6] Automatically pass public filter when no blacklist configured --- filter.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/filter.go b/filter.go index 703f7e4..0e75516 100644 --- a/filter.go +++ b/filter.go @@ -1,6 +1,10 @@ package htmlhouse func passesPublicFilter(app *app, html string) bool { + if app.cfg.BlacklistTerms == "" { + return true + } + spam := app.cfg.BlacklistReg.MatchString(html) return !spam }