From 196acdb134416471484125bad001358a03e1708e Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 6 Nov 2018 15:05:59 -0500 Subject: [PATCH 01/14] initial spam ui --- contrib/backends/srndv2/src/srnd/daemon.go | 6 +++ .../backends/srndv2/src/srnd/frontend_http.go | 1 + contrib/backends/srndv2/src/srnd/mod.go | 43 ++++++++++++++++- contrib/backends/srndv2/src/srnd/mod_http.go | 33 +++++++++++++ contrib/backends/srndv2/src/srnd/spam.go | 38 ++++++++++++--- contrib/backends/srndv2/src/srnd/store.go | 14 ++++++ contrib/backends/srndv2/src/srnd/util.go | 13 ++--- contrib/static/overchan.js | 47 +++++++++++++++++++ contrib/templates/placebo/board.mustache | 1 + contrib/templates/placebo/post.mustache | 1 + contrib/templates/placebo/thread.mustache | 1 + contrib/templates/placebo/ukko.mustache | 1 + 12 files changed, 183 insertions(+), 16 deletions(-) diff --git a/contrib/backends/srndv2/src/srnd/daemon.go b/contrib/backends/srndv2/src/srnd/daemon.go index 5f1259f..69cd8c0 100644 --- a/contrib/backends/srndv2/src/srnd/daemon.go +++ b/contrib/backends/srndv2/src/srnd/daemon.go @@ -535,6 +535,12 @@ func (self *NNTPDaemon) ExpireAll() { self.expire.ExpireOrphans() } +func (self *NNTPDaemon) MarkSpam(msgid string) { + if ValidMessageID(msgid) { + self.modEngine.MarkSpam(msgid) + } +} + // run daemon func (self *NNTPDaemon) Run() { self.spamFilter.Configure(self.conf.spamconf) diff --git a/contrib/backends/srndv2/src/srnd/frontend_http.go b/contrib/backends/srndv2/src/srnd/frontend_http.go index dcd3ca9..dd37673 100644 --- a/contrib/backends/srndv2/src/srnd/frontend_http.go +++ b/contrib/backends/srndv2/src/srnd/frontend_http.go @@ -1405,6 +1405,7 @@ func (self *httpFrontend) Mainloop() { m.Path("/mod/feeds").HandlerFunc(self.modui.ServeModPage).Methods("GET") m.Path("/mod/keygen").HandlerFunc(self.modui.HandleKeyGen).Methods("GET") m.Path("/mod/login").HandlerFunc(self.modui.HandleLogin).Methods("POST") + m.Path("/mod/spam").HandlerFunc(self.modui.HandlePostSpam).Methods("POST") m.Path("/mod/del/{article_hash}").HandlerFunc(self.modui.HandleDeletePost).Methods("GET") m.Path("/mod/ban/{address}").HandlerFunc(self.modui.HandleBanAddress).Methods("GET") m.Path("/mod/unban/{address}").HandlerFunc(self.modui.HandleUnbanAddress).Methods("GET") diff --git a/contrib/backends/srndv2/src/srnd/mod.go b/contrib/backends/srndv2/src/srnd/mod.go index c3ad8c0..19a387d 100644 --- a/contrib/backends/srndv2/src/srnd/mod.go +++ b/contrib/backends/srndv2/src/srnd/mod.go @@ -44,6 +44,10 @@ type ModUI interface { HandleKeyGen(wr http.ResponseWriter, r *http.Request) // handle admin command HandleAdminCommand(wr http.ResponseWriter, r *http.Request) + // handle mark a post as spam + HandlePostSpam(wr http.ResponseWriter, r *http.Request) + + // get outbound message channel MessageChan() chan NNTPMessage } @@ -57,6 +61,8 @@ const ModStick = ModAction("overchan-stick") const ModLock = ModAction("overchan-lock") const ModHide = ModAction("overchan-hide") const ModSage = ModAction("overchan-sage") +const ModSpam = ModAction("spam") +const ModHam = ModAction("ham") const ModDeleteAlt = ModAction("delete") type ModEvent interface { @@ -81,11 +87,15 @@ func (self simpleModEvent) String() string { } func (self simpleModEvent) Action() ModAction { - switch strings.Split(string(self), " ")[0] { + switch strings.ToLower(strings.Split(string(self), " ")[0]) { case "delete": return ModDelete case "overchan-inet-ban": return ModInetBan + case "spam": + return ModSpam + case "ham": + return ModHam } return "" } @@ -122,6 +132,11 @@ func overchanInetBan(encAddr, key string, expire int64) ModEvent { return simpleModEvent(fmt.Sprintf("overchan-inet-ban %s:%s:%d", encAddr, key, expire)) } +// create a mark as spam event +func modMarkSpam(msgid string) ModEvent { + return simpleModEvent(fmt.Sprintf("spam %s", msgid)) +} + // moderation message // wraps multiple mod events // is turned into an NNTPMessage later @@ -171,6 +186,8 @@ type ModEngine interface { HandleMessage(msgid string) // delete post of a poster DeletePost(msgid string) error + // mark message as spam + MarkSpam(msgid string) error // ban a cidr BanAddress(cidr string) error // do we allow this public key to delete this message-id ? @@ -190,9 +207,23 @@ type ModEngine interface { type modEngine struct { database Database store ArticleStore + spam *SpamFilter regen RegenFunc } +func (self *modEngine) MarkSpam(msgid string) (err error) { + if self.spam == nil { + err = self.store.MarkSpam(msgid) + } else { + f, err = self.store.OpenMessage(msgid) + if err == nil { + err = self.spam.MarkSpam(f) + f.Close() + } + } + return +} + func (self *modEngine) LoadMessage(msgid string) NNTPMessage { return self.store.GetMessage(msgid) } @@ -394,6 +425,10 @@ func (mod *modEngine) Do(ev ModEvent) { } else { log.Printf("invalid overchan-inet-ban: target=%s", target) } + } else if action == ModSpam { + if ValidMessageID(target) { + mod.MarkSpam(target) + } } else if action == ModHide { // TODO: implement } else if action == ModLock { @@ -434,6 +469,11 @@ func (mod *modEngine) Execute(ev ModEvent, pubkey string) { mod.Do(ev) } return + case ModSpam: + if mod.AllowJanitor(pubkey) { + mod.Do(ev) + } + return case ModHide: case ModLock: case ModSage: @@ -442,6 +482,7 @@ func (mod *modEngine) Execute(ev ModEvent, pubkey string) { if mod.AllowJanitor(pubkey) { mod.Do(ev) } + return default: // invalid action } diff --git a/contrib/backends/srndv2/src/srnd/mod_http.go b/contrib/backends/srndv2/src/srnd/mod_http.go index 56831df..475cd5b 100644 --- a/contrib/backends/srndv2/src/srnd/mod_http.go +++ b/contrib/backends/srndv2/src/srnd/mod_http.go @@ -523,6 +523,39 @@ func (self httpModUI) asAuthedWithMessage(scope string, handler func(ArticleEntr }, wr, req) } +func (self httpModUI) HandlePostSpam(wr http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + wr.WriteHeader(405) + return + } + resp := make(map[string]interface{}) + self.asAuthed("spam", func(path string) { + var mm ModMessage + keys := string.Split(r.FormValue("spam"), ",") + for _, k := range keys { + k = strings.TrimSpace(k) + go self.daemon.MarkSpam(k) + mm = append(mm, modMarkSpam(k)) + } + privkey_bytes := self.getSessionPrivkeyBytes(r) + if privkey_bytes == nil { + // this should not happen + log.Println("failed to get privkey bytes from session") + resp["error"] = "failed to get private key from session. wtf?" + } else { + // wrap and sign + nntp := wrapModMessage(mm) + nntp, err = signArticle(nntp, privkey_bytes) + if err == nil { + // federate + self.modMessageChan <- nntp + } + resp["error"] = err + } + }) + json.NewEncoder(wr).Encode(resp) +} + func (self httpModUI) HandleAddPubkey(wr http.ResponseWriter, r *http.Request) { } diff --git a/contrib/backends/srndv2/src/srnd/spam.go b/contrib/backends/srndv2/src/srnd/spam.go index 4d92cc2..094a38e 100644 --- a/contrib/backends/srndv2/src/srnd/spam.go +++ b/contrib/backends/srndv2/src/srnd/spam.go @@ -34,20 +34,44 @@ type SpamResult struct { IsSpam bool } +// feed spam subsystem a spam post +func (sp *SpamFilter) MarkSpam(msg io.Reader) (err error) { + var buff [65636]byte + + var u *user.User + u, err = user.Current() + if err != nil { + return + } + var conn *net.TCPConn + conn, err = sp.openConn() + if err != nil { + return + } + defer conn.Close() + fmt.Fprintf(conn, "TELL SPAMC/1.5\r\nUser: %s\r\nMessage-class: spam\r\nSet: local\r\n", u.Username) + io.CopyBuffer(conn, buf[:], msg) + conn.CloseWrite() + r := bufio.NewReader(conn) +} + +func (sp *SpamFilter) openConn() (*net.TCPConn, error) { + addr, err := net.ResolveTCPAddr("tcp", sp.addr) + if err != nil { + return nil, err + } + return net.DialTCP("tcp", nil, addr) +} + func (sp *SpamFilter) Rewrite(msg io.Reader, out io.WriteCloser, group string) (result SpamResult) { var buff [65636]byte if !sp.Enabled(group) { result.Err = ErrSpamFilterNotEnabled return } - var addr *net.TCPAddr - var c *net.TCPConn var u *user.User - addr, result.Err = net.ResolveTCPAddr("tcp", sp.addr) - if result.Err != nil { - return - } - c, result.Err = net.DialTCP("tcp", nil, addr) + var c *net.TCPConn + c, result.Err = sp.openConn() if result.Err != nil { return } diff --git a/contrib/backends/srndv2/src/srnd/store.go b/contrib/backends/srndv2/src/srnd/store.go index bba2361..1adbe7b 100644 --- a/contrib/backends/srndv2/src/srnd/store.go +++ b/contrib/backends/srndv2/src/srnd/store.go @@ -9,6 +9,7 @@ import ( "bytes" "compress/gzip" "errors" + "fmt" "io" "io/ioutil" "log" @@ -94,6 +95,12 @@ type ArticleStore interface { // get filepath for spam file via msgid SpamFile(msgid string) string + MarkHam(msgid string) error + UnmarkHam(msgid string) error + + // get filepath for ham + HamFile(msgid string) string + // iterate over all spam messages IterSpam(func(string) error) error @@ -115,6 +122,7 @@ type articleStore struct { identify_path string placeholder string spamdir string + hamdir string compression bool compWriter *gzip.Writer spamd *SpamFilter @@ -136,6 +144,8 @@ func createArticleStore(config map[string]string, thumbConfig *ThumbnailConfig, compression: config["compression"] == "1", spamd: spamd, spamdir: filepath.Join(config["store_dir"], "spam"), + hamdir: filepath.Join(config["store_dir"], "ham"), + thumbnails: thumbConfig, } store.Init() @@ -781,7 +791,11 @@ func (self *articleStore) AcceptTempArticle(msgid string) (err error) { } else { err = os.Rename(temp, store) } + } else { + err = fmt.Errorf("no such inbound article %s", temp) } + } else { + err = fmt.Errorf("invalid message id %s", msgid) } return } diff --git a/contrib/backends/srndv2/src/srnd/util.go b/contrib/backends/srndv2/src/srnd/util.go index fedd80a..21023f9 100644 --- a/contrib/backends/srndv2/src/srnd/util.go +++ b/contrib/backends/srndv2/src/srnd/util.go @@ -789,14 +789,11 @@ func storeMessage(daemon *NNTPDaemon, hdr textproto.MIMEHeader, body io.Reader) } else { log.Println("error processing message body", err) } - if err != nil { - // clean up - if ValidMessageID(msgid) { - fname := daemon.store.GetFilenameTemp(msgid) - log.Println("clean up", fname) - DelFile(fname) - } - log.Println("error processing message", err) + + // clean up + if ValidMessageID(msgid) { + fname := daemon.store.GetFilenameTemp(msgid) + DelFile(fname) } return } diff --git a/contrib/static/overchan.js b/contrib/static/overchan.js index 487ee05..6395b9b 100644 --- a/contrib/static/overchan.js +++ b/contrib/static/overchan.js @@ -9,6 +9,53 @@ var ready = function() { for(var idx = 0; idx < _onreadyfuncs.length; idx++) _onreadyfuncs[idx](); }; +var nntpchan_mod_mark_spam = function(longhash) { + var elem = document.getElementById(longhash); + if(!elem) return; + elem.dataset.spam = "yes"; + elem.innerText = "spam"; +}; + +var nntpchan_mod_commit_spam = function(elem) { + var formdata = new FormData(); + var posts = document.getElementsByClassName("post"); + var spams = []; + for (var idx = 0; idx < posts.length; idx ++) + { + if(posts[idx].dataset.spam == "yes") + { + spams.push_back(posts[idx].dataset.msgid); + } + } + formdata.set("spam", spams.join(",")); + var ajax = new XMLHttpRequest(); + ajax.onreadystatechange = function() { + if(ajax.readyState == 4) + { + if(ajax.status == 200) + { + // success (?) + var j = JSON.parse(ajax.responseText); + if(j.error) + { + elem.innerText = "could not mark as spam: " + j.error; + } + else + { + elem.innerText = "OK: marked as spam"; + } + } + else + { + elem.innerText = "post not marked as spam on server: "+ ajax.statusText; + } + } + }; + ajax.open("POST", "/mod/spam") + ajax.send(formdata); + +}; + var nntpchan_mod_delete = function(longhash) { var elem = document.getElementById(longhash); var ajax = new XMLHttpRequest(); diff --git a/contrib/templates/placebo/board.mustache b/contrib/templates/placebo/board.mustache index dcea38b..80aa05b 100644 --- a/contrib/templates/placebo/board.mustache +++ b/contrib/templates/placebo/board.mustache @@ -38,6 +38,7 @@ Most of the rest of the wild west.
{{board.Name}}
+

{{{form}}} {{#board.Threads}} diff --git a/contrib/templates/placebo/post.mustache b/contrib/templates/placebo/post.mustache index 25b1293..80b2838 100644 --- a/contrib/templates/placebo/post.mustache +++ b/contrib/templates/placebo/post.mustache @@ -31,6 +31,7 @@ {{/post.Attachments}} [Delete] + [Spam] {{post.Subject}} {{post.Name}} {{post.Frontend}} || {{post.Date}} {{{post.Pubkey}}} [Reply] {{post.ShortHash}} diff --git a/contrib/templates/placebo/thread.mustache b/contrib/templates/placebo/thread.mustache index 34e6ebb..9276cb3 100644 --- a/contrib/templates/placebo/thread.mustache +++ b/contrib/templates/placebo/thread.mustache @@ -48,6 +48,7 @@ Most of the rest of the wild west.
{{thread.Board}}
+

{{{form}}} {{#thread.BumpLock}} diff --git a/contrib/templates/placebo/ukko.mustache b/contrib/templates/placebo/ukko.mustache index 50d5e13..8303cda 100644 --- a/contrib/templates/placebo/ukko.mustache +++ b/contrib/templates/placebo/ukko.mustache @@ -31,6 +31,7 @@

CHANGOLIA

Most of the rest of the wild west. +
{{#prev}} From 5b8326745ce9eade00337f3ea3554d4df8283357 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 6 Nov 2018 15:15:51 -0500 Subject: [PATCH 02/14] fix build --- contrib/backends/srndv2/src/srnd/daemon.go | 4 +++- contrib/backends/srndv2/src/srnd/mod.go | 1 + contrib/backends/srndv2/src/srnd/mod_http.go | 5 +++-- contrib/backends/srndv2/src/srnd/spam.go | 6 ++++-- contrib/backends/srndv2/src/srnd/store.go | 6 ------ 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/contrib/backends/srndv2/src/srnd/daemon.go b/contrib/backends/srndv2/src/srnd/daemon.go index 69cd8c0..2a6b565 100644 --- a/contrib/backends/srndv2/src/srnd/daemon.go +++ b/contrib/backends/srndv2/src/srnd/daemon.go @@ -537,7 +537,9 @@ func (self *NNTPDaemon) ExpireAll() { func (self *NNTPDaemon) MarkSpam(msgid string) { if ValidMessageID(msgid) { - self.modEngine.MarkSpam(msgid) + if self.mod != nil { + self.mod.MarkSpam(msgid) + } } } diff --git a/contrib/backends/srndv2/src/srnd/mod.go b/contrib/backends/srndv2/src/srnd/mod.go index 19a387d..8223b05 100644 --- a/contrib/backends/srndv2/src/srnd/mod.go +++ b/contrib/backends/srndv2/src/srnd/mod.go @@ -215,6 +215,7 @@ func (self *modEngine) MarkSpam(msgid string) (err error) { if self.spam == nil { err = self.store.MarkSpam(msgid) } else { + var f io.ReadCloser f, err = self.store.OpenMessage(msgid) if err == nil { err = self.spam.MarkSpam(f) diff --git a/contrib/backends/srndv2/src/srnd/mod_http.go b/contrib/backends/srndv2/src/srnd/mod_http.go index 475cd5b..ea81baf 100644 --- a/contrib/backends/srndv2/src/srnd/mod_http.go +++ b/contrib/backends/srndv2/src/srnd/mod_http.go @@ -531,7 +531,8 @@ func (self httpModUI) HandlePostSpam(wr http.ResponseWriter, r *http.Request) { resp := make(map[string]interface{}) self.asAuthed("spam", func(path string) { var mm ModMessage - keys := string.Split(r.FormValue("spam"), ",") + var err error + keys := strings.Split(r.FormValue("spam"), ",") for _, k := range keys { k = strings.TrimSpace(k) go self.daemon.MarkSpam(k) @@ -552,7 +553,7 @@ func (self httpModUI) HandlePostSpam(wr http.ResponseWriter, r *http.Request) { } resp["error"] = err } - }) + }, wr, r) json.NewEncoder(wr).Encode(resp) } diff --git a/contrib/backends/srndv2/src/srnd/spam.go b/contrib/backends/srndv2/src/srnd/spam.go index 094a38e..70eab0f 100644 --- a/contrib/backends/srndv2/src/srnd/spam.go +++ b/contrib/backends/srndv2/src/srnd/spam.go @@ -36,7 +36,7 @@ type SpamResult struct { // feed spam subsystem a spam post func (sp *SpamFilter) MarkSpam(msg io.Reader) (err error) { - var buff [65636]byte + var buf [65636]byte var u *user.User u, err = user.Current() @@ -50,9 +50,11 @@ func (sp *SpamFilter) MarkSpam(msg io.Reader) (err error) { } defer conn.Close() fmt.Fprintf(conn, "TELL SPAMC/1.5\r\nUser: %s\r\nMessage-class: spam\r\nSet: local\r\n", u.Username) - io.CopyBuffer(conn, buf[:], msg) + io.CopyBuffer(conn, msg, buf[:]) conn.CloseWrite() r := bufio.NewReader(conn) + io.Copy(Discard, r) + return } func (sp *SpamFilter) openConn() (*net.TCPConn, error) { diff --git a/contrib/backends/srndv2/src/srnd/store.go b/contrib/backends/srndv2/src/srnd/store.go index 1adbe7b..d421e6c 100644 --- a/contrib/backends/srndv2/src/srnd/store.go +++ b/contrib/backends/srndv2/src/srnd/store.go @@ -95,12 +95,6 @@ type ArticleStore interface { // get filepath for spam file via msgid SpamFile(msgid string) string - MarkHam(msgid string) error - UnmarkHam(msgid string) error - - // get filepath for ham - HamFile(msgid string) string - // iterate over all spam messages IterSpam(func(string) error) error From cc4cee1322548246a79d51586a9485335d833173 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 6 Nov 2018 15:22:11 -0500 Subject: [PATCH 03/14] typofix --- contrib/static/overchan.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/static/overchan.js b/contrib/static/overchan.js index 6395b9b..253eb08 100644 --- a/contrib/static/overchan.js +++ b/contrib/static/overchan.js @@ -24,7 +24,7 @@ var nntpchan_mod_commit_spam = function(elem) { { if(posts[idx].dataset.spam == "yes") { - spams.push_back(posts[idx].dataset.msgid); + spams.push(posts[idx].dataset.msgid); } } formdata.set("spam", spams.join(",")); From 0e723979561d9141db009fe317468f8ccc9c030d Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 6 Nov 2018 15:28:02 -0500 Subject: [PATCH 04/14] more js crap --- contrib/static/overchan.js | 54 ++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/contrib/static/overchan.js b/contrib/static/overchan.js index 253eb08..94fb8ae 100644 --- a/contrib/static/overchan.js +++ b/contrib/static/overchan.js @@ -28,32 +28,48 @@ var nntpchan_mod_commit_spam = function(elem) { } } formdata.set("spam", spams.join(",")); - var ajax = new XMLHttpRequest(); - ajax.onreadystatechange = function() { - if(ajax.readyState == 4) + var jax = new XMLHttpRequest(); + jax.onreadystatechange = function() { + if(jax.readyState == 4) { - if(ajax.status == 200) + if(jax.status == 200) { - // success (?) - var j = JSON.parse(ajax.responseText); - if(j.error) - { - elem.innerText = "could not mark as spam: " + j.error; - } - else - { - elem.innerText = "OK: marked as spam"; - } + + var ajax = new XMLHttpRequest(); + ajax.setRequestHeader("X-CSRF-Token", jax.getResponseHeader("X-CSRF-Token")); + ajax.onreadystatechange = function() { + if(ajax.readyState == 4) + { + if(ajax.status == 200) + { + // success (?) + var j = JSON.parse(ajax.responseText); + if(j.error) + { + elem.innerText = "could not mark as spam: " + j.error; + } + else + { + elem.innerText = "OK: marked as spam"; + } + } + else + { + elem.innerText = "post not marked as spam on server: "+ ajax.statusText; + } + } + }; + ajax.open("POST", "/mod/spam") + ajax.send(formdata); } - else + else { - elem.innerText = "post not marked as spam on server: "+ ajax.statusText; + elem.innerText = "failed to moderate, not logged in"; } } }; - ajax.open("POST", "/mod/spam") - ajax.send(formdata); - + jax.open("GET", "/mod/"); + jax.send(); }; var nntpchan_mod_delete = function(longhash) { From 955efe33a1f32288ec1adddc30904bcbbe1a1c8e Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 6 Nov 2018 15:29:06 -0500 Subject: [PATCH 05/14] fug --- contrib/static/overchan.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/static/overchan.js b/contrib/static/overchan.js index 94fb8ae..46676fc 100644 --- a/contrib/static/overchan.js +++ b/contrib/static/overchan.js @@ -36,7 +36,6 @@ var nntpchan_mod_commit_spam = function(elem) { { var ajax = new XMLHttpRequest(); - ajax.setRequestHeader("X-CSRF-Token", jax.getResponseHeader("X-CSRF-Token")); ajax.onreadystatechange = function() { if(ajax.readyState == 4) { @@ -60,6 +59,7 @@ var nntpchan_mod_commit_spam = function(elem) { } }; ajax.open("POST", "/mod/spam") + ajax.setRequestHeader("X-CSRF-Token", jax.getResponseHeader("X-CSRF-Token")); ajax.send(formdata); } else From 57552f53e46ffe579c03fb2f5863c711ec8432f6 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 6 Nov 2018 15:41:15 -0500 Subject: [PATCH 06/14] actually use spamd --- contrib/backends/srndv2/src/srnd/daemon.go | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/backends/srndv2/src/srnd/daemon.go b/contrib/backends/srndv2/src/srnd/daemon.go index 2a6b565..4f9384a 100644 --- a/contrib/backends/srndv2/src/srnd/daemon.go +++ b/contrib/backends/srndv2/src/srnd/daemon.go @@ -1153,6 +1153,7 @@ func (self *NNTPDaemon) Setup() { } self.mod = &modEngine{ + spam: &self.spamFilter, store: self.store, database: self.database, regen: self.frontend.RegenOnModEvent, From c010b3f2c5d1ccf9303c451a0075cc4e7f4c52df Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 6 Nov 2018 15:44:57 -0500 Subject: [PATCH 07/14] more --- contrib/backends/srndv2/src/srnd/daemon.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/contrib/backends/srndv2/src/srnd/daemon.go b/contrib/backends/srndv2/src/srnd/daemon.go index 4f9384a..3d3ed28 100644 --- a/contrib/backends/srndv2/src/srnd/daemon.go +++ b/contrib/backends/srndv2/src/srnd/daemon.go @@ -538,7 +538,10 @@ func (self *NNTPDaemon) ExpireAll() { func (self *NNTPDaemon) MarkSpam(msgid string) { if ValidMessageID(msgid) { if self.mod != nil { - self.mod.MarkSpam(msgid) + err:= self.mod.MarkSpam(msgid) + if err != nil { + log.Println(err) + } } } } From 5c4eb739d6cc93d12de10951a99cd74e7554360d Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 6 Nov 2018 15:50:08 -0500 Subject: [PATCH 08/14] what --- contrib/backends/srndv2/src/srnd/daemon.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/contrib/backends/srndv2/src/srnd/daemon.go b/contrib/backends/srndv2/src/srnd/daemon.go index 3d3ed28..d095b6a 100644 --- a/contrib/backends/srndv2/src/srnd/daemon.go +++ b/contrib/backends/srndv2/src/srnd/daemon.go @@ -537,11 +537,9 @@ func (self *NNTPDaemon) ExpireAll() { func (self *NNTPDaemon) MarkSpam(msgid string) { if ValidMessageID(msgid) { - if self.mod != nil { - err:= self.mod.MarkSpam(msgid) - if err != nil { - log.Println(err) - } + err := self.mod.MarkSpam(msgid) + if err != nil { + log.Println(err) } } } From 515f42c664dc0af222b2e835c088bb77e10269cf Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 6 Nov 2018 15:58:21 -0500 Subject: [PATCH 09/14] eh --- contrib/backends/srndv2/src/srnd/mod_http.go | 48 ++++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/contrib/backends/srndv2/src/srnd/mod_http.go b/contrib/backends/srndv2/src/srnd/mod_http.go index ea81baf..35e4466 100644 --- a/contrib/backends/srndv2/src/srnd/mod_http.go +++ b/contrib/backends/srndv2/src/srnd/mod_http.go @@ -35,8 +35,8 @@ type httpModUI struct { cache CacheHandler } -func createHttpModUI(frontend *httpFrontend) httpModUI { - return httpModUI{frontend.regenAll, frontend.Regen, frontend.RegenerateBoard, frontend.deleteThreadMarkup, frontend.deleteBoardMarkup, make(chan NNTPMessage), frontend.daemon, frontend.daemon.store, frontend.store, frontend.prefix, frontend.prefix + "mod/", frontend.GetCacheHandler()} +func createHttpModUI(frontend *httpFrontend) *httpModUI { + return &httpModUI{frontend.regenAll, frontend.Regen, frontend.RegenerateBoard, frontend.deleteThreadMarkup, frontend.deleteBoardMarkup, make(chan NNTPMessage), frontend.daemon, frontend.daemon.store, frontend.store, frontend.prefix, frontend.prefix + "mod/", frontend.GetCacheHandler()} } @@ -44,7 +44,7 @@ func extractGroup(param map[string]interface{}) string { return extractParam(param, "newsgroup") } -func (self httpModUI) getAdminFunc(funcname string) AdminFunc { +func (self *httpModUI) getAdminFunc(funcname string) AdminFunc { if funcname == "template.reload" { return func(param map[string]interface{}) (interface{}, error) { tname, ok := param["template"] @@ -390,7 +390,7 @@ func (self httpModUI) HandleAdminCommand(wr http.ResponseWriter, r *http.Request }, wr, r) } -func (self httpModUI) CheckPubkey(pubkey, scope string) (bool, error) { +func (self *httpModUI) CheckPubkey(pubkey, scope string) (bool, error) { is_admin, err := self.daemon.database.CheckAdminPubkey(pubkey) if is_admin { // admin can do what they want @@ -413,7 +413,7 @@ func (self httpModUI) CheckPubkey(pubkey, scope string) (bool, error) { return false, err } -func (self httpModUI) CheckKey(privkey, scope string) (bool, error) { +func (self *httpModUI) CheckKey(privkey, scope string) (bool, error) { privkey_bytes, err := hex.DecodeString(privkey) if err == nil { pk, _ := naclSeedToKeyPair(privkey_bytes) @@ -424,17 +424,17 @@ func (self httpModUI) CheckKey(privkey, scope string) (bool, error) { return false, err } -func (self httpModUI) MessageChan() chan NNTPMessage { +func (self *httpModUI) MessageChan() chan NNTPMessage { return self.modMessageChan } -func (self httpModUI) getSession(r *http.Request) *sessions.Session { +func (self *httpModUI) getSession(r *http.Request) *sessions.Session { s, _ := self.store.Get(r, "nntpchan-mod") return s } // get the session's private key as bytes or nil if we don't have it -func (self httpModUI) getSessionPrivkeyBytes(r *http.Request) []byte { +func (self *httpModUI) getSessionPrivkeyBytes(r *http.Request) []byte { s := self.getSession(r) k, ok := s.Values["privkey"] if ok { @@ -451,7 +451,7 @@ func (self httpModUI) getSessionPrivkeyBytes(r *http.Request) []byte { // returns true if the session is okay for a scope // otherwise redirect to login page -func (self httpModUI) checkSession(r *http.Request, scope string) bool { +func (self *httpModUI) checkSession(r *http.Request, scope string) bool { s := self.getSession(r) k, ok := s.Values["privkey"] if ok { @@ -464,11 +464,11 @@ func (self httpModUI) checkSession(r *http.Request, scope string) bool { return false } -func (self httpModUI) writeTemplate(wr http.ResponseWriter, r *http.Request, name string) { +func (self *httpModUI) writeTemplate(wr http.ResponseWriter, r *http.Request, name string) { self.writeTemplateParam(wr, r, name, nil) } -func (self httpModUI) writeTemplateParam(wr http.ResponseWriter, r *http.Request, name string, param map[string]interface{}) { +func (self *httpModUI) writeTemplateParam(wr http.ResponseWriter, r *http.Request, name string, param map[string]interface{}) { if param == nil { param = make(map[string]interface{}) } @@ -481,7 +481,7 @@ func (self httpModUI) writeTemplateParam(wr http.ResponseWriter, r *http.Request // do a function as authenticated // pass in the request path to the handler -func (self httpModUI) asAuthed(scope string, handler func(string), wr http.ResponseWriter, r *http.Request) { +func (self *httpModUI) asAuthed(scope string, handler func(string), wr http.ResponseWriter, r *http.Request) { if self.checkSession(r, scope) { handler(r.URL.Path) } else { @@ -490,7 +490,7 @@ func (self httpModUI) asAuthed(scope string, handler func(string), wr http.Respo } // do stuff to a certain message if with have it and are authed -func (self httpModUI) asAuthedWithMessage(scope string, handler func(ArticleEntry, *http.Request) map[string]interface{}, wr http.ResponseWriter, req *http.Request) { +func (self *httpModUI) asAuthedWithMessage(scope string, handler func(ArticleEntry, *http.Request) map[string]interface{}, wr http.ResponseWriter, req *http.Request) { self.asAuthed(scope, func(path string) { // get the long hash if strings.Count(path, "/") > 2 { @@ -523,7 +523,7 @@ func (self httpModUI) asAuthedWithMessage(scope string, handler func(ArticleEntr }, wr, req) } -func (self httpModUI) HandlePostSpam(wr http.ResponseWriter, r *http.Request) { +func (self *httpModUI) HandlePostSpam(wr http.ResponseWriter, r *http.Request) { if r.Method != "POST" { wr.WriteHeader(405) return @@ -557,13 +557,13 @@ func (self httpModUI) HandlePostSpam(wr http.ResponseWriter, r *http.Request) { json.NewEncoder(wr).Encode(resp) } -func (self httpModUI) HandleAddPubkey(wr http.ResponseWriter, r *http.Request) { +func (self *httpModUI) HandleAddPubkey(wr http.ResponseWriter, r *http.Request) { } -func (self httpModUI) HandleDelPubkey(wr http.ResponseWriter, r *http.Request) { +func (self *httpModUI) HandleDelPubkey(wr http.ResponseWriter, r *http.Request) { } -func (self httpModUI) HandleUnbanAddress(wr http.ResponseWriter, r *http.Request) { +func (self *httpModUI) HandleUnbanAddress(wr http.ResponseWriter, r *http.Request) { self.asAuthed("ban", func(path string) { // extract the ip address // TODO: ip ranges and prefix detection @@ -593,7 +593,7 @@ func (self httpModUI) HandleUnbanAddress(wr http.ResponseWriter, r *http.Request } // handle ban logic -func (self httpModUI) handleBanAddress(msg ArticleEntry, r *http.Request) map[string]interface{} { +func (self *httpModUI) handleBanAddress(msg ArticleEntry, r *http.Request) map[string]interface{} { // get the article headers resp := make(map[string]interface{}) msgid := msg.MessageID() @@ -657,7 +657,7 @@ func (self httpModUI) handleBanAddress(msg ArticleEntry, r *http.Request) map[st return resp } -func (self httpModUI) handleDeletePost(msg ArticleEntry, r *http.Request) map[string]interface{} { +func (self *httpModUI) handleDeletePost(msg ArticleEntry, r *http.Request) map[string]interface{} { var mm ModMessage resp := make(map[string]interface{}) msgid := msg.MessageID() @@ -706,16 +706,16 @@ func (self httpModUI) handleDeletePost(msg ArticleEntry, r *http.Request) map[st } // ban the address of a poster -func (self httpModUI) HandleBanAddress(wr http.ResponseWriter, r *http.Request) { +func (self *httpModUI) HandleBanAddress(wr http.ResponseWriter, r *http.Request) { self.asAuthedWithMessage("ban", self.handleBanAddress, wr, r) } // delete a post -func (self httpModUI) HandleDeletePost(wr http.ResponseWriter, r *http.Request) { +func (self *httpModUI) HandleDeletePost(wr http.ResponseWriter, r *http.Request) { self.asAuthedWithMessage("login", self.handleDeletePost, wr, r) } -func (self httpModUI) HandleLogin(wr http.ResponseWriter, r *http.Request) { +func (self *httpModUI) HandleLogin(wr http.ResponseWriter, r *http.Request) { privkey := r.FormValue("privkey") msg := "failed login: " if len(privkey) == 0 { @@ -736,13 +736,13 @@ func (self httpModUI) HandleLogin(wr http.ResponseWriter, r *http.Request) { self.writeTemplateParam(wr, r, "modlogin_result", map[string]interface{}{"message": msg, csrf.TemplateTag: csrf.TemplateField(r)}) } -func (self httpModUI) HandleKeyGen(wr http.ResponseWriter, r *http.Request) { +func (self *httpModUI) HandleKeyGen(wr http.ResponseWriter, r *http.Request) { pk, sk := newNaclSignKeypair() tripcode := makeTripcode(pk) self.writeTemplateParam(wr, r, "keygen", map[string]interface{}{"public": pk, "secret": sk, "tripcode": tripcode}) } -func (self httpModUI) ServeModPage(wr http.ResponseWriter, r *http.Request) { +func (self *httpModUI) ServeModPage(wr http.ResponseWriter, r *http.Request) { if self.checkSession(r, "login") { wr.Header().Set("X-CSRF-Token", csrf.Token(r)) // we are logged in From 2265b4b2ae59efc44127e2d4b45f0344c62e8385 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 6 Nov 2018 16:03:44 -0500 Subject: [PATCH 10/14] more --- contrib/backends/srndv2/src/srnd/daemon.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contrib/backends/srndv2/src/srnd/daemon.go b/contrib/backends/srndv2/src/srnd/daemon.go index d095b6a..2c11ae1 100644 --- a/contrib/backends/srndv2/src/srnd/daemon.go +++ b/contrib/backends/srndv2/src/srnd/daemon.go @@ -546,7 +546,6 @@ func (self *NNTPDaemon) MarkSpam(msgid string) { // run daemon func (self *NNTPDaemon) Run() { - self.spamFilter.Configure(self.conf.spamconf) self.bind_addr = self.conf.daemon["bind"] listener, err := net.Listen("tcp", self.bind_addr) @@ -1152,6 +1151,8 @@ func (self *NNTPDaemon) Setup() { self.frontend = NewHTTPFrontend(self, self.cache, self.conf.frontend, self.conf.worker["url"]) } + + self.spamFilter.Configure(self.conf.spamconf) self.mod = &modEngine{ spam: &self.spamFilter, From 57f431ffd28d4108a85cf8b89af79df45a179c31 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 6 Nov 2018 16:09:46 -0500 Subject: [PATCH 11/14] more --- contrib/backends/srndv2/src/srnd/spam.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/backends/srndv2/src/srnd/spam.go b/contrib/backends/srndv2/src/srnd/spam.go index 70eab0f..ca940d9 100644 --- a/contrib/backends/srndv2/src/srnd/spam.go +++ b/contrib/backends/srndv2/src/srnd/spam.go @@ -49,7 +49,7 @@ func (sp *SpamFilter) MarkSpam(msg io.Reader) (err error) { return } defer conn.Close() - fmt.Fprintf(conn, "TELL SPAMC/1.5\r\nUser: %s\r\nMessage-class: spam\r\nSet: local\r\n", u.Username) + fmt.Fprintf(conn, "TELL SPAMC/1.5\r\nUser: %s\r\nMessage-class: spam\r\nSet: local\r\n\r\n", u.Username) io.CopyBuffer(conn, msg, buf[:]) conn.CloseWrite() r := bufio.NewReader(conn) From c89c06e15dcbbcab22151bd3b06a0d9da8a3721a Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 6 Nov 2018 16:25:01 -0500 Subject: [PATCH 12/14] fix --- contrib/backends/srndv2/src/srnd/spam.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/backends/srndv2/src/srnd/spam.go b/contrib/backends/srndv2/src/srnd/spam.go index ca940d9..c7f788d 100644 --- a/contrib/backends/srndv2/src/srnd/spam.go +++ b/contrib/backends/srndv2/src/srnd/spam.go @@ -49,7 +49,7 @@ func (sp *SpamFilter) MarkSpam(msg io.Reader) (err error) { return } defer conn.Close() - fmt.Fprintf(conn, "TELL SPAMC/1.5\r\nUser: %s\r\nMessage-class: spam\r\nSet: local\r\n\r\n", u.Username) + fmt.Fprintf(conn, "TELL SPAMC/1.5\r\nUser: %s\r\nMessage-class: spam\r\nSet: local,remote\r\n\r\n", u.Username) io.CopyBuffer(conn, msg, buf[:]) conn.CloseWrite() r := bufio.NewReader(conn) From ad07b95d96147e09416ebc85593fe042c7582cb3 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 6 Nov 2018 16:34:55 -0500 Subject: [PATCH 13/14] no --- contrib/backends/srndv2/src/srnd/spam.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/backends/srndv2/src/srnd/spam.go b/contrib/backends/srndv2/src/srnd/spam.go index c7f788d..ca940d9 100644 --- a/contrib/backends/srndv2/src/srnd/spam.go +++ b/contrib/backends/srndv2/src/srnd/spam.go @@ -49,7 +49,7 @@ func (sp *SpamFilter) MarkSpam(msg io.Reader) (err error) { return } defer conn.Close() - fmt.Fprintf(conn, "TELL SPAMC/1.5\r\nUser: %s\r\nMessage-class: spam\r\nSet: local,remote\r\n\r\n", u.Username) + fmt.Fprintf(conn, "TELL SPAMC/1.5\r\nUser: %s\r\nMessage-class: spam\r\nSet: local\r\n\r\n", u.Username) io.CopyBuffer(conn, msg, buf[:]) conn.CloseWrite() r := bufio.NewReader(conn) From 795fcbe37ce1cf030c5ffdb6d83ecc6a64137b7f Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 6 Nov 2018 16:47:56 -0500 Subject: [PATCH 14/14] disable spamtell for now --- contrib/backends/srndv2/src/srnd/daemon.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/backends/srndv2/src/srnd/daemon.go b/contrib/backends/srndv2/src/srnd/daemon.go index 2c11ae1..d8ec4b0 100644 --- a/contrib/backends/srndv2/src/srnd/daemon.go +++ b/contrib/backends/srndv2/src/srnd/daemon.go @@ -1155,7 +1155,7 @@ func (self *NNTPDaemon) Setup() { self.spamFilter.Configure(self.conf.spamconf) self.mod = &modEngine{ - spam: &self.spamFilter, + //spam: &self.spamFilter, store: self.store, database: self.database, regen: self.frontend.RegenOnModEvent,