summaryrefslogtreecommitdiff
path: root/mulkcms.lisp
diff options
context:
space:
mode:
Diffstat (limited to 'mulkcms.lisp')
-rw-r--r--mulkcms.lisp88
1 files changed, 66 insertions, 22 deletions
diff --git a/mulkcms.lisp b/mulkcms.lisp
index 3bef1f5..40bfc92 100644
--- a/mulkcms.lisp
+++ b/mulkcms.lisp
@@ -29,6 +29,11 @@
(random #x1000000000000)))
+(defun hashcash-hash-validp (text)
+ (let ((digest (ironclad:digest-sequence 'ironclad:sha256 (flexi-streams:string-to-octets text))))
+ (every #'zerop (subseq digest 0 2))))
+
+
(defun find-canonical-article-alias (article)
(query "SELECT alias FROM article_aliases WHERE article = $1 LIMIT 1"
article
@@ -133,16 +138,18 @@
:submit-button-label "Submit"
:title "Submit a comment"
:notes "<p><strong>Note:</strong>
- This website uses <a
- href=\"http://akismet.com/\">Akismet</a>
+ This website uses <span
+ class='spam-detection-method'><a
+ href=\"http://akismet.com/\">Akismet</a></span>
for spam detection.
E-mail addresses are never
- disclosed to
- anyone (including Akismet)
- other than the site owner.
- Comment format is plain
- text. Use blank lines to
- separate paragraphs.</p>"
+ disclosed to anyone <span
+ class='irrelevant-for-hashcash'>(including
+ Akismet)</span> other than
+ the site owner. Comment
+ format is plain text. Use
+ blank lines to separate
+ paragraphs.</p>"
:action (link-to :post-comment :article-id article)))
:edit-link (link-to :edit :article-id article)
:edit-button-label "Edit"
@@ -665,12 +672,18 @@
:link ""))
(submission-notice nil))
(when (assoc "post-comment" params :test #'equal)
- (let ((name (cdr (assoc "name" params :test #'equal)))
- (website (cdr (assoc "website" params :test #'equal)))
- (email (cdr (assoc "email" params :test #'equal)))
- (body (cdr (assoc "body" params :test #'equal)))
- (article (cdr (assoc "article" params :test #'equal)))
- (revision (cdr (assoc "revision" params :test #'equal))))
+ (let* ((name (cdr (assoc "name" params :test #'equal)))
+ (website (cdr (assoc "website" params :test #'equal)))
+ (email (cdr (assoc "email" params :test #'equal)))
+ (body (cdr (assoc "body" params :test #'equal)))
+ (article (cdr (assoc "article" params :test #'equal)))
+ (revision (cdr (assoc "revision" params :test #'equal)))
+ (tkey (cdr (assoc "transaction-key" params :test #'equal)))
+ (salt (cdr (assoc "salt" params :test #'equal)))
+ (spam-p (or (null tkey)
+ (null salt)
+ (not (hashcash-hash-validp
+ (format nil "~A:~A:~A" body tkey salt))))))
(with-transaction ()
(let ((comment (query "INSERT INTO comments(article, global_id)
VALUES ($1, $2)
@@ -685,22 +698,44 @@
email
website
:single!)))
+ (when tkey
+ (query "INSERT INTO used_transaction_keys(key) VALUES ($1)"
+ tkey
+ :none))
(query "INSERT INTO comment_revisions(comment, content, author, format, status, article_revision, submitter_ip, submitter_user_agent)
- VALUES ($1, $2, $3, 'text', 'pending', $4, $5, $6)"
+ VALUES ($1, $2, $3, 'text', $4, $5, $6, $7)"
comment
body
author
+ (if spam-p
+ "pending"
+ "spam")
revision
(hunchentoot:real-remote-addr)
(hunchentoot:user-agent)
:none)
(setq submission-notice
- "<p><strong>Note:</strong></p>
-
- <p>Your message has been received and put
- into the moderation queue. It is now
- waiting for approval by one of the site's
- administrators.</p>")))))
+ (cond
+ (spam-p "<p><strong>Warning:</strong></p>
+
+ <p>Your message could not be
+ verified as non-spam. If
+ JavaScript is enabled in your
+ browser, it may be broken in
+ some way. In this case, please
+ disable JavaScript support and
+ try again. Otherwise, feel free
+ to contact one of the site
+ administrators, who will be able
+ to manually approve your
+ comment.</p>")
+ (t "<p><strong>Note:</strong></p>
+
+ <p>Your message has been received and
+ classified as non-spam. It has thus
+ been put into the moderation queue and
+ is now awaiting approval by one of the
+ site's administrators.</p>")))))))
(expand-page page-template
(getf article-params :title)
(list* :articles (list article-params)
@@ -711,6 +746,14 @@
+(defun find-transaction-key-handler (path)
+ (when (string= path "RPC/generate-transaction-key")
+ (lambda ()
+ (with-db
+ (setf (hunchentoot:content-type*) "text/plain; charset=utf-8")
+ (format nil "~D" (query "SELECT nextval('transaction_key_seq')" :single!))))))
+
+
(defun keywordify (thing)
(intern (string-upcase (format nil "~A" thing)) "KEYWORD"))
@@ -730,4 +773,5 @@
(cond ((assoc "edit" params :test #'equal) :edit)
((assoc "comment-feed" params :test #'equal) :view-comment-feed)
((assoc "atom" params :test #'equal) :view-atom-entry)
- (t :view)))))
+ (t :view)))
+ (find-transaction-key-handler path)))